Commit Graph

51402 Commits

Author SHA1 Message Date
Andreas Rheinhardt c85508f5a9 avcodec/mpeg12dec: Allocate dummy frames for non-I fields
MPEG-2 allows to pair an intra field (as first field) together
with a P-field. In this case a conformant bitstream has to satisfy
certain restrictions in order to ensure that only the I field
is used for prediction. See section 7.6.3.5 of the MPEG-2
specifications.

We do not check these restrictions; normally we simply allocate
dummy frames for reference in order to avoid checks lateron.
This happens in ff_mpv_frame_start() and therefore does not happen
for a second field. This is inconsistent. Fix this by allocating
these dummy frames for the second field, too.

This already fixes two bugs:
1. Undefined pointer arithmetic in prefetch_motion() in
mpegvideo_motion.c where it is simply presumed that the reference
frame exists.
2. Several MPEG-2 hardware accelerations rely on last_picture
being allocated for P pictures and next picture for B pictures;
e.g. VDPAU returns VDP_STATUS_INVALID_HANDLE when decoding
an I-P fields pair because the forward_reference was set incorrectly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:50:12 +02:00
Andreas Rheinhardt 73676dd47a avcodec/mpegpicture: Mark dummy frames as such
This will allow to avoid outputting them.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:49:57 +02:00
Andreas Rheinhardt 99543c93ec avcodec/mpegvideo_dec: Factor allocating dummy frames out
This will allow to reuse it to allocate dummy frames for
the second field (which can be a P-field even if the first
field was an intra field).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:49:24 +02:00
Andreas Rheinhardt a30c95ed8a avcodec/mpegvideo_dec: Sync linesize and uvlinesize between threads
linesize and uvlinesize are supposed to be the common linesize of all
the Y/UV-planes of all the currently cached pictures.
ff_mpeg_update_thread_context() syncs the pictures, yet it did not sync
linesize and uvlinesize. This mostly works, because ff_alloc_picture()
only accepts new pictures if they coincide with the linesize of the
already provided pictures (if any).  Yet there is a catch: Linesize
changes are accepted when the dimensions change (in which case the
cached frames are discarded).

So imagine a scenario where all frame threads use the same dimension A
until a frame with a different dimension B is encountered in the
bitstream, only to be instantly reverted to A in the next picture. If
the user changes the linesize of the frames upon the change to dimension
B and keeps the linesize thereafter (possible if B > A),
ff_alloc_picture() will report an error when frame-threading is in use:
The thread decoding B will perform a frame size change and so will the
next thread in ff_mpeg_update_thread_context() as well as when decoding
its picture. But the next thread will (presuming it is not the same
thread that decoded B, i.e. presuming >= 3 threads) not perform a frame
size change, because the new frame size coincides with its old frame
size, yet the linesize it expects from ff_alloc_picture() is outdated,
so that it errors out.

It is also possible for the user to use the original linesizes for
the frame after the frame that reverted back to A; this will be
accepted, yet the assumption that of all pictures are the same
will be broken, leading to segfaults.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:49:03 +02:00
Andreas Rheinhardt d4b63885a6 avcodec/mpegpicture: Store linesize in ScratchpadContext
The mpegvideo-based codecs currently require the linesize to be
constant (except when the frame dimensions change); one reason
for this is that certain scratch buffers whose size depend on
linesize are only allocated once and are presumed to be correctly
sized if the pointers are != NULL.

This commit changes this by storing the actual linesize these
buffers belong to and reallocating the buffers if it does not
suffice. This is not enough to actually support changing linesizes,
but it is a start. And it is a prerequisite for the next patch.

Also don't emit an error message in case the source ctx's
edge_emu_buffer is unset in ff_mpeg_update_thread_context().
It need not be an error at all; e.g. it is a perfectly normal
state in case a hardware acceleration is used as the scratch
buffers are not allocated in this case (it is easy to run into
this issue with MPEG-4) or if the src context was not initialized
at all (e.g. because the first packet contained garbage).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:47:44 +02:00
Andreas Rheinhardt 0aaabe1fd7 avcodec/get_buffer: Remove redundant check
It is unnecessary to check for whether the number of planes
of an already existing audio pool coincides with the number
of planes to use for the frame: If the common format of both
is planar, then the number of planes coincides with the number
of channels for which there is already a check*; if not,
then both the existing pool as well as the frame use one pool.

