h26[45]parser: Fix emulation prevention byte detection
authorWangfei <fei.w.wang@intel.com>
Thu, 15 Aug 2019 02:58:01 +0000 (10:58 +0800)
committerJan Schmidt <thaytan@noraisin.net>
Mon, 19 Aug 2019 05:01:24 +0000 (05:01 +0000)
Add a separate epb_cache variable to the codecparser NalReader to
detect Emulation Prevention Bytes separately from the main bit cache.

This fixes problems where the existing logic can mistakenly detect
multiple EPB with a sequence like: 0x00 0x00 0x03 0x00 0x03. In that
case, the 5th byte should not be regarded as an EPB.

gst-libs/gst/codecparsers/nalutils.c
gst-libs/gst/codecparsers/nalutils.h

index d2c293d..511f7c9 100644 (file)
@@ -74,6 +74,7 @@ nal_reader_init (NalReader * nr, const guint8 * data, guint size)
   nr->bits_in_cache = 0;
   /* fill with something other than 0 to detect emulation prevention bytes */
   nr->first_byte = 0xff;
+  nr->epb_cache = 0xff;
   nr->cache = 0xff;
 }
 
@@ -88,20 +89,16 @@ nal_reader_read (NalReader * nr, guint nbits)
 
   while (nr->bits_in_cache < nbits) {
     guint8 byte;
-    gboolean check_three_byte;
 
-    check_three_byte = TRUE;
   next_byte:
     if (G_UNLIKELY (nr->byte >= nr->size))
       return FALSE;
 
     byte = nr->data[nr->byte++];
+    nr->epb_cache = (nr->epb_cache << 8) | byte;
 
     /* check if the byte is a emulation_prevention_three_byte */
-    if (check_three_byte && byte == 0x03 && nr->first_byte == 0x00 &&
-        ((nr->cache & 0xff) == 0)) {
-      /* next byte goes unconditionally to the cache, even if it's 0x03 */
-      check_three_byte = FALSE;
+    if ((nr->epb_cache & 0xffffff) == 0x3) {
       nr->n_epb++;
       goto next_byte;
     }
index 7e23ab1..c8d60bd 100644 (file)
@@ -50,6 +50,7 @@ typedef struct
   guint byte;                   /* Byte position */
   guint bits_in_cache;          /* bitpos in the cache of next bit */
   guint8 first_byte;
+  guint32 epb_cache;            /* cache 3 bytes to check emulation prevention bytes */
   guint64 cache;                /* cached bytes */
 } NalReader;