2.3 SDL線程函數 read_thread()
2.3.1 打開媒體檔案 avformat_open_input()
2.3.2 擷取媒體資訊 avformat_find_stream_info()
2.3.3 輸出媒體資訊 av_dump_format()
2.3.4 查找音/視訊/字幕stream_index資訊 av_find_best_stream()
2.3.5 啟動音視訊解碼線程 stream_component_open()
2.3.6 将音/視訊/字幕packet放對隊列 packet_queue_put()
2.3.7 擷取一幀壓縮編碼packet 資料 av_read_frame()
由文章篇幅過長,分三篇文章來學習ffplay.c 的源碼,
如下:
《【FFmpeg程式設計進階】(五)ffplay.c 源碼學習(1/3) 之 main 函數代碼流程》
《【FFmpeg程式設計進階】(五)ffplay.c 源碼學習(2/3) 之 SDL線程函數 read_thread()代碼流程》
《【FFmpeg程式設計進階】(五)ffplay.c 源碼學習(3/3) 之 event_loop()代碼流程》
本文連結:《【FFmpeg程式設計進階】(五)ffplay.c 源碼學習(2/3) 之 SDL線程函數 read_thread()代碼流程》
在該函數中,主要工作就是擷取 音頻/視訊/字幕的Packet包,然後放入對應的 Packet Queue 中
主要流程如下:
配置設定 <code>AVFormatContext</code> 結構體記憶體
打開媒體檔案,上下文資訊儲存在 ic 中
獲得媒體檔案資訊
修改SDL <code>window_title</code> 為 <code>file_name</code>
輸出媒體資訊到控制台上
擷取視訊、音頻、字幕對應的<code>stream_index</code>
基于流與視訊幀的寬高比,猜測視訊幀的螢幕寬高比, 重新設定SDL視窗的<code>size</code>
分别打開視訊/音頻/字幕解碼線程
如果檢測到網絡流 暫停,調用 <code>av_read_pause()</code> 暫停,否則調用<code>av_read_play()</code>繼續播放
如果是發現傳輸流 RTSP 或者是流媒體,則延時10ms再取下一個包
如果要跳轉播放,則先跳轉到位置,然後 清空播放<code>packet_queue</code>,再放新的packet 到隊列中
如果已經播放完畢,即隊列中沒有未播放的<code>stream</code>,則重新播放 或 自動退出
擷取一幀壓縮編碼資料(即一個<code>AVPacket</code>)
如果讀取失敗,或到檔案末尾,放入“空包”。放入空包意味着流的結束,一般在視訊讀取完成的時候放入空包。
将讀取到的壓縮編碼資料包放入 <code>packet_queue</code> 中
本函數源代碼分析見:《【FFmpeg程式設計進階】(六)avformat_open_input() 函數源代碼分析》
本函數源代碼分析見:《【FFmpeg程式設計進階】(八)avformat_find_stream_info() 函數代碼分析 - 擷取媒體資訊》
在通過<code>avformat_find_stream_info()</code>獲得媒體資訊後,可以通過<code>av_dump_format()</code> 将媒體資訊列印出來。
示例如下: