[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