codecparsers: h264: fix rbsp_more_data() implementation.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 10 Oct 2012 14:19:49 +0000 (16:19 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Mon, 24 Mar 2014 17:09:27 +0000 (18:09 +0100)
Account for trailing zero bits when checking for rbsp_more_data().

In particular, fix an hypothetical stream whereby rbsp_more_data()
is called in the following conditions for PPS header: NalReader
reached position 20, 12 bits are remaining and trailing data at
current byte position is c8 00.

rbsp_more_data() used to return TRUE whereas it should obviously
return FALSE because x8 00 represents a valid rbsp_trailing_bits()
structure.

https://bugzilla.gnome.org/show_bug.cgi?id=685890

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
gst-libs/gst/codecparsers/nalutils.c

index 0e68bc7..60ec0f3 100644 (file)
@@ -253,33 +253,42 @@ nal_reader_is_byte_aligned (NalReader * nr)
 gboolean
 nal_reader_has_more_data (NalReader * nr)
 {
-  guint remaining;
+  NalReader nr_tmp;
+  guint remaining, nbits;
+  guint8 rbsp_stop_one_bit, zero_bits;
 
   remaining = nal_reader_get_remaining (nr);
   if (remaining == 0)
     return FALSE;
 
-  if (remaining <= 8) {
-    guint8 rbsp_stop_one_bit;
+  nr_tmp = *nr;
+  nr = &nr_tmp;
 
-    if (!nal_reader_peek_bits_uint8 (nr, &rbsp_stop_one_bit, 1))
-      return FALSE;
-
-    if (rbsp_stop_one_bit == 1) {
-      guint8 zero_bits;
+  /* The spec defines that more_rbsp_data() searches for the last bit
+     equal to 1, and that it is the rbsp_stop_one_bit. Subsequent bits
+     until byte boundary is reached shall be zero.
 
-      if (remaining == 1)
-        return FALSE;
-
-      if (!nal_reader_peek_bits_uint8 (nr, &zero_bits, remaining))
-        return FALSE;
+     This means that more_rbsp_data() is FALSE if the next bit is 1
+     and the remaining bits until byte boundary are zero. One way to
+     be sure that this bit was the very last one, is that every other
+     bit after we reached byte boundary are also set to zero.
+     Otherwise, if the next bit is 0 or if there are non-zero bits
+     afterwards, then then we have more_rbsp_data() */
+  if (!nal_reader_get_bits_uint8 (nr, &rbsp_stop_one_bit, 1))
+    return FALSE;
+  if (!rbsp_stop_one_bit)
+    return TRUE;
 
-      if ((zero_bits - (1 << (remaining - 1))) == 0)
-        return FALSE;
-    }
+  nbits = --remaining % 8;
+  while (remaining > 0) {
+    if (!nal_reader_get_bits_uint8 (nr, &zero_bits, nbits))
+      return FALSE;
+    if (zero_bits != 0)
+      return TRUE;
+    remaining -= nbits;
+    nbits = 8;
   }
-
-  return TRUE;
+  return FALSE;
 }
 
 /***********  end of nal parser ***************/