Commit 3c0f6102 authored by Thomas Guillem's avatar Thomas Guillem Committed by Felix Paul Kühne

h264_nal: add h264_create_avcdec_config_record

Signed-off-by: default avatarFelix Paul Kühne <fkuehne@videolan.org>
parent 9fcd480f
......@@ -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);
......
......@@ -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)
{
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment