参考源代码中 libformat/output-example.c
参考代码 libavcodec/api-example.c 例子
http://howto-pages.org/ffmpeg/
http://en.wikipedia.org/wiki/Mpeg4
一个完整的视频包含 video 和 audio 两部分,采用不同的压缩算法,再采用某种方法将两个流压入到一个container 中, 从而组成一个完成的视频。
因此一个叫做xxx.mp4 的文件,表示的是如何将两个流数据压入container中的方法,而这个容器内部的视频流,音频流采用的是其它的压缩算法。
常见的视频压缩算法:H.263, H.264, Mpeg4 simple profile
其中android 支持播放 Mpeg4 simple profile, 并且libav 也可以直接生成mpeg4 simple profile 格式的视频,因此以这种视频格式为例子。
视频录制分成3个步骤:
初始化资源,写入视频头;
读取显卡数据,逐帧压入到流中;
释放资源,写入视频尾。
。
首先分析需要什么资源:
需要输出的文件的格式等信息 AVFormatContext
需要给输出文件 加入一个视频流 AVStream
对于一个视频流 需要 一个编码器 用来存放编码器的状态 AVCodecContext
编码器有对应的算法实现 AVCodec
需要一个buffer 临时存放编码的结果
需要一个AVFrame 用来存放没有被压缩的视频数据 通常格式是YUV420
需要一个buffer 实际存放 没有压缩的视频数据
初始化的流程:
建立AVFormatContext
添加流 AVStream
设置流的AVCodecContext 编码器状态
打开输出文件
压缩过程:
glReadPixel 读取显卡数据
sws_scale() 转化数据格式 从RGB 到 YUV
编码数据 avcodec_encode_video()
建立一个AVPacket 指向编码后的数据 和 流的编号
将AVPacket 写入container 中。
清理过程:
写入文件尾部
释放编码器
释放AVFrame
释放AVStream
释放AVFormatContext
关闭输出文件