參考源代碼中 libformat/output-example.c android
參考代碼 libavcodec/api-example.c 例子 算法
http://howto-pages.org/ffmpeg/ api
http://en.wikipedia.org/wiki/Mpeg4 ide
一個完整的視頻包含 video 和 audio 兩部分,採用不一樣的壓縮算法,再採用某種方法將兩個流壓入到一個container 中, 從而組成一個完成的視頻。 編碼
所以一個叫作xxx.mp4 的文件,表示的是如何將兩個流數據壓入container中的方法,而這個容器內部的視頻流,音頻流採用的是其它的壓縮算法。 spa
常見的視頻壓縮算法:H.263, H.264, Mpeg4 simple profile code
其中android 支持播放 Mpeg4 simple profile, 而且libav 也能夠直接生成mpeg4 simple profile 格式的視頻,所以以這種視頻格式爲例子。 orm
視頻錄製分紅3個步驟: 視頻
初始化資源,寫入視頻頭; ip
讀取顯卡數據,逐幀壓入到流中;
釋放資源,寫入視頻尾。
。
首先分析須要什麼資源:
須要輸出的文件的格式等信息 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
關閉輸出文件