X264-libx264編碼庫


X264編碼庫libx264實現真正的視頻編解碼,該編解碼算法是基於塊的混合編碼技術,即幀內/幀間預測,然后對預測值變換、量化,最后熵編碼所得。

編碼幀的類型分為I幀(x264_type_i)、P幀(x264_type_p)、B幀(x264_type_b),在H264中叫做圖像片Slice。

X264把整幀圖像看作一個Slice,片中有slice_type_i、slice_type_p、slice_type_b之分。

I幀只有slice_type_i,P幀有slice_type_i、slice_type_p,B幀三種片都有。

X264的H264視頻編碼過程可以分為三個步驟:首先根據規則判定當前幀的編碼類型,如果是B幀,要緩沖存放、獲取;然后對待編碼圖像進行幀內預測、幀間預測、整數DCT變換、量化和熵編碼;最后把壓縮的H264數據進行NAL層打包輸出。

 

X264編碼器有關的重要結構體:

x264_image_t:實際參與編碼的編碼幀圖像信息。

typedef struct
{
	int i_csp;          //圖像空間顏色
	int i_plane;        //圖像平面數目
	int i_stride[4];    //每個圖像平面的跨度,也就是每一行數據的字節數
	uint8_t *plane[4];  //每個圖像平面存放數據的起始地址,plane[0]是Y平面,plane[1]是U平面,plane[2]是V平面
}x264_image_t;          //待編碼的圖像

x264_picture_t:x264編碼器定義便於控制的圖像幀,描述一幀的特征。包含x264_image_t和x264_param_t結構體。

typedef struct
{
	int   i_type;            //幀的類型,初始化為auto,在編碼過程自行控制
	int   i_qpplus1;         //此參數減1代表當前幀的量化參數值
	int   i_pic_struct;      //幀的結構類型
	int   b_keyframe;        //輸出是否是關鍵幀
	int64_t   i_pts;         //一幀的顯示時間戳
	int64_t   i_dts;         //輸出解碼時間戳

	x264_param_t    *param;          
	x264_image_t     img;           
	x264_image_properties_t    prop;
	x264_hrd_t    hrd_timing;      
	void    *opaque;               
} x264_picture_t;            //x264編碼視頻幀

x264_param_t:初始化編碼器。

