The typical case is an application that use vgl callback with a GLX context,
vaapi decoder will initiliaze properly and provide a hw_frames_ctx context, but
due to the lack of interop, the decoder won't be usable and fallback to the sw
decoder, but hw_frames_ctx will still be set and will cause a crash later on.
If the va module succeed to open but is identified as unusable before the end of
FFmpeg getFormat callback, the module may have to do some cleanups in the
AVCodecContext.
the close callback will be called with a NULL AVCodecContext outside the
getFormat callback as the AVCodecContext ownership is transferred to FFmpeg
see e967f81f6a.
note, this does **not** affect cat-based module selection items
(of which there are just three in use by the core), since that
mechanism uses subcats not cats.
It's not allowed to modify ctx->hw_device_ctx after avcodec_open2().
Therefore, we need to create the hw_frames_ctx ourselves from it, and from
the get_format() callback. It can be easily done with the
avcodec_get_hw_frames_parameters() helper.
The surface frame count is now known from the Create() function,
therefore, the semaphore can be directly initialized, removing the need
for the pool_sem_init dirty hack.
Recover the hw pool size from the first Get() call (after the
AVCodecContext has been initialized) and use a semaphore to pace the
picture allocation from Get().
That way, we don't rely anymore av_hwframe_get_buffer() return values,
that returned the same error for internal error or when the pool was
full.
Fixes#26166
Contrary to all other hardware decoders, vaapi can't work with a
hwaccel_context anymore. It requires a hw_device_ctx or a hw_frames_ctx
to work.
This first implementation use a hw_device_ctx and let avcodec handle its
frames pool. It is also possible to handle hw_frames_ctx ourself to get
more controls.
Note: Most of the code could be reused by other va modules if we decide
to a hw_device_ctx.
Fixes#25707
We never use data[0] for anything, nor does avcodec, and it can
actually keep the same initialized value or be NULL.
In particular, it fixes avcodec decoder with vaapi vlc_va_t backend
which was generating VASurfaceID of value 0 to count, leading to the
following assertion:
vlc: ../../modules/codec/avcodec/video.c:1492: lavc_va_GetFrame: Assertion `frame->data[0] != NULL' failed.
[1] 154639 abort (core dumped) ./build-native/vlc <sample> --dec-dev=vaapi -vvv
The creator of the picture_context_t must set the video context if needed.
If set, the picture context must hold a reference to the video context.
When "copying" a picture (using the same surface in another picture context) a
new reference has to be acquired.
Add an inline function to get the video context from a picture.
In the end each VA module just needs to set the picture_context_t on the
outgoing picture. It doesn't need to allocate the picture itself for now.
The picture_context_t has destroy and copy callbacks which allow for
refcounting and detroying the resources when really not needed anymore.
Effectively reverts 2e4cd8756d.
The va_pool is refcounted. It releases its resources when it's not used anymore.
Either when the last surface from the pool is not used anymore or when it's
closed and no picture were used anymore.
The va module manages its own picture context structure that includes the
common structure used by all vaapi modules (vaapi_pic_context) and the
va_surface that is refcounted (so it can release the pool when the last surface
is used and the close is pending).
The table of VASurfaceID is allocated locally, in the same way it's done in
vlc_vaapi_PoolNew().
pictures are coming from the default allocator, there is no picture_sys_t
attached. But it's not used by vlc_vaapi_PicGetSurface() or
vlc_vaapi_PicGetDisplay(). It's only used by vlc_vaapi_PicAttachContext()
which we don't use anymore on pictures we send.
This is the same API used by the dxva modules.
Instead of filling the picture context during get().
We can't just allocate the picture in the generic VA code and fill
the picture->context and picsys data as we need to handle the destructor
for each picture and release the resources when the picture is last
released.
Only call decoder_GetDecoderDevice() in lavc_UpdateVideoFormat(). The
decoder_UpdateVideoOutput() is done afterwards.
After the call to lavc_UpdateVideoFormat() the received decoder device holds an
extra reference that needs to be released after the VA is created.
decoder_NewPicture() cannot be used until decoder_UpdateVideoOutput() is called.
So this patch temporarily breaks va modules relying on the picture_sys_t data
that used to be passed. It will be via the decoder device we just got.
The codec profile alone doesn't always give information on the bit depth or
chroma subsampling (see HEVC Range Extension).
The pixel format description is read in the lavc module rather than each VA so
they don't have to link with libavutil.
Replace picture_sys_t* by void* in picture_resource_t, and remove its
typedef in vlc_common.h (for ODR).
This implies to use void* for private data in the vaapi.
See #17078 and #18033
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>