From 0440cabf491f2f6e82e7bcde24a805ee966cbaab Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Tue, 25 Mar 2014 12:01:55 +0100 Subject: [PATCH] codecparsers: h264: add nal_reader_skip_long() helper. Add nal_reader_skip_long() helper function to allow an arbitrary number of bits to be skipped. The former nal_reader_skip() function is too limited to the actual cache size. Use this new function to simplify gst_h264_parser_parse_sei_message() default case, that skips unsupported payloads. v2: made args consistent from header to source file. Signed-off-by: Gwenole Beauchesne --- gst-libs/gst/codecparsers/gsth264parser.c | 11 +++-------- gst-libs/gst/codecparsers/nalutils.c | 22 ++++++++++++++++++++++ gst-libs/gst/codecparsers/nalutils.h | 1 + 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/codecparsers/gsth264parser.c b/gst-libs/gst/codecparsers/gsth264parser.c index 41489b88d6..f960824ac4 100644 --- a/gst-libs/gst/codecparsers/gsth264parser.c +++ b/gst-libs/gst/codecparsers/gsth264parser.c @@ -893,18 +893,13 @@ gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser, res = gst_h264_parser_parse_pic_timing (nalparser, &sei->payload.pic_timing, nr); break; - default:{ + default: /* Just consume payloadSize bytes, which does not account for emulation prevention bytes */ - guint nbits = payload_size % 8; - while (payload_size > 0) { - nal_reader_skip (nr, nbits); - payload_size -= nbits; - nbits = 8; - } + if (!nal_reader_skip_long (nr, payload_size)) + goto error; res = GST_H264_PARSER_OK; break; - } } /* When SEI message doesn't end at byte boundary, diff --git a/gst-libs/gst/codecparsers/nalutils.c b/gst-libs/gst/codecparsers/nalutils.c index 694066d954..5d20e818ad 100644 --- a/gst-libs/gst/codecparsers/nalutils.c +++ b/gst-libs/gst/codecparsers/nalutils.c @@ -113,9 +113,13 @@ nal_reader_read (NalReader * nr, guint nbits) return TRUE; } +/* Skips the specified amount of bits. This is only suitable to a + cacheable number of bits */ inline gboolean nal_reader_skip (NalReader * nr, guint nbits) { + g_assert (nbits <= 8 * sizeof (nr->cache)); + if (G_UNLIKELY (!nal_reader_read (nr, nbits))) return FALSE; @@ -124,6 +128,24 @@ nal_reader_skip (NalReader * nr, guint nbits) return TRUE; } +/* Generic version to skip any number of bits */ +gboolean +nal_reader_skip_long (NalReader * nr, guint nbits) +{ + /* Leave out enough bits in the cache once we are finished */ + const guint skip_size = 4 * sizeof (nr->cache); + guint remaining = nbits; + + nbits %= skip_size; + while (remaining > 0) { + if (!nal_reader_skip (nr, nbits)) + return FALSE; + remaining -= nbits; + nbits = skip_size; + } + return TRUE; +} + inline guint nal_reader_get_pos (const NalReader * nr) { diff --git a/gst-libs/gst/codecparsers/nalutils.h b/gst-libs/gst/codecparsers/nalutils.h index 5d231f22de..87a4b33669 100644 --- a/gst-libs/gst/codecparsers/nalutils.h +++ b/gst-libs/gst/codecparsers/nalutils.h @@ -57,6 +57,7 @@ void nal_reader_init (NalReader * nr, const guint8 * data, guint size); gboolean nal_reader_read (NalReader * nr, guint nbits); gboolean nal_reader_skip (NalReader * nr, guint nbits); +gboolean nal_reader_skip_long (NalReader * nr, guint nbits); guint nal_reader_get_pos (const NalReader * nr); guint nal_reader_get_remaining (const NalReader * nr); guint nal_reader_get_epb_count (const NalReader * nr);