From: Loren Merritt Date: Fri, 4 Nov 2005 11:39:58 +0000 (+0000) Subject: check (most of) the levels constaints. X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=87e5994706c76bd628c7e23f0dca95f05e922a7c;p=x264 check (most of) the levels constaints. set default max_mv_range based on level_idc. git-svn-id: svn://svn.videolan.org/x264/trunk@362 df754926-b1dd-0310-bc7b-ec298dee348c --- diff --git a/common/common.c b/common/common.c index 146c64c4..97449ad0 100644 --- a/common/common.c +++ b/common/common.c @@ -120,7 +120,7 @@ void x264_param_default( x264_param_t *param ) param->analyse.i_me_range = 16; param->analyse.i_subpel_refine = 5; param->analyse.b_chroma_me = 1; - param->analyse.i_mv_range = 512; + param->analyse.i_mv_range = -1; // set from level_idc param->analyse.i_chroma_qp_offset = 0; param->analyse.b_psnr = 1; diff --git a/encoder/encoder.c b/encoder/encoder.c index d49eff8f..9cbb28b1 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -365,6 +365,7 @@ static int x264_validate_parameters( x264_t *h ) h->param.rc.f_ip_factor = 1; h->param.rc.f_pb_factor = 1; h->param.analyse.b_psnr = 0; + h->param.analyse.i_chroma_qp_offset = 0; } if( ( h->param.i_width % 16 || h->param.i_height % 16 ) && !h->mb.b_lossless ) @@ -408,10 +409,24 @@ static int x264_validate_parameters( x264_t *h ) h->param.analyse.intra &= ~X264_ANALYSE_I8x8; } h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12); - h->param.analyse.i_mv_range = x264_clip3(h->param.analyse.i_mv_range, 32, 2048); if( !h->param.b_cabac ) h->param.analyse.i_trellis = 0; + { + const x264_level_t *l = x264_levels; + while( l->level_idc != 0 && l->level_idc != h->param.i_level_idc ) + l++; + if( l->level_idc == 0 ) + { + x264_log( h, X264_LOG_ERROR, "invalid level_idc: %d\n", h->param.i_level_idc ); + return -1; + } + if( h->param.analyse.i_mv_range <= 0 ) + h->param.analyse.i_mv_range = l->mv_range; + else + h->param.analyse.i_mv_range = x264_clip3(h->param.analyse.i_mv_range, 32, 2048); + } + if( h->param.rc.f_qblur < 0 ) h->param.rc.f_qblur = 0; if( h->param.rc.f_complexity_blur < 0 ) @@ -512,6 +527,8 @@ x264_t *x264_encoder_open ( x264_param_t *param ) h->pps = &h->pps_array[0]; x264_pps_init( h->pps, 0, &h->param, h->sps); + x264_validate_levels( h ); + x264_cqm_init( h ); h->mb.i_mb_count = h->sps->i_mb_width * h->sps->i_mb_height; diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c index e10de4c2..4a7cc5c5 100644 --- a/encoder/ratecontrol.c +++ b/encoder/ratecontrol.c @@ -192,6 +192,8 @@ int x264_ratecontrol_new( x264_t *h ) if( rc->b_2pass && h->param.rc.i_rf_constant ) x264_log(h, X264_LOG_ERROR, "constant rate-factor is incompatible with 2pass.\n"); + if( h->param.rc.i_vbv_max_bitrate && !h->param.rc.b_cbr && !h->param.rc.i_rf_constant ) + x264_log(h, X264_LOG_ERROR, "VBV is incompatible with constant QP.\n"); if( h->param.rc.i_vbv_max_bitrate < h->param.rc.i_bitrate && h->param.rc.i_vbv_max_bitrate > 0) x264_log(h, X264_LOG_ERROR, "max bitrate less than average bitrate, ignored.\n"); diff --git a/encoder/set.c b/encoder/set.c index 1cc3c255..7d905edb 100644 --- a/encoder/set.c +++ b/encoder/set.c @@ -473,3 +473,54 @@ void x264_sei_version_write( bs_t *s ) bs_rbsp_trailing( s ); } + +const x264_level_t x264_levels[] = +{ + { 10, 1485, 99, 152064, 64, 175, 64, 64, 0, 0, 0, 1 }, + { 9, 1485, 99, 152064, 128, 350, 64, 64, 0, 0, 0, 1 }, + { 11, 3000, 396, 345600, 192, 500, 128, 64, 0, 0, 0, 1 }, + { 12, 6000, 396, 912384, 384, 1000, 128, 64, 0, 0, 0, 1 }, + { 13, 11880, 396, 912384, 768, 2000, 128, 64, 0, 0, 0, 1 }, + { 20, 11880, 396, 912384, 2000, 2000, 128, 64, 0, 0, 0, 1 }, + { 21, 19800, 792, 1824768, 4000, 4000, 256, 64, 0, 0, 0, 0 }, + { 22, 20250, 1620, 3110400, 4000, 4000, 256, 64, 0, 0, 0, 0 }, + { 30, 40500, 1620, 3110400, 10000, 10000, 256, 32, 22, 0, 1, 0 }, + { 31, 108000, 3600, 6912000, 14000, 14000, 512, 16, 60, 1, 1, 0 }, + { 32, 216000, 5120, 7864320, 20000, 20000, 512, 16, 60, 1, 1, 0 }, + { 40, 245760, 8192, 12582912, 20000, 25000, 512, 16, 60, 1, 1, 0 }, + { 41, 245760, 8192, 12582912, 50000, 62500, 512, 16, 24, 1, 1, 0 }, + { 42, 522240, 8704, 13369344, 50000, 62500, 512, 16, 24, 1, 1, 1 }, + { 50, 589824, 22080, 42393600, 135000, 135000, 512, 16, 24, 1, 1, 1 }, + { 51, 983040, 36864, 70778880, 240000, 240000, 512, 16, 24, 1, 1, 1 }, + { 0 } +}; + +void x264_validate_levels( x264_t *h ) +{ + int mbs; + + const x264_level_t *l = x264_levels; + while( l->level_idc != 0 && l->level_idc != h->param.i_level_idc ) + l++; + + mbs = h->sps->i_mb_width * h->sps->i_mb_height; + if( l->frame_size < mbs + || l->frame_size*8 < h->sps->i_mb_width * h->sps->i_mb_width + || l->frame_size*8 < h->sps->i_mb_height * h->sps->i_mb_height ) + x264_log( h, X264_LOG_WARNING, "frame MB size (%dx%d) > level limit (%d)\n", + h->sps->i_mb_width, h->sps->i_mb_height, l->frame_size ); + +#define CHECK( name, limit, val ) \ + if( (val) > (limit) ) \ + x264_log( h, X264_LOG_WARNING, name " (%d) > level limit (%d)\n", (int)(val), (limit) ); + + CHECK( "DPB size", l->dpb, mbs * 384 * h->sps->i_num_ref_frames ); + CHECK( "VBV bitrate", l->bitrate, h->param.rc.i_vbv_max_bitrate ); + CHECK( "VBV buffer", l->cpb, h->param.rc.i_vbv_buffer_size ); + CHECK( "MV range", l->mv_range, h->param.analyse.i_mv_range ); + + if( h->param.i_fps_den > 0 ) + CHECK( "MB rate", l->mbps, (int64_t)mbs * h->param.i_fps_num / h->param.i_fps_den ); + + /* TODO check the rest of the limits */ +} diff --git a/encoder/set.h b/encoder/set.h index 62f3540e..9b18720d 100644 --- a/encoder/set.h +++ b/encoder/set.h @@ -29,5 +29,6 @@ void x264_sps_write( bs_t *s, x264_sps_t *sps ); void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *sps ); void x264_pps_write( bs_t *s, x264_pps_t *pps ); void x264_sei_version_write( bs_t *s ); +void x264_validate_levels( x264_t *h ); #endif diff --git a/x264.h b/x264.h index 581b734f..b63b844e 100644 --- a/x264.h +++ b/x264.h @@ -35,7 +35,7 @@ #include -#define X264_BUILD 39 +#define X264_BUILD 40 /* x264_t: * opaque handler for decoder and encoder */ @@ -240,6 +240,24 @@ typedef struct int b_aud; /* generate access unit delimiters */ } x264_param_t; +typedef struct { + int level_idc; + int mbps; // max macroblock processing rate (macroblocks/sec) + int frame_size; // max frame size (macroblocks) + int dpb; // max decoded picture buffer (bytes) + int bitrate; // max bitrate (kbit/sec) + int cpb; // max vbv buffer (kbit) + int mv_range; // max vertical mv component range (pixels) + int mvs_per_2mb; // max mvs per 2 consecutive mbs. + int slice_rate; // ?? + int bipred8x8; // limit bipred to >=8x8 + int direct8x8; // limit b_direct to >=8x8 + int frame_only; // forbid interlacing +} x264_level_t; + +/* all of the levels defined in the standard, terminated by .level_idc=0 */ +extern const x264_level_t x264_levels[]; + /* x264_param_default: * fill x264_param_t with default values and do CPU detection */ void x264_param_default( x264_param_t * );