mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 08:11:16 +00:00
h265parser: Skip unused SEI bits differently
3-byte emulation bytes can confuse the current code that skips bits at the end of an SEI. Use a simpler method that's also quicker because it skips all remaining bits in one go instead of 1 bit at a time.
This commit is contained in:
parent
5e7dbdf585
commit
18b54f8d34
1 changed files with 24 additions and 35 deletions
|
@ -2426,28 +2426,17 @@ error:
|
|||
return GST_H265_PARSER_ERROR;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nal_reader_has_more_data_in_payload (NalReader * nr,
|
||||
guint32 payload_start_pos_bit, guint32 payloadSize)
|
||||
{
|
||||
if (nal_reader_is_byte_aligned (nr) &&
|
||||
(nal_reader_get_pos (nr) == (payload_start_pos_bit + 8 * payloadSize)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstH265ParserResult
|
||||
gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
||||
guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
|
||||
{
|
||||
guint32 payloadSize;
|
||||
guint32 payloadSizeBytes;
|
||||
guint8 payload_type_byte, payload_size_byte;
|
||||
guint remaining, payload_size;
|
||||
guint32 payload_start_pos_bit;
|
||||
guint32 remaining, payload_size_bits, next;
|
||||
GstH265ParserResult res = GST_H265_PARSER_OK;
|
||||
|
||||
GST_DEBUG ("parsing \"Sei message\"");
|
||||
GST_DEBUG ("parsing \"SEI message\" %u bits available",
|
||||
nal_reader_get_remaining (nr));
|
||||
|
||||
memset (sei, 0, sizeof (*sei));
|
||||
|
||||
|
@ -2455,20 +2444,21 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
|||
READ_UINT8 (nr, payload_type_byte, 8);
|
||||
sei->payloadType += payload_type_byte;
|
||||
} while (payload_type_byte == 0xff);
|
||||
payloadSize = 0;
|
||||
payloadSizeBytes = 0;
|
||||
do {
|
||||
READ_UINT8 (nr, payload_size_byte, 8);
|
||||
payloadSize += payload_size_byte;
|
||||
payloadSizeBytes += payload_size_byte;
|
||||
}
|
||||
while (payload_size_byte == 0xff);
|
||||
|
||||
remaining = nal_reader_get_remaining (nr);
|
||||
payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
|
||||
payload_size_bits =
|
||||
payloadSizeBytes * 8 < remaining ? payloadSizeBytes * 8 : remaining;
|
||||
next = nal_reader_get_pos (nr) + payload_size_bits;
|
||||
|
||||
payload_start_pos_bit = nal_reader_get_pos (nr);
|
||||
GST_DEBUG
|
||||
("SEI message received: payloadType %u, payloadSize = %u bytes",
|
||||
sei->payloadType, payload_size);
|
||||
("SEI message received: payloadType %u, payloadSize = %u bits",
|
||||
sei->payloadType, payload_size_bits);
|
||||
|
||||
if (nal_type == GST_H265_NAL_PREFIX_SEI) {
|
||||
switch (sei->payloadType) {
|
||||
|
@ -2501,7 +2491,7 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
|||
default:
|
||||
/* Just consume payloadSize bytes, which does not account for
|
||||
emulation prevention bytes */
|
||||
if (!nal_reader_skip_long (nr, payload_size))
|
||||
if (!nal_reader_skip_long (nr, payload_size_bits))
|
||||
goto error;
|
||||
res = GST_H265_PARSER_OK;
|
||||
break;
|
||||
|
@ -2511,7 +2501,7 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
|||
default:
|
||||
/* Just consume payloadSize bytes, which does not account for
|
||||
emulation prevention bytes */
|
||||
if (!nal_reader_skip_long (nr, payload_size))
|
||||
if (!nal_reader_skip_long (nr, payload_size_bits))
|
||||
goto error;
|
||||
res = GST_H265_PARSER_OK;
|
||||
break;
|
||||
|
@ -2524,19 +2514,18 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
|||
* it is present, the size will be less than total PayloadSize since the
|
||||
* size of reserved_payload_extension is supposed to be
|
||||
* 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
|
||||
* the current implementation will still skip all unnecessary bits correctly.
|
||||
* In theory, we can have a more optimized implementation by skipping the
|
||||
* data left in PayLoadSize without out individually checking for each bits,
|
||||
* since the totoal size will be always less than payloadSize*/
|
||||
if (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
|
||||
payloadSize)) {
|
||||
/* Skip the byte alignment bits */
|
||||
if (!nal_reader_skip (nr, 1))
|
||||
* the current implementation will still skip all unnecessary bits correctly. */
|
||||
|
||||
/* Always make sure all the advertised SEI bits
|
||||
* were consumed during parsing. This is sufficient to skip to the next
|
||||
* byte aligned position after the SEI payload because we start
|
||||
* at a byte-aligned position and calculate the 'next' position as a
|
||||
* multiple of 8 bits, and this correctly skips any three-byte emulation
|
||||
* bytes encountered without getting confused. */
|
||||
if (next > nal_reader_get_pos (nr)) {
|
||||
GST_LOG ("Skipping %u unused SEI bits", next - nal_reader_get_pos (nr));
|
||||
if (!nal_reader_skip_long (nr, next - nal_reader_get_pos (nr)))
|
||||
goto error;
|
||||
while (!nal_reader_is_byte_aligned (nr)) {
|
||||
if (!nal_reader_skip (nr, 1))
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
Loading…
Reference in a new issue