*: In fact, one could reuse the pool in this case even if the
number of channels changes.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:37:16 +02:00
Andreas Rheinhardt 2786d34712 avcodec/ratecontrol: Avoid padding in RateControlEntry
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:37:11 +02:00
Andreas Rheinhardt 685cda26aa avcodec/mpegvideo, ratecontrol: Remove write-only skip_count
Write-only since 6cf0cb8935.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:36:37 +02:00
Andreas Rheinhardt 68a06640b1 avcodec/ratecontrol: Don't call ff_rate_control_uninit() ourselves
It is currently done inconsistently: Only one error path
(namely the one from init_pass2()) made ff_rate_control_init()
call ff_rate_control_uninit(); in other error paths
cleanup was left to the caller.

Given that the only caller of this function already performs
the necessary cleanup this commit changes this to always
rely on the caller to perform cleanup on error.

Also return the error code from init_pass2().

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:36:30 +02:00
Andreas Rheinhardt 0c9e04b0e2 avcodec/ratecontrol: Pass RCContext directly in ff_rate_control_uninit()
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:36:16 +02:00
Andreas Rheinhardt ba28222a14 avcodec/ratecontrol: Fix double free on error
Happens on init_pass2() failure.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-06-12 10:36:01 +02:00
Lynne bdd3c6ca50 aacdec_usac: always zero out alpha_q values for stereo streams
The issue is that if a frame has no complex stereo prediction,
the alpha values must all be assumed to be zero if the next frame
has complex prediction and uses delta coding.
2024-06-12 03:33:45 +02:00
Lynne d79fbad366 aacdec_usac: rename spectrum decode function and remove unused arg
The LC part of the decoder combines scalefactor application with
spectrum decoding, and this was the plan here, but that's not possible,
so change the function name.
2024-06-12 03:33:45 +02:00
Lynne 11a8e0a4e5 aacdec_usac: dequantize scalefactors after noise synthesis
The issue here is that the spec implied that the offset is done
on the dequantized scalefactor, but in fact, it is done on the
scalefactor offset. Delay dequantizing the scalefactors until
after noise synthesis is performed, and change to apply the
offset onto the offset.
2024-06-12 03:33:38 +02:00
Rémi Denis-Courmont 378d1b06c3 riscv: probe for Zbb extension at load time
Due to hysterical raisins, most RISC-V Linux distributions target a
RV64GC baseline excluding the Bit-manipulation ISA extensions, most
notably:
- Zba: address generation extension and
- Zbb: basic bit manipulation extension.
Most CPUs that would make sense to run FFmpeg on support Zba and Zbb
(including the current FATE runner), so it makes sense to optimise for
them. In fact a large chunk of existing assembler optimisations relies
on Zba and/or Zbb.

Since we cannot patch shared library code, the next best thing is to
carry a flag initialised at load-time and check it on need basis.
This results in 3 instructions overhead on isolated use, e.g.:
1:  AUIPC rd, %pcrel_hi(ff_rv_zbb_supported)
    LBU   rd, %pcrel_lo(1b)(rd)
    BEQZ  rd, non_Zbb_fallback_code
    // Zbb code here

The C compiler will typically load the flag ahead of time to reducing
latency, and can also keep it around if Zbb is used multiple times in a
single optimisation scope. For this to work, the flag symbol must be
hidden; otherwise the optimisation degrades with a GOT look-up to
support interposition:
1:  AUIPC rd, GOT_OFFSET_HI
    LD    rd, GOT_OFFSET_LO(rd)
    LBU   rd, (rd)
    BEQZ  rd, non_Zbb_fallback_code
    // Zbb code here