typedef struct
{
	unsigned int cpu;       //CPU 標志位 
	int  i_threads;         //並行編碼多幀
	int  b_sliced_threads;  //如果設置為false,一個slice只編碼成一個NALU,默認值是true
	int  b_deterministic;   //是否允許非確定性時線程優化
	int  b_cpu_independent; //強制采用典型行為,而不是采用獨立於CPU的優化算法
	int  i_sync_lookahead;  //線程超前緩存幀數
	int  i_width;           //視頻圖像的寬
	int  i_height;          //視頻圖像的高
	int  i_csp;             //色彩空間設置,僅支持I420
	int  i_level_idc;       //編碼復雜度
	int  i_frame_total;     //編碼幀的總數, 不知道默認為0即可

	struct
	{
		int  i_sar_height;    //樣本寬高比的高度
		int  i_sar_width;     //樣本寬高比的寬度
		int  i_vidformat;     //視頻在編碼/數字化之前是什么類型,默認"undef(不設置)"
		int  b_fullrange;     //樣本亮度和色度的計算方式,默認"off"
		int  i_colorprim;     //原始色度格式,默認"undef"
		int  i_transfer;      //轉換方式,默認"undef"
		int  i_colmatrix;     //設置從RGB計算得到亮度和色度所用的矩陣系數,默認"undef"
		int  i_chroma_loc;    //設置色度采樣位置,范圍0~5,默認0
	} vui;                    //vui參數集 : 視頻可用性信息、視頻標准化選項 


	//比特流參數 
	int  i_frame_reference;          //最大參考幀數目
	int  i_dpb_size;                 //Decoded picture buffer size
	int  i_keyint_max;               //設定IDR幀之間的最間隔,在此間隔設置IDR關鍵幀
	int  i_keyint_min;               //設定IDR幀之間的最小間隔, 場景切換小於此值編碼位I幀, 而不是 IDR幀
	int  i_scenecut_threshold;       //場景切換閾值,插入I幀
	int  b_intra_refresh;            //是否使用周期幀內刷新替代IDR幀
	int  i_bframe;                   //兩個參考幀之間的B幀數目
	int  i_bframe_adaptive;          //自適應B幀判定, 可選取值:X264_B_ADAPT_FAST等
	int  i_bframe_bias;              //控制B幀替代P幀的概率,范圍-100 ~ +100,該值越高越容易插入B幀,默認0
	int  i_bframe_pyramid;           //允許部分B幀為參考幀,可選取值:0=off,  1=strict hierarchical,  2=normal
	int  b_open_gop;                 //幀間的預測都是在GOP中進行,后一個GOP會參考前一個GOP的信息
	int  b_bluray_compat;            //支持藍光碟
	int  b_deblocking_filter;        //去塊濾波開關
	int  i_deblocking_filter_alphac0;//[-6, 6] -6 light filter, 6 strong
	int  i_deblocking_filter_beta;   //[-6, 6] 同上
	int  b_cabac;                    //自適應算術編碼cabac開關
	int  i_cabac_init_idc;           //給出算術編碼初始化時表格的選擇
	int  b_interlaced;               //隔行掃描
	int  b_constrained_intra;
	int  i_cqm_preset;               //自定義量化矩陣(CQM), 初始化量化模式為flat
	char *psz_cqm_file;              //讀取JM格式的外部量化矩陣文件,忽略其他cqm選項
	uint8_t  cqm_4iy[16];            //used only if i_cqm_preset == X264_CQM_CUSTOM  
	uint8_t  cqm_4py[16];
	uint8_t  cqm_4ic[16];
	uint8_t  cqm_4pc[16];
	uint8_t  cqm_8iy[64];
	uint8_t  cqm_8py[64];
	uint8_t  cqm_8ic[64];
	uint8_t  cqm_8pc[64];

	void(*pf_log)(void *, int i_level, const char *psz, va_list);     //日志函數
	void  *p_log_private;
	int    i_log_level;             //日志級別,不需要打印編碼信息時直接注釋掉即可
	int    b_visualize;             //是否顯示日志
	char   *psz_dump_yuv;           //重建幀的文件名

	struct
	{
		unsigned int intra;         //幀內分區
		unsigned int inter;         //幀間分區
		int  b_transform_8x8;
		int  i_weighted_pred;       //P幀權重
		int  b_weighted_bipred;     //B幀隱式加權
		int  i_direct_mv_pred;      //時間空間運動向量預測模式
		int  i_chroma_qp_offset;    //色度量化步長偏移量
		int  i_me_method;           //運動估計算法 (X264_ME_*)
		int  i_me_range;            //整像素運動估計搜索范圍 (from predicted mv) 
		int  i_mv_range;            //運動矢量最大長度. -1 = auto, based on level
		int  i_mv_range_thread;     //線程之間的最小運動向量緩沖.  -1 = auto, based on number of threads.
		int  i_subpel_refine;       //亞像素運動估計質量
		int  b_chroma_me;           //亞像素色度運動估計和P幀的模式選擇
		int  b_mixed_references;    //允許每個宏塊的分區有它自己的參考號
		int  i_trellis;             //Trellis量化提高效率,對每個8x8的塊尋找合適的量化值
		int  b_fast_pskip;          //快速P幀跳過檢測
		int  b_dct_decimate;        //P幀變換系數閾值
		int  i_noise_reduction;     //自適應偽盲區
		int  b_psy;                 //Psy優化開關,可能會增強細節
		float  f_psy_rd;            //Psy RD強度
		float  f_psy_trellis;       //Psy Trellis強度
		int  i_luma_deadzone[2];    //亮度量化中使用的盲區大小,{ 幀間, 幀內 }
		int  b_psnr;                //計算和打印PSNR信息
		int  b_ssim;                //計算和打印SSIM信息
	} analyse;                      //編碼分析參數

	struct
	{
		int  i_rc_method;         //碼率控制方式:X264_RC_CQP恆定質量,X264_RC_CRF恆定碼率,  X264_RC_ABR平均碼率
		int  i_qp_constant;       //指定P幀的量化值,0 - 51,0表示無損
		int  i_qp_min;            //允許的最小量化值,默認10
		int  i_qp_max;            //允許的最大量化值,默認51
		int  i_qp_step;           //量化步長,即相鄰兩幀之間量化值之差的最大值
		int   i_bitrate;          //平均碼率大小
		float  f_rf_constant;     //1pass VBR, nominal QP. 實際質量,值越大圖像越花,越小越清晰
		float  f_rf_constant_max; //最大碼率因子                           
		float  f_rate_tolerance;  //允許的誤差
		int    i_vbv_max_bitrate; //平均碼率模式下,最大瞬時碼率,默認0
		int    i_vbv_buffer_size; //碼率控制緩沖區的大小,單位kbit,默認0
		float  f_vbv_buffer_init; //設置碼率控制緩沖區(VBV)緩沖達到多滿(百分比),才開始回放,范圍0~1.0,默認0.9
		float  f_ip_factor;       //I幀和P幀之間的量化因子(QP)比值,默認1.4
		float  f_pb_factor;       //P幀和B幀之間的量化因子(QP)比值,默認1.3
		int   i_aq_mode;          //自適應量化(AQ)模式。0:關閉AQ;1:允許AQ在整個視頻中和幀內重新分配碼;2:自方差AQ(實驗階段),嘗試逐幀調整強度。
		float  f_aq_strength;     //AQ強度,減少平趟和紋理區域的塊效應和模糊度
		int   b_mb_tree;          //是否開啟基於macroblock的qp控制方法
		int   i_lookahead;        //決定mbtree向前預測的幀數
		int   b_stat_write;       //是否將統計數據寫入到文件psz_stat_out中
		char  *psz_stat_out;      //輸出文件用於保存第一次編碼統計數據
		int   b_stat_read;        //是否從文件psz_stat_in中讀入統計數據
		char  *psz_stat_in;       //輸入文件存有第一次編碼的統計數據
		float  f_qcompress;       //量化曲線(quantizer curve)壓縮因子。0.0 => 恆定比特率,1.0 => 恆定量化值
		float  f_qblur;           //時間上模糊量化,減少QP的波動(after curve compression)
		float  f_complexity_blur; //時間上模糊復雜性,減少QP的波動(before curve compression)
		x264_zone_t *zones;       //碼率控制覆蓋
		int    i_zones;           //number of zone_t's
		char  *psz_zones;         //指定區的另一種方法
	} rc;                         //碼率控制參數

	//Muxing復用參數 
	int  b_aud;                //生成訪問單元分隔符
	int  b_repeat_headers;     //是否復制sps和pps放在每個關鍵幀的前面
	int  b_annexb;             //值為true,則NALU之前是4字節前綴碼0x00000001;值為false,則NALU之前的4個字節為NALU長度
	int  i_sps_id;             //sps和pps的id號
	int  b_vfr_input;          //VFR輸入。1 :時間基和時間戳用於碼率控制  0 :僅幀率用於碼率控制
	uint32_t  i_fps_num;       //幀率的分子
	uint32_t  i_fps_den;       //幀率的分母
	uint32_t  i_timebase_num;  //時間基的分子
	uint32_t  i_timebase_den;  //時間基的分母
	int  b_pulldown;
	int  b_pic_struct;         //強制在Picture Timing SEI傳送pic_struct. 默認是未開啟
	int b_fake_interlaced;
	int  i_slice_max_size;     //每個slice的最大字節數,包括預計的NAL開銷
	int  i_slice_max_mbs;      //每個slice的最大宏塊數,重寫i_slice_count
	int  i_slice_count;        //每幀slice的數目,每個slice必須是矩形
} x264_param_t;

