[vlc-commits] h264_nal: add h264_get_spspps

Thomas Guillem git at videolan.org
Tue Apr 28 17:49:36 CEST 2015


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Apr 23 18:22:51 2015 +0200| [f815b9e52a34d27271b0cae71a25c277be6f4a0b] | committer: Thomas Guillem

h264_nal: add h264_get_spspps

It fetches the SPS and PPS pointers from an Annex B buffer.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f815b9e52a34d27271b0cae71a25c277be6f4a0b
---

 modules/packetizer/h264_nal.c |   68 +++++++++++++++++++++++++++++++++++++++++
 modules/packetizer/h264_nal.h |    6 ++++
 2 files changed, 74 insertions(+)

diff --git a/modules/packetizer/h264_nal.c b/modules/packetizer/h264_nal.c
index 2a375c2..9e7eb70 100644
--- a/modules/packetizer/h264_nal.c
+++ b/modules/packetizer/h264_nal.c
@@ -22,6 +22,8 @@
 
 #include <limits.h>
 
+static const uint8_t annexb_startcode[] = { 0x00, 0x00, 0x00, 0x01 };
+
 int convert_sps_pps( decoder_t *p_dec, const uint8_t *p_buf,
                      uint32_t i_buf_size, uint8_t *p_out_buf,
                      uint32_t i_out_buf_size, uint32_t *p_sps_pps_size,
@@ -138,6 +140,72 @@ void convert_h264_to_annexb( uint8_t *p_buf, uint32_t i_len,
     }
 }
 
+int h264_get_spspps( uint8_t *p_buf, size_t i_buf,
+                     uint8_t **pp_sps, size_t *p_sps_size,
+                     uint8_t **pp_pps, size_t *p_pps_size )
+{
+    uint8_t *p_sps = NULL, *p_pps = NULL;
+    size_t i_sps_size = 0, i_pps_size = 0;
+    int i_nal_type = NAL_UNKNOWN;
+
+    while( true )
+    {
+        int i_inc = 0;
+
+        if( i_buf > 5 && memcmp( p_buf, annexb_startcode, 4 ) == 0 )
+        {
+            i_nal_type = p_buf[4] & 0x1F;
+
+            /* size of startcode + nal_type */
+            i_inc = 5;
+
+            /* pointer to the beginning of the sps/pps  */
+            if( i_nal_type == NAL_SPS && !p_sps )
+                p_sps = p_buf;
+            if( i_nal_type == NAL_PPS && !p_pps )
+                p_pps = p_buf;
+        } else {
+            i_inc = 1;
+        }
+
+        /* cf. 7.4.1.2.3 */
+        if( i_nal_type == NAL_UNKNOWN || i_nal_type > 18
+         || (i_nal_type >= 10 && i_nal_type <= 12))
+            return -1;
+
+        /* update SPS/PPS size if the new NAL is different than the last one */
+        if( !i_sps_size && p_sps && i_nal_type != NAL_SPS )
+            i_sps_size = p_buf - p_sps;
+        if( !i_pps_size && p_pps && i_nal_type != NAL_PPS )
+            i_pps_size = p_buf - p_pps;
+
+        /* SPS/PPS are before the slices */
+        if (i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
+            break;
+
+        i_buf -= i_inc;
+        p_buf += i_inc;
+
+        if( i_buf == 0 )
+        {
+            /* update SPS/PPS size if we reach the end of the buffer */
+            if( !i_sps_size && p_sps )
+                i_sps_size = p_buf - p_sps;
+            if( !i_pps_size && p_pps )
+                i_pps_size = p_buf - p_pps;
+            break;
+        }
+    }
+    if( ( !p_sps || !i_sps_size ) && ( !p_pps || !i_pps_size ) )
+        return -1;
+    *pp_sps = p_sps;
+    *p_sps_size = i_sps_size;
+    *pp_pps = p_pps;
+    *p_pps_size = i_pps_size;
+
+    return 0;
+}
+
 bool h264_get_profile_level(const es_format_t *p_fmt, size_t *p_profile,
                             size_t *p_level, size_t *p_nal_size)
 {
diff --git a/modules/packetizer/h264_nal.h b/modules/packetizer/h264_nal.h
index 6358fe6..bc346cf 100644
--- a/modules/packetizer/h264_nal.h
+++ b/modules/packetizer/h264_nal.h
@@ -82,6 +82,12 @@ void convert_h264_to_annexb( uint8_t *p_buf, uint32_t i_len,
                              size_t i_nal_size,
                              struct H264ConvertState *state );
 
+/* Get the SPS/PPS pointers from an Annex B buffer
+ * Returns 0 if a SPS and/or a PPS is found */
+int h264_get_spspps( uint8_t *p_buf, size_t i_buf,
+                     uint8_t **pp_sps, size_t *p_sps_size,
+                     uint8_t **pp_pps, size_t *p_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_size);



More information about the vlc-commits mailing list