This patch adds code to provision the flag in libraries using bit
manipulation functions from libavutil: byte-swap, bit-weight and
counting leading or trailing zeroes.
2024-06-11 20:12:37 +03:00
Anton Khirnov 08ea7d6b8e lavc/hevcdec: constify source frame in hevc_ref_frame() 2024-06-11 17:39:35 +02:00
Anton Khirnov ccd391d6a3 lavc/hevcdec: do not unref current frame on frame_end() failure
It's a race with frame threading.
2024-06-11 17:39:35 +02:00
Anton Khirnov d725c737fe lavc/hevcdec: move some frame-end code to hevc_frame_end()
Specifically, calling hwaccel end_frame, verifying frame checksum,
and printing the frame-was-decoded message.
2024-06-11 17:39:35 +02:00
Anton Khirnov edb6a471c4 lavc/hevcdec: factor decoding a slice NALU out of decode_nal_unit() 2024-06-11 17:39:35 +02:00
Anton Khirnov 90e75c4ec9 lavc/hevcdec: drop a redundant multiple-frame-per-packet check 2024-06-11 17:39:35 +02:00
Anton Khirnov 3cd6492fb5 lavc/hevcdec: move the check for multiple frames in a packet
Do not do it in hls_slice_header(), which is the wrong place for it.
Avoids special magic return value of 1 in that function. The comment
mentioning potential corrupted state is no longer relevant, as
hls_slice_header() modifies no state beyond SliceHeader, which will only
get used for a valid frame.
2024-06-11 17:39:35 +02:00
Anton Khirnov a8f9d52c22 lavc/hevcdec: move setting slice_initialized out of hls_slice_header()
hls_slice_header() no longer modifies anything in HEVCContext besides
SliceHeader.
2024-06-11 17:39:35 +02:00
Anton Khirnov 82ded1ad3a lavc/hevcdec: move sequence increment/IDR handling to hevc_frame_start()
From hls_slice_header(). It is only done once per frame, so that is a
more appropriate place for this code.
2024-06-11 17:39:35 +02:00
Anton Khirnov a2e77caf37 lavc/hevcdec: set active PPS/SPS in hevc_frame_start()
Not in hls_slice_header(), as it should only be done once per frame.
2024-06-11 17:39:35 +02:00
Anton Khirnov 47d34ba7fb lavc/hevcdec: move constructing slice RPL to decode_slice_data() 2024-06-11 17:39:35 +02:00
Anton Khirnov fe171a3b51 lavc/hevcdec: move calling hwaccel decode_slice to decode_slice_data()
From decode_nal_unit(), as that is a more appropriate place for it.
2024-06-11 17:39:35 +02:00
Anton Khirnov 6ee550d83d lavc/hevcdec: move calling hwaccel start_frame to hevc_frame_start()
From decode_nal_unit(), as that is a more appropriate place for it.
2024-06-11 17:39:35 +02:00
Anton Khirnov 3bbb5d78c7 lavc/hevcdec: move per-slice local_ctx setup out of hls_slice_header()
Into decode_slice_data(). This is a step towards constifying
HEVCContext in hls_slice_header().
2024-06-11 17:39:35 +02:00
Anton Khirnov efc827bf6f lavc/hevcdec: move slice decoding dispatch to its own function
Also move there a sanity check from hls_decode_entry() that should also
be performed when WPP is active (note that the check is not moved to
hls_slice_header() because it requires the HEVCContext.tab_slice_address
to be set up).
2024-06-11 17:39:35 +02:00
Anton Khirnov 7cce612a26 lavc/hevcdec: move a slice segment sanity check to hls_slice_header()
Combine it with an existing similar check.
2024-06-11 17:39:35 +02:00
Anton Khirnov d43527a1a0 lavc/hevcdec: store slice header POC in SliceHeader
Rather than decoding directly into HEVCContext.poc.

This is a step towards constifying HEVCContext in hls_slice_header().
2024-06-11 17:39:35 +02:00
Anton Khirnov e4e9e1da15 lavc/hevcdec: drop redundant HEVCContext.threads_{type,number}
They are useless duplicates of corresponding AVCodecContext fields.
2024-06-11 17:39:35 +02:00
Anton Khirnov b0c29a45dc lavc/hevc/cabac: do not infer WPP use based on HEVCContext.threads_number
Pass this information explicitly instead.
2024-06-11 17:39:35 +02:00
Anton Khirnov d86ac94df2 lavc/hevcdec: output RASL frames based on the value of no_rasl_output_flag
Instead of an ad-hoc scheme. Also, combine skipping RASL frames with
skip_frame handling - current code seems flawed as it only executes for
the first slice of a RASL frame and unnecessarily unsets is_decoded,
which should not be set at this point anyway..

