1. 程式人生 > >關於ffmpeg中的VBR控制的討論

關於ffmpeg中的VBR控制的討論

很多朋友問起我關於ffmpeg 中VBR的問題,主要是該設定哪些引數,該 如何設定等問題。以前我也沒有研究過ffmpeg的VBR,所以就在網上查找了一下,無功而返,後面就看ffmpeg.c的原始碼,初步認為通過下面的參 數或選項便可以實現VBR的控制:

    { "b", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
    { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantiser scale (VBR)", "q" },
    { "qmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qmin}, "min video quantiser scale (VBR)", "q" },
    { "qmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qmax}, "max video quantiser scale (VBR)", "q" },
    { "lmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_lmin}, "min video lagrange factor (VBR)", "lambda" },
    { "lmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_lmax}, "max video lagrange factor (VBR)", "lambda" },
    { "mblmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_lmin}, "min macroblock quantiser scale (VBR)", "q" },
    { "mblmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_lmax}, "max macroblock quantiser scale (VBR)", "q" },
    { "qdiff", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qdiff}, "max difference between the quantiser scale (VBR)", "q" },
    { "qblur", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qblur}, "video quantiser scale blur (VBR)", "blur" },
    { "qsquish", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qsquish}, "how to keep quantiser between qmin and qmax (0 = clip, 1 = use differentiable function)", "squish" },
    { "qcomp", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qcomp}, "video quantiser scale compression (VBR)", "compression" },
    { "bt", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_tolerance}, "set video bitrate tolerance (in kbit/s)", "tolerance" },
    { "maxrate", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_max}, "set max video bitrate tolerance (in kbit/s)", "bitrate" },
    { "minrate", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" },
    { "bufsize", HAS_ARG | OPT_VIDEO, {(void*)opt_video_buffer_size}, "set ratecontrol buffer size (in kByte)", "size" },

這裡面我所知道的僅有:
    b                             設定一個目標位元速率
    qscale                     設定固定的量化因子
   qmin qmax               最小和最大量化因子,使用了該引數,就可以不使用qscale引數
   bt                            設定容許的位元速率誤差(固定誤差)
   maxrate minrate     設定最大和最小位元速率誤差(可變誤差)
   bufsize                    設定位元速率控制的緩衝區大小

    這裡面要特別注意的是maxrate和minrate兩個引數,他們並不是最大位元速率和最小位元速率,而是位元速率誤差範圍,最容易迷惑人的,其它的部分還請大家一 起來補充,並且最好能給出一些典型的引數值!

[轉]各引數在編碼時的作用

max_qdiff=3
//視訊中所有楨(包括i/b/P)的最大Q值差距

max_b_frames=2
//兩個非B楨之間的最大B楨數目。

qcompress=0.5
//浮點數值,表示在壓制“容易壓的場景”和“難壓的場景”時,允許Q值之比值的變化範圍。可選值是0.0-1.0。
mb_qmin=1
// MicroBlock的最小Q值
mb_qmax=31
// MicroBlock的最大Q值
pre_me=2
// 提前進行運動場景預測.
rc_eq=tex
//選擇位元速率控制的方法。TEX是方法之一。
lmin=1
//最小拉格朗日乘數。拉格朗日乘數法(lagrange multipler)是用來檢定瞬間平均值的一種統計學方法。
lmax=5
//最大拉格朗日乘數
qmin=1
//Q值最小值
qmax=5
//Q值最大值.
qblur=0
//浮點數,表示Q值的比例隨時間消減的程度,取之範圍是0.0-1.0,取0就是不消減。
spatial_cplx_masking=0.3
//浮點數,表示空間複雜性的masking力度。0.0-1.0

strict_std_compliance=-1
//表示嚴格遵照既定標準(MPEG4等等)

me_pre_cmp=2
//運動場景預判功能的力度。數值越大編碼時間越長。

rc_qsquish=1.0
//採用Qmin/Qmax的比值來限定和控制碼率的方法。選1表示區域性(即一個clip)採用此方法,選1表示全部採用。

rc_buffer_aggressivity=1.0
//浮點數. 表示開啟解碼器碼流緩衝(decoder bitstream buffer)

bit_rate_tolerance=8000000
//表示有多少bit的視訊流可以偏移出目前的設定.這裡的"設定"是指的cbr或者vbr.

mb_decision=0
//Macroblock的判定模式.有3種,0表示採用用Macroblock比較,2表示採用失真率(rate distortion)參考,1表示選擇0和2中位元速率需求最低的一種

b_quant_factor=1.25
//表示i/p與B的Q值比例因子,值越大B楨劣化越嚴重

b_quant_offset=1.25
//表示1/p與B的Q值比例的偏移量,值越大B楨劣化越嚴重.如果大於0,那麼下一個B的Q=前一個P的Q乘以b_quant_factor再加上 offset,如果小於0,則B的Q=負的normal_Q乘以factor加上offset.

i_quant_factor=0.8
//p和i的Q值比例因子,越接近1則P越優化.

i_quant_offset=0.0
//p和i的Q的偏移量

rc_strategy=2
//設定位元速率控制策略. 這個策略記不得了;(

b_frame_strategy=0
//B楨生成策略.(我也說不清)

luma_elim_threshold=0
//消除luma(亮度,"紅樓梯")門限

chroma_elim_threshold=0
//從名字上看像是消除色度錯誤的門限,不理解.

dct_algo=0
//離散餘弦變換演算法設定,有7種預設定,包括:
0:FF_DCT_AUTO
1:FF_DCT_FASTINT,
2:FF_DCT_INT ,
3:FF_DCT_MMX ,
4:FF_DCT_MLIB,
5:FF_DCT_ALTIVEC
6:FF_DCT_FAAN
有印象好像這些與設演算法是針對不同的CPU指令集作優化的,根據作壓制的機器CPU來選擇0-6.

lumi_masking=0.0
dark_masking=0.0
//這兩個表示對過亮或過暗的場景作masking的力度.0表示不作.

bit_rate 設定為 64000
bit_rate_tolerance 設定為 3000

實際輸出位元速率最高還是會遠遠超過64000+3000(當輸出關鍵禎的時候),有辦法真正控制最高位元速率不?

ffmpeg雖然大而全,其實bug是非常多的,還有很多功能沒有實現,

不如ffmpeg根本控制不住vbr的位元速率,

所以用ffmpeg的vbr就不用想了,除非自己修改完善

有關ffmpeg的進一步實現, 可以參考mplayer原始碼包下的mencoder的相關實現