https://github.com/shaobin0604/ffmpeg_tutorialgit
https://github.com/mpenkov/ffmpeg-tutorialgithub
http://dranger.com/ffmpeg/ubuntu
http://en.wikipedia.org/wiki/YUVide
http://en.wikipedia.org/wiki/.mpg函數
代碼:編碼
git clone git@github.com:liyonghelpme2/libavTest.gitspa
libav 是一系列 編碼解碼 音頻 圖像 視頻的庫。code
ubuntu 上 apt-get source libav 獲得源碼。orm
基本模塊包含: 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
能夠參考上方代碼,製做顯示紅綠藍條的視頻