PR #23833 opened by Diego de Souza (ddesouza)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23833
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23833.patch

avcodec_get_hw_frames_parameters() may invoke frame_params from an
application's get_format() callback. ff_get_format() clears the current
hwaccel before calling get_format(), so avctx->hwaccel is NULL at that
point.

The CUARRAY frame-parameter path dereferenced avctx->hwaccel to
distinguish CUDA from CUARRAY, causing callers such as mpv to crash.
Add per-variant callbacks that pass the registered pixel format
explicitly instead.

Fixes issue #23826.


>From d7d4c864ac0b7177e643d9b84464e9ea1a6f4f74 Mon Sep 17 00:00:00 2001
From: Diego de Souza <[email protected]>
Date: Thu, 16 Jul 2026 14:51:12 +0200
Subject: [PATCH] avcodec/nvdec: pass hw format explicitly to frame params

avcodec_get_hw_frames_parameters() may invoke frame_params from an
application's get_format() callback. ff_get_format() clears the current
hwaccel before calling get_format(), so avctx->hwaccel is NULL at that
point.

The CUARRAY frame-parameter path dereferenced avctx->hwaccel to
distinguish CUDA from CUARRAY, causing callers such as mpv to crash.
Add per-variant callbacks that pass the registered pixel format
explicitly instead.

Fixes issue #23826.
---
 libavcodec/nvdec.c        | 11 +++++++++--
 libavcodec/nvdec.h        |  1 +
 libavcodec/nvdec_av1.c    | 22 ++++++++++++++++++----
 libavcodec/nvdec_h264.c   | 22 ++++++++++++++++++----
 libavcodec/nvdec_hevc.c   | 23 +++++++++++++++++++----
 libavcodec/nvdec_mjpeg.c  |  2 +-
 libavcodec/nvdec_mpeg12.c | 29 +++++++++++++++++++++++------
 libavcodec/nvdec_mpeg4.c  | 21 +++++++++++++++++----
 libavcodec/nvdec_vc1.c    | 29 +++++++++++++++++++++++------
 libavcodec/nvdec_vp8.c    | 21 +++++++++++++++++----
 libavcodec/nvdec_vp9.c    | 21 +++++++++++++++++----
 11 files changed, 163 insertions(+), 39 deletions(-)

diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c
index 278061d572..0065834f06 100644
--- a/libavcodec/nvdec.c
+++ b/libavcodec/nvdec.c
@@ -1082,6 +1082,7 @@ int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, 
const uint8_t *buffer,
 
 int ff_nvdec_frame_params(AVCodecContext *avctx,
                           AVBufferRef *hw_frames_ctx,
+                          enum AVPixelFormat hw_format,
                           int dpb_size,
                           int supports_444)
 {
@@ -1089,6 +1090,13 @@ int ff_nvdec_frame_params(AVCodecContext *avctx,
     const AVPixFmtDescriptor *sw_desc;
     int cuvid_codec_type, cuvid_chroma_format, chroma_444;
 
+    /*
+     * This may be called from get_format() before avctx->hwaccel is set,
+     * so the selected hardware format is passed explicitly by the wrapper.
+     */
+    if (hw_format != AV_PIX_FMT_CUDA && hw_format != AV_PIX_FMT_CUARRAY)
+        return AVERROR_BUG;
+
     sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
     if (!sw_desc)
         return AVERROR_BUG;
@@ -1106,8 +1114,7 @@ int ff_nvdec_frame_params(AVCodecContext *avctx,
     }
     chroma_444 = supports_444 && cuvid_chroma_format == 
cudaVideoChromaFormat_444;
 
-    frames_ctx->format            = (avctx->hwaccel->pix_fmt == 
AV_PIX_FMT_CUARRAY)
-                                    ? AV_PIX_FMT_CUARRAY : AV_PIX_FMT_CUDA;
+    frames_ctx->format            = hw_format;
     // NVDEC target dimensions must be even-aligned for internal surface 
allocation.
     // For chroma-subsampled formats (420/422), the output dimensions must 
also be
     // even. For monochrome/444, keep the original output dimensions and only
diff --git a/libavcodec/nvdec.h b/libavcodec/nvdec.h
index 756192acd2..b63b7f5f3f 100644
--- a/libavcodec/nvdec.h
+++ b/libavcodec/nvdec.h
@@ -88,6 +88,7 @@ int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const 
uint8_t *buffer,
                                  uint32_t size);
 int ff_nvdec_frame_params(AVCodecContext *avctx,
                           AVBufferRef *hw_frames_ctx,
+                          enum AVPixelFormat hw_format,
                           int dpb_size,
                           int supports_444);
 int ff_nvdec_get_ref_idx(AVFrame *frame);
diff --git a/libavcodec/nvdec_av1.c b/libavcodec/nvdec_av1.c
index 45fc67375e..a3b87fbc56 100644
--- a/libavcodec/nvdec_av1.c
+++ b/libavcodec/nvdec_av1.c
@@ -335,13 +335,21 @@ static int nvdec_av1_decode_slice(AVCodecContext *avctx, 
const uint8_t *buffer,
     return 0;
 }
 
-static int nvdec_av1_frame_params(AVCodecContext *avctx, AVBufferRef 
*hw_frames_ctx)
+static int nvdec_av1_frame_params(AVCodecContext *avctx,
+                                  AVBufferRef *hw_frames_ctx,
+                                  enum AVPixelFormat hw_format)
 {
     /* Maximum of 8 reference frames, but potentially stored twice due to film 
grain */
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, 8 * 2, 0);
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format, 8 * 2, 0);
 }
 
 #if CONFIG_AV1_NVDEC_HWACCEL
