vlc | branch: master | Thomas Guillem <[email protected]> | Thu Jul 30 16:45:34 2015 +0200| [3c0f610282d18d867a2eb0d39530fbc4dd2c9fbd] | committer: Felix Paul Kühne
h264_nal: add h264_create_avcdec_config_record Signed-off-by: Felix Paul Kühne <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3c0f610282d18d867a2eb0d39530fbc4dd2c9fbd --- modules/codec/videotoolbox.m | 54 ++++++----------------------------------- modules/packetizer/h264_nal.c | 45 ++++++++++++++++++++++++++++++++++ modules/packetizer/h264_nal.h | 9 +++++++ 3 files changed, 62 insertions(+), 46 deletions(-) diff --git a/modules/codec/videotoolbox.m b/modules/codec/videotoolbox.m index 4efd2d8..f2fba34 100644 --- a/modules/codec/videotoolbox.m +++ b/modules/codec/videotoolbox.m @@ -347,55 +347,17 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block) p_sys->codec_level = sps_data.i_level; /* create avvC atom to forward to the HW decoder */ - bo_t bo; - bool status = bo_init(&bo, 1024); - - if (status != true) - { - free(p_alloc_buf); - return VLC_ENOMEM; - } - - bo_add_8(&bo, 1); /* configuration version */ - bo_add_8(&bo, sps_data.i_profile); - bo_add_8(&bo, sps_data.i_profile_compatibility); - bo_add_8(&bo, sps_data.i_level); - bo_add_8(&bo, 0xff); /* 0b11111100 | lengthsize = 0x11 */ - - bo_add_8(&bo, 0xe0 | (i_sps_size > 0 ? 1 : 0)); /* 0b11100000 | sps_count */ - - if (i_sps_size > 4) { - /* the SPS data we have got includes 4 leading - * bytes which we need to remove */ - uint8_t *fixed_sps = malloc(i_sps_size - 4); - for (int i = 0; i < i_sps_size - 4; i++) { - fixed_sps[i] = p_sps_buf[i+4]; - } - - bo_add_16be(&bo, i_sps_size - 4); - bo_add_mem(&bo, i_sps_size - 4, fixed_sps); - free(fixed_sps); - } - - bo_add_8(&bo, (i_pps_size > 0 ? 1 : 0)); /* pps_count */ - if (i_pps_size > 4) { - /* the PPS data we have got includes 4 leading - * bytes which we need to remove */ - uint8_t *fixed_pps = malloc(i_pps_size - 4); - for (int i = 0; i < i_pps_size - 4; i++) { - fixed_pps[i] = p_pps_buf[i+4]; - } - - bo_add_16be(&bo, i_pps_size - 4); - bo_add_mem(&bo, i_pps_size - 4, fixed_pps); - free(fixed_pps); - } + block_t *p_block = h264_create_avcdec_config_record(4, + &sps_data, p_sps_buf, i_sps_size, + p_pps_buf, i_pps_size); free(p_alloc_buf); + if (!p_block) + return VLC_EGENERIC; extradata = CFDataCreate(kCFAllocatorDefault, - bo.b->p_buffer, - bo.b->i_buffer); - bo_deinit(&bo); + p_block->p_buffer, + p_block->i_buffer); + block_Release(p_block); if (extradata) CFDictionarySetValue(extradata_info, CFSTR("avcC"), extradata); diff --git a/modules/packetizer/h264_nal.c b/modules/packetizer/h264_nal.c index a998b6a..3eaf81c 100644 --- a/modules/packetizer/h264_nal.c +++ b/modules/packetizer/h264_nal.c @@ -518,6 +518,51 @@ int h264_parse_pps( const uint8_t *p_pps_buf, int i_pps_size, return 0; } +block_t *h264_create_avcdec_config_record( size_t i_nal_length_size, + struct nal_sps *p_sps, + const uint8_t *p_sps_buf, + size_t i_sps_size, + const uint8_t *p_pps_buf, + size_t i_pps_size ) +{ + bo_t bo; + + /* The length of the NAL size is encoded using 1, 2 or 4 bytes */ + if( i_nal_length_size != 1 && i_nal_length_size != 2 + && i_nal_length_size != 4 ) + return NULL; + + /* 6 * int(8), i_sps_size - 4, 1 * int(8), i_pps_size - 4 */ + if( bo_init( &bo, 7 + i_sps_size + i_pps_size - 8 ) != true ) + return NULL; + + bo_add_8( &bo, 1 ); /* configuration version */ + bo_add_8( &bo, p_sps->i_profile ); + bo_add_8( &bo, p_sps->i_profile_compatibility ); + bo_add_8( &bo, p_sps->i_level ); + bo_add_8( &bo, 0xfc | (i_nal_length_size - 1) ); /* 0b11111100 | lengthsize - 1*/ + + bo_add_8( &bo, 0xe0 | (i_sps_size > 0 ? 1 : 0) ); /* 0b11100000 | sps_count */ + + if( i_sps_size > 4 ) + { + /* the SPS data we have got includes 4 leading + * bytes which we need to remove */ + bo_add_16be( &bo, i_sps_size - 4 ); + bo_add_mem( &bo, i_sps_size - 4, p_sps_buf + 4 ); + } + + bo_add_8( &bo, (i_pps_size > 0 ? 1 : 0) ); /* pps_count */ + if( i_pps_size > 4 ) + { + /* the PPS data we have got includes 4 leading + * bytes which we need to remove */ + bo_add_16be( &bo, i_pps_size - 4 ); + bo_add_mem( &bo, i_pps_size - 4, p_pps_buf + 4 ); + } + return bo.b; +} + bool h264_get_profile_level(const es_format_t *p_fmt, size_t *p_profile, size_t *p_level, size_t *p_nal_length_size) { diff --git a/modules/packetizer/h264_nal.h b/modules/packetizer/h264_nal.h index a67e607..d75ccab 100644 --- a/modules/packetizer/h264_nal.h +++ b/modules/packetizer/h264_nal.h @@ -139,6 +139,15 @@ int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size, int h264_parse_pps( const uint8_t *p_pps_buf, int i_pps_size, struct nal_pps *p_pps ); +/* Create a AVCDecoderConfigurationRecord from SPS/PPS + * Returns a valid block_t on success, must be freed with block_Release */ +block_t *h264_create_avcdec_config_record( size_t i_nal_length_size, + struct nal_sps *p_sps, + const uint8_t *p_sps_buf, + size_t i_sps_size, + const uint8_t *p_pps_buf, + size_t i_pps_size ); + /* Get level and Profile */ bool h264_get_profile_level(const es_format_t *p_fmt, size_t *p_profile, size_t *p_level, size_t *p_nal_length_size); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
