ffmpeg庫函式介紹
av_register_all()
呼叫了avcodec_register_all()。avcodec_register_all()註冊了和編解碼器有關的元件:硬體加速器,解碼器,編碼器,Parser,Bitstream Filter。av_register_all()除了呼叫avcodec_register_all()之外,還註冊了複用器,解複用器,協議處理器。
AVFormatContext:統領全域性的基本結構體。主要用於處理封裝格式(FLV/MKV/RMVB等)。
AVIOContext:輸入輸出對應的結構體,用於輸入輸出(讀寫檔案,RTMP
AVStream,AVCodecContext:視音訊流對應的結構體,用於視音訊編解碼。
AVFrame:儲存非壓縮的資料(視訊對應RGB/YUV畫素資料,音訊對應PCM取樣資料)
AVPacket:儲存壓縮資料(視訊對應H.264等碼流資料,音訊對應AAC/MP3等碼流資料)
1. int avformat_open_input(AVFormatContext **ps, const char *filename,
2.
函式用於開啟多媒體資料並且獲得一些相關的資訊。
來自 <http://blog.csdn.net/leixiaohua1020/article/details/44064715
ps:函式呼叫成功之後處理過的AVFormatContext結構體。
file:開啟的視音訊流的URL。
fmt:強制指定AVFormatContext中AVInputFormat的。這個引數一般情況下可以設定為NULL,這樣FFmpeg可以自動檢測AVInputFormat。
dictionay:附加的一些選項,一般情況下可以設定為NULL。
函式執行成功的話,其返回值大於等於0。
來自 <http://blog.csdn.net/leixiaohua1020/article/details/44064715>
3. int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
該函式可以讀取一部分視音訊資料並且獲得一些相關的資訊。
來自 <http://blog.csdn.net/leixiaohua1020/article/details/44084321>
ic:輸入的AVFormatContext。
options:額外的選項,目前沒有深入研究過。
函式正常執行後返回值大於等於0。
來自 <http://blog.csdn.net/leixiaohua1020/article/details/44084321>
4. AVCodec *avcodec_find_encoder(enum AVCodecID id);
函式的引數是一個編碼器的ID,返回查詢到的編碼器(沒有找到就返回NULL)。
5. AVCodec *avcodec_find_decoder(enum AVCodecID id);
函式的引數是一個解碼器的ID,返回查詢到的解碼器(沒有找到就返回NULL)。
其實這兩個函式的實質就是遍歷AVCodec連結串列並且獲得符合條件的元素。
6. int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
該函式用於初始化一個視音訊編解碼器的AVCodecContext
avctx:需要初始化的AVCodecContext。
codec:輸入的AVCodec
options:一些選項。例如使用libx264編碼的時候,“preset”,“tune”等都可以通過該引數設定。
7. int av_read_frame(AVFormatContext *s, AVPacket *pkt);
讀取碼流中的音訊若干幀或者視訊一幀。例如,解碼視訊的時候,每解碼一個視訊幀,需要先呼叫 av_read_frame()獲得一幀視訊的壓縮資料,然後才能對該資料進行解碼
通過av_read_packet(***),讀取一個包,需要說明的是此函式必須是包含整數幀的,不存在半幀的情況,以ts流為例,是讀取一個完整的PES包(一個完整pes包包含若干視訊或音訊es包),讀取完畢後,通過av_parser_parse2(***)分析出視訊一幀(或音訊若干幀),返回,下次進入迴圈的時候,如果上次的資料沒有完全取完,則st = s->cur_st;不會是NULL,即再此進入av_parser_parse2(***)流程,而不是下面的av_read_packet(**)流程,這樣就保證了,如果讀取一次包含了N幀視訊資料(以視訊為例),則呼叫av_read_frame(***)N次都不會去讀資料,而是返回第一次讀取的資料,直到全部解析完畢。
s:輸入的AVFormatContext
pkt:輸出的AVPacket
如果返回0則說明讀取正常。
再次呼叫本函式之前,必須使用av_free_packet釋放pkt所佔用的資源。
8. int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
int *got_picture_ptr,
const AVPacket *avpkt);
作用是解碼一幀視訊資料。輸入一個壓縮編碼的結構體AVPacket,輸出一個解碼後的結構體AVFrame。
int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int*got_frame_ptr, AVPacket *avpkt);
解碼一個音訊幀。輸入資料在AVPacket結構中,輸出資料在frame中,got_frame_ptr表示是否有資料輸出。
9. int avcodec_close(AVCodecContext *avctx);
avctx就是需要關閉的編碼器的AVCodecContext
void avformat_close_input(AVFormatContext **s);
函式用於關閉一個AVFormatContext,一般情況下是和avformat_open_input()成對使用的。
intavformat_network_init(void);
載socket庫以及網路加密協議相關的庫,為後續使用網路相關提供支援
開啟網路流的話,前面要加上函式avformat_network_init()
10.void av_dump_format(AVFormatContext *ic,
int index,
const char *url,
int is_output);
是一個手工除錯的函式,能使我們看到pFormatCtx->streams裡面有什麼內容。一般接下來我們使用av_find_stream_info()函式,它的作用是為pFormatCtx->streams填充上正確的資訊。
11. typedef struct AVPacket
12.{
13. int64_t pts;
14. int64_t dts;
15. int64_t pos;
16. uint8_t *data;//資料首地址
17. int size;
18. int stream_index;
19. int flags;//flags為標誌域,1表示該資料是一個關鍵幀
20. void(*destruct)(struct AVPacket*);//釋放資料緩衝區的函式指標
21.} AVPacket;
每一個包是一個完整的資料幀,來暫存解複用之後、解碼之前的媒體資料(一個音/視訊幀、一個字幕包等)及附加資訊(解碼時間戳、顯示時間戳、時長等)
AVPacket本身只是個容器,它data成員引用實際的資料緩衝區。這個緩衝區通常是由av_new_packet建立的,但也可能由 FFMPEG的API建立(如av_read_frame)。當某個AVPacket結構的資料緩衝區不再被使用時,要需要通過呼叫av_free_packet釋放
22. void av_init_packet(AVPacket *pkt)
23. int av_new_packet(AVPacket *pkt, int size)
來自 <http://blog.csdn.net/vintionnee/article/details/17734223>
24. int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples,
25. enum AVSampleFormat sample_fmt, int align)
音訊一般是採用成PCM格式,而計算PCM格式音訊尺寸,就需要如下幾個引數。
通道數,取樣頻率,採用格式。
通道數:個人理解,就是同時有個幾個裝置在進行音訊的取樣,最少為1,一般通道數越多,音質越好。
取樣頻率:(也稱為取樣速度或者取樣頻率)定義了每秒從連續訊號中提取並組成離散訊號的取樣個數,它用赫茲(Hz)來表示。
採用位數:既然取樣頻率表示每秒取樣的個數,那麼如何描述每個取樣點呢?用什麼方法獨立每個取樣點值的區別呢?也就是如何度量每個取樣點,而這正是取樣格式出現的意義。通常使用16bit,也就是2的16次方,共有65536個不同的度量值,這樣取樣位數越高,音訊度量化的就越精細,音質同樣也就越高。
所以音訊所佔用位元組數 = 通道數 * 採用頻率(Hz) * 採用位數(byte)
而在ffmpeg裡面就使用av_sample_get_buffer_size來計算音訊佔用的位元組數。
來自 <http://blog.csdn.net/oldmtn/article/details/48048687>
將avcodec_alloc_frame() 替換為 av_frame_alloc()。
來自 <http://blog.csdn.net/davebobo/article/details/51123917>