可見按照現有方式展示的話,影片畫面被拉長了。這是因為影片尺寸有三種寬高概念,說明如下:
1、取樣寬高比,指的是攝像頭在採集畫面時,方格內部的寬度與高度的取樣點數量比例。取樣寬高比的英文叫做“Sample Aspect Ratio”,簡稱SAR。
2、畫素寬高比,指的是影片畫面儲存到檔案時,寬度和高度各佔據多少畫素。畫素寬高比的英文叫做“Pixel Aspect Ratio”,簡稱PAR。
3、顯示寬高比,指的是影片畫面渲染到螢幕時,顯示出來的寬度與高度比例。顯示寬高比的英文叫做“Display Aspect Ratio”,簡稱DAR。
取樣寬高比對應AVCodecParameters結構的sample_aspect_ratio欄位,該欄位為分數型別AVRational。
畫素寬高比對應AVCodecContext結構的width與height兩個欄位,比例值等於width/height。
顯示寬高比對應最終要顯示的畫面尺寸,該值需要額外計算。多數時候sample_aspect_ratio的num與den均為1,表示寬高兩個方向的取樣點比例為1:1,此時畫素寬高比等於顯示寬高比。
由此可見,當sample_aspect_ratio的num與den均為1時,表示畫素點是個正方形,此時AVCodecContext結構的寬高就是影片的寬高,無需另外處理。只有sample_aspect_ratio的num不等於den時,表示畫素點是個長方形,才需要另外計算顯示寬高比,並根據影片高度計算影片的實際寬度。
已知三個寬高比的轉換式子如下:
令DAR=實際寬度/實際高度,則代入具體的欄位,可得詳細的轉換式子如下:
當實際高度為height時,表示保持原畫面尺寸,則實際的畫面寬度計算式子如下。
假如已經求得DAR值並儲存在變數display_aspect_ratio中,那麼實際寬度 = 實際高度 * PAR = 實際高度 * display_aspect_ratio.num / display_aspect_ratio.den。
根據上述所列的幾個計算式子,編寫如下的寬高比以及實際寬度的求解程式碼如下所示。
上述修改後的程式碼已經附在了《FFmpeg開發實戰:從零基礎到短影片上線》一書第10章的原始碼chapter10/playsync2.c中,這個c程式碼是playsync.c的改進版,能夠根據sample_aspect_ratio的寬高比例調整目標影片的畫面尺寸。
接著執行下面的編譯命令。
編譯完成後執行以下命令啟動測試程式,期望播放影片檔案meg.vob。
程式執行完畢,發現控制檯輸出以下的日誌資訊。
同時彈出SDL視窗播放影片畫面,如下圖所示:
可見畫面尺寸符合該影片的實際寬高比例,表示上述程式碼正確實現了調整影片尺寸的功能。