FFMPEG源码分析(二)
ffmpeg源碼分析之數據流
本文主要介紹ffmpeg的數據流,在ffmpeg中主要分有三個主要用途用于媒體流的解碼播放,媒體流的轉換(解碼之后再編碼)和媒體流錄制。
媒體流的解碼播放
在ffmpeg中媒體流的解碼播放流程如下圖:
其主要流程為從媒體文件中讀取出媒體流,然后送入媒體格式解碼器(demuxer)中去除多余的外衣--媒體格式。然后送入ffmpeg的codec的decode中進行解碼,最終生成顯示需要的YUV格式的圖片,然后再送入類似SDL中進行渲染。ffmpeg中媒體流的解碼播放流程相對比較來說其最大的難點在于pts的同步,在ffmpeg的ffplay中有很好的例子。例子中是啟動了多個線程來進行同步的。
媒體流的轉換
所謂媒體流的轉換分以下幾種情況:
一種是格式轉換,也相當于我們平時的換衣服一樣,只是換個樣式,換一種組織樣式以適應不同場合的需要。
一種是媒體編碼類型的轉換,例如將codec從mpeg4 to H264相當于不同的人來買同一個衣服,雖然外表(格式)看起來一樣但穿衣服的人已經發生了變化。
一種是媒體編碼類型和格式同時轉換,例如將格式為flv的轉換為mpeg4,同時將codec從mpeg4 to H264相當于不同的人穿了不同的衣服。
其流程如下圖:
其數據流前半部分同解碼流程一樣,后半部分則和解碼的流程相反。當解析出YUV圖片之后,然后編碼成另外一種codec,之后再將codec的數據加上一個外殼形成一個媒體文件然后通過byteIocontext寫入目標文件。
媒體流錄制
媒體流的錄制過程相當于媒體流轉換的后半部分流程從YUV文件到media文件。其流程為:
?
FFMPEG中的decoder的組織形式:
FFMPEG中codec的數據結構如下:
typedef struct AVCodec {
???? const char *name;
??? enum AVMediaType type;
??? enum CodecID id;
??? int priv_data_size;
??? int (*init)(AVCodecContext *);
??? int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
??? int (*close)(AVCodecContext *);
??? int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
??? int capabilities;
??? struct AVCodec *next;
??? void (*flush)(AVCodecContext *);
??? const AVRational *supported_framerates;
??? const enum PixelFormat *pix_fmts;??????
??? const char *long_name;
??? const int *supported_samplerates;??????
??? const enum SampleFormat *sample_fmts;??
??? const int64_t *channel_layouts;????????
} AVCodec;
這個數據結構分別用于decoder和encoder,當被decoder所用時函數指針encode為NULL,而當用于encode時其decode為NULL,在ffmpeg中通過向全局變量
static AVCodec *first_avcodec;
中添加新的codec變量。在查找的過程也是通過遍歷這個鏈表然后通過name來匹配相應的codec這個過程將會在以后的文章中詳細描述。在ffmpeg中formate的組織結構和codec類似。
版權所有:博水。轉載請注明出處:http://www.cnblogs.com/qingquan/
轉載于:https://www.cnblogs.com/qingquan/archive/2011/08/29/2158912.html
總結
以上是生活随笔為你收集整理的FFMPEG源码分析(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一起谈.NET技术,从.NET中委托写法
- 下一篇: HTML 5 Web Socket:下一