本文為作者原創,轉載請注明出處:https://www.cnblogs.com/leisure_chn/p/10235926.html
基於 FFmpeg 和 SDL 實現的簡易視頻播放器,主要分為讀取視頻文件解碼和調用 SDL 播放兩大部分。
前面三個實驗分別實現了最簡播放、視頻播放和音頻播放,本次實驗將視頻播放和音頻播放結合在一起。
FFmpeg 簡易播放器系列文章如下:
[1]. FFmpeg簡易播放器的實現1-最簡版
[2]. FFmpeg簡易播放器的實現2-視頻播放
[3]. FFmpeg簡易播放器的實現3-音頻播放
[4]. FFmpeg簡易播放器的實現4-音視頻播放
[5]. FFmpeg簡易播放器的實現5-音視頻同步
1. 視頻播放器基本原理
下圖引用自 “雷霄驊,視音頻編解碼技術零基礎學習方法”,因原圖太小,看不太清楚,故重新制作了一張圖片。
如下內容引用自 “雷霄驊,視音頻編解碼技術零基礎學習方法”:
解協議
將流媒體協議的數據,解析為標准的相應的封裝格式數據。視音頻在網絡上傳播的時候,常常采用各種流媒體協議,例如 HTTP,RTMP,或是 MMS 等等。這些協議在傳輸視音頻數據的同時,也會傳輸一些信令數據。這些信令數據包括對播放的控制(播放,暫停,停止),或者對網絡狀態的描述等。解協議的過程中會去除掉信令數據而只保留視音頻數據。例如,采用 RTMP 協議傳輸的數據,經過解協議操作后,輸出 FLV 格式的數據。解封裝
將輸入的封裝格式的數據,分離成為音頻流壓縮編碼數據和視頻流壓縮編碼數據。封裝格式種類很多,例如 MP4,MKV,RMVB,TS,FLV,AVI 等等,它的作用就是將已經壓縮編碼的視頻數據和音頻數據按照一定的格式放到一起。例如,FLV 格式的數據,經過解封裝操作后,輸出 H.264 編碼的視頻碼流和 AAC 編碼的音頻碼流。解碼
將視頻/音頻壓縮編碼數據,解碼成為非壓縮的視頻/音頻原始數據。音頻的壓縮編碼標准包含 AAC,MP3,AC-3 等等,視頻的壓縮編碼標准則包含 H.264,MPEG2,VC-1 等等。解碼是整個系統中最重要也是最復雜的一個環節。通過解碼,壓縮編碼的視頻數據輸出成為非壓縮的顏色數據,例如 YUV420P,RGB 等等;壓縮編碼的音頻數據輸出成為非壓縮的音頻抽樣數據,例如 PCM 數據。音視頻同步
根據解封裝模塊處理過程中獲取到的參數信息,同步解碼出來的視頻和音頻數據,並將視頻音頻數據送至系統的顯卡和聲卡播放出來。
2. 簡易播放器的實現-音視頻播放
2.1 實驗平台
實驗平台: openSUSE Leap 42.3
FFmpeg版本:4.1
SDL版本: 2.0.9
FFmpeg 開發環境搭建可參考 “FFmpeg開發環境構建”
2.2 源碼清單
使用如下命令下載源碼:
svn checkout https://github.com/leichn/exercises/trunk/source/ffmpeg/player_avideo
2.3 源碼流程分析
參考如下:
2.4 解復用線程
解復用線程就是 main() 函數所在的主線程。main() 函數作一些必要的初始化工作后,創建音頻處理線程和視頻處理線程。
然后 main() 函數進入主循環,從輸入文件中讀取 packet,並根據 packet 類型,將之放入視頻 packet 隊列或音頻 packet 隊列。
2.5 音頻處理線程
音頻處理線程是 SDL 庫內建線程。用戶提供回調函數供音頻處理線程調用。實現過程參考 “FFmpeg簡易播放器的實現3-音頻播放”
2.6 視頻處理線程
視頻處理線程實現視頻解碼及播放。實現過程參考 “FFmpeg簡易播放器的實現2-視頻播放”
3. 編譯與驗證
3.1 編譯
在源碼目錄運行:
./compiler.sh
3.2 驗證
選用 clock.avi 測試文件,測試文件下載(右鍵另存為):clock.avi
查看視頻文件格式信息:
ffprobe clock.avi
打印視頻文件信息如下:
[avi @ 0x9286c0] non-interleaved AVI
Input #0, avi, from 'clock.avi':
Duration: 00:00:12.00, start: 0.000000, bitrate: 42 kb/s
Stream #0:0: Video: msrle ([1][0][0][0] / 0x0001), pal8, 320x320, 1 fps, 1 tbr, 1 tbn, 1 tbc
Stream #0:1: Audio: truespeech ([34][0][0][0] / 0x0022), 8000 Hz, mono, s16, 8 kb/s
運行測試命令:
./ffplayer clock.avi
可以聽到每隔 1 秒播放一次“嘀”聲,聲音播放 12 次。時針每隔 1 秒跳動一格,跳動 12 次。聲音播放正常,畫面播放也正常,但是聲音和畫面不能對應,因為沒有考慮音視頻同步。下一次實驗研究音視頻同步問題。
4. 參考資料
[1] 雷霄驊,視音頻編解碼技術零基礎學習方法
[2] 雷霄驊,最簡單的基於FFMPEG+SDL的視頻播放器ver2(采用SDL2.0)
[3] SDL WIKI, https://wiki.libsdl.org/
[4] Martin Bohme, An ffmpeg and SDL Tutorial, Tutorial 03: Playing Sound
5. 修改記錄
2018-12-06 V1.0 初稿