]> git.sesse.net Git - x264/blobdiff - encoder/set.c
Bump dates to 2012
[x264] / encoder / set.c
index d3a5f606a98aa22fdbb6dc388212c16e26ba832b..e752a52e19bdac3ed23fc0b8d4a07202acd30915 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * set: header writing
  *****************************************************************************
- * Copyright (C) 2003-2011 x264 project
+ * Copyright (C) 2003-2012 x264 project
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Loren Merritt <lorenm@u.washington.edu>
@@ -46,6 +46,8 @@ static void scaling_list_write( bs_t *s, x264_pps_t *pps, int idx )
     const uint8_t *list = pps->scaling_list[idx];
     const uint8_t *def_list = (idx==CQM_4IC) ? pps->scaling_list[CQM_4IY]
                             : (idx==CQM_4PC) ? pps->scaling_list[CQM_4PY]
+                            : (idx==CQM_8IC+4) ? pps->scaling_list[CQM_8IY+4]
+                            : (idx==CQM_8PC+4) ? pps->scaling_list[CQM_8PY+4]
                             : x264_cqm_jvt[idx];
     if( !memcmp( list, def_list, len ) )
         bs_write1( s, 0 );   // scaling_list_present_flag
@@ -97,13 +99,19 @@ void x264_sei_write( bs_t *s, uint8_t *payload, int payload_size, int payload_ty
 
 void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
 {
+    int csp = param->i_csp & X264_CSP_MASK;
+
     sps->i_id = i_id;
     sps->i_mb_width = ( param->i_width + 15 ) / 16;
     sps->i_mb_height= ( param->i_height + 15 ) / 16;
+    sps->i_chroma_format_idc = csp >= X264_CSP_I444 ? CHROMA_444 :
+                               csp >= X264_CSP_I422 ? CHROMA_422 : CHROMA_420;
 
     sps->b_qpprime_y_zero_transform_bypass = param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0;
-    if( sps->b_qpprime_y_zero_transform_bypass )
+    if( sps->b_qpprime_y_zero_transform_bypass || sps->i_chroma_format_idc == CHROMA_444 )
         sps->i_profile_idc  = PROFILE_HIGH444_PREDICTIVE;
+    else if( sps->i_chroma_format_idc == CHROMA_422 )
+        sps->i_profile_idc  = PROFILE_HIGH422;
     else if( BIT_DEPTH > 8 )
         sps->i_profile_idc  = PROFILE_HIGH10;
     else if( param->analyse.b_transform_8x8 || param->i_cqm_preset != X264_CQM_FLAT )
@@ -127,8 +135,8 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
         sps->b_constraint_set3 = 1; /* level 1b with Baseline, Main or Extended profile is signalled via constraint_set3 */
         sps->i_level_idc      = 11;
     }
-    /* High 10 Intra profile */
-    if( param->i_keyint_max == 1 && sps->i_profile_idc == PROFILE_HIGH10 )
+    /* Intra profiles */
+    if( param->i_keyint_max == 1 && sps->i_profile_idc > PROFILE_HIGH )
         sps->b_constraint_set3 = 1;
 
     sps->vui.i_num_reorder_frames = param->i_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0;
@@ -196,12 +204,14 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
 
     sps->vui.b_signal_type_present = 0;
     sps->vui.i_vidformat = ( param->vui.i_vidformat >= 0 && param->vui.i_vidformat <= 5 ? param->vui.i_vidformat : 5 );
-    sps->vui.b_fullrange = ( param->vui.b_fullrange ? 1 : 0 );
+    sps->vui.b_fullrange = ( param->vui.b_fullrange >= 0 && param->vui.b_fullrange <= 1 ? param->vui.b_fullrange :
+                           ( csp >= X264_CSP_BGR ? 1 : 0 ) );
     sps->vui.b_color_description_present = 0;
 
     sps->vui.i_colorprim = ( param->vui.i_colorprim >= 0 && param->vui.i_colorprim <=  8 ? param->vui.i_colorprim : 2 );
     sps->vui.i_transfer  = ( param->vui.i_transfer  >= 0 && param->vui.i_transfer  <= 10 ? param->vui.i_transfer  : 2 );
-    sps->vui.i_colmatrix = ( param->vui.i_colmatrix >= 0 && param->vui.i_colmatrix <=  8 ? param->vui.i_colmatrix : 2 );
+    sps->vui.i_colmatrix = ( param->vui.i_colmatrix >= 0 && param->vui.i_colmatrix <=  8 ? param->vui.i_colmatrix :
+                           ( csp >= X264_CSP_BGR ? 0 : 2 ) );
     if( sps->vui.i_colorprim != 2 ||
         sps->vui.i_transfer  != 2 ||
         sps->vui.i_colmatrix != 2 )
@@ -267,7 +277,9 @@ void x264_sps_write( bs_t *s, x264_sps_t *sps )
 
     if( sps->i_profile_idc >= PROFILE_HIGH )
     {
-        bs_write_ue( s, 1 ); // chroma_format_idc = 4:2:0
+        bs_write_ue( s, sps->i_chroma_format_idc );
+        if( sps->i_chroma_format_idc == CHROMA_444 )
+            bs_write1( s, 0 ); // separate_colour_plane_flag
         bs_write_ue( s, BIT_DEPTH-8 ); // bit_depth_luma_minus8
         bs_write_ue( s, BIT_DEPTH-8 ); // bit_depth_chroma_minus8
         bs_write1( s, sps->b_qpprime_y_zero_transform_bypass );
@@ -290,10 +302,12 @@ void x264_sps_write( bs_t *s, x264_sps_t *sps )
     bs_write1( s, sps->b_crop );
     if( sps->b_crop )
     {
-        bs_write_ue( s, sps->crop.i_left   / 2 );
-        bs_write_ue( s, sps->crop.i_right  / 2 );
-        bs_write_ue( s, sps->crop.i_top    / 2 );
-        bs_write_ue( s, sps->crop.i_bottom / 2 );
+        int h_shift = sps->i_chroma_format_idc == CHROMA_420 || sps->i_chroma_format_idc == CHROMA_422;
+        int v_shift = sps->i_chroma_format_idc == CHROMA_420;
+        bs_write_ue( s, sps->crop.i_left   >> h_shift );
+        bs_write_ue( s, sps->crop.i_right  >> h_shift );
+        bs_write_ue( s, sps->crop.i_top    >> v_shift );
+        bs_write_ue( s, sps->crop.i_bottom >> v_shift );
     }
 
     bs_write1( s, sps->b_vui );
@@ -427,31 +441,36 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
     pps->b_transform_8x8_mode = param->analyse.b_transform_8x8 ? 1 : 0;
 
     pps->i_cqm_preset = param->i_cqm_preset;
+
     switch( pps->i_cqm_preset )
     {
     case X264_CQM_FLAT:
-        for( int i = 0; i < 6; i++ )
+        for( int i = 0; i < 8; i++ )
             pps->scaling_list[i] = x264_cqm_flat16;
         break;
     case X264_CQM_JVT:
-        for( int i = 0; i < 6; i++ )
+        for( int i = 0; i < 8; i++ )
             pps->scaling_list[i] = x264_cqm_jvt[i];
         break;
     case X264_CQM_CUSTOM:
         /* match the transposed DCT & zigzag */
         transpose( param->cqm_4iy, 4 );
-        transpose( param->cqm_4ic, 4 );
         transpose( param->cqm_4py, 4 );
+        transpose( param->cqm_4ic, 4 );
         transpose( param->cqm_4pc, 4 );
         transpose( param->cqm_8iy, 8 );
         transpose( param->cqm_8py, 8 );
+        transpose( param->cqm_8ic, 8 );
+        transpose( param->cqm_8pc, 8 );
         pps->scaling_list[CQM_4IY] = param->cqm_4iy;
-        pps->scaling_list[CQM_4IC] = param->cqm_4ic;
         pps->scaling_list[CQM_4PY] = param->cqm_4py;
+        pps->scaling_list[CQM_4IC] = param->cqm_4ic;
         pps->scaling_list[CQM_4PC] = param->cqm_4pc;
         pps->scaling_list[CQM_8IY+4] = param->cqm_8iy;
         pps->scaling_list[CQM_8PY+4] = param->cqm_8py;
-        for( int i = 0; i < 6; i++ )
+        pps->scaling_list[CQM_8IC+4] = param->cqm_8ic;
+        pps->scaling_list[CQM_8PC+4] = param->cqm_8pc;
+        for( int i = 0; i < 8; i++ )
             for( int j = 0; j < (i < 4 ? 16 : 64); j++ )
                 if( pps->scaling_list[i][j] == 0 )
                     pps->scaling_list[i] = x264_cqm_jvt[i];
@@ -459,7 +478,7 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
     }
 }
 
-void x264_pps_write( bs_t *s, x264_pps_t *pps )
+void x264_pps_write( bs_t *s, x264_sps_t *sps, x264_pps_t *pps )
 {
     bs_realign( s );
     bs_write_ue( s, pps->i_id );
@@ -496,8 +515,20 @@ void x264_pps_write( bs_t *s, x264_pps_t *pps )
             bs_write1( s, 0 ); // Cr = Cb
             if( pps->b_transform_8x8_mode )
             {
-                scaling_list_write( s, pps, CQM_8IY+4 );
-                scaling_list_write( s, pps, CQM_8PY+4 );
+                if( sps->i_chroma_format_idc == CHROMA_444 )
+                {
+                    scaling_list_write( s, pps, CQM_8IY+4 );
+                    scaling_list_write( s, pps, CQM_8IC+4 );
+                    bs_write1( s, 0 ); // Cr = Cb
+                    scaling_list_write( s, pps, CQM_8PY+4 );
+                    scaling_list_write( s, pps, CQM_8PC+4 );
+                    bs_write1( s, 0 ); // Cr = Cb
+                }
+                else
+                {
+                    scaling_list_write( s, pps, CQM_8IY+4 );
+                    scaling_list_write( s, pps, CQM_8PY+4 );
+                }
             }
         }
         bs_write_se( s, pps->i_chroma_qp_index_offset );
@@ -544,7 +575,7 @@ int x264_sei_version_write( x264_t *h, bs_t *s )
 
     memcpy( payload, uuid, 16 );
     sprintf( payload+16, "x264 - core %d%s - H.264/MPEG-4 AVC codec - "
-             "Copy%s 2003-2011 - http://www.videolan.org/x264.html - options: %s",
+             "Copy%s 2003-2012 - http://www.videolan.org/x264.html - options: %s",
              X264_BUILD, X264_VERSION, HAVE_GPL?"left":"right", opts );
     length = strlen(payload)+1;
 
@@ -613,6 +644,7 @@ void x264_sei_pic_timing_write( x264_t *h, bs_t *s )
 
 void x264_sei_frame_packing_write( x264_t *h, bs_t *s )
 {
+    int quincunx_sampling_flag = h->param.i_frame_packing == 0;
     bs_t q;
     uint8_t tmp_buf[100];
     bs_init( &q, tmp_buf, 100 );
@@ -622,7 +654,7 @@ void x264_sei_frame_packing_write( x264_t *h, bs_t *s )
     bs_write_ue( &q, 0 );                         // frame_packing_arrangement_id
     bs_write1( &q, 0 );                           // frame_packing_arrangement_cancel_flag
     bs_write ( &q, 7, h->param.i_frame_packing ); // frame_packing_arrangement_type
-    bs_write1( &q, 0 );                           // quincunx_sampling_flag
+    bs_write1( &q, quincunx_sampling_flag );      // quincunx_sampling_flag
 
     // 0: views are unrelated, 1: left view is on the left, 2: left view is on the right
     bs_write ( &q, 6, 1 );                        // content_interpretation_type
@@ -633,7 +665,7 @@ void x264_sei_frame_packing_write( x264_t *h, bs_t *s )
     bs_write1( &q, h->param.i_frame_packing == 5 && !(h->fenc->i_frame&1) ); // current_frame_is_frame0_flag
     bs_write1( &q, 0 );                           // frame0_self_contained_flag
     bs_write1( &q, 0 );                           // frame1_self_contained_flag
-    if ( /* quincunx_sampling_flag == 0 && */ h->param.i_frame_packing != 5 )
+    if ( quincunx_sampling_flag == 0 && h->param.i_frame_packing != 5 )
     {
         bs_write( &q, 4, 0 );                     // frame0_grid_position_x
         bs_write( &q, 4, 0 );                     // frame0_grid_position_y
@@ -726,7 +758,8 @@ int x264_validate_levels( x264_t *h, int verbose )
     int ret = 0;
     int mbs = h->sps->i_mb_width * h->sps->i_mb_height;
     int dpb = mbs * 384 * h->sps->vui.i_max_dec_frame_buffering;
-    int cbp_factor = h->sps->i_profile_idc==PROFILE_HIGH10 ? 12 :
+    int cbp_factor = h->sps->i_profile_idc>=PROFILE_HIGH422 ? 16 :
+                     h->sps->i_profile_idc==PROFILE_HIGH10 ? 12 :
                      h->sps->i_profile_idc==PROFILE_HIGH ? 5 : 4;
 
     const x264_level_t *l = x264_levels;