Add Sony XAVC, a flavour of AVC-Intra
authorKieran Kunhya <kierank@obe.tv>
Wed, 30 Aug 2017 15:05:41 +0000 (16:05 +0100)
committerHenrik Gramner <henrik@gramner.com>
Mon, 6 Aug 2018 21:24:13 +0000 (23:24 +0200)
common/base.c
common/set.c
common/set.h
encoder/encoder.c
encoder/set.c
tools/checkasm.c
x264.c
x264.h

index 0765482..f45ba23 100644 (file)
@@ -429,6 +429,8 @@ static void param_default( x264_param_t *param )
     param->i_opencl_device = 0;
     param->opencl_device_id = NULL;
     param->psz_clbin_file = NULL;
+    param->i_avcintra_class = 0;
+    param->i_avcintra_flavor = X264_AVCINTRA_FLAVOR_PANASONIC;
 }
 
 void x264_param_default( x264_param_t *param )
@@ -955,6 +957,8 @@ static int param_parse( x264_param_t *p, const char *name, const char *value )
         p->b_bluray_compat = atobool(value);
     OPT("avcintra-class")
         p->i_avcintra_class = atoi(value);
+    OPT("avcintra-flavor")
+        b_error |= parse_enum( value, x264_avcintra_flavor_names, &p->i_avcintra_flavor );
     OPT("sar")
     {
         b_error = ( 2 != sscanf( value, "%d:%d", &p->vui.i_sar_width, &p->vui.i_sar_height ) &&
index 1a74efb..319d88c 100644 (file)
@@ -94,7 +94,7 @@ int x264_cqm_init( x264_t *h )
         int start = w == 8 ? 4 : 0;\
         int j;\
         for( j = 0; j < i; j++ )\
-            if( !memcmp( h->pps->scaling_list[i+start], h->pps->scaling_list[j+start], size*sizeof(uint8_t) ) )\
+            if( !memcmp( h->sps->scaling_list[i+start], h->sps->scaling_list[j+start], size*sizeof(uint8_t) ) )\
                 break;\
         if( j < i )\
         {\
@@ -110,7 +110,7 @@ int x264_cqm_init( x264_t *h )
         }\
         for( j = 0; j < i; j++ )\
             if( deadzone[j] == deadzone[i] &&\
-                !memcmp( h->pps->scaling_list[i+start], h->pps->scaling_list[j+start], size*sizeof(uint8_t) ) )\
+                !memcmp( h->sps->scaling_list[i+start], h->sps->scaling_list[j+start], size*sizeof(uint8_t) ) )\
                 break;\
         if( j < i )\
         {\
@@ -148,14 +148,14 @@ int x264_cqm_init( x264_t *h )
         for( int i_list = 0; i_list < 4; i_list++ )
             for( int i = 0; i < 16; i++ )
             {
-                h->dequant4_mf[i_list][q][i] = def_dequant4[q][i] * h->pps->scaling_list[i_list][i];
-                     quant4_mf[i_list][q][i] = DIV(def_quant4[q][i] * 16, h->pps->scaling_list[i_list][i]);
+                h->dequant4_mf[i_list][q][i] = def_dequant4[q][i] * h->sps->scaling_list[i_list][i];
+                     quant4_mf[i_list][q][i] = DIV(def_quant4[q][i] * 16, h->sps->scaling_list[i_list][i]);
             }
         for( int i_list = 0; i_list < num_8x8_lists; i_list++ )
             for( int i = 0; i < 64; i++ )
             {
-                h->dequant8_mf[i_list][q][i] = def_dequant8[q][i] * h->pps->scaling_list[4+i_list][i];
-                     quant8_mf[i_list][q][i] = DIV(def_quant8[q][i] * 16, h->pps->scaling_list[4+i_list][i]);
+                h->dequant8_mf[i_list][q][i] = def_dequant8[q][i] * h->sps->scaling_list[4+i_list][i];
+                     quant8_mf[i_list][q][i] = DIV(def_quant8[q][i] * 16, h->sps->scaling_list[4+i_list][i]);
             }
     }
     for( int q = 0; q <= QP_MAX_SPEC; q++ )
index e019572..32ea96c 100644 (file)
@@ -140,6 +140,10 @@ typedef struct
     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;
 
 typedef struct
@@ -169,9 +173,6 @@ typedef struct
 
     int b_transform_8x8_mode;
 
-    int i_cqm_preset;
-    const uint8_t *scaling_list[8]; /* could be 12, but we don't allow separate Cb/Cr lists */
-
 } x264_pps_t;
 
 #define x264_cqm_init x264_template(cqm_init)
