天天看點

【FFmpeg程式設計進階】(五)ffplay.c 源碼學習(2/3) 之 SDL線程函數 read_thread()代碼流程 - 待更新

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> 将媒體資訊列印出來。

示例如下: