From: Kieran Kunhya Date: Sat, 21 Sep 2013 18:16:12 +0000 (+0100) Subject: Add AVC-Intra 1080p50/60 Class 100 parameters X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c9f2bceb1f37aeaf6b7ed730f0fd210ef8725cab;p=libx264 Add AVC-Intra 1080p50/60 Class 100 parameters Also add some compatibility fixes. --- diff --git a/encoder/encoder.c b/encoder/encoder.c index 471ef544..e365caa8 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -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; diff --git a/encoder/set.c b/encoder/set.c index bf83a0d4..61eb0061 100644 --- a/encoder/set.c +++ b/encoder/set.c @@ -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 ); diff --git a/encoder/set.h b/encoder/set.h index d6fb60a5..d70bec85 100644 --- a/encoder/set.h +++ b/encoder/set.h @@ -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 );