h26[45]parser: Fix emulation prevention byte detection

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.
This commit is contained in:
Wangfei 2019-08-15 10:58:01 +08:00 committed by Jan Schmidt
parent ca6657367c
commit 55db6413d7
2 changed files with 4 additions and 6 deletions

View 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;
}

View 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;