the ir option may exceed nbirs because its static range is independent
of the configured number of impulse responses. init() only clamps
prev_selir, leaving selir able to index ctx->inputs out of range.
with the default nbirs=1, afir=ir=1 reads ctx->inputs[2] and crashes.
clamp selir like process_command() and add a fate test.
Signed-off-by: Ayoub Nabil Boubagrat <237098474+ayoubnabil@users.noreply.github.com>
Clip integer expression results in the double domain before storing them. This keeps high-bit-depth samples within their declared range and gives NaN and infinities defined behavior while preserving float formats.
Fixes issue #24121.
An execution abandoned on error between start and submission left the
ownership mutex locked forever, deadlocking the context's next reuse.
Replace the submission fence with a timeline semaphore:
ff_vk_exec_start() claims the context by incrementing the awaited
value, the submission signals it, and the mutex only briefly guards
the dependency lists. Abandonment becomes ff_vk_exec_discard(), called
exactly once on a started, unsubmitted context: it frees the
dependencies, drops the recording, and un-claims by signalling from
the host - which a fence cannot do. ff_vk_exec_submit() cleans up
after its own failures; error paths which leaked the claim now
discard, and ff_vk_exec_start() failures are checked everywhere.
Several places in the code currently manually roll the return value
saving. This small signature change allows slicethread.c to collect
return values directly. Unlike the existing solutions which mostly
rely on collecting the return values in an array, we can just use an
atomic CAS to set the error iff no error has been set already.
We need a slight bit of extra complication to avoid breaking the ABI,
which requires keeping around the old names as deprecated aliases that
just set up the appropriate wrappers. However, fortunately, the way I
implemented the deprecated signatures allows callers to freely mix
avpriv_slicethread_execute() and avpriv_slicethread_execute2(), even
on contexts created with one or the other.
It's worth pointing out that this commit just changes the signatures,
but doesn't yet update the various to use the return value.
Signed-off-by: Niklas Haas <git@haasn.dev>
The dllimport attribute is meaningless on a pointer typedef and the
symbols are resolved with dlsym() anyway. Fixes -Wignored-attributes.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
When a CUDA frame with a supported RGB sw_format is received, map the
GPU device pointer directly into a LibTorch tensor using
torch::from_blob() with CUDA device options, bypassing cudaMemcpy
entirely.
Changes:
- Add fill_model_input_cuda() that extracts the CUdeviceptr from the
AVHWFramesContext and wraps it in a PyTorch GPU tensor with a no-op
deleter (memory owned by FFmpeg AVBuffer ref-counting).
- Handle GPU memory alignment padding via custom strides derived from
AVFrame linesize.
- Permute the mapped NHWC tensor to NCHW (PyTorch convention).
- Manage CUDA context explicitly with cuCtxPushCurrent/cuCtxPopCurrent
for thread safety in async filter graphs.
- Implement zero-copy Device-to-Device output mapping that writes the
model result directly into the output frame's VRAM, bypassing
ff_proc_from_dnn_to_frame / sws_scale entirely for CUDA frames.
- Add torch::cuda::synchronize() to prevent async race conditions
with downstream encoders (e.g. NVENC reading uninitialized frames).
- Add format validation in ff_dnn_zero_copy_supported_cuda() to reject
unsupported sw_formats and batching with CUDA zero-copy early.
- Register AV_PIX_FMT_CUDA in vf_dnn_processing pixel format list.
- Gracefully fall back to CPU path when sw_format is not a supported
RGB variant or when CONFIG_CUDA is not enabled.
Signed-off-by: Raja-89 <imraja729@gmail.com>
This reverts commit 795bccdaf5.
The heap-buffer-overflow was a symptom of the >8 bit boundary
conditions bug fixed in the previous commit. This workaround is no
longer needed.
This restores spatial-only interpolation of the whole frame for the
first and last fields, instead of running the temporal edge filter
against cloned reference frames on the outermost lines. Because of that
first frame references are updated to pre-fix values.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
The mrefs/prefs boundary conditions scaled the y limits by the number of
bytes per sample, even though the ref offsets are already expressed in
elements. For content deeper than 8 bits this clamped perfectly valid
in-bounds line taps.
Found by validating the libplacebo GPU port against this filter, which
matches exactly on 16-bit content everywhere except these lines.
This changes the output for >8 bit content on the affected lines.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
For a word mask register (where all the values are either
0x0 or 0xFFFF) a right logical shift by 15 is equivalent
to negating, so instead of negating the mask and then adding
it to another register one can simply subtract the mask from
the other register.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
ITU-R BS.1770 assigns a weight of 1.0 to height channels, but the
filter included the top-back channels in the 1.41 surround mask.
remove the top-back channels from that mask and add a FATE test for
the resulting loudness measurement.
fixes#23968.
Signed-off-by: Ayoub Nabil <237098474+ayoubnabil@users.noreply.github.com>
parse_channel_name() only rejects negative values on the named channel
path, while the numbered "c%d" path also checks against MAX_CHANNELS.
av_channel_from_string() accepts UNSD (512), UNK (768) and AMBI (1024),
and the id was then used directly to index used_in_ch[MAX_CHANNELS] on
the stack and pan->gain[out_ch_id][in_ch_id].
Before this change:
ffmpeg -f lavfi -i "anullsrc=cl=stereo" -af "pan=stereo|FL=AMBI" -f null -
af_pan.c:214:17: runtime error: index 1024 out of bounds for type 'int[64]'
The first out of bounds access is the read at the "reference twice"
check, so the symptom depends on what happens to be on the stack:
FL=UNK is silently accepted and produces silence, FL=UNSD reports
"Can not reference in channel 512 twice", and FL=AMBI aborts.
The check has to be at the caller and not in parse_channel_name(), which
is shared with the out channel path: there the named id is converted by
av_channel_layout_index_from_channel() into a layout index, so high ids
are legitimately supported and "pan=AMBI|AMBI=FL" works.
AVERROR_PATCHWELCOME is used because these are valid AVChannel values
that af_pan cannot represent: for named input channels the gain matrix is
indexed by the raw id, and the renumbering loop in config_props() is
bounded by MAX_CHANNELS as well, so such a mapping never worked.
The in_ch_id < 0 half is currently unreachable and only kept for symmetry
with the out channel check above.
Regression since 1f96db959c, which dropped
the "channel_id >= MAX_CHANNELS" part of the check when converting to the
new channel layout API.
Reported-by: karnakarreddi
Fixes: #22963
Signed-off-by: iSold Leo <s@qwqlog.com>
update ctx->ov_option.layout to the explict value which will be
used in function init_model_ov.
also move the code before input_resizable which uses the layout
Pool depth sets how far the CPU records ahead of the GPU, and has no relation
to the number of queues in a family.
Scaling it by the queue count only multiplied command pools, fences and context state.
Use a small fixed depth everywhere, and one context per thread only for threadsafe hwaccels,
which submit from every frame thread concurrently.
vf_dnn_processing.c and vf_dnn_detect.c both declare an uninitialized
DNNData model_input before using it. This commit initialize it.
Signed-off-by: younengxiao <steven.xiao@amd.com>
When loading a TorchScript model that does not contain any learnable
parameters (e.g., a purely functional model), the Torch backend would
crash during inference. This occurred because the code attempted to
dereference the first iterator of the model's parameter list
`parameters().begin()` to determine the device, which results in
Undefined Behavior when the parameter list is empty.
This commit fixes the issue by determining the inference device directly
from the user-configured `ctx->device` string instead of probing the
model parameters, allowing parameterless models to execute safely.
Testing:
1. Generate a parameterless model:
cat << 'EOF' > generate_model.py
import torch
class DummyModel(torch.nn.Module):
def forward(self, x):
return x
scripted_model = torch.jit.script(DummyModel())
scripted_model.save("dummy_model.pt")
EOF
python3 generate_model.py
2. Run inference (previously crashed, now succeeds):
./ffmpeg -y -i input.mp4 -vf 'format=rgb24,dnn_processing=dnn_backend=torch:model=dummy_model.pt' -frames:v 5 -f null -
Signed-off-by: Raja Rathour <imraja729@gmail.com>
amf_init_filter_config() returned the hardware pixel format (e.g.
AV_PIX_FMT_D3D11) as in_format when the input link carries D3D11VA or
DXVA2 hw frames. av_av_to_amf_format() maps hw formats to
AMF_SURFACE_UNKNOWN, so every AMF filter failed its component Init()
with AMF_INVALID_ARG (VQEnhancer, FRC) or AMF_NOT_SUPPORTED
(Converter, HQScaler). Return the underlying software format instead,
which is already validated against AMF a few lines above. Apply the
same mapping to the default output sw format, which otherwise ends up
as the hw pixel format in hwframes_out->sw_format when the output link
uses a hwaccel format.
Fixes e.g.:
ffmpeg -hwaccel d3d11va -hwaccel_output_format d3d11 -i in.mp4 -vf frc_amf -c:v hevc_amf out.mp4
Note: with D3D11VA input, the compute-based components (VQEnhancer,
HQScaler, VideoConverter) additionally require decode textures created
with D3D11_BIND_SHADER_RESOURCE, e.g.:
-init_hw_device d3d11va=dx11:,SHADER=1 -hwaccel_device dx11
FRC and DXVA2 input work with default decode textures.
This reverts commit f3431169da, which
introduced various regressions and hangs with at least exr, as
reported by fate, and potentially other codecs that are not as
thouroughly tested.
The arithmetic to process colors in premultiplied alpha is
completely different from the arithmetic for straight alpha.
Running a filter using straight arithmetic on premultiplied
will result in incorrect and sometimes invalid output.
Therefore, premultiplied alpha should only be selected for
filters that either explicitly support it or only use
elementary color arithmetic or none at all.
For other filters, automatic conversion will do its work.
This reverts commit 978a0821ee.
The stability of the negotiation process has never been studied
with multiple rounds.
It has always been documented to users that scale was the filter
to insert to manage format conversions. A second filter for
a specific type of conversion should never have been added:
the proper fix for the issue that this commit tried to fix is
to give scale the ability to handle premultiplication too.
When the filter graph is torn down early (e.g. at EOF with -frames:v),
the main thread calls dnn_free_model and destroys the request queue
while async inference threads may still be running. When a detached
thread finishes and tries to push its result back to the destroyed
queue, it triggers a segmentation fault.
Add ff_dnn_wait_requests() to dnn_backend_common which blocks
until all allocated request items (ctx->nireq) have been safely
returned to the request_queue. Call it from dnn_free_model in the
torch, tensorflow, openvino, and onnx backends before destroying the queue.
parse_dat(), parse_cube(), and parse_cinespace() multiply an untrusted LUT size
before allocate_3dlut() validates it, which can overflow int.
Use the validated lutsize2 computed by allocate_3dlut() instead.
Fixes: signed integer overflow