源码阅读 x264 - 常用结构体
本文主要对 x264 中的重要结构体进行介绍,包括的结构体有:
- struct x264_param_t
- struct cli_opt_t
- 更多结构体更新中
x264_param_t
结构体 x264_param_t 定义在 x264.h 中,是 x264 中最重要的结构体之一,主要用于初始化编码器。
typedef struct x264_param_t
{
/* CPU flags */
uint32_t cpu;
int i_threads; /* encode multiple frames in parallel */
int i_lookahead_threads; /* multiple threads for lookahead analysis */
int b_sliced_threads; /* Whether to use slice-based threading. */
int b_deterministic; /* whether to allow non-deterministic optimizations when threaded */
int b_cpu_independent; /* force canonical behavior rather than cpu-dependent optimal algorithms */
int i_sync_lookahead; /* threaded lookahead buffer */
/* Video Properties */
int i_width;
int i_height;
int i_csp; /* CSP of encoded bitstream */
int i_bitdepth;
int i_level_idc;
int i_frame_total; /* number of frames to encode if known, else 0 */
/* NAL HRD
* Uses Buffering and Picture Timing SEIs to signal HRD
* The HRD in H.264 was not designed with VFR in mind.
* It is therefore not recommendeded to use NAL HRD with VFR.
* Furthermore, reconfiguring the VBV (via x264_encoder_reconfig)
* will currently generate invalid HRD. */
int i_nal_hrd;
struct
{
/* they will be reduced to be 0 < x <= 65535 and prime */
int i_sar_height;
int i_sar_width;
int i_overscan; /* 0=undef, 1=no overscan, 2=overscan */
/* see h264 annex E for the values of the following */
int i_vidformat;
int b_fullrange;
int i_colorprim;
int i_transfer;
int i_colmatrix;
int i_chroma_loc; /* both top & bottom */
} vui;
/* Bitstream parameters */
int i_frame_reference; /* Maximum number of reference frames */
int i_dpb_size; /* Force a DPB size larger than that implied by B-frames and reference frames.
* Useful in combination with interactive error resilience. */
int i_keyint_max; /* Force an IDR keyframe at this interval */
int i_keyint_min; /* Scenecuts closer together than this are coded as I, not IDR. */
int i_scenecut_threshold; /* how aggressively to insert extra I frames */
int b_intra_refresh; /* Whether or not to use periodic intra refresh instead of IDR frames. */
int i_bframe; /* how many b-frame between 2 references pictures */
int i_bframe_adaptive;
int i_bframe_bias;
int i_bframe_pyramid; /* Keep some B-frames as references: 0=off, 1=strict hierarchical, 2=normal */
int b_open_gop;
int b_bluray_compat;
int i_avcintra_class;
int i_avcintra_flavor;
int b_deblocking_filter;
int i_deblocking_filter_alphac0; /* [-6, 6] -6 light filter, 6 strong */
int i_deblocking_filter_beta; /* [-6, 6] idem */
int b_cabac;
int i_cabac_init_idc;
int b_interlaced;
int b_constrained_intra;
int i_cqm_preset;
char *psz_cqm_file; /* filename (in UTF-8) of CQM file, JM format */
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];
/* Log */
void (*pf_log)( void *, int i_level, const char *psz, va_list );
void *p_log_private;
int i_log_level;
int b_full_recon; /* fully reconstruct frames, even when not necessary for encoding. Implied by psz_dump_yuv */
char *psz_dump_yuv; /* filename (in UTF-8) for reconstructed frames */
/* Encoder analyser parameters */
struct
{
unsigned int intra; /* intra partitions */
unsigned int inter; /* inter partitions */
int b_transform_8x8;
int i_weighted_pred; /* weighting for P-frames */
int b_weighted_bipred; /* implicit weighting for B-frames */
int i_direct_mv_pred; /* spatial vs temporal mv prediction */
int i_chroma_qp_offset;
int i_me_method; /* motion estimation algorithm to use (X264_ME_*) */
int i_me_range; /* integer pixel motion estimation search range (from predicted mv) */
int i_mv_range; /* maximum length of a mv (in pixels). -1 = auto, based on level */
int i_mv_range_thread; /* minimum space between threads. -1 = auto, based on number of threads. */
int i_subpel_refine; /* subpixel motion estimation quality */
int b_chroma_me; /* chroma ME for subpel and mode decision in P-frames */
int b_mixed_references; /* allow each mb partition to have its own reference number */
int i_trellis; /* trellis RD quantization */
int b_fast_pskip; /* early SKIP detection on P-frames */
int b_dct_decimate; /* transform coefficient thresholding on P-frames */
int i_noise_reduction; /* adaptive pseudo-deadzone */
float f_psy_rd; /* Psy RD strength */
float f_psy_trellis; /* Psy trellis strength */
int b_psy; /* Toggle all psy optimizations */
int b_mb_info; /* Use input mb_info data in x264_picture_t */
int b_mb_info_update; /* Update the values in mb_info according to the results of encoding. */
/* the deadzone size that will be used in luma quantization */
int i_luma_deadzone[2]; /* {inter, intra} */
int b_psnr; /* compute and print PSNR stats */
int b_ssim; /* compute and print SSIM stats */
} analyse;
/* Rate control parameters */
struct
{
int i_rc_method; /* X264_RC_* */
int i_qp_constant; /* 0=lossless */
int i_qp_min; /* min allowed QP value */
int i_qp_max; /* max allowed QP value */
int i_qp_step; /* max QP step between frames */
int i_bitrate;
float f_rf_constant; /* 1pass VBR, nominal QP */
float f_rf_constant_max; /* In CRF mode, maximum CRF as caused by VBV */
float f_rate_tolerance;
int i_vbv_max_bitrate;
int i_vbv_buffer_size;
float f_vbv_buffer_init; /* <=1: fraction of buffer_size.>1: kbit */
float f_ip_factor;
float f_pb_factor;
/* VBV filler: force CBR VBV and use filler bytes to ensure hard-CBR.
* Implied by NAL-HRD CBR. */
int b_filler;
int i_aq_mode; /* psy adaptive QP. (X264_AQ_*) */
float f_aq_strength;
int b_mb_tree; /* Macroblock-tree ratecontrol. */
int i_lookahead;
/* 2pass */
int b_stat_write; /* Enable stat writing in psz_stat_out */
char *psz_stat_out; /* output filename (in UTF-8) of the 2pass stats file */
int b_stat_read; /* Read stat from psz_stat_in and use it */
char *psz_stat_in; /* input filename (in UTF-8) of the 2pass stats file */
/* 2pass params (same as ffmpeg ones) */
float f_qcompress; /* 0.0 => cbr, 1.0 => constant qp */
float f_qblur; /* temporally blur quants */
float f_complexity_blur; /* temporally blur complexity */
x264_zone_t *zones; /* ratecontrol overrides */
int i_zones; /* number of zone_t's */
char *psz_zones; /* alternate method of specifying zones */
} rc;
/* Cropping Rectangle parameters: added to those implicitly defined by
non-mod16 video resolutions. */
struct
{
int i_left;
int i_top;
int i_right;
int i_bottom;
} crop_rect;
/* frame packing arrangement flag */
int i_frame_packing;
/* alternative transfer SEI */
int i_alternative_transfer;
/* Muxing parameters */
int b_aud; /* generate access unit delimiters */
int b_repeat_headers; /* put SPS/PPS before each keyframe */
int b_annexb; /* if set, place start codes (4 bytes) before NAL units,
* otherwise place size (4 bytes) before NAL units. */
int i_sps_id; /* SPS and PPS id number */
int b_vfr_input; /* VFR input. If 1, use timebase and timestamps for ratecontrol purposes.
* If 0, use fps only. */
int b_pulldown; /* use explicity set timebase for CFR */
uint32_t i_fps_num;
uint32_t i_fps_den;
uint32_t i_timebase_num; /* Timebase numerator */
uint32_t i_timebase_den; /* Timebase denominator */
int b_tff;
/* Pulldown:
* The correct pic_struct must be passed with each input frame.
* The input timebase should be the timebase corresponding to the output framerate. This should be constant.
* e.g. for 3:2 pulldown timebase should be 1001/30000
* The PTS passed with each frame must be the PTS of the frame after pulldown is applied.
* Frame doubling and tripling require b_vfr_input set to zero (see H.264 Table D-1)
*
* Pulldown changes are not clearly defined in H.264. Therefore, it is the calling app's responsibility to manage this.
*/
int b_pic_struct;
/* Fake Interlaced.
* 仅在 b_interlaced = 0 时使用
* 设置此标志可以将流标记为 PAFF 隔行,并且对所有帧进行渐进编码
* 对于编码 25p 和 30p 蓝光流非常有用。
*/
int b_fake_interlaced;
/* Don't optimize header parameters based on video content, e.g. ensure that splitting an input video, compressing
* each part, and stitching them back together will result in identical SPS/PPS. This is necessary for stitching
* with container formats that don't allow multiple SPS/PPS. */
int b_stitchable;
int b_opencl; /* use OpenCL when available */
int i_opencl_device; /* specify count of GPU devices to skip, for CLI users */
void *opencl_device_id; /* pass explicit cl_device_id as void*, for API users */
char *psz_clbin_file; /* filename (in UTF-8) of the compiled OpenCL kernel cache file */
/* Slicing parameters */
int i_slice_max_size; /* Max size per slice in bytes; includes estimated NAL overhead. */
int i_slice_max_mbs; /* Max number of MBs per slice; overrides i_slice_count. */
int i_slice_min_mbs; /* Min number of MBs per slice */
int i_slice_count; /* Number of slices per frame: forces rectangular slices. */
int i_slice_count_max; /* Absolute cap on slices per frame; stops applying slice-max-size
* and slice-max-mbs if this is reached. */
/* Optional callback for freeing this x264_param_t when it is done being used.
* Only used when the x264_param_t sits in memory for an indefinite period of time,
* i.e. when an x264_param_t is passed to x264_t in an x264_picture_t or in zones.
* Not used when x264_encoder_reconfig is called directly. */
void (*param_free)( void* );
/* Optional low-level callback for low-latency encoding. Called for each output NAL unit
* immediately after the NAL unit is finished encoding. This allows the calling application
* to begin processing video data (e.g. by sending packets over a network) before the frame
* is done encoding.
*
* This callback MUST do the following in order to work correctly:
* 1) Have available an output buffer of at least size nal->i_payload*3/2 + 5 + 64.
* 2) Call x264_nal_encode(h, dst, nal), where dst is the output buffer.
* After these steps, the content of nal is valid and can be used in the same way as if
* the NAL unit were output by x264_encoder_encode.
*
* This does not need to be synchronous with the encoding process: the data pointed to
* by nal (both before and after x264_nal_encode) will remain valid until the next
* x264_encoder_encode call. The callback must be re-entrant.
*
* This callback does not work with frame-based threads; threads must be disabled
* or sliced-threads enabled. This callback also does not work as one would expect
* with HRD -- since the buffering period SEI cannot be calculated until the frame
* is finished encoding, it will not be sent via this callback.
*
* Note also that the NALs are not necessarily returned in order when sliced threads is
* enabled. Accordingly, the variable i_first_mb and i_last_mb are available in
* x264_nal_t to help the calling application reorder the slices if necessary.
*
* When this callback is enabled, x264_encoder_encode does not return valid NALs;
* the calling application is expected to acquire all output NALs through the callback.
*
* It is generally sensible to combine this callback with a use of slice-max-mbs or
* slice-max-size.
*
* The opaque pointer is the opaque pointer from the input frame associated with this
* NAL unit. This helps distinguish between nalu_process calls from different sources,
* e.g. if doing multiple encodes in one process.
*/
void (*nalu_process)( x264_t *h, x264_nal_t *nal, void *opaque );
/* For internal use only */
void *opaque;
} x264_param_t;
cli_opt_t
typedef struct {
int b_progress;
int i_seek;
hnd_t hin;
hnd_t hout;
FILE *qpfile;
FILE *tcfile_out;
double timebase_convert_multiplier;
int i_pulldown;
} cli_opt_t;
x264_sps_t
typedef struct
{
int i_id;
int i_profile_idc;
int i_level_idc;
int b_constraint_set0;
int b_constraint_set1;
int b_constraint_set2;
int b_constraint_set3;
int i_log2_max_frame_num;
int i_poc_type;
/* poc 0 */
int i_log2_max_poc_lsb;
int i_num_ref_frames;
int b_gaps_in_frame_num_value_allowed;
int i_mb_width;
int i_mb_height;
int b_frame_mbs_only;
int b_mb_adaptive_frame_field;
int b_direct8x8_inference;
int b_crop;
struct
{
int i_left;
int i_right;
int i_top;
int i_bottom;
} crop;
int b_vui;
struct __vui vui;
int b_qpprime_y_zero_transform_bypass;
int i_chroma_format_idc;
int b_avcintra;
int i_cqm_preset;
const uint8_t *scaling_list[8]; /* could be 12, but we don't allow separate Cb/Cr lists */
} x264_sps_t;
struct __vui
struct __vui
{
int b_aspect_ratio_info_present;
int i_sar_width;
int i_sar_height;
int b_overscan_info_present;
int b_overscan_info;
int b_signal_type_present;
int i_vidformat;
int b_fullrange;
int b_color_description_present;
int i_colorprim;
int i_transfer;
int i_colmatrix;
int b_chroma_loc_info_present;
int i_chroma_loc_top;
int i_chroma_loc_bottom;
int b_timing_info_present;
uint32_t i_num_units_in_tick;
uint32_t i_time_scale;
int b_fixed_frame_rate;
int b_nal_hrd_parameters_present;
int b_vcl_hrd_parameters_present;
struct
{
int i_cpb_cnt;
int i_bit_rate_scale;
int i_cpb_size_scale;
int i_bit_rate_value;
int i_cpb_size_value;
int i_bit_rate_unscaled;
int i_cpb_size_unscaled;
int b_cbr_hrd;
int i_initial_cpb_removal_delay_length;
int i_cpb_removal_delay_length;
int i_dpb_output_delay_length;
int i_time_offset_length;
} hrd;
int b_pic_struct_present;
int b_bitstream_restriction;
int b_motion_vectors_over_pic_boundaries;
int i_max_bytes_per_pic_denom;
int i_max_bits_per_mb_denom;
int i_log2_max_mv_length_horizontal;
int i_log2_max_mv_length_vertical;
int i_num_reorder_frames;
int i_max_dec_frame_buffering;
/* FIXME to complete */
} vui;
x264_pixel_function_t
typedef struct
{
x264_pixel_cmp_t sad[8];
x264_pixel_cmp_t ssd[8];
x264_pixel_cmp_t satd[8];
x264_pixel_cmp_t ssim[7];
x264_pixel_cmp_t sa8d[4];
x264_pixel_cmp_t mbcmp[8]; /* either satd or sad for subpel refine and mode decision */
x264_pixel_cmp_t mbcmp_unaligned[8]; /* unaligned mbcmp for subpel */
x264_pixel_cmp_t fpelcmp[8]; /* either satd or sad for fullpel motion search */
x264_pixel_cmp_x3_t fpelcmp_x3[7];
x264_pixel_cmp_x4_t fpelcmp_x4[7];
x264_pixel_cmp_t sad_aligned[8]; /* Aligned SAD for mbcmp */
int (*vsad)( pixel *, intptr_t, int );
int (*asd8)( pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2, int height );
uint64_t (*sa8d_satd[1])( pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2 );
uint64_t (*var[4])( pixel *pix, intptr_t stride );
int (*var2[4])( pixel *fenc, pixel *fdec, int ssd[2] );
uint64_t (*hadamard_ac[4])( pixel *pix, intptr_t stride );
void (*ssd_nv12_core)( pixel *pixuv1, intptr_t stride1,
pixel *pixuv2, intptr_t stride2, int width, int height,
uint64_t *ssd_u, uint64_t *ssd_v );
void (*ssim_4x4x2_core)( const pixel *pix1, intptr_t stride1,
const pixel *pix2, intptr_t stride2, int sums[2][4] );
float (*ssim_end4)( int sum0[5][4], int sum1[5][4], int width );
/* multiple parallel calls to cmp. */
x264_pixel_cmp_x3_t sad_x3[7];
x264_pixel_cmp_x4_t sad_x4[7];
x264_pixel_cmp_x3_t satd_x3[7];
x264_pixel_cmp_x4_t satd_x4[7];
/* abs-diff-sum for successive elimination.
* may round width up to a multiple of 16. */
int (*ads[7])( int enc_dc[4], uint16_t *sums, int delta,
uint16_t *cost_mvx, int16_t *mvs, int width, int thresh );
/* calculate satd or sad of V, H, and DC modes. */
void (*intra_mbcmp_x3_16x16)( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_satd_x3_16x16) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_sad_x3_16x16) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_mbcmp_x3_4x4) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_satd_x3_4x4) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_sad_x3_4x4) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_mbcmp_x3_chroma)( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_satd_x3_chroma) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_sad_x3_chroma) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_mbcmp_x3_8x16c) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_satd_x3_8x16c) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_sad_x3_8x16c) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_mbcmp_x3_8x8c) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_satd_x3_8x8c) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_sad_x3_8x8c) ( pixel *fenc, pixel *fdec, int res[3] );
void (*intra_mbcmp_x3_8x8) ( pixel *fenc, pixel edge[36], int res[3] );
void (*intra_sa8d_x3_8x8) ( pixel *fenc, pixel edge[36], int res[3] );
void (*intra_sad_x3_8x8) ( pixel *fenc, pixel edge[36], int res[3] );
/* find minimum satd or sad of all modes, and set fdec.
* may be NULL, in which case just use pred+satd instead. */
int (*intra_mbcmp_x9_4x4)( pixel *fenc, pixel *fdec, uint16_t *bitcosts );
int (*intra_satd_x9_4x4) ( pixel *fenc, pixel *fdec, uint16_t *bitcosts );
int (*intra_sad_x9_4x4) ( pixel *fenc, pixel *fdec, uint16_t *bitcosts );
int (*intra_mbcmp_x9_8x8)( pixel *fenc, pixel *fdec, pixel edge[36], uint16_t *bitcosts, uint16_t *satds );
int (*intra_sa8d_x9_8x8) ( pixel *fenc, pixel *fdec, pixel edge[36], uint16_t *bitcosts, uint16_t *satds );
int (*intra_sad_x9_8x8) ( pixel *fenc, pixel *fdec, pixel edge[36], uint16_t *bitcosts, uint16_t *satds );
} x264_pixel_function_t;