Commit 61aaf76c authored by Thomas Guillem's avatar Thomas Guillem
Browse files

packetizer: h264: handle more than one SPS/PPS in h264_NAL_to_avcC

parent 0acb06af
......@@ -452,8 +452,8 @@ static int StartVideoToolbox(decoder_t *p_dec, const block_t *p_block)
if(!p_sys->b_is_avcc)
{
block_t *p_avcC = h264_NAL_to_avcC( p_sys->i_nal_length_size,
p_sps_nal, i_sps_nalsize,
p_pps_nal, i_pps_nalsize);
&p_sps_nal, &i_sps_nalsize, 1,
&p_pps_nal, &i_pps_nalsize, 1);
if (!p_avcC) {
msg_Warn(p_dec, "buffer creation failed");
return VLC_EGENERIC;
......
......@@ -21,6 +21,8 @@
# include "config.h"
#endif
#include <assert.h>
#include "h264_nal.h"
#include "hxxx_nal.h"
......@@ -632,40 +634,56 @@ IMPL_h264_generic_decode( h264_decode_pps, h264_picture_parameter_set_t,
h264_parse_picture_parameter_set_rbsp, h264_release_pps )
block_t *h264_NAL_to_avcC( uint8_t i_nal_length_size,
const uint8_t *p_sps_buf,
size_t i_sps_size,
const uint8_t *p_pps_buf,
size_t i_pps_size )
const uint8_t **pp_sps_buf,
const size_t *p_sps_size, uint8_t i_sps_count,
const uint8_t **pp_pps_buf,
const size_t *p_pps_size, uint8_t i_pps_count )
{
if( i_pps_size > UINT16_MAX || i_sps_size > UINT16_MAX )
return NULL;
/* 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;
if( i_sps_count == 0 || i_sps_count > H264_SPS_ID_MAX || i_pps_count == 0 )
return NULL;
/* Calculate the total size of all SPS and PPS NALs */
size_t i_spspps_size = 0;
for( size_t i = 0; i < i_sps_count; ++i )
{
assert( pp_sps_buf[i] && p_sps_size[i] );
if( p_sps_size[i] < 4 || p_sps_size[i] > UINT16_MAX )
return NULL;
i_spspps_size += p_sps_size[i] + 2 /* 16be size place holder */;
}
for( size_t i = 0; i < i_pps_count; ++i )
{
assert( pp_pps_buf[i] && p_pps_size[i] );
if( p_pps_size[i] > UINT16_MAX)
return NULL;
i_spspps_size += p_pps_size[i] + 2 /* 16be size place holder */;
}
bo_t bo;
/* 6 * int(8), i_sps_size, 1 * int(8), i_pps_size */
if( bo_init( &bo, 7 + i_sps_size + i_pps_size ) != true )
/* 1 + 3 + 1 + 1 + 1 + i_spspps_size */
if( bo_init( &bo, 7 + i_spspps_size ) != true )
return NULL;
bo_add_8( &bo, 1 ); /* configuration version */
bo_add_mem( &bo, 3, &p_sps_buf[1] ); /* i_profile/profile_compatibility/level */
bo_add_mem( &bo, 3, &pp_sps_buf[0][1] ); /* i_profile/profile_compatibility/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 )
bo_add_8( &bo, 0xe0 | i_sps_count ); /* 0b11100000 | sps_count */
for( size_t i = 0; i < i_sps_count; ++i )
{
bo_add_16be( &bo, i_sps_size );
bo_add_mem( &bo, i_sps_size, p_sps_buf );
bo_add_16be( &bo, p_sps_size[i] );
bo_add_mem( &bo, p_sps_size[i], pp_sps_buf[i] );
}
bo_add_8( &bo, (i_pps_size > 0 ? 1 : 0) ); /* pps_count */
if( i_pps_size )
bo_add_8( &bo, i_pps_count ); /* pps_count */
for( size_t i = 0; i < i_pps_count; ++i )
{
bo_add_16be( &bo, i_pps_size );
bo_add_mem( &bo, i_pps_size, p_pps_buf );
bo_add_16be( &bo, p_pps_size[i] );
bo_add_mem( &bo, p_pps_size[i], pp_pps_buf[i] );
}
return bo.b;
......
......@@ -171,10 +171,10 @@ bool h264_AnnexB_get_spspps( const uint8_t *p_buf, size_t i_buf,
/* Create a AVCDecoderConfigurationRecord from non prefixed SPS/PPS
* Returns a valid block_t on success, must be freed with block_Release */
block_t *h264_NAL_to_avcC( uint8_t i_nal_length_size,
const uint8_t *p_sps_buf,
size_t i_sps_size,
const uint8_t *p_pps_buf,
size_t i_pps_size );
const uint8_t **pp_sps_buf,
const size_t *p_sps_size, uint8_t i_sps_count,
const uint8_t **pp_pps_buf,
const size_t *p_pps_size, uint8_t i_pps_count );
/* Convert AVCDecoderConfigurationRecord SPS/PPS to Annex B format */
uint8_t * h264_avcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
......
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