[vlc-commits] packetizer: h264: handle more than one SPS/PPS in h264_NAL_to_avcC
Thomas Guillem
git at videolan.org
Wed Mar 29 15:49:44 CEST 2017
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Mar 24 08:16:22 2017 +0100| [61aaf76c93b820dc90fbf97eaa775d4e8dc62276] | committer: Thomas Guillem
packetizer: h264: handle more than one SPS/PPS in h264_NAL_to_avcC
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=61aaf76c93b820dc90fbf97eaa775d4e8dc62276
---
modules/codec/videotoolbox.m | 4 ++--
modules/packetizer/h264_nal.c | 54 ++++++++++++++++++++++++++++---------------
modules/packetizer/h264_nal.h | 8 +++----
3 files changed, 42 insertions(+), 24 deletions(-)
diff --git a/modules/codec/videotoolbox.m b/modules/codec/videotoolbox.m
index 0924a50..9bf538d 100644
--- a/modules/codec/videotoolbox.m
+++ b/modules/codec/videotoolbox.m
@@ -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;
diff --git a/modules/packetizer/h264_nal.c b/modules/packetizer/h264_nal.c
index f7b189d..0cf6b2c 100644
--- a/modules/packetizer/h264_nal.c
+++ b/modules/packetizer/h264_nal.c
@@ -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;
diff --git a/modules/packetizer/h264_nal.h b/modules/packetizer/h264_nal.h
index c83be4e..c32610d 100644
--- a/modules/packetizer/h264_nal.h
+++ b/modules/packetizer/h264_nal.h
@@ -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,
More information about the vlc-commits
mailing list