index 5cbeb68..7316a58 100644 (file)
@@ -817,21 +817,34 @@ static int validate_parameters( x264_t *h, int b_open )
         memcpy( h->param.cqm_4ic, avcintra_lut[type][res][i].cqm_4ic, sizeof(h->param.cqm_4ic) );
         memcpy( h->param.cqm_8iy, avcintra_lut[type][res][i].cqm_8iy, sizeof(h->param.cqm_8iy) );
 
-        /* Need exactly 10 slices of equal MB count... why?  $deity knows... */
-        h->param.i_slice_max_mbs = ((h->param.i_width + 15) / 16) * ((h->param.i_height + 15) / 16) / 10;
-        h->param.i_slice_max_size = 0;
-        /* The slice structure only allows a maximum of 2 threads for 1080i/p
-         * and 1 or 5 threads for 720p */
-        if( h->param.b_sliced_threads )
+        /* Sony XAVC flavor much more simple */
+        if( h->param.i_avcintra_flavor == X264_AVCINTRA_FLAVOR_SONY )
         {
-            if( res )
-                h->param.i_threads = X264_MIN( 2, h->param.i_threads );
-            else
+            h->param.i_slice_count = 8;
+            /* Sony XAVC unlike AVC-Intra doesn't seem to have a QP floor */
+        }
+        else
+        {
+            /* Need exactly 10 slices of equal MB count... why?  $deity knows... */
+            h->param.i_slice_max_mbs = ((h->param.i_width + 15) / 16) * ((h->param.i_height + 15) / 16) / 10;
+            h->param.i_slice_max_size = 0;
+            /* The slice structure only allows a maximum of 2 threads for 1080i/p
+             * and 1 or 5 threads for 720p */
+            if( h->param.b_sliced_threads )
             {
-                h->param.i_threads = X264_MIN( 5, h->param.i_threads );
-                if( h->param.i_threads < 5 )
-                    h->param.i_threads = 1;
+                if( res )
+                    h->param.i_threads = X264_MIN( 2, h->param.i_threads );
+                else
+                {
+                    h->param.i_threads = X264_MIN( 5, h->param.i_threads );
+                    if( h->param.i_threads < 5 )
+                        h->param.i_threads = 1;
+                }
             }
+
+            /* Official encoder doesn't appear to go under 13
+             * and Avid cannot handle negative QPs */
+            h->param.rc.i_qp_min = X264_MAX( h->param.rc.i_qp_min, QP_BD_OFFSET + 1 );
         }
 
         if( type )
@@ -841,10 +854,6 @@ static int validate_parameters( x264_t *h, int b_open )
             h->param.vui.i_sar_width  = 4;
             h->param.vui.i_sar_height = 3;
         }
-
-        /* Official encoder doesn't appear to go under 13
-         * and Avid cannot handle negative QPs */
-        h->param.rc.i_qp_min = X264_MAX( h->param.rc.i_qp_min, QP_BD_OFFSET + 1 );
     }
 
     h->param.rc.f_rf_constant = x264_clip3f( h->param.rc.f_rf_constant, -QP_BD_OFFSET, 51 );
@@ -3582,7 +3591,13 @@ int     x264_encoder_encode( x264_t *h,
             if( nal_end( h ) )
                 return -1;
             if( h->param.i_avcintra_class )
-                h->out.nal[h->out.i_nal-1].i_padding = 256 - h->out.nal[h->out.i_nal-1].i_payload - NALU_OVERHEAD;
+            {
+                int total_len = 256;
+                /* Sony XAVC uses an oversized PPS instead of SEI padding */
+                if( h->param.i_avcintra_flavor == X264_AVCINTRA_FLAVOR_SONY )
+                    total_len += h->param.i_height == 1080 ? 18*512 : 10*512;
+                h->out.nal[h->out.i_nal-1].i_padding = total_len - h->out.nal[h->out.i_nal-1].i_payload - NALU_OVERHEAD;
+            }
             overhead += h->out.nal[h->out.i_nal-1].i_payload + h->out.nal[h->out.i_nal-1].i_padding + NALU_OVERHEAD;
         }
 
