[vlc-commits] [Git][videolan/vlc][master] 2 commits: avcodec: va: re-use previous vctx when possible
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Sat Nov 8 10:44:04 UTC 2025
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
5827e946 by Thomas Guillem at 2025-11-08T11:30:17+01:00
avcodec: va: re-use previous vctx when possible
Add cfg->vctx_prev, only valid from ffmpeg_RecreateVa() (for VAAPI).
This will be used to use the previous context when a format change is
triggered by a flush.
- - - - -
b1596c8d by Thomas Guillem at 2025-11-08T11:30:17+01:00
avcodec: vaapi: try to keep previous vctx
Keep the previous vctx if present and if it is using the same
format/size.
This will allow to avoid recreating a vout because of a vctx change (on
flush).
Fixes #29434
- - - - -
3 changed files:
- modules/codec/avcodec/va.h
- modules/codec/avcodec/vaapi.c
- modules/codec/avcodec/video.c
Changes:
=====================================
modules/codec/avcodec/va.h
=====================================
@@ -59,6 +59,15 @@ struct vlc_va_cfg
*/
video_format_t *video_fmt_out;
+ /**
+ * Pointer to the previous video context
+ *
+ * Only valid if use_hwframes is true and when recreating the va module.
+ * This context can be re-used (held, and set to vctx_out) if the internal
+ * format/size matches the new cfg.
+ */
+ vlc_video_context *vctx_prev;
+
/**
* Pointer to the used video context
*
=====================================
modules/codec/avcodec/vaapi.c
=====================================
@@ -246,6 +246,38 @@ error:
return VLC_EGENERIC;
}
+static int AVHWFramesContextCompare(const AVHWFramesContext *c1,
+ const AVHWFramesContext *c2)
+{
+ return c1->width == c2->width && c1->height == c2->height &&
+ c1->format == c2->format && c1->sw_format == c2->sw_format &&
+ c1->initial_pool_size == c2->initial_pool_size ? 0 : 1;
+}
+
+static vlc_video_context *
+ReuseVideoContext(vlc_video_context *vctx, AVBufferRef *hwframes_ref_new)
+{
+ if (vctx == NULL)
+ return NULL;
+
+ struct vaapi_vctx *vaapi_vctx =
+ vlc_video_context_GetPrivate(vctx, VLC_VIDEO_CONTEXT_VAAPI);
+
+ AVHWFramesContext *hwframes_ctx_prev =
+ (AVHWFramesContext*)vaapi_vctx->hwframes_ref->data;
+
+ AVHWFramesContext *hwframes_ctx_new =
+ (AVHWFramesContext*)hwframes_ref_new->data;
+
+ if (AVHWFramesContextCompare(hwframes_ctx_prev, hwframes_ctx_new) != 0)
+ return NULL;
+
+ vctx = vlc_video_context_Hold(vctx);
+ av_buffer_unref(&vaapi_vctx->hwframes_ref);
+ vaapi_vctx->hwframes_ref = hwframes_ref_new;
+ return vctx;
+}
+
static int Create(vlc_va_t *va, struct vlc_va_cfg *cfg)
{
AVCodecContext *ctx = cfg->avctx;
@@ -360,23 +392,27 @@ static int Create(vlc_va_t *va, struct vlc_va_cfg *cfg)
return VLC_EGENERIC;
}
- vlc_video_context *vctx =
- vlc_video_context_Create(dec_device, VLC_VIDEO_CONTEXT_VAAPI,
- sizeof(struct vaapi_vctx), &vaapi_ctx_ops);
+ vlc_video_context *vctx = ReuseVideoContext(cfg->vctx_prev, hwframes_ref);
if (vctx == NULL)
{
- av_buffer_unref(&hwframes_ref);
- av_buffer_unref(&ctx->hw_frames_ctx);
- return VLC_EGENERIC;
- }
+ vctx =
+ vlc_video_context_Create(dec_device, VLC_VIDEO_CONTEXT_VAAPI,
+ sizeof(struct vaapi_vctx), &vaapi_ctx_ops);
+ if (vctx == NULL)
+ {
+ av_buffer_unref(&hwframes_ref);
+ av_buffer_unref(&ctx->hw_frames_ctx);
+ return VLC_EGENERIC;
+ }
- struct vaapi_vctx *vaapi_vctx =
- vlc_video_context_GetPrivate(vctx, VLC_VIDEO_CONTEXT_VAAPI);
+ struct vaapi_vctx *vaapi_vctx =
+ vlc_video_context_GetPrivate(vctx, VLC_VIDEO_CONTEXT_VAAPI);
- vaapi_vctx->va_dpy = va_dpy;
- vaapi_vctx->hwframes_ref = hwframes_ref;
- vlc_sem_init(&vaapi_vctx->pool_sem, hwframes_ctx->initial_pool_size);
- vaapi_vctx->dynamic_pool = hwframes_ctx->initial_pool_size < 1;
+ vaapi_vctx->va_dpy = va_dpy;
+ vaapi_vctx->hwframes_ref = hwframes_ref;
+ vlc_sem_init(&vaapi_vctx->pool_sem, hwframes_ctx->initial_pool_size);
+ vaapi_vctx->dynamic_pool = hwframes_ctx->initial_pool_size < 1;
+ }
msg_Info(va, "Using %s", vaQueryVendorString(va_dpy));
=====================================
modules/codec/avcodec/video.c
=====================================
@@ -750,7 +750,8 @@ static void ffmpeg_CloseVa(decoder_t *p_dec, AVCodecContext *context)
static int ffmpeg_OpenVa(decoder_t *p_dec, AVCodecContext *p_context,
enum AVPixelFormat hwfmt,
const AVPixFmtDescriptor *src_desc,
- vlc_decoder_device *dec_device)
+ vlc_decoder_device *dec_device,
+ vlc_video_context *vctx)
{
decoder_sys_t *p_sys = p_dec->p_sys;
@@ -762,6 +763,7 @@ static int ffmpeg_OpenVa(decoder_t *p_dec, AVCodecContext *p_context,
.fmt_in = p_dec->fmt_in,
.dec_device = dec_device,
.video_fmt_out = &p_dec->fmt_out.video,
+ .vctx_prev = vctx,
.vctx_out = NULL,
.use_hwframes = false,
.extra_pictures = 0,
@@ -792,8 +794,10 @@ static int ffmpeg_RecreateVa(decoder_t *p_dec, AVCodecContext *p_context,
enum AVPixelFormat swfmt)
{
decoder_sys_t *p_sys = p_dec->p_sys;
+ assert(p_sys->use_hwframes);
assert(p_sys->vctx_out != NULL);
+ vlc_video_context *vctx = vlc_video_context_Hold(p_sys->vctx_out);
vlc_decoder_device *dec_device =
vlc_video_context_HoldDevice(p_sys->vctx_out);
@@ -802,9 +806,10 @@ static int ffmpeg_RecreateVa(decoder_t *p_dec, AVCodecContext *p_context,
const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(swfmt);
int ret = ffmpeg_OpenVa(p_dec, p_context, p_sys->pix_fmt,
- src_desc, dec_device);
+ src_desc, dec_device, vctx);
if (dec_device != NULL)
vlc_decoder_device_Release(dec_device);
+ vlc_video_context_Release(vctx);
return ret;
}
@@ -921,7 +926,8 @@ int InitVideoHwDec( vlc_object_t *obj )
if (ret != VLC_SUCCESS)
continue;
- ret = ffmpeg_OpenVa(p_dec, p_context, hwfmts[i], src_desc, dec_device);
+ ret = ffmpeg_OpenVa(p_dec, p_context, hwfmts[i], src_desc, dec_device,
+ NULL);
if (dec_device != NULL)
vlc_decoder_device_Release(dec_device);
@@ -2140,7 +2146,7 @@ no_reuse:
if (ret != VLC_SUCCESS)
continue;
- ret = ffmpeg_OpenVa(p_dec, p_context, hwfmt, src_desc, dec_device);
+ ret = ffmpeg_OpenVa(p_dec, p_context, hwfmt, src_desc, dec_device, NULL);
if (dec_device != NULL)
vlc_decoder_device_Release(dec_device);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/29b0a17233ea014cb5576541adbe8ad48cdc5ca7...b1596c8d18854c1f693388e9f2dff0a46792ef98
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/29b0a17233ea014cb5576541adbe8ad48cdc5ca7...b1596c8d18854c1f693388e9f2dff0a46792ef98
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list