x264編碼詳細文字全過程
(1) x264_param_default( x264_param_t *param )
作用: 對編碼器進行參數設定
cqm:量化表相關信息
csp:
量化表相關信息裏的memset( param->cqm_4iy, 16, 16 );
memset( param->cqm_4ic, 16, 16 );
memset( param->cqm_4py, 16, 16 );
memset( param->cqm_4pc, 16, 16 );
memset( param->cqm_8iy, 16, 64 );
memset( param->cqm_8py, 16, 64 );
(2)static int Parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt ) 初始化
1. getopt_long(nargc, nargv, options, long_options, idx) 得到入口地址的向量與方式的選則
2. getopt_internal(nargc, nargv, options) 解析入口地址向量
(3) static int Encode( x264_param_t *param, cli_opt_t *opt )
/* Create a copy of param */ h->param=param
/* VUI */vui信息主要包括幀率、圖像尺寸等信息
/* Init x264_t */
x264_sps_init( h->sps, 0, &h->param );序列圖像集
x264_pps_init( h->pps, 0, &h->param, h->sps);圖像參數集
/* Init frames. */ 初始化並開闢幀空間
/* init mb cache */ 對前一宏塊的信息保存,因爲是初始化,所以作爲第一個宏塊的參考,後面會有x264_macroblock_cache_load( h, i_mb_x, i_mb_y );它是將要編碼的宏塊的周圍的宏塊的值讀進來, 要想得到當前塊的預測值,要先知道上面,左面的預測值
/* init cabac adaptive model */
/* init CPU functions */ 初始化cpu對各種分塊的參數設定
/* rate control */
1. x264_t *x264_encoder_open ( x264_param_t *param ) 這個函數是對不正確的參數進行修改,並對各結構體參數和cabac編碼,預測等需要的參數進行初始化
2、p_read_frame( &pic, opt->hin, i_frame + opt->i_seek, param->i_width, param->i_height )
讀取一幀,並把這幀設爲prev
3. i_file += Encode_frame( h, opt->hout, &pic );進入核心碼層
核心編碼層的總流程圖:(x264.c)
1. x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out )對幀進行編碼
2. i_size = x264_nal_encode( data, &i_data, 1, &nal[i] ) 網絡打包編碼
3. i_file += p_write_nalu( hout, data, i_size ) 把網絡包寫入到輸出文件中去
4. 返回,對下一幀進行編碼
下面一頁是詳細的流程圖:
一.幀內詳細流程圖:
(1). x264_encoder_encode( h, &nal, &i_nal, pic, &pic_out )對幀進行編碼
1. /* 1: Copy the picture to a frame and move it to a buffer */
x264_frame_t*fenc=x264_frame_get( h->frames.unused );
x264_frame_copy_picture( h, fenc, pic_in );
fenc->i_frame = h->frames.i_input++;
x264_frame_put( h->frames.next, fenc );
x264_frame_init_lowres( h->param.cpu, fenc );//裏面包含低象素的擴展,很多for循環,應該是抽頭計算和半精度象素的擴展,要認真看
(2). 264_slicetype_decide( h );對slice類型的判定,裏面也要看一下
(3). while( IS_X264_TYPE_B( h->frames.next[bframes]->i_type ) )
bframes++;
x264_frame_put(h->frames.current,x264_frame_get( &h->frames.next[bframes] ) );這主要是因爲B幀必須等後面的非B幀編碼結束後才能編碼,所以把暫時不編的一系列B幀存入隊列中,一直到非B幀才取出進行編碼,之後再進行前面的B幀編碼
do_encode:
(4). 建立list0 & list1.我感覺
x264_reference_build_list( h, h->fdec->i_poc, i_slice_type );
比特率控制初始化
x264_ratecontrol_start(h, i_slice_type, h->fenc->i_qpplus1 );
(5). 創建slice的頭部數據
x264_slice_init( h, i_nal_type, i_slice_type, i_global_qp );
(6) i_frame_size = x264_slices_write( h );這是編碼的關鍵了
1. x264_slice_header_write(&h->out.bs,&h->sh,h->i_nal_ref_idc ); /* Slice header */
2. 一些初始化工作
3. for(mb_xy=h->sh.i_first_mb, i_skip = 0; mb_xy < h->sh.i_last_mb; mb_xy++ )對一個slice中每個宏塊進行循環遍歷編碼,其中const int i_mb_y = mb_xy / h->sps->i_mb_width;和const int i_mb_x = mb_xy % h->sps->i_mb_width;是對宏塊位置在slice中的x,y座標的定位,這個for語句幾乎覆蓋了整個x264_slices_write()函數
4. x264_macroblock_cache_load( h, i_mb_x, i_mb_y ); 它是將要編碼的宏塊的周圍的宏塊的值讀進來, 要想得到當前塊的預測值,要先知道上面,左面的預測值!
5. *****x264_macroblock_analyse( h );重點。通過一系列的SAD算出最優化方案,例如把I幀16×16的宏塊分成16個4×4分別計算SAD和與原16×16SAD比較我感覺,在下面一層再詳細分析。
a. x264_mb_analyse_intra( h, &analysis, COST_MAX );我感覺是在一個16×16的SAD,4個8×8的SAD和,16個4×4SAD和中選出最優方式進行,可能我的理解不對,裏面的x264_mb_encode_i4x4( h, idx, a->i_qp );i8×8幾個函數的跟蹤有問題,跟得我都找不到,要仔細看(現在又能跟到了)
這邊好像如果是直流分量在這裏就進行量化ZIGZAG掃描了,不用等到x264_macroblock_encode( h )再完成了
b. x264_analyse_update_cache( h, &analysis ); 有對色度塊的模式選擇的計算,好像也有更新信息以爲下次的預測作爲參考
6. x264_macroblock_encode( h );
a. 判斷宏塊的類型
b. 根據判斷的類型進行DCT,量化,ZIGZAG,並記錄當前的模式爲下次編碼宏塊(亞宏塊)做參考
ZIGZAG的實現不明白(原來ZIGZAG有宏定義,在上面,現在明白了),反量化和IDCT的過程跟不進去,應該是彙編了!函數如下:( I 4×4 中 x264_mb_encode_i4x4( h, i, i_qp );)
x264_mb_dequant_4x4( dct4x4, h->dequant4_mf[CQM_4IY], i_qscale );
h->dctf.add4x4_idct( p_dst, i_stride, dct4x4 );
還有,這個函數跟蹤不進去,應該是重構圖像的反變換吧
h->dctf.add4x4_idct( p_dst, i_stride, dct4x4 );
h->mb.cache.intra4x4_pred_mode[x264_scan8[i]]=x264_mb_pred_mode4x4_fix(i_mode);這個值到底是怎麼根據前面的模式改變的,可能是上面兩個函數沒能更進去所以模糊
c. 對色度塊進行編碼,QP限制在0-51之間,選定預測模式(DC的話值全爲128)
x264_mb_encode_8x8_chroma( h, !IS_INTRA( h->mb.i_type ), i_qp );裏面對兩個色度信號分別編碼,與亮度信號類似
d. 求亮度和色度的cbp,完全不明白是怎麼求的,需要解決!現在有點明白,每個比特代表子塊是不是全爲0,但還沒有全部明白,色度塊cbp中0x02表示有AC,DC 0x01表示只有DC,
e.利用CBP判斷要不要SKIP.,裏面還關係到向量預測,明天好好看一下。 其中
h->mb.qp[h->mb.i_mb_xy] = h->mb.i_last_qp;這個爲讀下一個 qp的保存,不然解碼端是讀不出下一個 qp的,
關於CBP的理解還存在問題,他的8位比特各個代表的意思還不是十分明確,反正是對DC,AC的編碼的選擇。185頁有介紹(新一代視頻壓縮標準畢厚傑)
7. 選用CABAC還是CAVLC
CABAC的原理實現沒仔細看
8. x264_macroblock_cache_save( h );保存以爲下次的預測作爲參考
9. 一些收尾工作,爲下次宏塊作準備(看的比較粗)
x264基於經驗和感覺的碼率控制策略 收藏
前提:
1 high-complexity or high-motion scenes,細節將不會很明顯,此時高qp也是浪費
2 where motion compensation works well,在景物邊沿的失真,只需在一幀中去掉,以後就都不會有.在這裏投入有限的bits可以獲得最好的圖像質量性價比
3 已經編碼一frame,可以預測其他qp下所需bit數.預測距離越遠越不精確
4隨着frame重要性降低,他們只配用更大的qp,i ,p ,參考b ,disposable b.依次降低
5H.264支持1frame內不同mb使用不同qp,x264不支持,而由rc返回統一qp。但有那個功能函數存在那個函數僅精確到每一行mb變一次qp
所以rc策略如下:
2pass:
step1 1pass編碼,由qp推斷某qp下framesize *0.6符合目標frame size的限制,得到這個qp
step2 修改qp 以滿足requested total size(total是指整個Gop的大小,分段先編一邊再一邊)
step3 encode根據實際大小值修正預測的qp,並額外增加short-term compensation,針對開始和結束部分沒有很多bits餘地的位置.
1pass: abr (average bit rate )
step1 用半尺寸快速運動估計和SATD residuals 替換1st pass中相關部分,獲得預測
step2 用之前的樣本估計scale
step3 Overflow compensation 和2pass相似 限制filesize 犧牲圖像質量
1pass,:constant bitrate (VBV compliant)!!!
VBV是指: Video Buffer Verifier
The Video Buffer Verifier (VBV) is a model hypothetical decoder buffer that will not overflow or underflow when fed a conforming MPEG bit stream. 包含2個因素.size和造成的delay
step1 same as abr
step2 Scaling factor is based on a local average (dependent on VBV buffer size) instead of all past frames
step3 stricter Overflow compensation , additional term to hard limit the QPs if the VBV is near empty. no hard limit is done for a full VBV這裏更加嚴格的空限制,防止沒有bits可以送出,破壞了cbr的傳輸
1pass, constant ratefactor: Constant Rate Factor (or Constant Quality)
(1) Same as ABR.
(2) The scaling factor is a constant based on the --crf argument.
(3) No overflow compensation is done.
ratefactor是指:
constant quantizer:
QPs are simply based on frame type.
RC中的蛋雞悖論:爲了計算當前幀中宏塊的
RDO,需利用已定qp確定當前幀或宏塊的cost預測每個宏塊的mode mv ref等.
ratecontrol是在確定mode mv ref後決定qp,在此之前qp不能獲得。
於是rdo與rc不知道先做哪個了.
x264命令行參數解釋 收藏
本文對應的是x264命令行模式,VFW方式也用相同的參數,不過是圖形界面,可以自己找對應的英文。
使用格式:x264 默認選項 -o 輸出文件 輸入文件 [長x寬]
輸入支持格式:RAW/y4m/avi/avs(編譯時可選)
輸出支持格式:264/mkv/mp4(編譯時可選)
x264的許多參數可以有-/--兩種輸入法,筆者也不知道爲什麼。以下等價參數用“參
數1/參數2 <必需數值格式>”表示,參數尾部()內爲個人推薦。
-h/--help 幫助
幀類型選項:
-I/--keyint <整數> 最大IDR幀間距,默認250
-i/--min-keyint <整數> 最小IDR幀間距,默認25
--scenecut <整數> 畫面動態變化限,當超出此值時插入I幀,默認40
-b/--bframes <整數> 在IP幀之間可插入的B幀數量最大值,範圍0~16,默認0
--no-b-adapt 關閉自適應B幀判定(-b設爲1時可用,其他不推薦)
--b-bias <整數> 控制插入B幀判定,範圍-100~+100,越高越容易插入B幀,默認0
--b-pyramid 允許B幀做參考幀
--no-cabac 關閉內容自適應二進制算術編碼(CABAC,高效率的熵編碼)(會
提高速度,但嚴重影響質量)
-r/--ref <整數> 最大參考幀數,範圍0~16,默認1
--nf 關閉環路濾波(一種除馬賽克算法)
-f/--filter <alpha:beta>設置環路濾波的AlphaC和Beta的參數,範圍-6-6,默認都爲0
碼率控制選項:
-q/--qp <整數> 固定量化模式並設置使用的量化值,範圍0~51,0爲無損壓縮,默認26
-B/--bitrate <整數> 設置平均碼率
--crf <整數> 質量模式,量化值動態可變(目前不太成熟,質量不如設置固定量化值)
--qpmin <整數> 設置最小量化值,範圍0~51,默認10
--qpmax <整數> 設置最大量化值,範圍0~51,默認51
--qpstep <整數> 設置相鄰幀之間的量化值差,範圍0~50,默認4
--ratetol <小數> 平均碼率模式下,瞬時碼率可以偏離的倍數,範圍0.1~100.0,默認1.
0
--vbv-maxrate <整數> 平均碼率模式下,最大瞬時碼率,默認0(與-B設置相同)
--vbv-bufsize <整數> 碼率控制緩衝區的大小,單位kbit,默認0
--vbv-init <小數> 碼率控制緩衝區數據保留的最大數據量與緩衝區大小之比,範圍0~1.
0,默認0.9
--ipratio <小數> I幀和P幀之間的量化係數,默認1.40
--pbratio <小數> P幀和B幀之間的量化係數,默認1.30
--色度-qp-offset <整數> 色度和亮度之間的量化差,範圍-12~+12,默認0
-p/--pass <1|2|3> 多次壓縮碼率控制
1:第一次壓縮,創建統計文件
2:按建立的統計文件壓縮並輸出,不覆蓋統計文件,
3:按建立的統計文件壓縮,優化統計文件
--stats <字符串> 統計文件的名稱,默認"x264_2pass.log"
--rceq <字符串> 速率控制公式,默認"blurCplx^(1-qComp)"
--qcomp <小數> 線性量化控制,0.0爲固定碼率,1.0爲固定量化值,默認0.6,只用於2-
pass和質量模式
--cplxblur <小數> 根據相鄰幀平滑量化值比例的最大值,範圍0~99.9,默認20.0,只用
於2-pass和質量模式
--qblur <小數> 對統計文件結果平滑量化值比例的最大值,範圍0~99.9,默認0.5,只用於
2-pass
--zones <z0>/<z1>/… 分段量化,格式爲:<開始幀>,<結束幀>,<選項>,可選項爲:q=<
整數>(量化值)或b=<小數>(碼率倍數)
分析選項:
-A/--analyse <字符串> 動態塊劃分方法,默認"p8x8,b8x8,i8x8,i4x4"。可選項:p8x8/
p4x4/b8x8/i8x8/i4x4;none/all(p4x4需要p8x8. i8x8需要--8x8dct)
--direct <字符串> 動態預測方式,默認"spatial"。可選項:none/spatial/temp
oral/auto
-w/--weightb 允許B幀加權預測(可以減少相鄰B幀質量低的影響)
--me <字符串> 對全像素塊動態預測搜索的方式,默認"hex",可選項:
dia:菱形搜索,半徑1 (快)
hex:正六邊形搜索,半徑2
umh:可變半徑六邊形搜索
esa:全面搜索(很慢,而且效果與umh幾乎相同)
--merange <整數> --me爲umh/esa時的搜索半徑,最大64,默認16
-m/--subme <整數> 動態預測和分區方式,可選項1~7,默認5(與壓縮質量和時間關係密切
,1是7速度的四倍以上)
1:用全像素塊進行動態搜索,對每個塊再用快速模式進行四分之一像素塊精確搜索
2:用半像素塊進行動態搜索,對每個塊再用快速模式進行四分之一像素塊精確搜索
3:用半像素塊進行動態搜索,對每個塊再用質量模式進行四分之一像素塊精確搜索
4:用快速模式進行四分之一像素塊精確搜索
5:用質量模式進行四分之一像素塊精確搜索
6:進行I、P幀像素塊的速率失真最優化(rdo)
7:進行I、P幀運動矢量及塊內部的速率失真最優化(質量最好)
--b-rdo B幀也進行rdo,需要--subme在6以上
--mixed-refs 可以在一幀內使用不同參考幀
--no-chroma-me 不進行色度的動態預測
--bime 可以平均B幀參考塊的運動矢量
-8/--8x8dct 可以使用8x8的離散餘弦變換(DCT)
-t/--trellis <整數> Trellis量化,對每個8x8的塊尋找合適的量化值,需要CABAC,
默認0
0:關閉
1:只在最後編碼時使用
2:一直使用
--no-fast-pskip 關閉快速P幀跳過檢測
--no-dct-decimate 關閉P幀聯合編碼(可以增加細節,但也會增大體積)
--nr <整數> 噪聲去除,範圍0~100000,默認0
--cqm <字符串> 設置外部量化矩陣格式,默認"flat",可選項:jvt/flat
--cqmfile <字符串> 讀取JM格式的外部量化矩陣文件,自動忽略其他--cqm*選項
--cqm4 <list> 設置4x4的量化矩陣,用逗號分開,範圍1~255的16個整數
--cqm8 <list> 設置8x8的量化矩陣,用逗號分開,範圍1~255的64個整數
--cqm4i/--cqm4p/--cqm8i/--cqm8p 設置I、P幀不同的量化矩陣
--cqm4iy/--cqm4ic/--cqm4py/--cqm4pc 設置亮度、色度不同的量化矩陣
視頻標準化選項:
這些選項與編碼無關,不過如果要用mp4之類的播放器,可以設置,風險自擔
--sar width:height 設置長寬比
--overscan <字符串> 過掃描線,默認"undef"(不設置),可選項:show(觀看)/crop(去除
)
--videoformat <字符串> 視頻格式,默認"undef",可選項:component/pal/ntsc/secam
/mac/undef
--fullrange <字符串> Specify full range samples setting,默認"off",可選項:
off/on(我也不明白這是幹什麼的,請高手指點)
--colorprim <字符串> 原始色度格式,默認"undef",可選項:undef/bt709/bt470m/
bt470bg,smpte170m/smpte240m/film
--transfer <字符串> 轉換方式,默認"undef",可選項:undef/bt709/bt470m/bt47
0bg/linear,log100/log316/smpte170m/smpte240m
--colormatrix <字符串> 色度矩陣設置,默認"undef",undef/bt709/fcc/bt470bg,smpt
e170m/smpte240m/GBR/YCgCo
--chromaloc <整數> 色度樣本指定,範圍0~5,默認0
輸入、輸出選項:
--level <字符串> 設定等級(as defined by Annex A)(不明白,請高手指點)
--fps <小數> 設定幀率
--seek <整數> 設定起始幀
--frames <整數> 最大編碼幀數
-o/--output 指定輸出文件
--threads <整數> 編碼線程(使用分片技術)
--thread-input 在編碼線程中運行Avisynth
--no-asm 關閉全部CPU優化指令
--no-psnr 關閉PSNR計算
--quiet 安靜模式
-v/--verbose 顯示每一個幀的信息
--progress 顯示編碼進程
--visualize 顯示運動矢量
--sps-id <整數> 設置SPS和PPS的ID值,默認0
--aud 使用數據單元定義符號
x264中重要結構體說明 收藏
首先解釋一下cli_opt_t的這個_t代表結構圖可能是type的意思。同時還有很多i_ b_等作爲前綴的變量,其中的I_表示int類型的變量 b表示bool類型的。依次類推。
正式進入主題。
typedef struct {
int b_progress;
int i_seek;
hnd_t hin;
hnd_t hout;
FILE *qpfile;
} cli_opt_t;
此結構體是記錄一些與編碼關係較小的設置信息的opt=option。結構體內部的變量都可以通過讀取main()的參數獲得。也就是argv。
b_progress表示一個bool類型的變量,看參數幫助 也就是x264--help你會知道,他是用來控制是否顯示編碼進度的一個東西。取值爲0,1.
I_seek 整數類型 表示開始從哪一幀編碼。因爲不一定從這個文件的第一幀開始編碼,這是可以控制的。
Hnd_t(hnd=handle)是一個空指針, void *在C語言裏空指針是有幾個特性的,他是一個一般化指針,可以指向任何一種類型,但卻不能解引用,需要解引用的時候,需要進行強制轉換。採用空指針的策略,應該是爲了聲明變量的簡便和統一。
Hin 指向輸入yuv文件的指針。
Hout 指向編碼過後生成的文件的指針。
Qpfile 是一個指向文件類型的指針,他是文本文件,其每一行的格式是framenum frametype QP
用於強制指定某些幀或者全部幀的幀類型和QP(quant param量化參數)的值。
x264_param_default( ¶m );
這部分設置編碼參數的缺省值
附結構體param中部分變量的意義:
param->i_csp = X264_CSP_I420; // 設置輸入的視頻採樣的格式
param->vui.i_sar_width = 0; //VUI:video usability information
param->i_fps_num = 10; //幀率
param->i_fps_den = 1; //用兩個整型的數的比值,來表示幀率
/* Encoder parameters */
param->i_frame_reference = 1; //參考幀的最大幀數。
param->i_bframe = 0; //兩個參考幀之間的B幀數目。
param->b_deblocking_filter = 1; //去塊效應相關
param->b_cabac = 0; //cabac的開關
param->i_cabac_init_idc = -1;
param->rc.b_cbr = 1; //constant bitrate 恆定碼率控制模式
param->rc.i_bitrate = 0; //默認的碼率
param->rc.i_rc_buffer_size = 0; //buffer的大小
param->rc.i_rc_init_buffer = 0; //
param->rc.i_rc_sens = 100; ///* rate control sensitivity
param->rc.i_rc_method = X264_RC_NONE; //碼率控制,CQP(恆定質量)、//CRF(恆定碼率)、ABR(平均碼率)
param->rc.i_qp_constant = 26; //qp的初始值,最大最小的qp值,
param->rc.i_qp_min = 10; //最小的qp值
param->rc.i_qp_max = 51; //最大的qp值
param->rc.i_qp_step = 4; //qp[步長step。
param->rc.f_ip_factor = 1.4; //ip--i幀p幀的qp的差值
param->rc.f_pb_factor = 1.3; //pb--p幀b幀的qp的差值
/* Log */ //整個param的一個log文件
/*analyse */
param->analyse.intra = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8; //楨內分析
param->analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_I8x8 |X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16; //楨間分析
param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL; //預測模式
param->analyse.i_me_method = X264_ME_HEX; //運動估計模式
param->analyse.i_me_range = 16; //運動估計範圍
param->analyse.i_subpel_refine = 5;
param->analyse.b_chroma_me = 1;
param->analyse.i_mv_range_thread = -1;
param->analyse.i_mv_range = -1; // set from level_idc
param->analyse.i_direct_8x8_inference = -1; // set from level_idc
param->analyse.i_chroma_qp_offset = 0;
param->analyse.b_fast_pskip = 1;
param->analyse.b_dct_decimate = 1;
param->analyse.i_luma_deadzone[0] = 21;
param->analyse.i_luma_deadzone[1] = 11;
param->analyse.b_psnr = 1;
param->analyse.b_ssim = 1;
param->i_cqm_preset = X264_CQM_FLAT; //自定義量化矩陣(CQM),初始化量化模式爲flat
typedef struct
{
/* In: force picture type (if not auto)
* If x264 encoding parameters are violated in the forcing of picture types,
* x264 will correct the input picture type and log a warning.
* The quality of frametype decisions may suffer if a great deal of fine-grained
* mixing of auto and forced frametypes is done.
* Out: type of the picture encoded */
int i_type;
/* In: force quantizer for > 0 */
int i_qpplus1;
/* In: user pts, Out: pts of encoded picture (user)*/
int64_t i_pts;
/* In: raw data */
x264_image_t img;
} x264_picture_t;
具體的含義理解參考了read_frame_yuv()x264_picture_alloc();
I_type 指明被編碼圖像的類型,有X264_TYPE_AUTO X264_TYPE_IDR X264_TYPE_I X264_TYPE_P X264_TYPE_BREF X264_TYPE_B可供選擇,初始化爲AUTO,說明由x264在編碼過程中自行控制。
I_qpplus1 :此參數減1代表當前畫面的量化參數值。
I_pts :program time stamp 程序時間戳,指示這幅畫面編碼的時間戳。
Img :存放真正一副圖像的原始數據。
typedef struct
{
int i_csp;
int i_plane;
int i_stride[4];
uint8_t *plane[4];
} x264_image_t;
Csp: color space parameter 色彩空間參數 X264只支持I420
i_Plane 代表色彩空間的個數。一般爲3,YUV,初始化爲
x264常用options整理 收藏
x264源碼解析
2009年11月12日 星期四 22:44
x264源碼解析(01)
|
1、x264學習筆記(9)--x264中16x16運動搜索過程
函數實現是函數 static void x264_mb_analyse_inter_p16x16( x264_t *h, x264_mb_analysis_t *a )
1、大循環是參考幀的循環,從最近的一個參考幀開始搜索,一直到最遠的一個參考幀;
2、調用x264_mb_predict_mv_16x16函數,以上、右上、左塊運動矢量的中值m.mvp作爲候
選運動矢量。
3、調用x264_mb_predict_mv_ref16x16函數,尋找其它候選運動矢量。這些候選者包括:
空間相鄰的左、左上、上、右上塊的MV;第0個參考幀中的當前塊、右邊塊、下邊快運動矢
量乘以時間差權重。
4、調用x264_me_search_ref進行運動搜索。搜索時先從所有候選運動矢量中選出最佳的起
點,然後使用小鑽石法、六邊形法、UMH或者全搜索搜索出最佳的整像素位置。
5、x264_me_search_ref調用refine_subpel進行1/2和1/4運動搜索。兩者都使用小鑽石法
。
6、搜索出最佳運動矢量後,如果當前是最近一個參考幀,而且最佳SA(T)D小與檢測門限,
則嘗試對其進行P_SKIP編碼。
7、保存搜索結果。
2、x264學習筆記(10)---分像素的運動估計總結
得到分像素的值函數是下面兩個函數,對照着
(1) static uint8_t *get_ref( uint8_t *src[4], int i_src_stride,
uint8_t *dst, int * i_dst_stride,
int mvx,int mvy,
int i_width, int i_height )
{
int qpel_idx = ((mvy&3)<<2) + (mvx&3); //取出運動矢量的分像素部分。
int offset = (mvy>>2)*i_src_stride + (mvx>>2); //偏移到所選的整像素點
uint8_t *src1 = src[hpel_ref0[qpel_idx]] + offset + ((mvy&3) == 3) * i_src_stride;
/*src1和src2都分別指向的是1/2像素塊,關鍵是這個hpel_ref0[qpel_idx]和hpel_ref1[qpel_idx],下面將詳細介紹。
注意一點就是參考幀定義了uint8_t *p_fref[2][32][4+2]; /* last: lN, lH, lV, lHV, cU, cV */
這裏面的 4+2 的這個2代表色度,而這個4分別代表整像素,在整像素水平右邊的1/2像素,在整像素垂直下面的1/2像素和整像素右下角的1/2像素。1/2像素的值已經在前面函數裏面插值存好了,只要調用就可以了,而如果要進行1/4像素估計,要臨時插值。現在這個函數 get_ref 中,src[0]、src[1]、src[2]、src[3]這傳進來的就是分別是 lN, lH, lV, lHV
*/
if( qpel_idx & 5 ) /* qpel interpolation needed */
{
uint8_t *src2 = src[hpel_ref1[qpel_idx]] + offset + ((mvx&3) == 3);
pixel_avg( dst, *i_dst_stride, src1, i_src_stride,
src2, i_src_stride, i_width, i_height );//1/4搜索時需要臨時插值函數
return dst;
}
else
{
*i_dst_stride = i_src_stride;
return src1;
}
}
按照 畢厚傑 的《新一代視頻壓縮編碼標準——H.264/AVC》關於運動矢量那一節的介紹。看圖6.22
那四個像素點,G爲整像素點 b、h、i分別是lH, lV, lHV,也就是水平,垂直和對角線的值。
G b
h i
對應爲
src[0] src[1]
src[2] src[3]
現在看這兩個數組
static const int hpel_ref0[16] = {0,1,1,1,0,1,1,1,2,3,3,3,0,1,1,1};
static const int hpel_ref1[16] = {0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2};
也按像素的平面圖畫出來的話
src[hpel_ref0[qpel_idx]]爲
0 1 1 1
0 1 1 1
2 3 3 3
0 1 1 1
src[hpel_ref1[qpel_idx]]爲
0 0 0 0
2 2 3 2
2 2 3 2
2 2 3 2
這上面的數字 0、1、2、3分別代表 整像素、水平1/2像素值、垂直1/2像素值 和對角線1/2像素值,也就是畢厚傑書中的 G、b、h、I 。這裏要注意src[hpel_ref0[qpel_idx]]最後一行的 0 1 1 1 和src[hpel_ref1[qpel_idx]]最右邊一列0 2 2 2不是當前的整像素0的1/2像素,而分別是其下面和右邊一個整像素的對應的1/2像素值,因爲 ((mvy&3) == 3) * i_src_stride 和((mvx&3) == 3)。
爲什麼要這麼來排,是因爲要根據1/4像素是通過1/2像素線性插值的公式來的,具體看下面這個函數。
(2) static inline void pixel_avg( uint8_t *dst, int i_dst_stride,
uint8_t *src1, int i_src1_stride,
uint8_t *src2, int i_src2_stride,
int i_width, int i_height )
{ //1/4搜索時需要臨時插值函數
int x, y;
for( y = 0; y < i_height; y++ )
{
for( x = 0; x < i_width; x++ )
{
dst[x] = ( src1[x] + src2[x] + 1 ) >> 1; //利用相鄰半像素和兩個像素取平均插值
}
dst += i_dst_stride;
src1 += i_src1_stride;
src2 += i_src2_stride;
}
} 不過最後我有個疑問,那就是1/4插值後,應該原來的1/2 值保持不變的.但是分析發現,這個 b 、h、 i 這三個1/2像素中,h和i是不變的,不過 b會發生變化. 個人覺得 static const int hpel_ref1[16] = {0,0,0,0,2,2,3,2,2,2,3,2,2,2,3,2};如果改爲 static const int hpel_ref1[16] = {0,0,1,0,2,2,3,2,2,2,3,2,2,2,3,2};則 b也不會發生變化. 所以這裏打個問號?
3、x264學習筆記(11)---關於運動矢量MV不傳輸的問題
昨天看到H.264樂園羣裏面有人在討論運動矢量MV不用傳輸的問題,就去看了下x264源代碼,作個總結
編碼端: 運動估計搜索得到的運動矢量MV是不需要傳送的,需要傳送的是MVD,MVD即運動矢量MV(運動估計得到)和運動矢量的預測矢量MVP(預測得到)的差值。
MVD = MV - MVP
解碼端:通過預測得到MVP,將傳輸過來的MVD和MVP相加得到 MV = MVD + MVP,然後用這個MV去參考幀中獲取預測象素值,最後把這個預測值和殘差加一起, 作爲重構像素值
x264中把這個過程放在了熵編碼階段,在這個函數裏 x264_macroblock_write_cabac
MVD並保存下來以備傳輸的函數如下:
static inline void x264_cabac_mb_mvd( x264_t *h, x264_cabac_t *cb, int i_list, int idx, int width, int height )
{
int mvp[2];
int mdx, mdy;
/* Calculate mvd */
x264_mb_predict_mv( h, i_list, idx, width, mvp ); //預測MVP
mdx = h->mb.cache.mv[i_list][x264_scan8[idx]][0] - mvp[0]; //計算MVD
mdy = h->mb.cache.mv[i_list][x264_scan8[idx]][1] - mvp[1];
/* encode */
x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 0, mdx ); //編碼
x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 1, mdy );
/* save value */
x264_macroblock_cache_mvd( h, block_idx_x[idx], block_idx_y[idx], width, height, i_list, mdx, mdy ); // 保存MVD
}
4、firstime
MV預測過程詳解(附圖)
===========第一步:確定相鄰塊===========
MV 預測以宏塊分割(或亞宏塊分割,如果宏塊存在亞分割)爲單位,同一個宏塊分割(或亞宏塊分割)內所有 4*4 塊 MV 預測值相同。以每個宏塊分割(或亞宏塊分割)的左上角像素 pixel1 和右上角像素 pixel2 爲參考點來確定相鄰塊則:
pixel1 左側相鄰像素所在 4*4 塊爲當前宏塊分割(或亞宏塊分割)的相鄰塊 A
pixel1 上方相鄰像素所在 4*4 塊爲當前宏塊分割(或亞宏塊分割)的相鄰塊 B
pixel2 右上對角線像素所在 4*4 塊爲當前宏塊分割(或亞宏塊分割)的相鄰塊 C
pixel1 左上對角線像素所在 4*4 塊爲當前宏塊分割(或亞宏塊分割)的相鄰塊 D
圖片附件: MV預測示意圖.JPG (2006-9-29 11:14 AM, 85.25 K)
以最複雜的 8*8 宏塊分割類型爲例(此時只存在亞宏塊分割),分析如下:
假設圖中黑色框表示宏塊、每個綠色框表示一個 4*4 塊、每個紅色框表示一個 8*8 塊。當前宏塊的宏塊分割模式爲 8*8(如圖中紅色線),其亞宏塊分割模式分別爲:第一個 8*8 塊爲 8*8,第二個 8*8 塊爲 4*4(如圖中藍色線),第三個 8*8 塊爲 4*8(如圖中藍色線),第四個 8*8 塊爲 8*4(如圖中藍色線)。則按照上述方法來確定相鄰塊的方法如下:
第一個預測對象爲第一個 8*8 塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 7 號 4*4 塊,B 爲 2 號 4*4 塊,C 爲 4 號 4*4 塊,D 爲 1 號 4*4 塊。9、14、15 與 8 具有相同 MV 預測值
第二個預測對象爲第二個 8*8 塊的第一個 4*4 塊,即 10 號塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 9 號4*4塊,B 爲 4 號4*4塊,C 爲 5 號 4*4 塊, D 爲 3 號 4*4 塊
第三個預測對象爲第二個 8*8 塊的第二個 4*4 塊,即 11 號塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 10 號4*4塊,B 爲 5 號4*4塊,C 爲 6 號 4*4 塊,D 爲 4 號 4*4 塊
第四個預測對象爲第二個 8*8 塊的第三個 4*4 塊,即 16 號塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 15 號4*4塊,B 爲 10 號4*4塊,C 爲 11 號 4*4 塊,D 爲 9 號 4*4 塊
第五個預測對象爲第二個 8*8 塊的第四個 4*4 塊,即 17 號塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 16 號4*4塊,B 爲 11 號4*4塊,C 爲 12 號 4*4 塊,D 爲 10 號 4*4 塊
第六個預測對象爲第三個 8*8 塊的第一個 4*8 塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 19 號 4*4 塊,B 爲 14 號 4*4 塊,C 爲 15 號 4*4 塊,D 爲 13 號 4*4 塊。26 與 20 具有相同 MV 預測值
第七個預測對象爲第三個 8*8 塊的第二個 4*8 塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 20 號 4*4 塊,B 爲 15 號 4*4 塊,C 爲 16 號 4*4 塊,D 爲 14 號 4*4 塊。27 與 21 具有相同 MV 預測值
第八個預測對象爲第四個 8*8 塊的第一個 8*4 塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 21 號 4*4 塊,B 爲 16 號 4*4 塊,C 爲 18 號 4*4 塊,D 爲 15 號 4*4 塊。23 與 22 具有相同 MV 預測值
第九個預測對象爲第四個 8*8 塊的第二個 8*4 塊,以其左上角像素 pixel1 和右上角像素 pixel2 爲參考點,則:A 爲 27 號 4*4 塊,B 爲 22 號 4*4 塊,C 爲 24 號 4*4 塊,D 爲 21 號 4*4 塊。29 與 28 具有相同 MV 預測值
===========第二步:確定 A、B、C 的可用性===========
根據 A、B、C 所在宏塊是否存在或者是否允許參與預測來判斷。如果 C 不可用,採用 D 代替 C
===========第三步:預測 MV ===========
1、如果 A、B、C 三個參考塊中只有一個與當前預測對象爲同一參考幀,則選取該參考塊的 MV 作爲最終 MV 預測值
2、當前宏塊是否爲 8*16 或者 16*8 分割:
(1)、如果當前宏塊爲 8*16 分割類型:
對於左邊 8*16 分割,如果 A 與當前分割爲同一參考幀,則採用 A 的 MV 爲該分割的最終 MV 預測值
對於右邊 8*16 分割,如果 C 與當前分割爲同一參考幀,則採用 C 的 MV 爲該分割的最終 MV 預測值
(2)、如果當前宏塊爲 16*8 分割類型:
對於上邊 16*8 分割,如果 B 與當前分割爲同一參考幀,則採用 B 的 MV 爲該分割的最終 MV 預測值
對於下邊 16*8 分割,如果 A 與當前分割爲同一參考幀,則採用 A 的 MV 爲該分割的最終 MV 預測值
3、其餘情況並且 B、C 中有一個可用或者兩者都可用,則採用中值預測(取 A、B、C 三者中MV的中值爲最終 MV 預測值)
4、其餘情況並且 B、C 皆不可用,則採用 A 的 MV 爲最終 MV 預測值
【注】:1、宏塊分割時的相鄰塊確定方法與第一步所述過程雷同:16*16 相當於 8*8,8*16、16*8 分別相當於 4*8、8*4
2、對於不可用的相鄰塊,其 MV 仍然可能參與 MV 預測,但其值爲 0。例如:A 不可用,B、C 可用,則最終可能仍然是在 A、B、C 中取中值,但此時 A 的 MV 爲 0;
3、對於不可用的相鄰塊,其參考幀索引被設置爲 -1,即必然與當前預測對象非同一參考幀;
4、可以驗證:同時滿足第三步的第一、第二兩種情況時,按第一種情況計算 MV 預測值與按第二種情況計算 MV 預測值等效;
5、該預測過程即爲標準 8.4.1.3 小節的內容,在 JM86 中對應的代碼爲 SetMotionVectorPredictor 函數;
6、MBAFF 情況下的相鄰塊均指對應位置(co-locate)塊。
常規選項設置
在常規選項欄中的參數設置及含義如下:
輸出路徑:設置最後生成的MP4-AVC所在的目錄。
建議:設置到的分區有較大的剩餘空間
保持文件夾結構:減少文件碎片。
建議:勾選
在視頻選項欄中的參數設置及含義如下:
模式:設置轉換視頻時所採用的編碼方式。可選項:
1.Bitrate-based固定比特率;
2.Quality-based動態比特率,基於質量模式,文件大小不可控;
3.Two-Pass轉換兩遍
4.Three-Pass轉換三遍。
建議:選擇Quality-based
滑條:設置轉換時使用的比特率(Bitrate-based、Two-Pass、Three-Pass,範圍0Kbps-20000Kbps)及原來視屏質量的百分比(Quality-based範圍1-100),數值越大質量越好,文件越大。其中在Quality-based模式下數值調整到100(--crf 0)爲無損壓縮,且文件大小不能預測。
建議:在Quality-based模式下設置爲52
轉換視頻流:設置MediaCoder對視頻進行編碼時的參數。只有勾選了該項後,纔會啓用編碼器對原始視頻進行編碼。
建議:勾選
格式編碼設置
格式:設置轉換後臨時的視屏文件(未與音頻文件封裝之前)的格式。可選項:XviD、H.264、MPEG1、MPEG2、MPEG4、Theora、Flash Video、Dirac Video、Windows Media Video、RealMedia、H.263、H.263+、H.261、MS-MPEG4-V2、DV Video、Motion JPEG、Lossless JPEG、Huffyuv、
Snow、AMV、Raw Video
建議:選擇H.264
(注意:格式的選擇會影響下面容器的選擇,不是所有的格式都能封裝到一個容器中的!由於我們是轉MP4-AVC的所以格式選擇H.264!)
容器:最後進行封裝時使用的容器,如XXXX.AVI就是使用的AVI作爲容器。可選項:Default、AVI、MP4、Matroska、MPEG1、MPEG2、MPEG2-TS、Flash Video、ASF、3GP、3GP2、MOV、MJPEG、RealMedia、DV Forma、OGG、NUT、PMP、Raw Stream
建議:選擇MP4 java強烈推薦:Matroska (MKV)
(注意:很多轉換任務一開始就報有關容器的錯誤,是因爲混流軟件對轉換後的音頻文件或視頻文件無法混流所致.具體MediaCoder的混流器能封裝什麼格式的視頻文件和音頻文件,請參考其他有關資料!)
複製視屏流:當勾選參數時,MediaCoder不會對原始視頻進行轉換,而是直接無損提取。
建議:不勾選
(注意:只有勾選轉換視頻流時,複製視頻流的設置纔會有效!)
來源:設置MediaCoder對原視屏解碼時所使用的解碼方式。可選項:Bypass、MPlayer、MEncoder、FFmpeg、WM Decoder、JM Decoder、AviSynth、File Stream
建議:勾選自動選擇
(注意:只有不勾選自動選擇時才能選擇以上解碼方式,不正確的選擇會導致文件轉換失敗!)
編碼器:設置MediaCoder對視屏編碼時所使用的編碼器。可選項:MEncoder、FFmpeg、x264、JM Encoder、XviD、Theora Encoder、Dirac、WM Encoder、VFW Encoder、AMV Encoder、Stream Dumper、Frame Dumper、x264 Remote
建議:選擇x264
(注意:只有不勾選自動選擇後才能選擇以上編碼器。不正確選擇會導致轉換失敗.要轉換MP4-AVC則必須選擇x264以防轉換失敗!)
右邊選區點擊x264選項欄進行視頻質量的設置
規格:壓縮時使用規格模式。可選項:Auto、Baseline、Main、High
建議:選擇Main 現在的MP4如艾諾v6000HDV 可以用High
(注意:需要在PSP上播放的MP4-AVC必須選擇Main,否則PSP無法播放!)
級別:--Level:表示編、解碼等級
(注意:無論是轉480x272的MP4-AVC,還是720x480的MP4-AVC建議選擇Level3.0,防止PSP無法播放!)
參考幀數:--ref:最大參考幀數,範圍0-16。該參數對質量和壓縮比都有提高。
建議:設置大於1
B幀數:--bframes:在I幀與P幀之間可插入B幀數量的最大值,範圍0-16。
建議:設置大於1
運動估算模式
運動估算模式:--me:對全像素塊動態預測搜索的方式,可選項:
Diamond:菱形搜索,搜索半徑爲1;
Hexagonal:正六邊形搜索,搜索半徑爲2;
Uneven Multi-Hexagon:可變半徑六邊形搜索;
Exhaustive:全面搜索;
Hadamard Exhaustive:用Hadamard方式進行全面搜索,比Exhaustive更慢。
建議:選擇Uneven Multi-Hexagon
(注意:建議設爲Uneven Multi-Hexagon;Exhaustive和Hadamard Exhaustive實在太慢了,而且畫面質量提高極不明顯。除非你不怕浪費時間且追求高質量畫面的骨灰級玩家並且很相信自己機器配置那麼就選Hadamard Exhaustive吧!)。
子像素質量優化:--subme:動態預測和分區方式,可選項1-9
1:用全像素塊進行動態搜索,對每個塊再用快速模式進行四分之一像素塊精確搜索
2:用半像素塊進行動態搜索,對每個塊再用快速模式進行四分之一像素塊精確搜索
3:用半像素塊進行動態搜索,對每個塊再用質量模式進行四分之一像素塊精確搜索
4:用快速模式進行四分之一像素塊精確搜索
5:用質量模式進行四分之一像素塊精確搜索
6:進行I、P幀像素塊的速率失真最優化(rdo)
7:進行全部幀像素塊的速率失真最優化
8:進行I、P幀運動矢量及塊內部的速率失真最優化
9:進行全部幀運動矢量及塊內部的速率失真最優化
建議:選擇7
(注意:該選項選擇的數值越大畫面質量越好,而編碼的速度越慢!)
運動估算半徑:--merange:當運動估算模式選項中選擇Uneven Multi-Hexagon或Exhaustive時的搜索半徑,最大64。
建議:設置爲16
幀的相關設置
2.x264的參數設置
點擊高級進行有關x264編碼器的高級參數設置
(注意:當要更改參數時,選中該參數後在對話框左下角進行參數選擇更改,如果是數值型的參數在填入參數數值後點擊對話框左下角的Apply進行保存,每改一個數值型參數都要點擊Apply保存。非數值型參數則不用點擊任何按鈕即可保存。右下角Revert爲恢復默認值。沒有說明的只需保持默認即可!)
Bitstream profile:壓縮時使用規格模式。可選項:Auto、Baseline、Main、High建議:選擇Main
(注意:需要在PSP上播放的MP4-AVC必須選擇Main,否則PSP無法播放!)
Bitstream level:--Level:表示編、解碼等級
(注意:無論是轉480x272的MP4-AVC,還是720x480的MP4-AVC建議該參數選擇爲30,防止PSP無法播放!)
P frame Quantitizer:--qp:固定量化模式並設置使用的量化值。
Maximum interval between IDR-frames:--keyint:最大IDR幀間距。一般來說壓制動畫時,可以增大該值。
默認值:250
Minimum interval between IDR-frames:--min-keyint:最小IDR幀間距。一般來說壓制動畫時,可以減小該值。
默認值:25
Frames used as predictors in B and P frames:--ref:最大參考幀數,範圍0-16。該參數對質量和壓縮比都有提高。
建議:大於1
(注意:數值越高速度越慢!)
Maximum B frames between I and P frames:--bframes:在I幀與P幀之間可插入B幀數量的最大值,範圍0-16。
建議:大於1
(注意:數值越高速度越慢!)
Adaptive B-frame decision method:--b-adapt:自適應B幀判定模式。0:關閉;1:快速;2:優化。下拉菜單中:0-Off爲:關閉,1-Fast爲:快速,2-Optimal爲:優化。默認值爲:1-Fast。
建議:選擇2-Optimal
(注意:當該選項選擇爲2時, Number of B-frames參數設置較高時,編碼速度會下降!)。
B-frames used as for predicting:--b-pyramid:允許B幀做參考幀。
建議:選擇No
Alpha parameter of deblocking filter:設置環路濾波的AlphaC的參數,範圍-6-6。
默認值:0
Beta parameter of deblocking filter:設置環路濾波的Beta的參數,範圍-6-6。
默認值:0
(注意:Alpha parameter of deblocking filter和Beta parameter of deblocking filter在X264中的參數爲--deblock 0:0前一個0對應Alpha parameter of deblocking filter的參數值,後一個0對應Beta parameter of deblocking filter的參數值!)
熵編碼與緩衝
Use CABAC:內容自適應二進制算術編碼,高效率的熵編碼。關閉該參數時會嚴重降低畫面質量,但是能提高編碼速度。(當不勾選該項時該參數顯示爲:--no-cabac)。
默認值:選擇Yes
Minimum quantizer:--qpmin:設置最小量化值,範圍0-51。
默認值:10
Maximum quantizer:--qpmax:設置最大量化值,範圍0-51。
默認值:51
Quantizer step:--qpstep:設置相鄰幀之間的量化值差,範圍0-50。
默認值:4
Maximum local bitrate:--vbv-maxrate:平均碼率模式下,最大瞬時碼率 (與-B設置相同)。
默認值:0
(注意:該參數的取值與在ABR編碼模式下的Bitrate(碼率)保持一致!)
Averaging period for maximum local bitrate:--vbv-bufsize:碼率控制緩衝區的大小,單位kbit。
默認值:0
Initial buffer occupancy:--vbv-init:碼率控制緩衝區數據保留的最大數據量與衝區大小之比,範圍0-1.0。
默認值:0.9
Quantizer compression percentage:--qcomp:線性量化控制,0.0爲固定碼率,1.0爲固定量化值,只能用於二次壓縮和基於質量的壓縮模式。
默認值:60
Direct macroblocks prediction:--direct:動態預測方式。可選項:None、Spatial、Temporal、Auto。
默認值:Temporal。
建議:選擇Auto
Use weighted prediction for B-frames:--weightb:允許B幀加權預測,可以減少相鄰B幀質量低的影響,對質量和壓縮比都有提高,且對速度影響極少。
建議:選擇Yes
(注意:要使該參數生效需要讓Maximum B frames between I and P frames設置大於1!)
Enable all macroblock type:動態塊劃分方法,在Level較低時允許使用包括8x8、4x8、4x4劃分方法。
建議:選擇Yes
(注意:如果要使用這些劃分方法,需要Subpel refinement quality設置大於等於5!)
Adaptive spatial transform size:允許動態劃分方法在4x4和8x8DCT之間自動選擇,並且允許使用i8x8動態劃分方法。
建議:選擇Yes
(注意:如果選擇No那麼只是用4x4DCT動態預測!)
動態預測與分區
Fullpixel motion estimation algorithm:--me:對全像素塊動態預測搜索的方式,可選項:
Diamond:菱形搜索,搜索半徑爲1;
Hexagonal:正六邊形搜索,搜索半徑爲2;
Uneven Multi-Hexagon:可變半徑六邊形搜索;
Exhaustive:全面搜索;
Hadamard Exhaustive:用Hadamard方式進行全面搜索,比Exhaustive更慢。
建議:選擇Uneven Multi-Hexagon
(注意:建議設爲Uneven Multi-Hexagon;Exhaustive和Hadamard Exhaustive實在太慢了,而且質量提高極不明顯。除非你不怕浪費時間且追求高質量畫面的骨灰級玩家並且很相信自己機器配置,那麼就選Hadamard Exhaustive吧!)
Motion search radius:--merange:Fullpixel motion estimation algorithm選擇爲Uneven Multi-Hexagon或Exhaustive時的搜索半徑,最大64。
默認值:16
Ignore chroma in motion estimation:不進行色度的動態預測。
建議:選擇No
(注意:當選則Yes時該參數顯示爲:--no-chroma-me!)
Subpel refinement quality:--subme:動態預測和分區方式,可選項1-9
1:用全像素塊進行動態搜索,對每個塊再用快速模式進行四分之一像素塊精確搜索
2:用半像素塊進行動態搜索,對每個塊再用快速模式進行四分之一像素塊精確搜索
3:用半像素塊進行動態搜索,對每個塊再用質量模式進行四分之一像素塊精確搜索
4:用快速模式進行四分之一像素塊精確搜索
5:用質量模式進行四分之一像素塊精確搜索
6:進行I、P幀像素塊的速率失真最優化(rdo)
7:進行全部幀像素塊的速率失真最優化
8:進行I、P幀運動矢量及塊內部的速率失真最優化
9:進行全部幀運動矢量及塊內部的速率失真最優化
建議:設置爲7
(注意:該選項選擇的數值越大畫面質量越好速度越慢!)
Psy算法與量化值
Psychovisual optimization strength for RDO:--psy-rd 0:0:在rdo中使用Psy算法(一種心理視覺模型)。
默認值:1.0
建議:0
(注意:這個參數對應--psy-rd 0:0中前面的數值!當Subpel refinement quality參數大於等於6時才能使用該這個參數。該參數會影響到Chroma Qp Offset參數。當設置該數設置爲1.0時Chroma Qp Offset會自動設置爲-2;當該參數設置爲0時Chroma Qp Offset會自動設置爲0!)
Psychovisual optimization strength for Trellis:--psy-rd 0:0sy-Trellis量化,可提高細節,但會大幅提高碼率。
默認值:0.0。
(注意:該參數需要Subpel refinement quality參數大於等於6且Trellis參數大於等於1才能使用。這個參數對應--psy-rd 0:0中後面的數值!)
Mixed reference frame:--mixed-refs:可以在一幀內使用不同參考幀。該參數能提高畫面質量,但對速度影響較大。
默認值:不勾選
建議:勾選
Rate-distortion optimal quantization(trellis):--trellis:Trellis量化,對每個8x8的塊尋找合適的量化值,需要勾選CABAC才能使用該參數。可選項:
Disabled:關閉(0);
Enabled only for the final encode:只在最後編碼時使用(1);
Enabled during all mode decision:一直使用(2)。
默認值:0
建議:開啓該參數
(注意:該參數能提畫面高質量,配置較低的電腦且對畫面質量沒有要求的用戶可以選擇Enabled only for the final encode,配置較高的電腦且對畫面質量有要求的用戶可以選擇Enabled during all mode decision;畫面質量:Enabled only for the final encode比Enabled during all mode decision差!編碼速度:Enabled only for the final encode比Enabled during
all mode decision快!)
量化模式等設置
How AQ distribures bits:--aq-mode:自適應量化模式,可以在1幀中不同宏塊間重新分配量化值,能提高暗部細節,但會提高碼率。不能在固定量化模式(Const.Quantizer模式)中使用。0:關閉;1:開啓。可選項:
Disabled:關閉(0);
Variance:AQ開啓(1)。
默認值:Variance AQ(1)
Reduce blocking and blurring in flat and texture areas:--aq-strength:AQ強度,減小低細節宏塊的量化值。可選項:Weak、Normal、Strong。
默認值:Normal
Intra luma quantization deadzone:--deadzone-intra:設置intra模式下,亮度死區量化值,範圍0-32。
默認值:11
Inter luma quantization deadzone:--deadzone-inter:設置inter模式下,亮度死區量化值,範圍0-32;
默認值:21
Performs early skip detection in P-frames:關閉P幀快速跳過的檢測。
默認值:Yes
建議:勾選No
(注意:勾選No後視屏參數中顯示爲:--no-fast-pskip!)
Eliminate DCT blocks with small coefficient:關閉P幀聯合編碼。關閉該項後可以增加細節,但也會增大體積。
默認值:Yes
建議:勾選No
(注意:勾選No後視屏參數中顯示爲:--no-dct-decimate!)
Noise reduction:--nr:噪聲去除,範圍0-100000。
默認值:0
Interlaced video content:--interlaced:啓用純交錯模式。用於隔行掃描的源。
默認值:No
Global header:在基於碼率的編碼模式下 SPS和PPS只會在開頭出現一次。許多播放器(如索尼的PSP)需要使用這一功能.默認會讓PPS在每個階段重複檢測。
默認值:No
Use access unit delimiters:--aud:使用數據定義符號。
默認值:No
Enable picture timing data:允許畫面啓用定時數據。
默認值:No
Set SPS and PPS id number:--sps-id:設置SPS和PPS的ID值。
默認值:0
JM-compatible custom quant matrices file:--cqmfile:讀取JM格式的外部量化矩陣文件。
默認值:空
(注意:如果設置了該選項x264會自動忽略其他--cqm選項)
編碼線程與加速
Threads:--threads:編碼線程,使用多線程技術。多核CPU可以選擇自己的CPU核數加快編碼速度。
默認值:0(自動)
Non-deterministic:--non-deterministic:非確定性。可以稍微減少多線程的開銷。
默認值:Yes
Crop overscan setting:--overscan:過掃描線。可選項:
Undefined:不設置
Show:觀看
Crop:去除
默認值:Undefined(不設置)
Video format:--videoformat:視頻格式,有點像播放制式。
可選項:Component、Pal、Ntsc、Secam、Mac、Undefined.
默認值:Undefined
Full range samples setting:--fullrange:指定顏色全範圍樣本設置。
默認值:No
Color Primaries:--colorprim:原始色度格式。
默認值:空
Transfer characteristics:--transfer:轉換方式。
默認值:空
Color matrix setting:--colormatrix:色度矩陣設置.
默認值:空
Chroma sample location:--chromaloc:色度樣本指定,範圍0-5。
默認值:0
(注意:以上畫有波浪線的參數關係到MP4播放器能否正常播放,強烈列建議如果使用是MP4播放器不要設置以上畫波浪線的參數,默認即可!)
Turbo Mode:在多次編碼時通過降低Subpel refinement quality參數和Frames used as predictors in B and P frames參數從而加速第一次編碼的速度。
可選項:
Disabled:禁止使用加速功能。
Reduce subq:保持Subpel refinement quality參數爲用戶設置參數不變,降低Frames used as predictors in B and P frames參數爲1。
Reduce subq and frameref to 1:將Subpel refinement quality參數和Frames used as predictors in B and P frames參數都降低爲1.
默認值:Reduce subq and frameref to 1
(注意:碼速度Reduce subq and frameref to 1的編碼速度大於Reduce subq大於Disabled;編碼質量Disabled優於Reduce subq優於Reduce subq and frameref to 1!)
在音頻選項欄中的參數設置及含義如下:
轉換音頻流:對原始音頻進行編碼。只有勾選該項後,纔會啓用編碼器對原始音頻進行編碼。
建議:勾選
(注意:當轉換音頻流不勾選時,MediaCoder所轉換的MP4-AVC是沒有聲音的!)
音頻解碼方式
來源:設置MediaCoder對原視頻的音頻解碼時所使用的解碼方式。可選項:Default、MPlayer、Mencoder、FFmpeg、Winamp Input Plugins、AviSynth、Lame MP3 Decoder、FLAC Decoder、WavPack Decoder、APE Decoder、Waveform File、Waveform Composer、CD Audio
建議:勾選自動選擇
(注意:只有不勾選自動選擇時才能選擇以上解碼方式,不正確的選擇會導致文件轉換失敗!)
編碼器:設置MediaCoder對視頻的音頻編碼時所使用的編碼器。可選項:Lame MP3、Vorbis、Nero Encoder、FAAC、CT AAC+、3GPP AAC+、Windows Media Audio、Helix MP3、Fraunhofer IIS MP3、MusePack、Speex、AMR、Ffmpeg、MEncoder、WavPack、FLAC、APE、TTA、ALS、OptimFROG、lossyWAV、Waveform、Stream Dumper、Generic CLI
建議:選擇Nero Encoder
(注意:Fraunhofer IIS MP3和 AMR是沒有安裝的,用戶如有需要,點擊彈出的對話框中的確定後在自動彈出的網頁中下載安裝編碼器。其他編碼器中有少部分不能進行參數調整。要轉換MP4-AVC建議選擇Nero Encoder以防轉換失敗!)
複製音頻流:當勾選參數時,MediaCoder不會對原始音頻進行轉換,而是直接無損提取。
建議:不勾選
(注意:只有勾選轉換音頻流時,複製音頻流的設置纔會有效!)
右邊選區點擊Nero Encoder選項欄進行音頻質量的設置
規格:設置編碼時所採用的編碼規範。可選項:Auto、LC-AAC、HE-AAC、HE-AAC V2
建議:選擇Auto
碼率模式:設置MediaCoder對音屏編碼時採用的編碼方式。可選項:
1.Target Quality動態編碼率(VBR);
2.Target Bitrate平均編碼率(ABR);
3.CBR固定編碼率(CBR);
建議:選擇Target Quality
碼率/質量:設置音頻編碼器的的編碼質量。當編碼模式選擇Target Bitrate或CBR時,範圍8-320,數值越大音質越好,編碼後的文件越大;當編碼模式選擇Target Quality時,範圍0-100,數值越大音質越好。
建議:編碼模式選擇Target Quality時調整到60
(注意:選用Target Quality轉換的音頻文件的大小不可預測!)
Hint Track:增加音頻索引。
建議:不勾選
音軌ID:當視頻文件有多個音軌時(不是多個聲道),可以選取不同的音軌。
建議:默認
外部文件:當轉換時需要採用別的音頻文件配音時,可以在添加需要轉換的視頻文件後,勾選該項並進行其他音頻文件的選擇。
建議:一般情況下不勾選
(注意:只有添加視頻文件後才能啓用該選項的設置!)
音軌模式選擇
雙音軌模式:當原視頻文件包含兩條音軌時,可將這兩條音軌同時轉換並封裝。
建議:不勾選
分辨率:勾選該項後可以調整MP4-AVC的分辨率,由於PSP的最佳分辨率爲480x272所以我們就設置爲480x272即可。如果要轉720x480的MP4-AVC請參照下面畫面裁剪中加黑邊的教程,或參照AVS腳本編寫教程來加黑邊,兩者任選其一。
畫面裁剪:默認:Disabled
雙擊Video Filters出現子選項後,先雙擊Scaling將Enable選項設置爲true(左下角選擇Yes)然後在Width(寬)和Height(高)中輸入調整後的分辨率;
然後雙擊Expanding將Enable選項設置爲true(左下角選擇Yes)然後在Width(寬)和Height(高)中輸入加黑邊後的最終分辨率;
不使用黑邊功能時將Expanding的Enable選項設置爲false(左下角選擇No)即可。
圖中設置的實際含義:將畫面調整爲704x480再在左右兩邊各加8像素黑邊((720-704)÷2),變爲720x480輸出。
去除黑邊:點擊裁剪器在彈出的窗口中的模式中選擇Auto Detect即可自動除去黑邊。點擊完成即可。
(注意:如果在使用AVS時,已經在腳本寫入裁剪信息,那麼以上裁剪設置忽略!)
幀率:調整MP4-AVC的幀率,不勾選則會採用原視頻的幀率。
建議:不勾選
(注意:如果非要更改幀率,選擇的幀率應該小於或等於原始文件的幀率,如果發現改變幀率後MP4-AVC的聲音與畫面不同步,那麼就不要勾選該項!)
寬高比:設置轉換後的視頻文件的寬高比。
建議:不勾選
畫面旋轉:設置MP4-AVC播放時的畫面方向。
默認值:不勾選
效果:可以實時顯示正在編碼的畫面。
默認值:勾選
(注意:轉換過程中效果畫面不流暢、沒有聲音是正常現象。如果效果畫面爲一片漆黑,說明視頻轉換出錯,請檢查設置的參數是否正確!)
在聲音選項欄中的參數設置及含義如下:
聲道:設置轉換後音頻的聲道數。可選項:Original、Mono(Left)、Mono(Right)、Stereo、4Channels、4.1Channels、5.1Channels
建議:選擇Stereo
(注意:選擇多聲道會導致轉換失敗,因爲音頻選項中的來源如果選擇自動,那麼會優先使用Mencoder,Mencoder不支持多聲道輸出,且PSP不支持多聲道MP4-AVC的播放!如果需要保留多聲道,請在音頻選項中的來源手動選擇其他解碼器,如MPlayer等!)
聲道映射:勾選後可以將左聲道映射到右聲道,這樣就可以將單聲道轉爲立體聲。
建議:根據自己的需要進行設置
(例如:影片在播放時同時有國語和其他語言時,可以將國語聲道映射到非國語聲道,這樣轉換後的MP4-AVC的聲道依然會是立體聲且爲國語發聲.)
輸出聲道數:設置映射後音頻的聲道數。
建議:如開啓聲道映射功能後選擇2
音量:調整轉換後聲音過大或過小的問題。範圍-200dB-60dB。該參數根據自己的實際情況及需要自行調整,聲音過大就調整到0dB以下,相反,聲音過小就調整到0dB以上。0dB是不進行任何調整。
音量自平衡:當無法把握音量參數時使用的選項。可選項:
Disabled:不使用;
Mode1:自動增大音量;
Mode2:自動減少音量;
建議:選擇Disabled
常用提示
- 別拿x264作爲降噪濾鏡的替代品。確保輸入與你想要的輸出看起來一樣(忽略壓縮導致的質量損失)。否則會降低x264的運行效率。
- 若編碼時CPU佔用率達不到100%,問題八成出在輸入上:
- Raw YUV輸入很容易受IO速度的限制,raw輸入的一幀體積大小=寬*高*位深(YV12爲12) / 8(bits -> bytes) / 1024 (bytes -> kbytes) /1024 (kbytes -> mbytes)
- Avisynth腳本運行於單線程,有些濾鏡可以使用多餘的線程,但速度增益不大。
- ffmpeg (即ffms2)在x264中只支持單線程解碼。
- Flash h.264解碼器 (及其它) 不支持加權P幀預測(weighted P-frame prediction)--weightp,直至10.1版本,但截止至本文寫成時,該版本目前使用率還不廣。若目前使用率還不廣,則在編碼Flash時,需設置--weightp 0。
- Apple的QuickTime播放器有諸多解碼問題,特別是涉及到參考幀數目時。若想保持對QuickTime的兼容性,請參考QuickTime編碼建議,畢竟蘋果用戶數量龐大。
命令行使用建議
x264設置可分爲三類:1. 需要直接設定的
如 --bitrate, --keyint, --slices等等。取決於輸出系統的要求,因此x264的預設會忽略這些設置。
2. 應該通過預設(preset)來設定的
預設系統出現之前,編碼者需要輸入一大段代碼,手工指定每一個參數。很多人爭論是--subme 9 搭配--me hex 好些,還是--subme 7搭配--me tesa好些。都瘋了!幫幫忙,忘掉這些吧。就用--preset, --tune和--profile就好了。
3. 應該無視的
--qcomp, --scenecut等等。這些設定早該內部設定死了。它們對於現在的命令行來說,除了讓人頭疼外,根本毫無意義。瘋狂調冷門參數,覺得有用的人,省省吧。
VBV編碼
x264中的VBV (視頻緩衝驗證Video Buffer Verifier)系統用於限制輸出碼率,以適用於低帶寬環境下的流媒體。h.264的VBV模型基於解碼端"VBV緩衝"的理念。h.264流由客戶端下載保存於VBV緩衝內。每一幀必須完整下載入緩衝中,方可解碼。
x264有三種控制VBV緩衝的選項:
- 緩衝大小由--vbv-bufsize指定,單位是kbit
- 緩衝的填充速率由--vbv-maxrate指定,單位是kbit/sec
- 由--vbv-init指定緩衝必須填滿一定的百分比,纔可開始回放。
例子
例 1
用途: 編碼的視頻用於硬盤上觀看。建議: 不要指定任何VBV設置。硬盤的傳輸率足夠快,無需設置VBV限制。
例 2
用途: 編碼的視頻用於封裝成藍光兼容的文件。建議: 藍光規範限制最大視頻碼率爲40mbit,最大緩衝爲30mbit。所以設定 --bluray-compat --vbv-maxrate 40000 --vbv-bufsize 30000
注:爲兼容藍光,x264還需要其它選項。但這兩項對於VBV部分的兼容,是足夠了。
例 3
用途: 編碼的視頻通過在線Flash流媒體播放,如Youtube建議: 你需要視頻能很快開始,所以緩衝不能超過0.5秒(大概)。假設觀看者的網速需求是512kbit/sec,且90%的帶寬用於在線觀看,另外96kbit/sec的帶寬用於音頻,那麼只剩下364kbit/sec的帶寬給x264。所以指定--vbv-maxrate 364 --vbv-buffer 182
注:在線視頻的啓動延時不僅僅是VBV設置,上述僅是理想情況下的假設。
藍光編碼
kierank已做了詳細研究,詳見 creating Blu-Ray compliant files with x264 here. 對於1080p的簡單例子如下:x264 --bluray-compat --bitrate X --preset veryslow --weightp 0 --bframes 3 --nal-hrd vbr --vbv-maxrate 40000 --vbv-bufsize 30000 --level 4.1 --keyint X --b-pyramid strict --slices 4 --fake-interlaced --aud --colorprim "bt709" --transfer "bt709" --colormatrix "bt709" --sar 1:1 --pass 1 -o output.file input.file x264 --bluray-compat --bitrate X --preset veryslow --weightp 0 --bframes 3 --nal-hrd vbr --vbv-maxrate 40000 --vbv-bufsize 30000 --level 4.1 --keyint X --b-pyramid strict --slices 4 --fake-interlaced --aud --colorprim "bt709" --transfer "bt709" --colormatrix "bt709" --sar 1:1 --pass 2 -o output.file input.file設置keyint爲幀率。需要的話,用更快些的預設。按需增加--tune參數。關閉--weightp,僅因爲某些硬件解碼器會出問題,並非因爲藍光規範不支持。
編碼延時
取決於編碼設定,x264會把一些幀放進內部緩衝,以提升質量。對於離線編碼,延時無所謂。但如果是用於廣播或流媒體,此延時不可接受。用下面的僞代碼,可以計算出x264的緩衝幀數(即編碼延時)。若用libx264 API,參見x264_encoder_delayed_frames
delay = 0 if b-adapt=2 and not (nopass or pass2): delay = MAX(bframes,3)*4 else: delay = bframes if mb-tree or vbv: delay = MAX(delay,rc_lookahead) if not sliced-threads: delay = delay + threads - 1 delay = delay + sync-lookahead if vbv and (vfr-input or abr or pass1: delay = delay + 1降低x264的延時是可能的,但是會降低質量。若需零延時,設置--tune zerolatency。若你可以接受一丁點兒小延時(如小於1秒),最好還是允許延時。下列步驟可以降低延遲,當延遲足夠小時,就別再進行後續步驟了:
- 從初始值開始
- 關閉sync-lookahead
- 降低rc-lookahead,但別小於10
- 降低threads(比如從12降到6)
- 使用切片線程(sliced threads)
- 禁用rc-lookahead
- 禁用b-frames
- 實在不行,就用--tune zerolatency
兼容QuickTime的編碼
對於如何編碼能在QuickTime中完美播放的h.264視頻,各種過時的錯誤信息隨處可見,如“QT只支持1個B幀”、“QT不支持pyramidal B幀”兩條,對於Quick Time Player 7.7就已不正確了。早期版本的Quick Time Player還曾有一個qpmin/dct的問題,令播放器不能處理低量化值(小於4)結合8x8 DCT Transform,然而此問題已在Quick Time Player X中修復。
兼容QuickTime Player X
Apple發佈的QuickTime Player X中的h.264解碼部件是個很不錯的解碼器,只有一個大問題沒解決。你也許很奇怪,那些只能用老版本播放器,或是拒絕升級至QTX的用戶怎麼辦?其實不必擔心,因爲OS X系統全局(包括QuickTime)所用的解碼器並不是播放器自帶的解碼部件。此全局解碼器會隨着系統的更新包而自動更新,無需用戶更新QuickTime Player。所以,當我們提到QuickTime Player X時,自動假設只要系統爲10.6 Snow Leopard或更高版本,則自帶了已修正了的Apple h.264解碼部件,哪怕用戶沒有安裝QTX。現在,Apple h.264解碼器還存在的唯一的大缺陷:
- 較高的參考幀數(15或更高)結合較高的B幀,會導致畫面出現馬賽克及變形。此問題在使用"veryslow" preset時會遇到,因爲它使用了16個參考幀。
- 將參考幀數目限制在1-14範圍內。查找對於所需h.264 level及分辨率所對應的可接受的參考幀數量,然後保證該值不超過14。不過,使用超過5個參考幀就意義不大了,且4個參考幀是1080p視頻最常見level所允許的最大值,因此不妨選擇4個參考幀來編碼你你所有的視頻,不論分辨率:--ref 4 (對於編碼Level 5以上的視頻,你可以參見各level所需,挑選高一點的值,但不要超過14)。
兼容QuickTime Player 7.7
任何版本的操作系統,若有“安裝QuickTime Player X”的選項,就會擁有已更新的QTX解碼器。不幸的是,這意味着只包括OS X 10.6 Snow Leopard及更高版本系統的用戶。所以,若想讓10.5 Leopard的用戶能播放你的視頻,你就要再閱讀下邊的內容了,因爲他們只能用QuickTime Player 7.7。不過,Leopard用戶已經小於<10%且不斷減少中,你也許不必在乎他們了。但話說回來,想要兼容他們老舊的Apple h.264解碼器也很容易,只需稍微犧牲一點質量,你八成會覺得這麼做值得。解碼器缺陷:
- 低量化值(小於4)結合8x8 DCT Transform在QuickTime Player 7.7及更低版本中會產生錯亂的解碼結果。
- 設置--qpmin 4,以防止編碼器使用更低的量化值。會造成極小的質量損失,但遠遠好過禁用8x8 DCT。
結論
網上別處看來的全都無視,那些信息極其老舊,早已不屬實多年了。兼容QuickTime最簡單的建議:結合上述兩個解決辦法,最大化兼容性,令10.5 Leopard及更高版本的用戶都能完美播放,這樣就覆蓋了99%的Mac用戶。
非想要讓所有Mac用戶都能播放的話,就用--ref 4 --qpmin 4來編碼所有視頻。