@@ -3689,7 +3704,7 @@ int     x264_encoder_encode( x264_t *h,
         h->i_cpb_delay_pir_offset_next = h->fenc->i_cpb_delay;
 
     /* Filler space: 10 or 18 SEIs' worth of space, depending on resolution */
-    if( h->param.i_avcintra_class )
+    if( h->param.i_avcintra_class && h->param.i_avcintra_flavor != X264_AVCINTRA_FLAVOR_SONY )
     {
         /* Write an empty filler NAL to mimic the AUD in the P2 format*/
         nal_start( h, NAL_FILLER, NAL_PRIORITY_DISPOSABLE );
index 628518a..da4a8a1 100644 (file)
@@ -40,15 +40,15 @@ static void transpose( uint8_t *buf, int w )
             XCHG( uint8_t, buf[w*i+j], buf[w*j+i] );
 }
 
-static void scaling_list_write( bs_t *s, x264_pps_t *pps, int idx )
+static void scaling_list_write( bs_t *s, x264_sps_t *sps, int idx )
 {
     const int len = idx<4 ? 16 : 64;
     const uint8_t *zigzag = idx<4 ? x264_zigzag_scan4[0] : x264_zigzag_scan8[0];
-    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]
+    const uint8_t *list = sps->scaling_list[idx];
+    const uint8_t *def_list = (idx==CQM_4IC) ? sps->scaling_list[CQM_4IY]
+                            : (idx==CQM_4PC) ? sps->scaling_list[CQM_4PY]
+                            : (idx==CQM_8IC+4) ? sps->scaling_list[CQM_8IY+4]
+                            : (idx==CQM_8PC+4) ? sps->scaling_list[CQM_8PY+4]
                             : x264_cqm_jvt[idx];
     if( !memcmp( list, def_list, len ) )
         bs_write1( s, 0 );   // scaling_list_present_flag
@@ -240,6 +240,44 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
         sps->vui.i_log2_max_mv_length_horizontal =
         sps->vui.i_log2_max_mv_length_vertical = (int)log2f( X264_MAX( 1, param->analyse.i_mv_range*4-1 ) ) + 1;
     }
+
+    sps->b_avcintra = !!param->i_avcintra_class;
+    sps->i_cqm_preset = param->i_cqm_preset;
+
+    switch( sps->i_cqm_preset )
+    {
+    case X264_CQM_FLAT:
+        for( int i = 0; i < 8; i++ )
+            sps->scaling_list[i] = x264_cqm_flat16;
+        break;
+    case X264_CQM_JVT:
+        for( int i = 0; i < 8; i++ )
+            sps->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_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 );
+        sps->scaling_list[CQM_4IY] = param->cqm_4iy;
+        sps->scaling_list[CQM_4PY] = param->cqm_4py;
+        sps->scaling_list[CQM_4IC] = param->cqm_4ic;
+        sps->scaling_list[CQM_4PC] = param->cqm_4pc;
+        sps->scaling_list[CQM_8IY+4] = param->cqm_8iy;
+        sps->scaling_list[CQM_8PY+4] = param->cqm_8py;
+        sps->scaling_list[CQM_8IC+4] = param->cqm_8ic;
+        sps->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( sps->scaling_list[i][j] == 0 )
+                    sps->scaling_list[i] = x264_cqm_jvt[i];
+        break;
+    }
 }
 
 void x264_sps_init_reconfigurable( x264_sps_t *sps, x264_param_t *param )
@@ -283,7 +321,26 @@ void x264_sps_write( bs_t *s, x264_sps_t *sps )
         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 );
-        bs_write1( s, 0 ); // seq_scaling_matrix_present_flag
+        /* Exactly match the AVC-Intra bitstream */
+        bs_write1( s, sps->b_avcintra ); // seq_scaling_matrix_present_flag
+        if( sps->b_avcintra )
+        {
+            scaling_list_write( s, sps, CQM_4IY );
+            scaling_list_write( s, sps, CQM_4IC );
+            scaling_list_write( s, sps, CQM_4IC );
+            bs_write1( s, 0 ); // no inter
+            bs_write1( s, 0 ); // no inter
+            bs_write1( s, 0 ); // no inter
+            scaling_list_write( s, sps, CQM_8IY+4 );
+            bs_write1( s, 0 ); // no inter
+            if( sps->i_chroma_format_idc == CHROMA_444 )
+            {
+                scaling_list_write( s, sps, CQM_8IC+4 );
+                bs_write1( s, 0 ); // no inter
+                scaling_list_write( s, sps, CQM_8IC+4 );
+                bs_write1( s, 0 ); // no inter
+            }
+        }
     }
 
     bs_write_ue( s, sps->i_log2_max_frame_num - 4 );
