[vlc-devel] [PATCH 1/4] h264_nal: add h264_create_avcdec_config_record

Thomas Guillem thomas at gllm.fr
Thu Jul 30 16:45:34 CEST 2015


---
 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 a5b3c47..d9490f1 100644
--- a/modules/codec/videotoolbox.m
+++ b/modules/codec/videotoolbox.m
@@ -320,55 +320,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);
-- 
2.1.4




More information about the vlc-devel mailing list