FFmpeg Principle學(xué)習(xí)open_output_file打開輸出文件
open_output_file()打開輸出文件流程
open_output_file()打開輸出文件的流程,跟open_input_file()打開輸入文件的流程是非常類似的。
都是創(chuàng)建一個文件管理器,輸出的文件管理器是struct OutputFile,然后添加輸出流OutputStream,創(chuàng)建編碼器上下文ost->enc_ctx。
不過跟打開輸入文件一樣,都只是創(chuàng)建了編碼器實例,但是都還沒真正打開編碼器。
打開編碼器是在init_output_stream()函數(shù)里面的,如下:
if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) {...}
打開解碼器是在init_input_stream()函數(shù)里面的,如下:
if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) {...}
在講解open_output_file()函數(shù)的邏輯之前,需要先學(xué)習(xí)struct OutputFile結(jié)構(gòu),推薦閱讀《OutputFile數(shù)據(jù)結(jié)構(gòu)分析》
open_output_file()函數(shù)流程圖

由于open_output_file()的流程比較長,所以拆成了兩列來畫,中間的兩列其實是一列。
open_output_file()函數(shù)的邏輯其實比上面的流程圖更加復(fù)雜的,有比較多的細(xì)枝末節(jié)的邏輯,例如一些賦值操作,nb_stream_maps的邏輯,處理 metadata,chapters,programs 的數(shù)據(jù)等等,這些邏輯其實在簡單場景下不會跑進(jìn)去,所以可以先不管。
我說的簡單場景,是指下面這樣一條命令。juren-5s.mp4的下載地地址:GitHub
ffmpeg -i juren-5s.mp4 juren-5s-copy.mp4
本章節(jié),大部分的代碼分析都是基于簡單場景的。
簡單場景下,沒有使用復(fù)雜濾鏡的選項-filter_complex,所以只會調(diào)init_simple_filtergraph()函數(shù)來初始化濾鏡。
ffmpeg.exe的轉(zhuǎn)換器就是這么實現(xiàn)的,即便你命令行沒有使用濾鏡,他也會創(chuàng)建一個空白的濾鏡,這是為了讓邏輯更加通用。
open_output_file()函數(shù)里面有比較多的復(fù)雜濾鏡的邏輯,通常都是判斷nb_filtergraphs是否大于 0,這些邏輯你可以暫時不看。
簡單場景下,nb_filtergraphs會是 0 。
open_output_file()函數(shù)重點
open_output_file()函數(shù)里面有 4 個重點的地方。
第一個重點: 選出最高分辨率的視頻流,選出最多聲道數(shù)的音頻流。
如果 mp4 文件有多個視頻流,多個音頻,ffmpeg.exe轉(zhuǎn)換器會選出最好的那個來進(jìn)行處理,如下:

第二個重點: new_video_stream()函數(shù)的 最后一個參數(shù),如下:

最后一個參數(shù)source_index代表輸出流對應(yīng)的輸入流,在簡單場景下,輸出流都是對應(yīng)一個輸入流。
但是在復(fù)雜濾鏡下,有可能是多個輸入流合并輸出一個輸出流,所以在復(fù)雜濾鏡下,source_index會設(shè)置成 -1,代表沒有對應(yīng)的輸入流。
第三個重點:初始化簡單濾鏡,如下:

注意ist->decoding_needed會因此變成 非 0,所以對應(yīng)的輸入流會進(jìn)行解碼操作。
第四個重點: 設(shè)置出口濾鏡的寬高等等信息,由于出口濾鏡出來的AVFrame會進(jìn)行編碼,然后保存進(jìn)去容器,所以出口濾鏡的寬高,采樣等等,必須更容器的保持一致。

后面的都是一些簡單場景不會跑進(jìn)去的邏輯,如下:

至此,open_output_file()函數(shù)分析完畢。
以上就是FFmpeg Principle學(xué)習(xí)open_output_file打開輸出文件的詳細(xì)內(nèi)容,更多關(guān)于FFmpeg Principle打開輸出文件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android4.4開發(fā)之電池低電量告警提示原理與實現(xiàn)方法分析
這篇文章主要介紹了Android4.4開發(fā)之電池低電量告警提示原理與實現(xiàn)方法,結(jié)合實例形式分析了Android4.4電池電量警告的原理及相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
android時間選擇控件之TimePickerView使用方法詳解
這篇文章主要為大家詳細(xì)介紹了android時間選擇控件之TimePickerView的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-09-09
android獲取當(dāng)前接入點信息判斷是ctwap還是ctnet實例代碼
這篇文章主要介紹了android獲取當(dāng)前接入點信息判斷是ctwap還是ctnet的方法,大家參考使用吧2013-11-11
Android中對RecyclerView Adapter封裝解析
本篇文章主要介紹了Android中對RecyclerView Adapter封裝解析。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06

