The HLS seek fixture leaves the MPEG-2 encoder thread count automatic.
On a single CPU, two sampled video packets have sizes 2289 and 3904
instead of the multithreaded reference's 2330 and 3860, failing FATE.
Pin the video encoder to one thread and update the two affected packet
sizes. Packet timestamps, positions, and seek results are unchanged.
Validated fate-seek-hls with freshly generated input three times each
under CPU affinity masks containing one, two, and eight CPUs. Before
this change the single-CPU runs reproduce the exact reported failure;
afterwards all nine runs pass with identical test output.
Fixes: #24579
Assisted-by: Fairy
Nellymoser expects the caller to set the samplerate, as it
doesn't read it from the bitstream. However the generic check
for this is bypassed as it has the AV_CODEC_CAP_CHANNEL_CONF
capability because it does set the channel configuration,
however that cap also bypasses the generic samplerate check.
This is mostly harmless as nellymoser doesn't care about the
samplerate, but since f566032bfd it would cause an AVERROR_BUG
to be returned to the caller, so better reject it outright in
the decoder.
Signed-off-by: Marvin Scholz <epirat07@gmail.com>
(cherry picked from commit 23918b3200)
During USAC decoding (ff_aac_usac_decode_frame), configuration elements
can be mapped and instantiated via che_configure(). For newly allocated
ChannelElement structs, che_configure calls sbr_ctx_alloc_init() which
dynamically allocates ac->che[type][id]. However, che_configure did not
subsequently map the output pointer of the nested SingleChannelElement
elements back to their statically-sized internal ret_buf arrays, causing
a null pointer dereference during IMDCT windowing.
The fix explicitly initializes these pointers following allocation.
Signed-off-by: Marvin Scholz <epirat07@gmail.com>
(cherry picked from commit 8319541103)
call_kernel() obtains the command buffer and compute encoder from
property getters (mtlQueue.commandBuffer, buffer.computeCommandEncoder),
which return autoreleased references under the non-ARC build, and then
releases them via ff_objc_release(). That is an over-release: when the
enclosing autorelease pool is drained, the objects are released a second
time and the process crashes with EXC_BAD_ACCESS in objc_release.
On current macOS this is reproducible with the ffmpeg CLI itself. The
filter thread's thread-local autorelease pool is popped during pthread
TSD cleanup at thread exit, so any run that used yadif_videotoolbox
crashes when the filter thread terminates:
ffmpeg -init_hw_device videotoolbox=vt -filter_hw_device vt \
-f lavfi -i testsrc2=size=640x480:rate=30 \
-vf setfield=tff,format=nv12,hwupload,yadif_videotoolbox,\
hwdownload,format=nv12 -frames:v 20 -f null -
Thread 11 Crashed:: vf#0:0
0 libobjc.A.dylib objc_release + 16
1 libobjc.A.dylib AutoreleasePoolPage::releaseUntil(objc_object**) + 204
2 libobjc.A.dylib objc_autoreleasePoolPop + 244
3 libobjc.A.dylib objc_tls_direct_base<...>::dtor_(void*) + 156
4 libsystem_pthread.dylib _pthread_tsd_cleanup + 620
5 libsystem_pthread.dylib _pthread_exit + 84
Host applications hit the same crash earlier, for example when a
dispatch queue drains its last-resort pool after a work item that ran
the filter.
Wrap the kernel invocation in @autoreleasepool and drop the manual
releases, making the pool pop the single balanced release and draining
the Metal transients once per frame. The ff_objc_release() calls on the
s->mtl* members in do_uninit() stay: those hold owned references
obtained from new* methods.
(cherry picked from commit 7f2e5cdd7c)
export_film_grain() copied cb_mult, cb_luma_mult and cb_offset (and the
Cr equivalents) straight from the bitstream, where they are coded with
a bias of 128, 128 and 256. AVFilmGrainAOMParams holds them unbiased:
the uv_offset documentation gives a range of [-256, 255], the AFGS1
parser in aom_film_grain.c subtracts the bias, the film grain
synthesizer uses the values as signed multipliers and offsets, and
libdav1d exports them unbiased. The AR coefficients a few lines above
are already unbiased the same way.
With -export_side_data film_grain and a hwaccel, the native decoder
therefore exported values 128 or 256 higher than libdav1d for the
same stream, and any consumer applying the exported grain scaled
chroma noise wrong.
Signed-off-by: lusoris <lusoris@proton.me>
(cherry picked from commit 2a8c6d30b9)
All pools rotated through a family's queues in lockstep from index 0,
colliding on the same queue at the same time. Give each pool a phase
from a per-family, per-library counter: video pools are pinned to the
queue it selects, as sessions order their execution anyway, while all
other pools rotate starting from it. On e.g. Intel, a transcode now
runs decode and encode on separate engines of the shared video family.
The counters are seeded once with a random value, so that separate
processes, and separate copies of this code within one process,
de-phase statistically on drivers with a fixed queue-to-engine mapping.
Also assigns ffv1enc's per-context index once, at init.
(cherry picked from commit d0d7d81317)
[lusoris: include thread.h for ff_thread_once(); master gets it through vulkan.h]
Signed-off-by: lusoris <lusoris@proton.me>
Host image layout transitions may only originate from a layout in
pCopySrcLayouts, or from UNDEFINED, discarding the contents. The host
transfer path transitioned from whatever layout the frame was last
left in, which for pool-recycled frames can be a video layout, which
no driver lists as host-copyable.
Uploads overwrite the entire image, so transition from UNDEFINED
there. Downloads have to preserve the contents, so route frames in a
non-host-copyable layout through the GPU path.
(cherry picked from commit ac16cfb86e)
Signed-off-by: lusoris <lusoris@proton.me>
Seeking an input opened with the http or libcurl "offset" option to the
next segment's offset does not work, because its AVIOContext counts from
0 while the protocol seeks to file offsets, so the seek skipped as many
bytes as the request started at. A seek also cannot extend a request past
its end offset. Keep reading from the same input when the next segment
follows within the requested range, and open it with a new request
otherwise. Keep the requested end with each input, extend prefetched
requests over their run too, and reuse a connection only after its reply
was read to the end.
Only hls.c and dashdec.c pass "offset". The AVIOContext starts its
position at 0 and never learns the protocol's start offset. Initializing
the position from the protocol in ffio_fdopen would fix that for
everyone, but the crypto and cache protocols and probing with an offset
report positions in their own coordinates and break with it, so avoid
the seek here instead.
Note that external users that pass "offset" themselves see the same
thing, positions and seeks on such an input are relative to the request
start rather than to the file, and this commit only avoids the seek in
hls.c instead of fixing that accounting.
Fixes: 0616685b1eFixes: #25000
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
(cherry picked from commit d9242028a6)
ff_dxva2_common_end_frame() adds a reference to the decoder to
frame->buf[], so that the decoder outlives the frames decoded with it.
It is called from the hwaccel end_frame() callback, which with frame
threading may run after ff_thread_finish_setup(). From that point on,
other threads may copy the frame: the H.264 decoder keeps a separate
AVFrame per picture in each thread and synchronizes them in
update_thread_context() with av_frame_replace(), which reads
frame->buf[] while the decoding thread may be writing to it. As noted
in fa77cb258b ("avcodec/h264dec: Fix data race when updating
decode_error_flags"), a decoding thread must not modify any field that
av_frame_ref() copies after ff_thread_finish_setup().
This has been observed as an intermittent access violation in
av_buffer_replace() when decoding H.264 with D3D11VA and frame
threading on Windows on Arm: the copying thread read a non-NULL
frame->buf[1] entry, but saw the fields of the AVBufferRef it points
to as zero, and dereferenced the NULL buffer pointer when incrementing
the reference count.
Store the decoder reference in FrameDecodeData.hwaccel_priv instead,
as nvdec does for its per-frame state. The decode data is attached to
frame->private_ref when the buffer is allocated, before
ff_thread_finish_setup(), and all references to the frame share it, so
update_thread_context() only takes a new reference to it. The decoder
reference is added to frame->buf[] by hwaccel_priv_post_process(),
which runs in the caller's thread when the frame is returned, so
returned frames keep the decoder alive. Since the decode data
is shared, the second field of a field pair no longer adds a second
decoder reference to the frame.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
(cherry picked from commit 538d10d187)
It was set to a sub-frame value so the caller would then pass such small frames
to the encoder, which would then get buffered internally before being
processed. Because of this, the actual frame size would not end up being
propagated back to the caller, which resulted in said bogus internal value
being used by muxers.
Set frame_size to the actual final value and adapt the encoder to expect full
frames.
Fixes issue #24899.
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit 7ef5a794c4)
Limit the 8-bit column filter to the pixels remaining in the current slice. Pass slice_end - y at all three call sites so both the 8-bit and high-bit-depth column filters receive the correct remaining width. This handles partial 16-pixel blocks at frame and thread-slice boundaries. The non-column callbacks do not use this argument.
Fixes: #YWH-PGM40646-36
(cherry picked from commit 8b9e02cc17)
In ff_silk_decode_superframe, when coded_channels is 1, redundancy[1]
and active[1] are not read from the bitstream. However, decoding LBRR
frames accesses redundancy[1] when j == 0:
int active1 = (j == 0 && !(redundancy[1] & (1 << i))) ? 0 : 1;
which causes an uninitialized variable read under MemorySanitizer.
Zero-initialize the active and redundancy arrays to prevent reading
uninitialized values.
Signed-off-by: Vitaly Sokolov <vsokolov@google.com>
Signed-off-by: Marvin Scholz <epirat07@gmail.com>
(cherry picked from commit f3daf49b50)
816d74e0bb made frames without psy analysis at EOF silent. The frame
that follows the last input frame to flush its MDCT overlap is always
such a frame, so the last CELT_OVERLAP samples of the stream were lost
whenever it was needed, i.e. when the length of the stream is a
multiple of frame_size or less than CELT_OVERLAP samples short of one.
It was also coded as a one byte packet, which the MPEG-TS muxer
rejects.
Encode it like any other frame instead. Its psy analysis data is
zeroed, which leaves it with the default frame parameters.
Fixes: #24196
(cherry picked from commit 2e0a770b8e)
Silent frames were coded with zero bytes, which decoders take as a lost
frame and conceal by extrapolating the preceding audio, rather than
outputting silence. A packet of such frames is also only one or two
bytes long, and the MPEG-TS muxer rejects packets shorter than two.
Code the silence flag in a two byte frame like libopus does, and keep
the encoder state in sync with the decoder after it: the decoder
predicts the band energies of the next frame from CELT_ENERGY_SILENCE,
and the pre-emphasis filter state at the start of the next overlap is
zero. As silent frames no longer have a size of zero, leave them out of
the rate control explicitly.
(cherry picked from commit b726a3b8c4)
The trailing CELT_OVERLAP samples of a frame are filtered again as the
overlap of the next frame, so the filter state saved for the next frame
has to be the one from right before them. The code relied on packets
being assembled from 120 sample input frames for this, which is no
longer the case since c3aea7628c, and saved the state from the end of
the previous frame instead. The first overlap sample of every frame was
then filtered differently than when it was encoded as part of the
previous frame.
(cherry picked from commit 49975b25a0)
The overlap of a frame is the tail of the previous frame as it was
encoded, which was zero padded if the input frame was shorter than
frame_size. The last CELT_OVERLAP input samples were copied instead,
so when the last input frame was short and a frame followed it to flush
its overlap, the end of the stream was distorted.
The padding of a short input frame was also written at the start of the
sample buffer instead of after the input frame's samples.
(cherry picked from commit 7e1bc799b2)
When the range coded data and the raw bits of a frame did not meet, the
bytes between them were copied from the stale contents of the range
coder buffer, and when there were no raw bits, the bytes after the range
coded data were left as whatever the packet buffer held. Zero them
instead, like libopus does.
(cherry picked from commit 574c34228c)
The decoder can't know where a seek landed, so the "delay_samples" way to
discard the decoder delay in the first frame is not truly viable, so it needs
to be removed.
Add a call to aacDecoder_DecodeFrame() with the AACDEC_CLRHIST flag set, as the
call to aacDecoder_SetParam() with the AAC_TPDEC_CLEAR_BUFFER setting was
seemingly not enough to truly flush all the fdkaac internal buffers.
Should fix issue #24527.
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit b894a6f7c1)
Shift timestamps when available, and take into account the caller requested
samples to be discarded alongside the decoder delay.
Should fix issue #24526.
Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit c8595be8e6)
Fixes: out of array access
Fixes: division by zero
Fixes: vdfZuLhrGLdR
Found-by: zhang xingxing
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 590fb407b0)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: out of array access
Fixes: Af5rtPnOunVT
Found-by: Umar Pathan (Umar0x)
Signed-off-by: Umar Pathan <hello@umar.ac>
(cherry picked from commit a809a784ec)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: out of array write
Found-by: Michael Niedermayer with Forgejo Fairy
(cherry picked from commit 68845e26f7)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: out of array write
Fixes: 9vZSLhhnp3ps
Found-by: Kai Martin, KG3N Research
(cherry picked from commit e058af88ab)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Fixes: invalid free
Fixes: 6Qd6MOq0EvLi
Found-by: Gabe Sherman (Trail of Bits)
(cherry picked from commit 094a2f8a2a)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
At the time that this code was introduced into FFmpeg in April 2022 by commit
b9a25963f7, it was correct as written. The latest release of
lcms2 at the time was 2.13.1 in which `cmsDeleteContext(NULL)` was a no-op.
Since lcms2 version 2.15, released Mar 2023, the same call is no longer a no-op and
instead means destroy the global context. The new behavior is justifiable as being
consistent with the rest of lcms2's API, where passing NULL for a cmsContext argument
means operate on the global context. For example `cmsDupContext(NULL, ...)` constructs a
context duplicated from the global context; `cmsPluginTHR(NULL, ...)` registers a plugin
into the global context.
The upstream commit that introduced the behavior change for `cmsDeleteContext` is:
a9e4601ceb
In FFmpeg, the new behavior leads to a memory leak if `ff_icc_context_uninit` is ever
called on an `FFIccContext` without `ff_icc_context_init`. Here is why that can happen,
and here is how it leads to a memory leak.
Naively, uninitializing something which was never initialized seems like it shouldn't
happen, but in this case these contexts are *lazily* initialized and *unconditionally*
deinitialized. `FFIccContext` is a member of `AVCodecInternal`:
// libavcodec/internal.h:148-150
#if CONFIG_LCMS2
FFIccContext icc; /* used to read and write embedded ICC profiles */
#endif
It is initialized conditionally by the snippet of `detect_colorspace` shown below, or by
similary shaped code in libavcodec/encode.c. The `avci->icc.avctx` guards "has it already
been initialized". The early returns beforehand are codepaths for which `icc` will not be
initialized, and will remain all-zero as allocated by `av_mallocz` in
`ff_decode_internal_alloc`.
// libavcodec/decode.c:534-542
if (!(avctx->flags2 & AV_CODEC_FLAG2_ICC_PROFILES))
return 0;
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_ICC_PROFILE);
if (!sd || !sd->size)
return 0;
if (!avci->icc.avctx) {
ret = ff_icc_context_init(&avci->icc, avctx);
Later, `avci->icc` is uninitialized unconditionally by `ff_codec_close`:
// libavcodec/avcodec.c:447-480
if (avcodec_is_open(avctx)) {
...
#if CONFIG_LCMS2
ff_icc_context_uninit(&avci->icc);
#endif
So every codec closed without `AV_CODEC_FLAGS2_ICC_PROFILES`, or without an ICC side-data
packet, reaches `ff_icc_context_uninit` on a never-initialized context.
As part of `cmsDeleteContext(NULL)` destroying lcms2's global context, it runs
`cmsUnregisterPlugins()` and destroys `globalContext.MemPool`. Since the global context is
shared by every user of lcms2 in the process, closing an FFmpeg codec silently tears down
unrelated libraries' lcms2 state. The most visible symptom is that
`_cmsRegisterMutexPlugin(NULL, NULL)` nulls out the mutex callbacks, after which
`cmsCloseProfile()` leaks each profile's `UsrMutex` and profiles opened later are left
without any locking at all.
The fix is to delete only contexts created by FFmpeg.
Signed-off-by: David Tolnay <dtolnay@gmail.com>
(cherry picked from commit 705286a8a7)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Affects filters like vf_tonemap, vf_nlmeans_vulkan and vf_zscale that use
NAN as an explicit default value to indicate "not set by user".
Signed-off-by: Niklas Haas <git@haasn.dev>
(cherry picked from commit 5815e6343c)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Reject negative recording durations for input and output -t before they reach streamcopy or trim handling. Keep -t 0 accepted.
Signed-off-by: 张永鹏 <roc63@outlook.com>
(cherry picked from commit 629a5b4b0f)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
When the first slice of a picture is skipped, an undecodable RASL
after a seek or avctx->skip_frame, the remaining slices were still
parsed against the stale context and failed the PPS change, dependent
slice, or missing first slice checks, logging a decoding error per
slice. Drop them before parsing instead.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
(cherry picked from commit e5eb7581dd)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
In VVC, there are two schemes for addressing reference pictures in
the DPB:
1. Normally, the POC of the reference picture is signaled using a delta
from the current picture POC.
2. In the case of long-term reference pictures (LTRPs), which may be far
away from the current POC, the absolute value of the LTRP POC is
signalled. This scheme has two sub-schemes:
a. Signalling the entirety of the absolute value of the LTRP
POC would be expensive, so in most cases we only signal the
sps_log2_max_pic_order_cnt_lsb_minus4 + 4 least-significant bits
of the LTRP POC.
b. In the case of a collision in the least-significant bits,
the full POC is signalled.
Both schemes are implemented in find_ref_idx. The use_msb parameter
of find_ref_idx is nonzero in the case of schemes 1 and 2b, and zero in
the case of scheme 2a.
This commit fixes a bug in scheme 2a. The issue arises from the fact
that the current picture is stored in the DPB at the time find_ref_idx
is invoked in FFmpeg's implementation, whereas in the specification the
current picture is not yet considered part of the DPB. The current
picture may have a POC which shares least-significant bits with an LTRP.
The specification does not identify this as a collision however (see the
condition in 7.4.10, under the semantics of
delta_poc_msb_cycle_present_flag), and so scheme 2a is used rather than
scheme 2b. If the current frame precedes the correct LTRP in the DPB,
FFmpeg's implementation then interprets the signalling to mean a frame
which references itself. The problematic callsite identifies this as an
issue and returns an AVERROR_INVALIDDATA, but this scenario can occur in
valid bitstreams. For example, the conformance bitstream
LTRP_A_ERICSSON_3 has one such instance. FFmpeg gets away with decoding
it currently because the LTRP precedes the current picture in the DPB,
but this is by chance rather than design.
The commit addresses this issue by skipping over the current picture
inside the main loop of find_ref_idx. An unambiguous reference to the
current picture is still syntactically possible but illegal when using
scheme 2b. The handling of this case is moved from find_ref_idx to the
caller, which allows for simplifying find_ref_idx.
Signed-off-by: Frank Plowman <post@frankplowman.com>
(cherry picked from commit 2b3609ab61)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>