ffmpeg -list_devices true -f dshow -i dummy
USB2.0 PC CAMERA
ffplay -ar 16000 -channels 1 -f s16le -i xxx.pcm
ffplay -f rawvideo -video_size 1280x720 xxx.yuv
ffmpeg -r 25 -f dshow -s 640x480 -i video="USB2.0 PC CAMERA":audio="麦克风 (USB2.0 MIC)" -vcodec libx264 -b 600k -acodec libvo_aacenc -channels 1 -ab 128k -f flv rtmp://192.168.1.2/record/pi
ffmpeg -f dshow -i video="USB2.0 PC CAMERA":audio="麦克风 (USB2.0 MIC)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -acodec libvo_aacenc -channels 1 -ab 128k -f flv rtmp://192.168.1.2/record/pi
av_rescale_q(a,b,c)是用来把时间戳从一个时基调整到另外一个时基时候用的函数。它基本的动作是计算a*b/c
参看最新版本的ffmpeg,av_read_frame是对av_read_packet的封装,它就是frame不是packet 。需要对ffmpeg里面的几个概念澄清一下:
frame:是指直观上完整的视频帧或音频帧,注意可以指视频也可以指音频,一般是未解码的;
packet:是形式上的概念,指视频或音频的包,这里的包未必是完整的完整的视频帧或音频帧,可能是一帧视频的一部分。
picture:指直观上完整图象,只能指视频,简言之,picture是解压后的视频frame;
特别要区分frame和packet。frame很好理解,直观的帧。但frame有两个问题:一是每个压缩后的frame通常都比较大,特别是视频;二是每个frame的压缩后的大小都不一样; 这两个原因都使frame不便于存储和传输,所以就引入了packet的概念。
packet是文件容器和传递层面的一个技术概念,而frame是一般人都能理解的直观概念。对于视频,一个frame通常会被划分为等大的多个packet,但是它们的时间戮是相同的。
ffmpeg中av_read_frame读出的完整的帧,不是包,在函数内部已经保证了帧的完整性。对于视频,av_read_frame读出的就是完整的一帧视频,不会是半帧或多帧;对于音频,av_read_frame读出的可能是多帧,但也是完整的,不存在半帧的情况。
av_rescale_rnd a*b/c
filter 语法
; 表示不同线路的filter
, 表示同一个线路的filter
: 分割同一个filter中的参数,
If the option value itself is a list of items (e.g. the format filter takes a list of pixel formats), the items in the list are usually separated by ’|’.
A filter with no input pads is called a "source", a filter with no output pads is called a "sink".
AVFormatContext = {AVInputFormat, AVOutputFormat, AVIOContext};
AVIOContext = {read, write, seek}
AVInputFormat = {read_header,read_packet,read_close,read_seek};
AVOutputFormat = {write_header, write_packet, write_trailer, interleave_packet}
URLContext = {interrupt_callback, rw_timeout}
URLProtocol = {url_read, url_write, url_seek, url_close}
libavdevices 其实就是muxer/demuxer 归到avformat里
格式回归协议:(format - avio context)
AVFormatContext <<--- avformat_open_input -> avio_open2 {ffurl_open 关联了URLContext; ffio_fdopen 生成了AVIOContext; 并且把URLProtocol某些成员的信息赋值给AVIOContext.} -> av_probe_input_buffer 获取其他信息 ->avio_read->AVIOContext->
av_read_packet --->> s->iformat->read_packet(AVFormatContext*, pkt) ->调用avio_r8(ctx->pb,); 绕了半天format终于回归avioctx;
av_write_packet -->> av_write_frame -> ctx->oformat->write_packet -> 调用avio_w8(ctx->pb,);
AVIOContext <<----->> AVInputFormat \ AVOutputFormat
*s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
(void*)ffurl_read, (void*)ffurl_write, (void*)ffurl_seek);
ffmpeg accelerate http://stackoverflow.com/questions/23289157/how-to-use-hardware-acceleration-with-ffmpeg
mac:
avcodec_find_decoder_by_name("h264_vda");
linux:
avcodec_find_decoder_by_name("h264_vdpau");
avcodec_find_decoder_by_name("h264_vaapi")