講解FFmpeg多媒體格式轉(zhuǎn)換之前先講下我們?cè)诟袷睫D(zhuǎn)換過程中需要用到的API及FFmpeg相關(guān)的結(jié)構(gòu)體介紹豪治,通過這篇文章介紹在來學(xué)習(xí)多媒體格式轉(zhuǎn)換時(shí)腦海中就會(huì)對(duì)整個(gè)流程有一個(gè)清晰的思路。
API列表介紹
avformat_open_input()
打開輸入文件并創(chuàng)建封裝格式AVFormatContext
avformat_alloc_output_context2()/avformat_free_context()
輸出多媒體文件上下文,對(duì)應(yīng)的是avformat_alloc_input_context2()
輸入多媒體上下文avformat_new_stream()
創(chuàng)建一個(gè)新的音視頻流avcodec_parameters_copy()
拷貝多媒體參數(shù)信息,多媒體數(shù)據(jù)中有很多參數(shù),比如視頻幀率,音頻采樣率等等勉失,因?yàn)槲覀冎皇寝D(zhuǎn)換格式,需要將原來的參數(shù)復(fù)制到新的多媒體數(shù)據(jù)中
多媒體文件寫入相關(guān)的API
avio_open()
打開封裝格式上下文中的AVIOContext *pb
原探,打開之后才能給往AVFormatContext
中寫入數(shù)據(jù)avformat_write_header()
乱凿,F(xiàn)Fmpeg將它支持的所有多媒體格式頭封裝成流的api,只需要調(diào)用這個(gè)函數(shù)FFmpeg會(huì)通過格式判斷來寫入相應(yīng)頭多媒體頭信息av_write_frame()/av_interleaved_write_frame()
寫入多媒體信息咽弦,兩個(gè)函數(shù)都可以寫入多媒體文件av_write_trailer()
寫入多媒體尾部信息徒蟆,與頭部信息對(duì)應(yīng)。
相關(guān)結(jié)構(gòu)體介紹:
-
struct AVFormatContext
:封裝格式的上下文离唬,用于存儲(chǔ)所有都視頻信息后专,其內(nèi)部重要變量如下
struct AVInputFormat *iformat:輸入數(shù)據(jù)的封裝格式
AVIOContext *pb:輸入數(shù)據(jù)的緩存
unsigned int nb_streams:視音頻流的個(gè)數(shù)
AVStream **streams:視音頻流
char filename[1024]:文件名
int64_t duration:時(shí)長(單位:微秒us划鸽,轉(zhuǎn)換為秒需要除以1000000)
int bit_rate:比特率(單位bps输莺,轉(zhuǎn)換為kbps需要除以1000)
AVDictionary *metadata:元數(shù)據(jù)
-
struct AVStream
是存儲(chǔ)每一個(gè)視頻/音頻流信息的結(jié)構(gòu)體,下面是結(jié)構(gòu)體中的重要變量如下:
int index:標(biāo)識(shí)該視頻/音頻流
AVCodecContext *codec:指向該視頻/音頻流的>
AVCodecContext(它們是一一對(duì)應(yīng)的關(guān)系)
AVRational time_base:時(shí)基裸诽。通過該值可以把PTS嫂用,DTS轉(zhuǎn)化為真正的時(shí)間。FFMPEG其他結(jié)構(gòu)體中也有這個(gè)字段丈冬,但是根據(jù)我的經(jīng)驗(yàn)嘱函,只有AVStream中的time_base是可用的。PTS*time_base=真正的時(shí)間
int64_t duration:該視頻/音頻流長度
AVDictionary *metadata:元數(shù)據(jù)信息
AVRational avg_frame_rate:幀率(注:對(duì)視頻來說埂蕊,這個(gè)挺重要的)
AVPacket attached_pic:附帶的圖片往弓。比如說一些MP3,AAC音頻文件附帶的專輯封面蓄氧。
-
struct AVIOContext
是FFMPEG管理輸入輸出數(shù)據(jù)的結(jié)構(gòu)體函似。AVIOContext中有以下幾個(gè)變量比較重要:
unsigned char *buffer:緩存開始位置
int buffer_size:緩存大小(默認(rèn)32768)
unsigned char *buf_ptr:當(dāng)前指針讀取到的位置
unsigned char *buf_end:緩存結(jié)束的位置
void *opaque:URLContext結(jié)構(gòu)
-
struct AVPacket
是存儲(chǔ)壓縮編碼數(shù)據(jù)相關(guān)信息的結(jié)構(gòu)體喉童,重要的變量有以下幾個(gè):
uint8_t *data:壓縮編碼的數(shù)據(jù)撇寞。
例如對(duì)于H.264來說。1個(gè)AVPacket的data通常對(duì)應(yīng)一個(gè)NAL。
注意:在這里只是對(duì)應(yīng)蔑担,而不是一模一樣牌废。他們之間有微小的差別:使用FFMPEG類庫分離出多媒體文件中的H.264碼流
因此在使用FFMPEG進(jìn)行視音頻處理的時(shí)候,常称∥眨可以將得到的AVPacket的data數(shù)據(jù)直接寫成文件鸟缕,從而得到視音頻的碼流文件。
int size:data的大小
int64_t pts:顯示時(shí)間戳
int64_t dts:解碼時(shí)間戳
int stream_index:標(biāo)識(shí)該AVPacket所屬的視頻/音頻流排抬。
最后附一張F(tuán)Fmpeg關(guān)鍵結(jié)構(gòu)體的關(guān)系圖: