來源:http://blog.csdn.net/chance_yin/article/details/10323441php
1、研究數字多媒體,首先要了解幾個基本術語(ffmpeg的相關文檔幾乎都是英文的,不弄懂幾個基本術語看文檔仍是比較吃力的)java
一、容器/文件 (Container/file) ,既多媒體源文件git
二、媒體流(Stream):與時間相關的一段連續數據。既某一時刻對應某個數據,這樣的多個連續數據組在一塊兒就成了媒體流。數組
三、數據幀/數據包(Frame/Packet):一個媒體流由大量的數據幀構成。數據幀也是編解碼器最小的處理單元。數據結構
2、FFmpeg 基礎---FFmpeg中重要的幾個數據結構app
一、AVCodecContext,這是一個描述編解碼器上下文的數據結構,包含了衆多編解碼器須要的參數信息less
若是是單純使用libavcodec,這部分信息須要調用者進行初始化;若是是使用整個FFMPEG庫,這部分信息在調用 avformat_open_input和avformat_find_stream_info的過程當中根據文件的頭信息及媒體流內的頭部信息完成初始 化。其中幾個主要域的釋義以下:ide
二、AVStream 該結構體描述一個媒體流函數
主要域的釋義以下,其中大部分域的值能夠由avformat_open_input根據文件頭的信息肯定,缺乏的信息須要經過調用avformat_find_stream_info讀幀及軟解碼進一步獲取:oop
三、AVFormatContext,這個結構體描述了一個媒體文件或媒體流的構成和基本信息
這是FFMpeg中最爲基本的一個結構,是其餘全部結構的根,是一個多媒體文件或流的根本抽象。其中:
一般,這個結構由avformat_open_input在內部建立並以缺省值初始化部分紅員。可是,若是調用者但願本身建立該結構,則須要顯式爲該結構的一些成員置缺省值——若是沒有缺省值的話,會致使以後的動做產生異常。如下成員須要被關注:
四、AVPacket
FFMPEG使用AVPacket來暫存媒體數據包及附加信息(解碼時間戳、顯示時間戳、時長等),這樣的媒體數據包所承載的每每不是原始格式的音視頻數據,而是以某種方式編碼後的數據,編碼信息由對應的媒體流結構AVStream給出。AVPacket包含如下數據域:
AVPacket結構自己只是個容器,它使用data成員引用實際的數據緩衝區。這個緩衝區的管理方式有兩種,其一是經過調用av_new_packet 直接建立緩衝區,其二是引用已經存在的緩衝區。緩衝區的釋放經過調用av_free_packet實現,其內部實現也採用了兩種不一樣的釋放方式,第一種方 式是調用AVPacket的destruct函數,這個destruct函數多是缺省的av_destruct_packet,對應 av_new_packet或av_dup_packet建立的緩衝區,也多是某個自定義的釋放函數,表示緩衝區的提供者但願使用者在結束緩衝區的時候 按照提供者指望的方式將其釋放,第二種方式是僅僅將data和size的值清0,這種狀況下每每是引用了一個已經存在的緩衝區,AVPacket的 destruct指針爲空。
在使用AVPacket時,對於緩衝區的提供者,必須注意經過設置destruct函數指針指定正確的釋放方式,若是緩衝區提供者打算本身釋放緩衝區,則 切記將destruct置空;而對於緩衝區的使用者,務必在使用結束時調用av_free_packet釋放緩衝區(雖然釋放操做可能只是一個假動做)。 若是某個使用者打算較長時間內佔用一個AVPacket——好比不打算在函數返回以前釋放它——最好調用av_dup_packet進行緩衝區的克隆,將 其轉化爲自有分配的緩衝區,以避免對緩衝區的不當佔用形成異常錯誤。av_dup_packet會爲destruct指針爲空的AVPacket新建一個緩 衝區,而後將原緩衝區的數據拷貝至新緩衝區,置data的值爲新緩衝區的地址,同時設destruct指針爲av_destruct_packet。
3、時間信息 / 多媒體同步
時間信息用於實現多媒體同步。
同步的目的在於展現多媒體信息時,可以保持媒體對象之間固有的時間關係。同步有兩類,一類是流內同步,其主要任務是保證單個媒體流內的時間關係,以知足感 知要求,如按照規定的幀率播放一段視頻;另外一類是流間同步,主要任務是保證不一樣媒體流之間的時間關係,如音頻和視頻之間的關係(lipsync)。
對於固定速率的媒體,如固定幀率的視頻或固定比特率的音頻,能夠將時間信息(幀率或比特率)置於文件首部(header),如AVI的hdrl List、MP4的moov box,還有一種相對複雜的方案是將時間信息嵌入媒體流的內部,如MPEG TS和Real video,這種方案能夠處理變速率的媒體,亦可有效避免同步過程當中的時間漂移。
FFMPEG會爲每個數據包打上時間標籤,以更有效地支持上層應用的同步機制。時間標籤有兩種,一種是DTS,稱爲解碼時間標籤,另外一種是PTS,稱爲 顯示時間標籤。對於聲音來講 ,這兩個時間標籤是相同的,但對於某些視頻編碼格式,因爲採用了雙向預測技術,會形成DTS和PTS的不一致。
無雙向預測幀的狀況:
圖像類型: I P P P P P P ... I P P DTS: 0 1 2 3 4 5 6... 100 101 102 PTS: 0 1 2 3 4 5 6... 100 101 102
有雙向預測幀的狀況:
圖像類型: I P B B P B B ... I P B DTS: 0 1 2 3 4 5 6 ... 100 101 102 PTS: 0 3 1 2 6 4 5 ... 100 104 102
對於存在雙向預測幀的狀況,一般要求解碼器對圖像重排序,以保證輸出的圖像順序爲顯示順序:
解碼器輸入:I P B B P B B (DTS) 0 1 2 3 4 5 6 (PTS) 0 3 1 2 6 4 5 解碼器輸出:X I B B P B B P (PTS) X 0 1 2 3 4 5 6
時間信息的獲取:
經過調用avformat_find_stream_info,多媒體應用能夠從AVFormatContext對象中拿到媒體文件的時間信息:主要是總 時間長度和開始時間,此外還有與時間信息相關的比特率和文件大小。其中時間信息的單位是AV_TIME_BASE:微秒。