[vlc-commits] codec hxxx: fix parsing avcc

Francois Cartegnie git at videolan.org
Wed Mar 29 15:49:47 CEST 2017


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Mar 28 16:19:25 2017 +0200| [1e49d593042d1fb8c1663ee91ebd72a4b4dfefa2] | committer: Thomas Guillem

codec hxxx: fix parsing avcc

Signed-off-by: Thomas Guillem <thomas at gllm.fr>

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

 modules/codec/hxxx_helper.c | 57 ++++++++++++++++++++++++++++-----------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/modules/codec/hxxx_helper.c b/modules/codec/hxxx_helper.c
index efe31fc..7b71478 100644
--- a/modules/codec/hxxx_helper.c
+++ b/modules/codec/hxxx_helper.c
@@ -250,6 +250,39 @@ fprintf(stderr, "new PPS parsed: %u\n", p_pps->i_id);
 }
 
 static int
+helper_process_avcC_h264(struct hxxx_helper *hh, const uint8_t *p_buf,
+                         size_t i_buf)
+{
+    if (i_buf < H264_MIN_AVCC_SIZE)
+        return VLC_EGENERIC;
+
+    p_buf += 5; i_buf -= 5;
+
+    for (unsigned int j = 0; j < 2 && i_buf > 0; j++)
+    {
+        /* First time is SPS, Second is PPS */
+        const unsigned int i_num_nal = p_buf[0] & (j == 0 ? 0x1f : 0xff);
+        p_buf++; i_buf--;
+
+        for (unsigned int i = 0; i < i_num_nal && i_buf >= 2; i++)
+        {
+            uint16_t i_nal_size = (p_buf[0] << 8) | p_buf[1];
+            if (i_nal_size > i_buf - 2)
+                return VLC_EGENERIC;
+            bool b_unused;
+            int i_ret = h264_helper_parse_nal(hh, p_buf, i_nal_size + 2, 2,
+                                              &b_unused);
+            if (i_ret != VLC_SUCCESS)
+                return i_ret;
+            p_buf += i_nal_size + 2;
+            i_buf -= i_nal_size + 2;
+        }
+    }
+
+    return VLC_SUCCESS;
+}
+
+static int
 h264_helper_set_extra(struct hxxx_helper *hh, const void *p_extra,
                       size_t i_extra)
 {
@@ -261,44 +294,24 @@ h264_helper_set_extra(struct hxxx_helper *hh, const void *p_extra,
     }
     else if (h264_isavcC(p_extra, i_extra))
     {
-        bool b_unused;
-
         hh->i_nal_length_size = (((uint8_t*)p_extra)[4] & 0x03) + 1;
         if (!helper_nal_length_valid(hh))
             return VLC_EGENERIC;
         hh->b_is_xvcC = true;
 
-        if (hh->b_need_xvcC)
-            return h264_helper_parse_nal(hh, p_extra, i_extra,
-                                         hh->i_nal_length_size, &b_unused);
-
-        size_t i_buf;
-        uint8_t *p_buf = h264_avcC_to_AnnexB_NAL(p_extra, i_extra, &i_buf,
-                                                 NULL);
-        if (!p_buf)
-        {
-            msg_Dbg(hh->p_obj, "h264_avcC_to_AnnexB_NAL failed");
-            return VLC_EGENERIC;
-        }
-        fprintf(stderr, "got annex b extra: %d (nal: %d)\n", i_buf, hh->i_nal_length_size);
-
         /* XXX h264_AVC_to_AnnexB() works only with a i_nal_length_size of 4.
          * If nal_length_size is smaller than 4, fallback to SW decoding. I
          * don't know if it's worth the effort to fix h264_AVC_to_AnnexB() for
          * a smaller nal_length_size. Indeed, this case will happen only with
          * very small resolutions, where hardware decoders are not that useful.
          * -Thomas */
-        if (hh->i_nal_length_size != 4)
+        if (!hh->b_need_xvcC && hh->i_nal_length_size != 4)
         {
             msg_Dbg(hh->p_obj, "nal_length_size is too small");
-            free(p_buf);
             return VLC_EGENERIC;
         }
 
-        int i_ret = h264_helper_parse_nal(hh, p_buf, i_buf,
-                                          hh->i_nal_length_size, &b_unused);
-        free(p_buf);
-        return i_ret;
+        return helper_process_avcC_h264(hh, p_extra, i_extra);
     }
     else /* Can't handle extra that is not avcC */
         return VLC_EGENERIC;



More information about the vlc-commits mailing list