Commit 87e59947 authored by Loren Merritt's avatar Loren Merritt

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
parent 1e80b69b
......@@ -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;
......
......@@ -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;
......
......@@ -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");
......
......@@ -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 */
}
......@@ -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
......@@ -35,7 +35,7 @@
#include <stdarg.h>
#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 * );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment