1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-15 14:13:16 +02:00

avcodec/cbs_mpeg2: Simplify splitting fragment

avpriv_find_start_code() supports non-contiguous buffers
by maintaining a state that allows to find start codes
that span across multiple buffers; a consequence thereof
is that avpriv_find_start_code() is given a zero-sized
buffer, it does not modify this state, so that it appears
as if a start code was found if the state contained a start code.

This can e.g. happen with Sequence End units in MPEG-2 and
to counter this, cbs_mpeg2_split_fragment() reset the state
when it has already encountered the end of the fragment
in order to add the last unit (if it is only of the form 00 00 01 xy)
only once; it also used a flag to set whether this is the final unit.

Yet this can be improved by simply resetting state unconditionally
(thereby avoiding a branch); the flag can be removed by just checking
whether we have a valid start code (of the next unit to add)
at the end.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2022-02-04 14:17:33 +01:00
parent 66d7a21132
commit 115ac90ec9

View File

@@ -149,7 +149,6 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
uint32_t start_code = -1; uint32_t start_code = -1;
size_t unit_size; size_t unit_size;
int err; int err;
int final = 0;
start = avpriv_find_start_code(frag->data, frag->data + frag->data_size, start = avpriv_find_start_code(frag->data, frag->data + frag->data_size,
&start_code); &start_code);
@@ -161,14 +160,11 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
do { do {
unit_type = start_code & 0xff; unit_type = start_code & 0xff;
if (start == frag->data + frag->data_size) { // Reset start_code to ensure that avpriv_find_start_code()
// The last four bytes form a start code which constitutes // really reads a new start code and does not reuse the old
// a unit of its own. In this situation avpriv_find_start_code // start code in any way (as e.g. happens when there is a
// won't modify start_code at all so modify start_code so that // Sequence End unit at the very end of a packet).
// the next unit will be treated as the last unit. start_code = UINT32_MAX;
start_code = 0;
}
end = avpriv_find_start_code(start--, frag->data + frag->data_size, end = avpriv_find_start_code(start--, frag->data + frag->data_size,
&start_code); &start_code);
@@ -183,7 +179,6 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
} else { } else {
// We didn't find a start code, so this is the final unit. // We didn't find a start code, so this is the final unit.
unit_size = end - start; unit_size = end - start;
final = 1;
} }
err = ff_cbs_append_unit_data(frag, unit_type, (uint8_t*)start, err = ff_cbs_append_unit_data(frag, unit_type, (uint8_t*)start,
@@ -192,7 +187,9 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
return err; return err;
start = end; start = end;
} while (!final);
// Do we have a further unit to add to the fragment?
} while ((start_code >> 8) == 0x000001);
return 0; return 0;
} }