FFmpeg伪解复用
通常我们从音视频角度来看,muxer
是把多个视频流,多个音频流封装在一个文件里面,例如把 H.264
跟 aac
数据封装在 mp4 里面,所以 mp4
是一种封装格式。
解析 mp4
格式,提取出来 H.264
或者 aac
数据,这个过程叫做 demuxer
(解复用)。flv
也是一种封装格式,也有 demuxer
解复用。
但是,在 FFmpeg 的 API 函数的角度来看,demuxer
不只是 flv
,mp4
这些常规的封装格式。FFmpeg 为了 API 函数使用起来比较统一,他弄了一个伪解复用的东西出来。
你在命令行里,也可以使用 pcm
,yuv
,或者 h.264
的数据作为输入,如下:
提示:素材可以在 百度网盘 进行下载。
ffmpeg -s 480x270 -pix_fmt yuv420p -f rawvideo -i juren-2s.yuv -c:v h264 -f mp4 juren-2s.mp4
ffmpeg -ar 48000 -ac 2 -f s16le -i juren-5s.pcm -c:a aac -f mp4 juren-5s.mp4
ffmpeg -f h264 -i juren-6s.h264 -c:v copy -f mp4 juren-6s.mp4
ffmpeg -f mp4 -i juren-6s.mp4 -c:v copy -f flv juren-6s.flv
其实从音视频标准格式来看,yuv
,pcm
都是原始数据,并不是一种封装格式。而 H.264 是编码后的裸数据,严格来说也不算是 muxer
。
但是 FFmpeg 依然为 yuv
设计了一个 rawvideo
解复用器,为 pcm
设计了一个 s16le
解复用器 ,如下:
可以看到,rawvideo
这个 demuxer
的实现是 rawvideodec.c
,这个文件是放在 libavformat
目录下的,跟 flv
,mp4
的实现放在同一个目录。
av_read_frame()
函数会从 rawvideo
里面读取到一个 AVPacket
,然后丢给 伪解码器,进而拿到 AVFrame
,伪解码器的实现在 libavcodec/rawdec.c
,如下:
在 ffmpeg.c
里面,对 yuv
数据进行 demuxer
跟 对 mp4
进行 demuxer
的函数调用流程是完全一样的,这样使用跟理解起来比较简单。
TODO:这里补充一个 yuv,pcm,h.264 的代码示例加深理解。