libav 制作视频

https://github.com/shaobin0604/ffmpeg_tutorial

https://github.com/mpenkov/ffmpeg-tutorial

http://dranger.com/ffmpeg/

http://en.wikipedia.org/wiki/YUV

http://en.wikipedia.org/wiki/.mpg

代码:

git clone  git@github.com:liyonghelpme2/libavTest.git

 

libav 是一系列 编码解码 音频 图像 视频的库。

ubuntu 上 apt-get source libav 得到源码。

基本模块包含: libavcodec  libavformat libavutil libavdevice 等。

    安装好这些模块之后, 在 /usr/share/doc/libavcodec-dev/ 文件夹下有一个例子,

     在源代码文件夹中有一个avplay.c 的例子,

参考这两个例子 以及 一些tutorials 和 源代码,写一个将 RGB 值 转化成 视频程序。

主要参考  /usr/share/doc/libavcodec-dev/ 下的例子:

在其中有一个 video_encode_example 的函数, 该函数将 程序生成的一段数据  构造一个视频, 可以将该函数拷到新文件中, 同时写一个main函数,

在main函数中首先注册所有的 codec 解码编码器, 接着调用video_encode_example 函数生成一个mpg 视频。

#include<libavcodec/avcodec.h>

#include<libavformat/avformat.h>

av_register_all();

video_encode_example();

gcc xxx.c -lavcodec -lavformat

 

这个程序使用MPEG1VIDEO 编码解码器 将 YUV 空间的帧 转化成 一个MPEG1 标准的视频, YUV 和熟悉的RGB 颜色空间 之间通过一个矩阵进行转化, 关于YUV 参考http://en.wikipedia.org/wiki/YUV

一个MPEG文件可能包含多个流stream 音频, 视频, 字幕等。每个流包含多个帧frame,有关键帧,向后预测帧向前预测帧等。参考MPEG  http://en.wikipedia.org/wiki/.mpg

 

将程序中生成的一帧帧图像 压入视频中基本过程:

分配编码解码器:

    分配codec 编码解码器 分配codec的上下文(编码解码的过程是一个执行状态机的过程,上下文中会保存当前编码解码的状态)AVCodec AVCodecContext

avcodec_alloc_context3

   设定上下文中的格式信息,包括视频的宽度 高度, bitrate, 帧率,每帧的像素格式等;

   设定好上下文之后,可以在该上下文环境下,打开编码解码器,开始编码解码工作;avcodec_open

 

接着逐帧生成视频:

    分配帧结构 和 帧数据缓冲区 用于放每一帧的YUV数据  AVFrame    avcodec_alloc_frame    picture_buf = malloc()

    分配输出video 文件的缓冲区,out_buf = malloc(), 这个buffer 需要足够空间用于容纳一帧  outbuf_size 缓冲的大小

    生成 40帧:每一帧压入视频中avcodec_encode_video, 接者将生成的数据写入到文件中, 循环压入下一帧。mpeg格式中 多个帧之间是存在一定关系的,因此压入某一帧生成的数据量是不一定的,但是当前生成的数据是独立的,可以写入文件中。(个人理解)

 

 生成每一帧的YUV,对于RGB值比较好理解,例如要生成红色的 就是255 0 0 需要转化成对应的 YUV值, 在 libavutil 的colorspace头文件中有 RGB_TO_Y_CCIR 等函数用于转化代码 用于从RGB  空间转化到 YUV空间。

   其中YUV 空间的 Y 空间宽度 高度是屏幕宽度高度,而UV 空间每个点的值是2*2矩阵点的平均值,因此数据宽度,高度只有Y的1半。而这3个通道的数据是放在3个不同的plane中的,可以参考avpicture_fill 函数的实现,这个函数实现了,设置每种类型图片buffer的填充。

   在pixdesc.c 文件中的AVPixFmtDescriptor 中描述了每种帧格式缓冲区数据的放置方法,主要结构是AVPixFmtDescriptor

 

可以参考上方代码,制作显示红绿蓝条的视频 

 

 

 

 

 

 

 

 

posted @ 2012-12-25 22:58  liyonghelpme  阅读(193)  评论(0编辑  收藏  举报