]> git.sesse.net Git - x264/commitdiff
check (most of) the levels constaints.
authorLoren Merritt <pengvado@videolan.org>
Fri, 4 Nov 2005 11:39:58 +0000 (11:39 +0000)
committerLoren Merritt <pengvado@videolan.org>
Fri, 4 Nov 2005 11:39:58 +0000 (11:39 +0000)
set default max_mv_range based on level_idc.

git-svn-id: svn://svn.videolan.org/x264/trunk@362 df754926-b1dd-0310-bc7b-ec298dee348c

common/common.c
encoder/encoder.c
encoder/ratecontrol.c
encoder/set.c
encoder/set.h
x264.h

index 146c64c4a54414a6e381083b0c9468bcf98144ce..97449ad0363ad4813bf0f01f6755c6d3a9feb848 100644 (file)
@@ -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;
 
index d49eff8ff0fb67a1e2c4b0f3578e75fa001cc881..9cbb28b14c90e8cc34a07a5fcbf34c34f6c4ec83 100644 (file)
@@ -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;
index e10de4c2dfcb51148f15254faaa5828ad21199c2..4a7cc5c5edb5104a18bc01731d01915c2b0af849 100644 (file)
@@ -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");
index 1cc3c255022f0779f32dc812b6773f27ebb192c0..7d905edb7cc130f410be712013bae98ecea57344 100644 (file)
@@ -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 */
+}
index 62f3540efb5574723ad093008cf55b03182d0f82..9b18720d4bbf1fc336c11f171a4f1e22f4cb0d85 100644 (file)
@@ -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 581b734fd77daa23e8d761f571e1710c2c94d200..b63b844e937448f5306da3aac22723b508fbe942 100644 (file)
--- a/x264.h
+++ b/x264.h
@@ -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 * );