Add AVC-Intra 1080p50/60 Class 100 parameters
authorKieran Kunhya <kieran@kunhya.com>
Sat, 21 Sep 2013 18:16:12 +0000 (19:16 +0100)
committerJason Garrett-Glaser <jason@x264.com>
Wed, 30 Oct 2013 20:02:27 +0000 (13:02 -0700)
Also add some compatibility fixes.

encoder/encoder.c
encoder/set.c
encoder/set.h

index fc43078..2ff4515 100644 (file)
@@ -631,7 +631,7 @@ static int x264_validate_parameters( x264_t *h, int b_open )
             uint16_t frame_size;
             const uint8_t *cqm_4ic;
             const uint8_t *cqm_8iy;
-        } avcintra_lut[2][2][5] =
+        } avcintra_lut[2][2][7] =
         {
             {{{ 60000, 1001, 0,  912, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
               {    50,    1, 0, 1100, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
@@ -640,7 +640,9 @@ static int x264_validate_parameters( x264_t *h, int b_open )
               { 24000, 1001, 0,  912, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy }},
              {{ 30000, 1001, 1, 1820, x264_cqm_avci50_4ic, x264_cqm_avci50_1080i_8iy },
               {    25,    1, 1, 2196, x264_cqm_avci50_4ic, x264_cqm_avci50_1080i_8iy },
+              { 60000, 1001, 0, 1820, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
               { 30000, 1001, 0, 1820, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+              {    50,    1, 0, 2196, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
               {    25,    1, 0, 2196, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
               { 24000, 1001, 0, 1820, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy }}},
             {{{ 60000, 1001, 0, 1848, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy },
@@ -650,7 +652,9 @@ static int x264_validate_parameters( x264_t *h, int b_open )
               { 24000, 1001, 0, 1848, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy }},
              {{ 30000, 1001, 1, 3692, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },
               {    25,    1, 1, 4444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },
+              { 60000, 1001, 0, 3692, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
               { 30000, 1001, 0, 3692, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+              {    50,    1, 0, 4444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
               {    25,    1, 0, 4444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
               { 24000, 1001, 0, 3692, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }}}
         };
@@ -695,7 +699,7 @@ static int x264_validate_parameters( x264_t *h, int b_open )
         int i;
         uint32_t fps_num = h->param.i_fps_num, fps_den = h->param.i_fps_den;
         x264_reduce_fraction( &fps_num, &fps_den );
-        for( i = 0; i < 5; i++ )
+        for( i = 0; i < 7; i++ )
         {
             if( avcintra_lut[type][res][i].fps_num == fps_num &&
                 avcintra_lut[type][res][i].fps_den == fps_den &&
@@ -704,7 +708,7 @@ static int x264_validate_parameters( x264_t *h, int b_open )
                 break;
             }
         }
-        if( i == 5 )
+        if( i == 7 )
         {
             x264_log( h, X264_LOG_ERROR, "FPS %d/%d%c not compatible with AVC-Intra\n",
                       h->param.i_fps_num, h->param.i_fps_den, PARAM_INTERLACED ? 'i' : 'p' );
@@ -3574,25 +3578,21 @@ int     x264_encoder_encode( x264_t *h,
     if( h->param.b_avcintra_compat )
     {
         /* Write an empty filler NAL to mimic the AUD in the P2 format*/
-        if( h->param.b_avcintra_compat )
-        {
-            x264_nal_start( h, NAL_FILLER, NAL_PRIORITY_DISPOSABLE );
-            x264_filler_write( h, &h->out.bs, 0 );
-            if( x264_nal_end( h ) )
-                return -1;
-            overhead += h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD;
-        }
+        x264_nal_start( h, NAL_FILLER, NAL_PRIORITY_DISPOSABLE );
+        x264_filler_write( h, &h->out.bs, 0 );
+        if( x264_nal_end( h ) )
+            return -1;
+        overhead += h->out.nal[h->out.i_nal-1].i_payload + NALU_OVERHEAD;
 
         /* All lengths are magic lengths that decoders expect to see */
         /* "UMID" SEI */
         x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
-        if( x264_sei_avcintra_write( h, &h->out.bs, 497, "UMID" ) < 0 )
+        if( x264_sei_avcintra_umid_write( h, &h->out.bs ) < 0 )
             return -1;
         if( x264_nal_end( h ) )
             return -1;
         overhead += h->out.nal[h->out.i_nal-1].i_payload + SEI_OVERHEAD;
 
-
         int unpadded_len;
         int total_len;
         if( h->param.i_height == 1080 )
@@ -3607,7 +3607,7 @@ int     x264_encoder_encode( x264_t *h,
         }
         /* "VANC" SEI */
         x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
-        if( x264_sei_avcintra_write( h, &h->out.bs, unpadded_len, "VANC" ) < 0 )
+        if( x264_sei_avcintra_vanc_write( h, &h->out.bs, unpadded_len ) < 0 )
             return -1;
         if( x264_nal_end( h ) )
             return -1;
index bf83a0d..61eb006 100644 (file)
@@ -31,6 +31,7 @@
 
 // Indexed by pic_struct values
 static const uint8_t num_clock_ts[10] = { 0, 1, 1, 1, 2, 2, 3, 3, 2, 3 };
+const static uint8_t avcintra_uuid[] = {0xF7, 0x49, 0x3E, 0xB3, 0xD4, 0x00, 0x47, 0x96, 0x86, 0x86, 0xC9, 0x70, 0x7B, 0x64, 0x37, 0x2A};
 
 static void transpose( uint8_t *buf, int w )
 {
@@ -725,10 +726,34 @@ void x264_sei_dec_ref_pic_marking_write( x264_t *h, bs_t *s )
     x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_DEC_REF_PIC_MARKING );
 }
 
-int x264_sei_avcintra_write( x264_t *h, bs_t *s, int len, const char *msg )
+int x264_sei_avcintra_umid_write( x264_t *h, bs_t *s )
+{
+    uint8_t data[512];
+    const char *msg = "UMID";
+    const int len = 497;
+
+    memset( data, 0xff, len );
+    memcpy( data, avcintra_uuid, sizeof(avcintra_uuid) );
+    memcpy( data+16, msg, strlen(msg) );
+
+    data[20] = 0x13;
+    /* These bytes appear to be some sort of frame/seconds counter in certain applications,
+     * but others jump around, so leave them as zero for now */
+    data[21] = data[22] = 0;
+
+    data[28] = 0x14;
+    data[36] = 0x60;
+    data[41] = 0x22; /* Believed to be some sort of end of basic UMID identifier */
+
+    x264_sei_write( &h->out.bs, data, len, SEI_USER_DATA_UNREGISTERED );
+
+    return 0;
+}
+
+int x264_sei_avcintra_vanc_write( x264_t *h, bs_t *s, int len )
 {
-    const static uint8_t avcintra_uuid[] = {0xF7, 0x49, 0x3E, 0xB3, 0xD4, 0x00, 0x47, 0x96, 0x86, 0x86, 0xC9, 0x70, 0x7B, 0x64, 0x37, 0x2A};
     uint8_t data[6000];
+    const char *msg = "VANC";
     if( len > sizeof(data) )
     {
         x264_log( h, X264_LOG_ERROR, "AVC-Intra SEI is too large (%d)\n", len );
index d6fb60a..d70bec8 100644 (file)
@@ -38,7 +38,8 @@ void x264_sei_buffering_period_write( x264_t *h, bs_t *s );
 void x264_sei_pic_timing_write( x264_t *h, bs_t *s );
 void x264_sei_dec_ref_pic_marking_write( x264_t *h, bs_t *s );
 void x264_sei_frame_packing_write( x264_t *h, bs_t *s );
-int  x264_sei_avcintra_write( x264_t *h, bs_t *s, int len, const char *msg );
+int  x264_sei_avcintra_umid_write( x264_t *h, bs_t *s );
+int  x264_sei_avcintra_vanc_write( x264_t *h, bs_t *s, int len );
 void x264_sei_write( bs_t *s, uint8_t *payload, int payload_size, int payload_type );
 void x264_filler_write( x264_t *h, bs_t *s, int filler );