x264_nal_t:x264_nal_t里的數據在下一次調用x264_encoder_encode之后就無效了,因此要在調用或者使用之前使用它。

typedef struct
{
	int  i_ref_idc;        // Nal的優先級
	int  i_type;           // Nal的類型
	int  b_long_startcode; // 是否采用長前綴碼0x00000001
	int  i_first_mb;       // 如果Nal為一條帶,則表示該條帶第一個宏塊的指數
	int  i_last_mb;        // 如果Nal為一條帶,則表示該條帶最后一個宏塊的指數
	int  i_payload;        // payload 的字節大小
	uint8_t *p_payload;    // 存放編碼后的數據,已經封裝成Nal單元
} x264_nal_t;

 

X264編碼器有關的功能函數:

功能函數包括VCL編碼和NAL打包。

VCL編碼函數包括:

    創建編碼器x264_encoder_open();

    編碼圖像x264_encoder_encode();

    關閉編碼器x264_encoder_close();

NAL打包函數:

    x264_nal_encode();

//x264_picture_alloc:申請一幀圖像空間,需要調用x264_picture_clean釋放申請的內存
void x264_picture_alloc(x264_picture_t *pic, int i_csp, int i_width, int i_height);
//x264_picture_clean:釋放x264_picture_alloc申請的有關資源,視頻結構體是x264_picture_t
void x264_picture_clean(x264_picture_t *pic);

//x264_encoder_open:創建編碼器句柄,讀入x264_param_t的所有參數
x264_t *x264_encoder_open(x264_param_t*);
//x264_encoder_headers:寫SPS和PPS數據
int x264_encoder_headers(x264_t*, x264_nal_t**, int*);

//x264_encoder_encode:編碼一幀圖像
int x264_encoder_encode(x264_t *, x264_nal_t **pp_nal, int *pi_nal,x264_picture_t *pic_in,x264_picture_t *pic_out);
//x264_encoder_close:關閉編碼器句柄
void x264_encoder_close(x264_t*);
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM