Calling ff_h264_field_end() when the per-field state is not properly
initialized leads to all kinds of undefined behaviour.
CC: libav-stable@libav.org
Bug-Id: 977 978 992
This could happen when there was a frame number gap and frame threading was used.
Debugging-by: Ronald S. Bultje <rsbultje@gmail.com>
Debugging-by: Justin Ruggles <justin.ruggles@gmail.com>
Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
CC:libav-stable@libav.org
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Since we only know whether a NAL unit corresponds to a new field after
parsing the slice header, this requires reorganizing the calls to slice
parsing, per-slice/field/frame init and actual decoding.
In the previous code, the function for slice header decoding also
immediately started a new field/frame as necessary, so any slices
already queued for decoding would no longer be decodable.
After this patch, we first parse the slice header, and if we determine
that a new field needs to be started we decode all the queued slices.
This function's purpose is not very well defined. Currently it does two
(only marginally related) things: selecting the next output frame and
calling ff_thread_finish_setup() for frame threading. The first of those
more properly belongs under field_start(), while the second can be
called directly from decode_nal_units().
Currently, SPS.mb_height is actually what the spec calls
PicHeightInMapUnits, which is half the frame height when interlacing is
allowed. Calling this 'mb_height' is quite confusing, and there are at
least two associated bugs where this field is treated as the actual
frame height - in the h264 parser and in the code computing maximum
reordering buffer size for a given level.
Fix those issues (and avoid possible future ones) by exporting the real
frame height in this field.
This is a more appropriate place for this. H264Context.recovery_frame is
shared between frame threads, so modifying it where it is right now is
invalid.
Move the NAL unit types into it. This will allow to stop including the
whole decoder-specific h264dec.h in some code that is unrelated to the
decoder and only needs some enum values.
Right now this code is mixed with selecting the next output frame. Move
it to a separate function called from h264_field_start(), which is a
more appropriate place for this.
While the value of those variables will be constant for the whole frame,
they are only used in two functions called from slice header decoding.
Moving them to the per-slice context allows us to make the H264Context
passed to slice_header_parse() constant.
There is no bitstream parsing in that block and messing with
decoder-global state is not something that belongs into header parsing.
Nothing else in this function depends on the value of current_slice,
except for two validity checks. Those checks are also moved out of
slice_header_parse().
Replace the decoder-global nal_unit_type/nal_ref_idc variables with the
per-NAL ones. The decoder-global ones still cannot be removed because
they are used by hwaccels.
The only difference is that the first of them contains a
ff_h264_flush_change() call. While that is not necessary in the second
block, it should cause no problems either.
Reduce the verbosity of the reinit log message from info to verbose,
since now it will be displayed during every decode session.
Do it right before the MMCOs are applied to the DPB. This will allow
moving the frame_start() call out of the slice header parsing, since
generating the implicit MMCOs needs to be done after frame_start().
They are stored in the slice header, so technically they are per-slice
(though they must be the same in every slice). This will simplify the
following commits.
This function does not do any bitstream parsing and it depends on the
current frame being allocated, so this will allow the frame_start() to
be moved out eventually.
This will allow postponing the reference list construction (and by
consequence some other functions, like frame_start) until the whole
slice header has been parsed.
That function is currently very long and entangles bitstream parsing and
decoder configuration. This makes the code much harder to read than
necessary.
Begin splitting the code that configures the decoder state based on the
slice header information from the parsing of the slice header.
In such a case, decode the MBs in parallel without the loop filter, then
execute the filter serially.
The ref2frm array was previously moved to H264SliceContext. That was
incorrect, since it applies to all the slices and should properly be in
H264Context (it did not actually break decoding, since this distinction
only becomes relevant with slice threading and deblocking_filter=1,
which was not implemented before this commit). The ref2frm array is thus
moved back to H264Context.