@@ -439,43 +496,6 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
     pps->b_redundant_pic_cnt = 0;
 
     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 < 8; i++ )
-            pps->scaling_list[i] = x264_cqm_flat16;
-        break;
-    case X264_CQM_JVT:
-        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_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_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;
-        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];
-        break;
-    }
 }
 
 void x264_pps_write( bs_t *s, x264_sps_t *sps, x264_pps_t *pps )
@@ -501,26 +521,27 @@ void x264_pps_write( bs_t *s, x264_sps_t *sps, x264_pps_t *pps )
     bs_write1( s, pps->b_constrained_intra_pred );
     bs_write1( s, pps->b_redundant_pic_cnt );
 
-    if( pps->b_transform_8x8_mode || pps->i_cqm_preset != X264_CQM_FLAT )
+    int b_scaling_list = !sps->b_avcintra && sps->i_cqm_preset != X264_CQM_FLAT;
+    if( pps->b_transform_8x8_mode || b_scaling_list )
     {
         bs_write1( s, pps->b_transform_8x8_mode );
-        bs_write1( s, (pps->i_cqm_preset != X264_CQM_FLAT) );
-        if( pps->i_cqm_preset != X264_CQM_FLAT )
+        bs_write1( s, b_scaling_list );
+        if( b_scaling_list )
         {
-            scaling_list_write( s, pps, CQM_4IY );
-            scaling_list_write( s, pps, CQM_4IC );
+            scaling_list_write( s, sps, CQM_4IY );
+            scaling_list_write( s, sps, CQM_4IC );
             bs_write1( s, 0 ); // Cr = Cb
-            scaling_list_write( s, pps, CQM_4PY );
-            scaling_list_write( s, pps, CQM_4PC );
+            scaling_list_write( s, sps, CQM_4PY );
+            scaling_list_write( s, sps, CQM_4PC );
             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 );
+                scaling_list_write( s, sps, CQM_8IY+4 );
+                scaling_list_write( s, sps, CQM_8PY+4 );
                 if( sps->i_chroma_format_idc == CHROMA_444 )
                 {
-                    scaling_list_write( s, pps, CQM_8IC+4 );
-                    scaling_list_write( s, pps, CQM_8PC+4 );
+                    scaling_list_write( s, sps, CQM_8IC+4 );
+                    scaling_list_write( s, sps, CQM_8PC+4 );
                     bs_write1( s, 0 ); // Cr = Cb
                     bs_write1( s, 0 ); // Cr = Cb
                 }
index 5f1e275..8ad148d 100644 (file)
@@ -861,7 +861,7 @@ static int check_dct( int cpu_ref, int cpu_new )
     h->param.analyse.i_luma_deadzone[1] = 0;
     h->param.analyse.b_transform_8x8 = 1;
     for( int i = 0; i < 6; i++ )
-        h->pps->scaling_list[i] = x264_cqm_flat16;
+        h->sps->scaling_list[i] = x264_cqm_flat16;
     x264_cqm_init( h );
     x264_quant_init( h, 0, &qf );
 
@@ -2037,14 +2037,14 @@ static int check_quant( int cpu_ref, int cpu_new )
         if( i_cqm == 0 )
         {
             for( int i = 0; i < 6; i++ )
-                h->pps->scaling_list[i] = x264_cqm_flat16;
-            h->param.i_cqm_preset = h->pps->i_cqm_preset = X264_CQM_FLAT;
+                h->sps->scaling_list[i] = x264_cqm_flat16;
+            h->param.i_cqm_preset = h->sps->i_cqm_preset = X264_CQM_FLAT;
         }
         else if( i_cqm == 1 )
         {
             for( int i = 0; i < 6; i++ )
-                h->pps->scaling_list[i] = x264_cqm_jvt[i];
-            h->param.i_cqm_preset = h->pps->i_cqm_preset = X264_CQM_JVT;
+                h->sps->scaling_list[i] = x264_cqm_jvt[i];
+            h->param.i_cqm_preset = h->sps->i_cqm_preset = X264_CQM_JVT;
         }
         else
         {
@@ -2056,8 +2056,8 @@ static int check_quant( int cpu_ref, int cpu_new )
                 for( int i = 0; i < 64; i++ )
                     cqm_buf[i] = 1;
             for( int i = 0; i < 6; i++ )
-                h->pps->scaling_list[i] = cqm_buf;
-            h->param.i_cqm_preset = h->pps->i_cqm_preset = X264_CQM_CUSTOM;
+                h->sps->scaling_list[i] = cqm_buf;
+            h->param.i_cqm_preset = h->sps->i_cqm_preset = X264_CQM_CUSTOM;
         }
 
         h->param.rc.i_qp_min = 0;
diff --git a/x264.c b/x264.c
index fb39288..d67d105 100644 (file)
--- a/x264.c
+++ b/x264.c
@@ -935,6 +935,8 @@ static void help( x264_param_t *defaults, int longhelp )
     H1( "      --bluray-compat         Enable compatibility hacks for Blu-ray support\n" );
     H1( "      --avcintra-class <integer> Use compatibility hacks for AVC-Intra class\n"
         "                                  - 50, 100, 200\n" );
+    H1( "      --avcintra-flavor <string> AVC-Intra flavor [\"%s\"]\n"
+        "                                  - %s\n", x264_avcintra_flavor_names[0], stringify_names( buf, x264_avcintra_flavor_names ) );
     H1( "      --stitchable            Don't optimize headers based on video content\n"
         "                              Ensures ability to recombine a segmented encode\n" );
     H1( "\n" );
@@ -1038,6 +1040,7 @@ static struct option long_options[] =
     { "open-gop",          no_argument, NULL, 0 },
     { "bluray-compat",     no_argument, NULL, 0 },
     { "avcintra-class", required_argument, NULL, 0 },
+    { "avcintra-flavor", required_argument, NULL, 0 },
     { "min-keyint",  required_argument, NULL, 'i' },
     { "keyint",      required_argument, NULL, 'I' },
     { "intra-refresh",     no_argument, NULL, 0 },
diff --git a/x264.h b/x264.h
index 3e8951f..5f7294e 100644 (file)
--- a/x264.h
+++ b/x264.h
@@ -45,7 +45,7 @@ extern "C" {
 
 #include "x264_config.h"
 
-#define X264_BUILD 156
+#define X264_BUILD 157
 
 /* Application developers planning to link against a shared library version of
  * libx264 from a Microsoft Visual Studio or similar development environment
@@ -170,6 +170,7 @@ typedef struct x264_nal_t
 #define X264_ANALYSE_PSUB16x16  0x0010  /* Analyse p16x8, p8x16 and p8x8 */
 #define X264_ANALYSE_PSUB8x8    0x0020  /* Analyse p8x4, p4x8, p4x4 */
 #define X264_ANALYSE_BSUB16x16  0x0100  /* Analyse b16x8, b8x16 and b8x8 */
+
 #define X264_DIRECT_PRED_NONE        0
 #define X264_DIRECT_PRED_SPATIAL     1
 #define X264_DIRECT_PRED_TEMPORAL    2
@@ -202,6 +203,10 @@ typedef struct x264_nal_t
 #define X264_KEYINT_MIN_AUTO         0
 #define X264_KEYINT_MAX_INFINITE     (1<<30)
 
+/* AVC-Intra flavors */
+#define X264_AVCINTRA_FLAVOR_PANASONIC 0
+#define X264_AVCINTRA_FLAVOR_SONY      1
+
 static const char * const x264_direct_pred_names[] = { "none", "spatial", "temporal", "auto", 0 };
 static const char * const x264_motion_est_names[] = { "dia", "hex", "umh", "esa", "tesa", 0 };
 static const char * const x264_b_pyramid_names[] = { "none", "strict", "normal", 0 };
@@ -215,6 +220,7 @@ static const char * const x264_transfer_names[] = { "", "bt709", "undef", "", "b
 static const char * const x264_colmatrix_names[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m", "smpte240m", "YCgCo", "bt2020nc", "bt2020c",
                                                      "smpte2085", "chroma-derived-nc", "chroma-derived-c", "ICtCp", 0 };
 static const char * const x264_nal_hrd_names[] = { "none", "vbr", "cbr", 0 };
+static const char * const x264_avcintra_flavor_names[] = { "panasonic", "sony", 0 };
 
 /* Colorspace type */
 #define X264_CSP_MASK           0x00ff  /* */
@@ -338,6 +344,7 @@ typedef struct x264_param_t
     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 */