Some RASL frames in fate-hevc-afd-tc-sei that were previously discarded
are now output.
2024-06-11 17:39:35 +02:00
Anton Khirnov 3115c84015 lavc/hevcdec: only set no_rasl_output_flag for IRAP frames
Its meaning is only specified for IRAP frames.

As it's currently never used otherwise, this should not change decoder
behaviour, but will be useful in future commits.
2024-06-11 17:39:35 +02:00
Anton Khirnov 381b70e173 lavc/hevcdec: do not pass HEVCContext to ff_hevc_frame_nb_refs()
Pass the only things required from it - slice header and PPS -
explicitly.

Will be useful in the following commits to avoid mofiying HEVCContext in
hls_slice_header().
2024-06-11 17:39:35 +02:00
Anton Khirnov 07eb60c0da lavc/hevcdec: only call export_stream_params_from_sei() once per frame
Not once per each slice header, as it makes no sense and may cause races
with frame threading.
2024-06-11 17:39:35 +02:00
Anton Khirnov 01b379a93e lavc/hevcdec: move pocTid0 computation to hevc_frame_start()
It is only done once per frame. Also, rename the variable to poc_tid0 to
be consistent with our naming conventions.
2024-06-11 17:39:35 +02:00
Anton Khirnov 5e438511ab lavc/hevcdec: do not pass HEVCContext to decode_lt_rps()
Pass the two numbers needed from it explicitly.

Makes it clear that HEVCContext is not modified by this function.
2024-06-11 17:39:35 +02:00
Anton Khirnov 0892ec947c lavc/hevcdec: pass SliceHeader explicitly to pred_weight_table()
And replace the HEVCContext* parameter by void *logctx.

Makes it clear that only SliceHeader is modified by this function.
2024-06-11 17:39:35 +02:00
Anton Khirnov 90fc331b0f lavc/hevcdec: only ignore INVALIDDATA in decode_nal_unit()
All other errors should cause a failure, regardless of the value of
err_recognition. Also, print a warning message when skipping invalid NAL
units.
2024-06-11 17:39:35 +02:00
Anton Khirnov 8eb134f4f9 lavc/hevcdec: drop an always-zero variable 2024-06-11 17:39:35 +02:00
Anton Khirnov 8c8072c29c lavc/hevcdec: move active PPS from HEVCParamSets to HEVCContext
"Currently active PPS" is a property of the decoding process, not of the
list of available parameter sets.
2024-06-11 17:39:34 +02:00
Anton Khirnov 0f47342c12 lavc/hevcdec: stop accessing parameter sets through HEVCParamSets
Instead, accept PPS/SPS as function arguments.

Makes the code shorter and significantly reduces diff in future commits.
2024-06-11 17:39:34 +02:00
Anton Khirnov 38b8ae4112 lavc/hevc/pred: stop accessing parameter sets through HEVCParamSets
Instead, accept PPS/SPS as function arguments.

Makes the code shorter and significantly reduces diff in future commits.
2024-06-11 17:39:34 +02:00
Anton Khirnov d0868d70ea lavc/hevc/cabac: stop accessing parameter sets through HEVCParamSets
Instead, accept PPS/SPS as function arguments.

Makes the code shorter and significantly reduces diff in future commits.
2024-06-11 17:39:34 +02:00
Anton Khirnov b38aecffec lavc/hevc/filter: stop accessing parameter sets through HEVCParamSets
Instead, accept PPS as a function argument and retrieve SPS through it.

Makes the code shorter and significantly reduces diff in future commits.
2024-06-11 17:39:34 +02:00
Anton Khirnov fb873a05b3 lavc/hevc/mvs: stop accessing parameter sets through HEVCParamSets
Instead, accept PPS as a function argument and retrieve SPS through it.

Makes the code shorter and significantly reduces diff in future commits.
2024-06-11 17:39:34 +02:00
Anton Khirnov 6ddba110eb lavc/hevc/parser: stop using HEVCParamSets.[psv]ps
The parser does not need to preserve these between frames.
2024-06-11 17:39:34 +02:00
Anton Khirnov 2e46d68f55 lavc/hevc_ps: make SPS hold a reference to its VPS
SPS and its dependent PPSes depend on, and are parsed for, specific VPS data.

This will be useful in following commits.
2024-06-11 17:39:34 +02:00