2014年1月20日 星期一

ffmpeg -- 使用 ffmpeg 命令降低 H.264 檔案大小

參考 x264EncodingGuide,使用裡頭的一個例子進行轉檔,以減少檔案大小。如下:
ABR (Average Bit Rate)
ffmpeg -i input -c:v libx264 -b:v 256k output.mp4 
轉好後的檔案的確降低 bitrate,但轉換後的檔案卻多出了 B-frame,如此可能會造成某些串流播放器播放時的困難。


以下記錄此問題的解決過程:

1. 只要轉檔時設定為 Baseline profile,便不會有 b-frame    

    摘錄 https://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping
    --bframes (x264)
    -bf  (FFmpeg)
    B-frames are a core element of H.264 and are more efficient in H.264 than any previous standard. Some specific targets, such as HD-DVD and Blu-Ray, have limitations on the number of consecutive B-frames. Most, however, do not; as a result, there is rarely any negative effect to setting this to the maximum (16) since x264 will, if B-adapt is used, automatically choose the best number of B-frames anyways. This parameter simply serves to limit the max number of B-frames. Note that Baseline Profile, such as that used by iPods, does not support B-frames. Recommended default: 16

2. 修改 ffmpeg 命令 

    參考 https://trac.ffmpeg.org/wiki/x264EncodingGuide 
原本作法 
ffmpeg -i input -c:v libx264 -b:v 1000k output.mp4 
此時 output.mp4 的 Encode Settings 如下: 
cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=6 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=15 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=abr / mbtree=1 / bitrate=256 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00

更改如下 
ffmpeg -i 7h800-2.mp4 -c:v libx264 -b:v 256k -profile:v baseline output.mp4 
此時 output.mp4 的 Encode Settings 如下:  
cabac=0 / ref=3 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=6 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=250 / keyint_min=15 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=abr / mbtree=1 / bitrate=128 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00

若檔案有aac,則需要加上 -strict -2 
ffmpeg -i 7h800-2.mp4 -c:v libx264 -strict -2 -b:v 256k -profile:v baseline output.mp4


3. 判斷轉換後的檔案是否仍存在 B-frame 

    參考 http://stackoverflow.com/questions/19642736/count-frames-in-h-264-bitstream 
使用命令如下 ffprobe -show_streams -count_frames -pretty filename,檢視輸出結果中的 "has_b_frames"

其他參考資料: