今天接到一個需求,需要把YUV序列轉換為無損的MP4鹿蜀。一開始準備是用x264編碼,把QP設置為0。但這樣壓縮后分冈,我比較了一下,發(fā)現(xiàn)實際上還是有損的淳衙。而且QP設置為0后箫攀,普通的播放器根本不能打開,只能用基于ffmpeg的播放器才能正常播放梢睛。后來想到265有Transform Quantizer Bypass(TQB)技術深碱,本身就就支持無損編碼敷硅,遂進行了嘗試。
ffmpeg把YUV無損轉換為MP4的命令行代碼:
ffmpeg -s 1920x1080 -pix_fmt yuv420p -r 60 -i .\BallUnderWater_1920x1080_60fps.yuv
-c:v libx265 -preset ultrafast -x265-params lossless=1 output_265.mp4
主要在x265指定了lossless=1(開始無損壓縮)參數(shù)。
現(xiàn)在我們雖然得到了轉換后的MP4文件锉走,但是我想進一步驗證得到的文件到底是不是無損的。在查詢官方文檔的時候我看了官方給出了兩種驗證方式:
- 在轉換完成后藕届,命令行中最后一行只要出現(xiàn)
lossless compression ratio
就表明是無損壓縮 - 可以通過計算原始YUV的hash值和轉換為MP4視頻后的hash挪蹭。若hash值一致,則說明是無損轉換休偶。這里是計算整個視頻的hash值的例子和單獨對每一個視頻單獨幀計算hash值例子梁厉。
通過計算hash和framehash,發(fā)現(xiàn)原始視頻的hash和frame與轉換后得到的MP4文件的hash和framehash值完全一致踏兜。著說明確實是無損壓縮词顾。
更進一步,既然是無損壓縮纳本,那么把MP4文件轉換為YUV(我們叫做新YUV)面睛,再計算原始YUV和新YUV的PSNR,那么每一幀的PSNR肯定都是無窮大茵肃。為啥是先把MP4文件轉換為YUV呢?這是因為MP4文件的timebase和原始YUV的timebase不一致,那么兩者的每一幀不能一一對應种冬,其計算出的PSNR就不準確了。
話不多說异袄,開動讽营!
- 把MP4文件轉換為YUV
ffmpeg -i .\BallUnderWater_1920x1080_60fps.mp4 newyuv.yuv
- 計算兩個YUV文件的PSNR
ffmpeg -s 1920x1080 -pix_fmt yuv420p -r 60 -i .\BallUnderWater_1920x1080_60fps.yuv -s 1920x1080
-pix_fmt yuv420p -r 60 -i .\newyuv.yuv -lavfi psnr=stats_file=psnr_logfile.txt -f null -
最終的PSNR結果如下面兩張圖糖荒,可以看出PNSR確實為無窮大品腹。