+static int nvdec_av1_cuda_frame_params(AVCodecContext *avctx,
+                                       AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_av1_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
+}
+
 const FFHWAccel ff_av1_nvdec_hwaccel = {
     .p.name               = "av1_nvdec",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -350,7 +358,7 @@ const FFHWAccel ff_av1_nvdec_hwaccel = {
     .start_frame          = nvdec_av1_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = nvdec_av1_decode_slice,
-    .frame_params         = nvdec_av1_frame_params,
+    .frame_params         = nvdec_av1_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -358,6 +366,12 @@ const FFHWAccel ff_av1_nvdec_hwaccel = {
 #endif
 
 #if CONFIG_AV1_NVDEC_CUARRAY_HWACCEL
+static int nvdec_av1_cuarray_frame_params(AVCodecContext *avctx,
+                                          AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_av1_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
+}
+
 const FFHWAccel ff_av1_nvdec_cuarray_hwaccel = {
     .p.name               = "av1_nvdec_cuarray",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -366,7 +380,7 @@ const FFHWAccel ff_av1_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_av1_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = nvdec_av1_decode_slice,
-    .frame_params         = nvdec_av1_frame_params,
+    .frame_params         = nvdec_av1_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
diff --git a/libavcodec/nvdec_h264.c b/libavcodec/nvdec_h264.c
index 83ec456e34..41a2eecc26 100644
--- a/libavcodec/nvdec_h264.c
+++ b/libavcodec/nvdec_h264.c
@@ -167,14 +167,22 @@ static int nvdec_h264_decode_slice(AVCodecContext *avctx, 
const uint8_t *buffer,
 }
 
 static int nvdec_h264_frame_params(AVCodecContext *avctx,
-                                   AVBufferRef *hw_frames_ctx)
+                                   AVBufferRef *hw_frames_ctx,
+                                   enum AVPixelFormat hw_format)
 {
     const H264Context *h = avctx->priv_data;
     const SPS       *sps = h->ps.sps;
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->ref_frame_count + 
sps->num_reorder_frames, 0);
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format,
+                                 sps->ref_frame_count + 
sps->num_reorder_frames, 0);
 }
 
 #if CONFIG_H264_NVDEC_HWACCEL
+static int nvdec_h264_cuda_frame_params(AVCodecContext *avctx,
+                                        AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_h264_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
+}
+
 const FFHWAccel ff_h264_nvdec_hwaccel = {
     .p.name               = "h264_nvdec",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -183,7 +191,7 @@ const FFHWAccel ff_h264_nvdec_hwaccel = {
     .start_frame          = nvdec_h264_start_frame,
     .end_frame            = ff_nvdec_end_frame,
     .decode_slice         = nvdec_h264_decode_slice,
-    .frame_params         = nvdec_h264_frame_params,
+    .frame_params         = nvdec_h264_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -191,6 +199,12 @@ const FFHWAccel ff_h264_nvdec_hwaccel = {
 #endif
 
 #if CONFIG_H264_NVDEC_CUARRAY_HWACCEL
+static int nvdec_h264_cuarray_frame_params(AVCodecContext *avctx,
+                                           AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_h264_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
+}
+
 const FFHWAccel ff_h264_nvdec_cuarray_hwaccel = {
     .p.name               = "h264_nvdec_cuarray",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -199,7 +213,7 @@ const FFHWAccel ff_h264_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_h264_start_frame,
     .end_frame            = ff_nvdec_end_frame,
     .decode_slice         = nvdec_h264_decode_slice,
-    .frame_params         = nvdec_h264_frame_params,
+    .frame_params         = nvdec_h264_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
diff --git a/libavcodec/nvdec_hevc.c b/libavcodec/nvdec_hevc.c
index 601ace7d29..0d7368f9af 100644
--- a/libavcodec/nvdec_hevc.c
+++ b/libavcodec/nvdec_hevc.c
@@ -301,11 +301,14 @@ static int nvdec_hevc_decode_slice(AVCodecContext *avctx, 
const uint8_t *buffer,
 }
 
 static int nvdec_hevc_frame_params(AVCodecContext *avctx,
-                                   AVBufferRef *hw_frames_ctx)
+                                   AVBufferRef *hw_frames_ctx,
+                                   enum AVPixelFormat hw_format)
 {
     const HEVCContext *s = avctx->priv_data;
     const HEVCSPS *sps = s->pps->sps;
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, 
sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + 1, 1);
+    int dpb_size = sps->temporal_layer[sps->max_sub_layers - 
1].max_dec_pic_buffering + 1;
+
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format, dpb_size, 1);
 }
 
 static int nvdec_hevc_decode_init(AVCodecContext *avctx) {
@@ -324,6 +327,12 @@ static int nvdec_hevc_decode_init(AVCodecContext *avctx) {
 }
 
 #if CONFIG_HEVC_NVDEC_HWACCEL
+static int nvdec_hevc_cuda_frame_params(AVCodecContext *avctx,
+                                        AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_hevc_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
+}
+
 const FFHWAccel ff_hevc_nvdec_hwaccel = {
     .p.name               = "hevc_nvdec",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -332,7 +341,7 @@ const FFHWAccel ff_hevc_nvdec_hwaccel = {
     .start_frame          = nvdec_hevc_start_frame,
     .end_frame            = ff_nvdec_end_frame,
     .decode_slice         = nvdec_hevc_decode_slice,
-    .frame_params         = nvdec_hevc_frame_params,
+    .frame_params         = nvdec_hevc_cuda_frame_params,
     .init                 = nvdec_hevc_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -340,6 +349,12 @@ const FFHWAccel ff_hevc_nvdec_hwaccel = {
 #endif
 
 #if CONFIG_HEVC_NVDEC_CUARRAY_HWACCEL
+static int nvdec_hevc_cuarray_frame_params(AVCodecContext *avctx,
+                                           AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_hevc_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
+}
+
 const FFHWAccel ff_hevc_nvdec_cuarray_hwaccel = {
     .p.name               = "hevc_nvdec_cuarray",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -348,7 +363,7 @@ const FFHWAccel ff_hevc_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_hevc_start_frame,
     .end_frame            = ff_nvdec_end_frame,
     .decode_slice         = nvdec_hevc_decode_slice,
-    .frame_params         = nvdec_hevc_frame_params,
+    .frame_params         = nvdec_hevc_cuarray_frame_params,
     .init                 = nvdec_hevc_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
diff --git a/libavcodec/nvdec_mjpeg.c b/libavcodec/nvdec_mjpeg.c
index f0c9416397..417b3c5c54 100644
--- a/libavcodec/nvdec_mjpeg.c
+++ b/libavcodec/nvdec_mjpeg.c
@@ -69,7 +69,7 @@ static int nvdec_mjpeg_frame_params(AVCodecContext *avctx,
                                   AVBufferRef *hw_frames_ctx)
 {
     // Only need storage for the current frame
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, 1, 0);
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA, 1, 0);
 }
 
 const FFHWAccel ff_mjpeg_nvdec_hwaccel = {
diff --git a/libavcodec/nvdec_mpeg12.c b/libavcodec/nvdec_mpeg12.c
index 34524488f1..ca94e3cb31 100644
--- a/libavcodec/nvdec_mpeg12.c
+++ b/libavcodec/nvdec_mpeg12.c
@@ -96,12 +96,21 @@ static int nvdec_mpeg12_start_frame(AVCodecContext *avctx,
 }
 
 static int nvdec_mpeg12_frame_params(AVCodecContext *avctx,
-                                  AVBufferRef *hw_frames_ctx)
+                                     AVBufferRef *hw_frames_ctx,
+                                     enum AVPixelFormat hw_format)
 {
     // Each frame can at most have one P and one B reference
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, 2, 0);
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format, 2, 0);
 }
 
+#if CONFIG_MPEG1_NVDEC_HWACCEL || CONFIG_MPEG2_NVDEC_HWACCEL
+static int nvdec_mpeg12_cuda_frame_params(AVCodecContext *avctx,
+                                          AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_mpeg12_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
+}
+#endif
+
 #if CONFIG_MPEG2_NVDEC_HWACCEL
 const FFHWAccel ff_mpeg2_nvdec_hwaccel = {
     .p.name               = "mpeg2_nvdec",
@@ -111,13 +120,21 @@ const FFHWAccel ff_mpeg2_nvdec_hwaccel = {
     .start_frame          = nvdec_mpeg12_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_mpeg12_frame_params,
+    .frame_params         = nvdec_mpeg12_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
 };
 #endif
 
+#if CONFIG_MPEG1_NVDEC_CUARRAY_HWACCEL || CONFIG_MPEG2_NVDEC_CUARRAY_HWACCEL
+static int nvdec_mpeg12_cuarray_frame_params(AVCodecContext *avctx,
+                                             AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_mpeg12_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
+}
+#endif
+
 #if CONFIG_MPEG2_NVDEC_CUARRAY_HWACCEL
 const FFHWAccel ff_mpeg2_nvdec_cuarray_hwaccel = {
     .p.name               = "mpeg2_nvdec_cuarray",
@@ -127,7 +144,7 @@ const FFHWAccel ff_mpeg2_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_mpeg12_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_mpeg12_frame_params,
+    .frame_params         = nvdec_mpeg12_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -143,7 +160,7 @@ const FFHWAccel ff_mpeg1_nvdec_hwaccel = {
     .start_frame          = nvdec_mpeg12_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_mpeg12_frame_params,
+    .frame_params         = nvdec_mpeg12_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -159,7 +176,7 @@ const FFHWAccel ff_mpeg1_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_mpeg12_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_mpeg12_frame_params,
+    .frame_params         = nvdec_mpeg12_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
diff --git a/libavcodec/nvdec_mpeg4.c b/libavcodec/nvdec_mpeg4.c
index 7f31edfe35..cda04edfd2 100644
--- a/libavcodec/nvdec_mpeg4.c
+++ b/libavcodec/nvdec_mpeg4.c
@@ -108,13 +108,20 @@ static int nvdec_mpeg4_decode_slice(AVCodecContext 
*avctx, const uint8_t *buffer
 }
 
 static int nvdec_mpeg4_frame_params(AVCodecContext *avctx,
-                                  AVBufferRef *hw_frames_ctx)
+                                    AVBufferRef *hw_frames_ctx,
+                                    enum AVPixelFormat hw_format)
 {
     // Each frame can at most have one P and one B reference
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, 2, 0);
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format, 2, 0);
 }
 
 #if CONFIG_MPEG4_NVDEC_HWACCEL
+static int nvdec_mpeg4_cuda_frame_params(AVCodecContext *avctx,
+                                         AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_mpeg4_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
+}
+
 const FFHWAccel ff_mpeg4_nvdec_hwaccel = {
     .p.name               = "mpeg4_nvdec",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -123,7 +130,7 @@ const FFHWAccel ff_mpeg4_nvdec_hwaccel = {
     .start_frame          = nvdec_mpeg4_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = nvdec_mpeg4_decode_slice,
-    .frame_params         = nvdec_mpeg4_frame_params,
+    .frame_params         = nvdec_mpeg4_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -131,6 +138,12 @@ const FFHWAccel ff_mpeg4_nvdec_hwaccel = {
 #endif
 
 #if CONFIG_MPEG4_NVDEC_CUARRAY_HWACCEL
+static int nvdec_mpeg4_cuarray_frame_params(AVCodecContext *avctx,
+                                            AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_mpeg4_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
+}
+
 const FFHWAccel ff_mpeg4_nvdec_cuarray_hwaccel = {
     .p.name               = "mpeg4_nvdec_cuarray",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -139,7 +152,7 @@ const FFHWAccel ff_mpeg4_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_mpeg4_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = nvdec_mpeg4_decode_slice,
-    .frame_params         = nvdec_mpeg4_frame_params,
+    .frame_params         = nvdec_mpeg4_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
diff --git a/libavcodec/nvdec_vc1.c b/libavcodec/nvdec_vc1.c
index 05fd63a353..55f3a17191 100644
--- a/libavcodec/nvdec_vc1.c
+++ b/libavcodec/nvdec_vc1.c
@@ -153,12 +153,21 @@ static int nvdec_vc1_decode_slice(AVCodecContext *avctx, 
const uint8_t *buffer,
 }
 
 static int nvdec_vc1_frame_params(AVCodecContext *avctx,
-                                  AVBufferRef *hw_frames_ctx)
+                                  AVBufferRef *hw_frames_ctx,
+                                  enum AVPixelFormat hw_format)
 {
     // Each frame can at most have one P and one B reference
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, 2, 0);
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format, 2, 0);
 }
 
+#if CONFIG_VC1_NVDEC_HWACCEL || CONFIG_WMV3_NVDEC_HWACCEL
+static int nvdec_vc1_cuda_frame_params(AVCodecContext *avctx,
+                                       AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_vc1_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
+}
+#endif
+
 #if CONFIG_VC1_NVDEC_HWACCEL
 const FFHWAccel ff_vc1_nvdec_hwaccel = {
     .p.name               = "vc1_nvdec",
@@ -168,13 +177,21 @@ const FFHWAccel ff_vc1_nvdec_hwaccel = {
     .start_frame          = nvdec_vc1_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = nvdec_vc1_decode_slice,
-    .frame_params         = nvdec_vc1_frame_params,
+    .frame_params         = nvdec_vc1_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
 };
 #endif
 
+#if CONFIG_VC1_NVDEC_CUARRAY_HWACCEL || CONFIG_WMV3_NVDEC_CUARRAY_HWACCEL
+static int nvdec_vc1_cuarray_frame_params(AVCodecContext *avctx,
+                                          AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_vc1_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
+}
+#endif
+
 #if CONFIG_VC1_NVDEC_CUARRAY_HWACCEL
 const FFHWAccel ff_vc1_nvdec_cuarray_hwaccel = {
     .p.name               = "vc1_nvdec_cuarray",
@@ -184,7 +201,7 @@ const FFHWAccel ff_vc1_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_vc1_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = nvdec_vc1_decode_slice,
-    .frame_params         = nvdec_vc1_frame_params,
+    .frame_params         = nvdec_vc1_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -200,7 +217,7 @@ const FFHWAccel ff_wmv3_nvdec_hwaccel = {
     .start_frame          = nvdec_vc1_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_vc1_frame_params,
+    .frame_params         = nvdec_vc1_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -216,7 +233,7 @@ const FFHWAccel ff_wmv3_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_vc1_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_vc1_frame_params,
+    .frame_params         = nvdec_vc1_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
diff --git a/libavcodec/nvdec_vp8.c b/libavcodec/nvdec_vp8.c
index 241cced65b..ad9c55b9fc 100644
--- a/libavcodec/nvdec_vp8.c
+++ b/libavcodec/nvdec_vp8.c
@@ -89,13 +89,20 @@ static int nvdec_vp8_start_frame(AVCodecContext *avctx,
 }
 
 static int nvdec_vp8_frame_params(AVCodecContext *avctx,
-                                  AVBufferRef *hw_frames_ctx)
+                                  AVBufferRef *hw_frames_ctx,
+                                  enum AVPixelFormat hw_format)
 {
     // VP8 uses a fixed size pool of 3 possible reference frames
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, 3, 0);
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format, 3, 0);
 }
 
 #if CONFIG_VP8_NVDEC_HWACCEL
+static int nvdec_vp8_cuda_frame_params(AVCodecContext *avctx,
+                                       AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_vp8_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
+}
+
 const FFHWAccel ff_vp8_nvdec_hwaccel = {
     .p.name               = "vp8_nvdec",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -104,7 +111,7 @@ const FFHWAccel ff_vp8_nvdec_hwaccel = {
     .start_frame          = nvdec_vp8_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_vp8_frame_params,
+    .frame_params         = nvdec_vp8_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -112,6 +119,12 @@ const FFHWAccel ff_vp8_nvdec_hwaccel = {
 #endif
 
 #if CONFIG_VP8_NVDEC_CUARRAY_HWACCEL
+static int nvdec_vp8_cuarray_frame_params(AVCodecContext *avctx,
+                                          AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_vp8_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
+}
+
 const FFHWAccel ff_vp8_nvdec_cuarray_hwaccel = {
     .p.name               = "vp8_nvdec_cuarray",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -120,7 +133,7 @@ const FFHWAccel ff_vp8_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_vp8_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_vp8_frame_params,
+    .frame_params         = nvdec_vp8_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
diff --git a/libavcodec/nvdec_vp9.c b/libavcodec/nvdec_vp9.c
index 73eee1c926..cab65b90f8 100644
--- a/libavcodec/nvdec_vp9.c
+++ b/libavcodec/nvdec_vp9.c
@@ -168,13 +168,20 @@ static int nvdec_vp9_start_frame(AVCodecContext *avctx,
 }
 
 static int nvdec_vp9_frame_params(AVCodecContext *avctx,
-                                  AVBufferRef *hw_frames_ctx)
+                                  AVBufferRef *hw_frames_ctx,
+                                  enum AVPixelFormat hw_format)
 {
     // VP9 uses a fixed size pool of 8 possible reference frames
-    return ff_nvdec_frame_params(avctx, hw_frames_ctx, 8, 0);
+    return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format, 8, 0);
 }
 
 #if CONFIG_VP9_NVDEC_HWACCEL
+static int nvdec_vp9_cuda_frame_params(AVCodecContext *avctx,
+                                       AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_vp9_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
+}
+
 const FFHWAccel ff_vp9_nvdec_hwaccel = {
     .p.name               = "vp9_nvdec",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -183,7 +190,7 @@ const FFHWAccel ff_vp9_nvdec_hwaccel = {
     .start_frame          = nvdec_vp9_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_vp9_frame_params,
+    .frame_params         = nvdec_vp9_cuda_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
@@ -191,6 +198,12 @@ const FFHWAccel ff_vp9_nvdec_hwaccel = {
 #endif
 
 #if CONFIG_VP9_NVDEC_CUARRAY_HWACCEL
+static int nvdec_vp9_cuarray_frame_params(AVCodecContext *avctx,
+                                          AVBufferRef *hw_frames_ctx)
+{
+    return nvdec_vp9_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
+}
+
 const FFHWAccel ff_vp9_nvdec_cuarray_hwaccel = {
     .p.name               = "vp9_nvdec_cuarray",
     .p.type               = AVMEDIA_TYPE_VIDEO,
@@ -199,7 +212,7 @@ const FFHWAccel ff_vp9_nvdec_cuarray_hwaccel = {
     .start_frame          = nvdec_vp9_start_frame,
     .end_frame            = ff_nvdec_simple_end_frame,
     .decode_slice         = ff_nvdec_simple_decode_slice,
-    .frame_params         = nvdec_vp9_frame_params,
+    .frame_params         = nvdec_vp9_cuarray_frame_params,
     .init                 = ff_nvdec_decode_init,
     .uninit               = ff_nvdec_decode_uninit,
     .priv_data_size       = sizeof(NVDECContext),
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to