This is possible because the lifetime of these structures coincide.
It has the advantage of allowing to remove AVHWFramesInternal
from the public header; given that AVHWFramesInternal.priv is no more,
most accesses to AVHWFramesInternal are no more; indeed, the only
field accessed of it outside of hwcontext.c is the internal frame pool,
making this commit very simple.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This is possible because the lifetime of both coincide.
Besides reducing the number of allocations this also simplifies
access to VAAPIFramesContext as one no longer has to
go through AVHWFramesInternal.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This is possible because the lifetime of both coincide.
Besides reducing the number of allocations this also simplifies
access to VAAPIDeviceContext as one no longer has to
go through AVHWDeviceInternal.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
av_hwframe_transfer_data try with src_ctx first. If the operation
failed with AVERROR(ENOSYS), it will try again with dst_ctx. Return
AVERROR(EINVAL) makes the second step being skipped.
Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
According to description of vaExportSurfaceHandle in libva, vaSyncSurface
must be called if the contents of the surface will be read.
Fixes ticket #9967.
Reviewed-by: Zhao Zhili <zhilizhao@tencent.com>
Signed-off-by: Fei Wang <fei.w.wang@intel.com>
There can be more than one available render node, and it's not
guaranteed the first node we come across is the correct one. In
particular, 'vgem' devices are common, and are
never VAAPI-enabled and thus not valid here.
We have a 'kernel_driver' arg already for specifying a single driver we
*do* want, but it doesn't support a negation, nor a list. It's easier
just to automatically skip 'vgem' anyway, to avoid foisting this burden
on users.
This has precedent in libva-utils already:
bfb6b98ed62a exclude vgem node and invalid drm node in vainfo
bfb6b98ed6
Signed-off-by: Brian Norris <briannorris@chromium.org>
With the necessary pixel formats defined, we can now expose support for
the remaining 10/12bit combinations that VAAPI can handle.
Specifically, we are adding support for:
* HEVC
** 12bit 420
** 10bit 422
** 12bit 422
** 10bit 444
** 12bit 444
* VP9
** 10bit 444
** 12bit 444
These obviously require actual hardware support to be usable, but where
that exists, it is now enabled.
Note that unlike YUVA/YUVX, the Intel driver does not formally expose
support for the alphaless formats XV30 and XV360, and so we are
implicitly discarding the alpha from the decoder and passing undefined
values for the alpha to the encoder. If a future encoder iteration was
to actually do something with the alpha bits, we would need to use a
formal alpha capable format or the encoder would need to explicitly
accept the alphaless format.
As vaapi doesn't actually do anything useful with the alpha channel,
and we have an alphaless format available, let's use that instead.
The changes here are mostly 1:1 switching, but do note the explicit
change in the number of declared channels from 4 to 3 to reflect that
the alpha is being ignored.
Commit e050959103 implemented passing in
modifiers by using the PRIME_2 memory type, which only exists in v2 of
the library.
To still support v1 of the library, conditionally compile using
VA_CHECK_VERSION() for both the new code and the old code before
the commit.
Note PRIME_2 memory was introduced from VA-API 1.1, so use
VA_CHECK_VERSION(1, 1, 0) instead of VA_CHECK_VERSION(2, 0, 0) (Haihao)
Signed-off-by: Ingo Brückl <ib@wupperonline.de>
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
This way we can pass explicit modifiers in. Sometimes the
modifier matters for the number of memory planes that
libva accepts, in particular when dealing with
driver-compressed textures. Furthermore the driver might
not actually be able to determine the implicit modifier
if all the buffer-passing has used explicit modifier.
All these issues should be resolved by passing in the
modifier, and for that we switch to using the PRIME_2
memory type.
Tested with experimental radeonsi patches for modifiers
and kmsgrab. Also tested with radeonsi without the
patches to double-check it works without PRIME_2 support.
v2:
Cache PRIME_2 support to avoid doing two calls every time on
libva drivers that do not support it.
v3:
Remove prime2_vas usage.
Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
The V4L2 driver does not actually have an associated DRM device at all, so
users work around the requirement by giving libva an unrelated display-only
device instead (which is fine, because it doesn't actually do anything with
that device). This was broken by bc9b6358fb
forcing a render node, because the display-only device did not have an
associated render node to use. Fix that by just passing through the
original non-render DRM fd if we can't find a render node.
Reported-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Tested-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
hwcontext_vaapi maps different VA fourcc to the same pix_fmt for U/V
plane swap cases, however duplicate formats are not expected in sw_format
list when merging formats.
For example:
ffmpeg -loglevel debug -init_hw_device vaapi -filter_hw_device vaapi0 \
-f lavfi -i smptebars -vf \
"hwupload=derive_device=vaapi,scale_vaapi,hwdownload,format=yuv420p" \
-vframes 1 -f null -
Without this fix, an auto scaler is required for the above command
Duplicate formats in ff_merge_formats detected
[auto_scaler_0 @ 0x560df58f4550] Setting 'flags' to value 'bicubic'
[auto_scaler_0 @ 0x560df58f4550] w:iw h:ih flags:'bicubic' interl:0
[Parsed_hwupload_0 @ 0x560df58f0ec0] auto-inserting filter
'auto_scaler_0' between the filter 'graph 0 input from stream 0:0' and
the filter 'Parsed_hwupload_0'
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
This allows for users who derive devices to set options for the
new device context they derive.
The main use case of this is to allow users to enable extensions
(such as surface drawing extensions) in Vulkan while deriving from
the device their frames are on. That way, users don't need to write
any initialization code themselves, since the Vulkan spec invalidates
mixing instances, physical devices and active devices.
Apart from Vulkan, other hwcontexts ignore the opts argument since they
don't support options at all (or in VAAPI and OpenCL's case, options are
currently only used for device selection, which device_derive overrides).
If we are given a non-render node, try to find the matching render node and
fail if that isn't possible.
libva will not accept a non-render device which is not DRM master, because
it requires legacy DRM authentication to succeed in that case:
<https://github.com/intel/libva/blob/master/va/drm/va_drm.c#L68-L75>. This
is annoying for kmsgrab because in most recording situations DRM master is
already held by something else (such as a windowing system), leading to
device derivation not working and forcing the user to create the target
VAAPI device separately.
VA_RT_FORMAT describes the desired sampling format for surface.
When creating surface, VA_RT_FORMAT will be used firstly to choose
the expected fourcc/media_format for the surface. And the fourcc
will be revised by the value of VASurfaceAttribPixelFormat.
Add vaapi_format_map support for new pixel_format Y210.
This is fundamental for both VA-API and QSV.
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Opening the device via X11 (DRI2/DRI3) rather than opening a DRM render
node directly is only useful if you intend to use the legacy X11 interop
functions. That's never true for the ffmpeg utility, and a library user
who does want this will likely provide their own display instance rather
than making a new one here.
For example: -init_hw_device vaapi:/dev/dri/renderD128,driver=foo
This may be more convenient that using the environment variable, and allows
loading different drivers for different devices in the same process.
Iterate over available render devices and pick the first one which looks
usable. Adds an option to specify the name of the kernel driver associated
with the desired device, so that it is possible to select a specific type
of device in a multiple-device system without knowing the card numbering.
For example: -init_hw_device vaapi:,kernel_driver=amdgpu will select only
devices using the "amdgpu" driver (as used with recent AMD graphics cards).
Kernel driver selection requires libdrm to work.
Give the entries in the VAAPI format map table an explicit type and add
functions to do the necessary lookups. Add another field to this table
indicating whether the chroma planes are swapped (as in YV12), and use
that rather than explicit comparisons where swapping is needed.
Clarify that the list is the naughty list, and therefore being on it is
not desirable. The i965 driver does not need to be on the list after
version 2.0 (when the standard parameter buffer rendering behaviour was
changed).
Every fourcc in vaapi_drm_format_map should be in
vaapi_format_map, so add an assert to ensure we have the right maps.
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
The old vaAcquireBufferHandle() API works in fewer cases and provides
less information than the current vaExportSurfaceHandle(), but it exists
on older versions and is already used by the OpenCL code.
Fixes building with VAAPI but not libdrm, which was broken by
389f4c3e0d. Just unconditionally include
the header, since it doesn't depend on libdrm being present.
Drivers can support a format for surfaces without also supporting it for
images, so we can't assume that sw_format is usable for transfer. This
would previously hit an assert in cases where it isn't.