mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-02 21:48:55 +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;
|
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
|
static GstH265ParserResult
|
||||||
gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
||||||
guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
|
guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
|
||||||
{
|
{
|
||||||
guint32 payloadSize;
|
guint32 payloadSizeBytes;
|
||||||
guint8 payload_type_byte, payload_size_byte;
|
guint8 payload_type_byte, payload_size_byte;
|
||||||
guint remaining, payload_size;
|
guint32 remaining, payload_size_bits, next;
|
||||||
guint32 payload_start_pos_bit;
|
|
||||||
GstH265ParserResult res = GST_H265_PARSER_OK;
|
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));
|
memset (sei, 0, sizeof (*sei));
|
||||||
|
|
||||||
|
@ -2455,20 +2444,21 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
||||||
READ_UINT8 (nr, payload_type_byte, 8);
|
READ_UINT8 (nr, payload_type_byte, 8);
|
||||||
sei->payloadType += payload_type_byte;
|
sei->payloadType += payload_type_byte;
|
||||||
} while (payload_type_byte == 0xff);
|
} while (payload_type_byte == 0xff);
|
||||||
payloadSize = 0;
|
payloadSizeBytes = 0;
|
||||||
do {
|
do {
|
||||||
READ_UINT8 (nr, payload_size_byte, 8);
|
READ_UINT8 (nr, payload_size_byte, 8);
|
||||||
payloadSize += payload_size_byte;
|
payloadSizeBytes += payload_size_byte;
|
||||||
}
|
}
|
||||||
while (payload_size_byte == 0xff);
|
while (payload_size_byte == 0xff);
|
||||||
|
|
||||||
remaining = nal_reader_get_remaining (nr);
|
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
|
GST_DEBUG
|
||||||
("SEI message received: payloadType %u, payloadSize = %u bytes",
|
("SEI message received: payloadType %u, payloadSize = %u bits",
|
||||||
sei->payloadType, payload_size);
|
sei->payloadType, payload_size_bits);
|
||||||
|
|
||||||
if (nal_type == GST_H265_NAL_PREFIX_SEI) {
|
if (nal_type == GST_H265_NAL_PREFIX_SEI) {
|
||||||
switch (sei->payloadType) {
|
switch (sei->payloadType) {
|
||||||
|
@ -2501,7 +2491,7 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
||||||
default:
|
default:
|
||||||
/* Just consume payloadSize bytes, which does not account for
|
/* Just consume payloadSize bytes, which does not account for
|
||||||
emulation prevention bytes */
|
emulation prevention bytes */
|
||||||
if (!nal_reader_skip_long (nr, payload_size))
|
if (!nal_reader_skip_long (nr, payload_size_bits))
|
||||||
goto error;
|
goto error;
|
||||||
res = GST_H265_PARSER_OK;
|
res = GST_H265_PARSER_OK;
|
||||||
break;
|
break;
|
||||||
|
@ -2511,7 +2501,7 @@ gst_h265_parser_parse_sei_message (GstH265Parser * parser,
|
||||||
default:
|
default:
|
||||||
/* Just consume payloadSize bytes, which does not account for
|
/* Just consume payloadSize bytes, which does not account for
|
||||||
emulation prevention bytes */
|
emulation prevention bytes */
|
||||||
if (!nal_reader_skip_long (nr, payload_size))
|
if (!nal_reader_skip_long (nr, payload_size_bits))
|
||||||
goto error;
|
goto error;
|
||||||
res = GST_H265_PARSER_OK;
|
res = GST_H265_PARSER_OK;
|
||||||
break;
|
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
|
* it is present, the size will be less than total PayloadSize since the
|
||||||
* size of reserved_payload_extension is supposed to be
|
* size of reserved_payload_extension is supposed to be
|
||||||
* 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
|
* 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
|
||||||
* the current implementation will still skip all unnecessary bits correctly.
|
* 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,
|
/* Always make sure all the advertised SEI bits
|
||||||
* since the totoal size will be always less than payloadSize*/
|
* were consumed during parsing. This is sufficient to skip to the next
|
||||||
if (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
|
* byte aligned position after the SEI payload because we start
|
||||||
payloadSize)) {
|
* at a byte-aligned position and calculate the 'next' position as a
|
||||||
/* Skip the byte alignment bits */
|
* multiple of 8 bits, and this correctly skips any three-byte emulation
|
||||||
if (!nal_reader_skip (nr, 1))
|
* 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;
|
goto error;
|
||||||
while (!nal_reader_is_byte_aligned (nr)) {
|
|
||||||
if (!nal_reader_skip (nr, 1))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
Loading…
Reference in a new issue