diff mbox series

[FFmpeg-devel,23/23] avutil/hwcontext: Allocate AVHWFramesCtx jointly with its internals

Message ID DU0P250MB07475EA343225459B3AE8CB78F482@DU0P250MB0747.EURP250.PROD.OUTLOOK.COM
State New
Headers show
Series [FFmpeg-devel,01/23] avutil/hwcontext_opencl: Use proper OpenCLFramesContext | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 fail Make fate failed

Commit Message

Andreas Rheinhardt Feb. 12, 2024, 12:03 a.m. UTC
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>
---
 libavutil/hwcontext.c              | 158 ++++++++++++++---------------
 libavutil/hwcontext.h              |   8 --
 libavutil/hwcontext_cuda.c         |   5 +-
 libavutil/hwcontext_d3d11va.c      |   7 +-
 libavutil/hwcontext_d3d12va.c      |   4 +-
 libavutil/hwcontext_dxva2.c        |   7 +-
 libavutil/hwcontext_internal.h     |  14 ++-
 libavutil/hwcontext_opencl.c       |   4 +-
 libavutil/hwcontext_qsv.c          |   6 +-
 libavutil/hwcontext_vaapi.c        |   6 +-
 libavutil/hwcontext_vdpau.c        |   7 +-
 libavutil/hwcontext_videotoolbox.c |   4 +-
 libavutil/hwcontext_vulkan.c       |   8 +-
 13 files changed, 121 insertions(+), 117 deletions(-)
diff mbox series

Patch

diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index 8ecefd2bc4..a0192f4fa9 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -232,23 +232,23 @@  static const AVClass hwframe_ctx_class = {
 
 static void hwframe_ctx_free(void *opaque, uint8_t *data)
 {
-    AVHWFramesContext *ctx = (AVHWFramesContext*)data;
+    FFHWFramesContext *ctxi = (FFHWFramesContext*)data;
+    AVHWFramesContext *ctx  = &ctxi->p;
 
-    if (ctx->internal->pool_internal)
-        av_buffer_pool_uninit(&ctx->internal->pool_internal);
+    if (ctxi->pool_internal)
+        av_buffer_pool_uninit(&ctxi->pool_internal);
 
-    if (ctx->internal->hw_type->frames_uninit)
-        ctx->internal->hw_type->frames_uninit(ctx);
+    if (ctxi->hw_type->frames_uninit)
+        ctxi->hw_type->frames_uninit(ctx);
 
     if (ctx->free)
         ctx->free(ctx);
 
-    av_buffer_unref(&ctx->internal->source_frames);
+    av_buffer_unref(&ctxi->source_frames);
 
     av_buffer_unref(&ctx->device_ref);
 
     av_freep(&ctx->hwctx);
-    av_freep(&ctx->internal);
     av_freep(&ctx);
 }
 
@@ -256,16 +256,14 @@  AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
 {
     FFHWDeviceContext *device_ctx = (FFHWDeviceContext*)device_ref_in->data;
     const HWContextType  *hw_type = device_ctx->hw_type;
+    FFHWFramesContext *ctxi;
     AVHWFramesContext *ctx;
     AVBufferRef *buf, *device_ref = NULL;
 
-    ctx = av_mallocz(sizeof(*ctx));
-    if (!ctx)
+    ctxi = av_mallocz(sizeof(*ctxi));
+    if (!ctxi)
         return NULL;
-
-    ctx->internal = av_mallocz(sizeof(*ctx->internal));
-    if (!ctx->internal)
-        goto fail;
+    ctx  = &ctxi->p;
 
     if (hw_type->frames_hwctx_size) {
         ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size);
@@ -289,13 +287,12 @@  AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
     ctx->format     = AV_PIX_FMT_NONE;
     ctx->sw_format  = AV_PIX_FMT_NONE;
 
-    ctx->internal->hw_type = hw_type;
+    ctxi->hw_type = hw_type;
 
     return buf;
 
 fail:
     av_buffer_unref(&device_ref);
-    av_freep(&ctx->internal);
     av_freep(&ctx->hwctx);
     av_freep(&ctx);
     return NULL;
@@ -331,24 +328,25 @@  fail:
 
 int av_hwframe_ctx_init(AVBufferRef *ref)
 {
-    AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data;
+    FFHWFramesContext *ctxi = (FFHWFramesContext*)ref->data;
+    AVHWFramesContext *ctx  = &ctxi->p;
     const enum AVPixelFormat *pix_fmt;
     int ret;
 
-    if (ctx->internal->source_frames) {
+    if (ctxi->source_frames) {
         /* A derived frame context is already initialised. */
         return 0;
     }
 
     /* validate the pixel format */
-    for (pix_fmt = ctx->internal->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) {
+    for (pix_fmt = ctxi->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) {
         if (*pix_fmt == ctx->format)
             break;
     }
     if (*pix_fmt == AV_PIX_FMT_NONE) {
         av_log(ctx, AV_LOG_ERROR,
                "The hardware pixel format '%s' is not supported by the device type '%s'\n",
-               av_get_pix_fmt_name(ctx->format), ctx->internal->hw_type->name);
+               av_get_pix_fmt_name(ctx->format), ctxi->hw_type->name);
         return AVERROR(ENOSYS);
     }
 
@@ -358,14 +356,14 @@  int av_hwframe_ctx_init(AVBufferRef *ref)
         return ret;
 
     /* format-specific init */
-    if (ctx->internal->hw_type->frames_init) {
-        ret = ctx->internal->hw_type->frames_init(ctx);
+    if (ctxi->hw_type->frames_init) {
+        ret = ctxi->hw_type->frames_init(ctx);
         if (ret < 0)
             goto fail;
     }
 
-    if (ctx->internal->pool_internal && !ctx->pool)
-        ctx->pool = ctx->internal->pool_internal;
+    if (ctxi->pool_internal && !ctx->pool)
+        ctx->pool = ctxi->pool_internal;
 
     /* preallocate the frames in the pool, if requested */
     if (ctx->initial_pool_size > 0) {
@@ -376,8 +374,8 @@  int av_hwframe_ctx_init(AVBufferRef *ref)
 
     return 0;
 fail:
-    if (ctx->internal->hw_type->frames_uninit)
-        ctx->internal->hw_type->frames_uninit(ctx);
+    if (ctxi->hw_type->frames_uninit)
+        ctxi->hw_type->frames_uninit(ctx);
     return ret;
 }
 
@@ -385,12 +383,12 @@  int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref,
                                     enum AVHWFrameTransferDirection dir,
                                     enum AVPixelFormat **formats, int flags)
 {
-    AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
+    FFHWFramesContext *ctxi = (FFHWFramesContext*)hwframe_ref->data;
 
-    if (!ctx->internal->hw_type->transfer_get_formats)
+    if (!ctxi->hw_type->transfer_get_formats)
         return AVERROR(ENOSYS);
 
-    return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats);
+    return ctxi->hw_type->transfer_get_formats(&ctxi->p, dir, formats);
 }
 
 static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
@@ -445,7 +443,6 @@  fail:
 
 int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
 {
-    AVHWFramesContext *ctx;
     int ret;
 
     if (!dst->buf[0])
@@ -458,41 +455,41 @@  int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
      * the specific combination of hardware.
      */
     if (src->hw_frames_ctx && dst->hw_frames_ctx) {
-        AVHWFramesContext *src_ctx =
-            (AVHWFramesContext*)src->hw_frames_ctx->data;
-        AVHWFramesContext *dst_ctx =
-            (AVHWFramesContext*)dst->hw_frames_ctx->data;
+        FFHWFramesContext *src_ctx =
+            (FFHWFramesContext*)src->hw_frames_ctx->data;
+        FFHWFramesContext *dst_ctx =
+            (FFHWFramesContext*)dst->hw_frames_ctx->data;
 
-        if (src_ctx->internal->source_frames) {
+        if (src_ctx->source_frames) {
             av_log(src_ctx, AV_LOG_ERROR,
                    "A device with a derived frame context cannot be used as "
                    "the source of a HW -> HW transfer.");
             return AVERROR(ENOSYS);
         }
 
-        if (dst_ctx->internal->source_frames) {
+        if (dst_ctx->source_frames) {
             av_log(src_ctx, AV_LOG_ERROR,
                    "A device with a derived frame context cannot be used as "
                    "the destination of a HW -> HW transfer.");
             return AVERROR(ENOSYS);
         }
 
-        ret = src_ctx->internal->hw_type->transfer_data_from(src_ctx, dst, src);
+        ret = src_ctx->hw_type->transfer_data_from(&src_ctx->p, dst, src);
         if (ret == AVERROR(ENOSYS))
-            ret = dst_ctx->internal->hw_type->transfer_data_to(dst_ctx, dst, src);
+            ret = dst_ctx->hw_type->transfer_data_to(&dst_ctx->p, dst, src);
         if (ret < 0)
             return ret;
     } else {
         if (src->hw_frames_ctx) {
-            ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
+            FFHWFramesContext *ctx = (FFHWFramesContext*)src->hw_frames_ctx->data;
 
-            ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
+            ret = ctx->hw_type->transfer_data_from(&ctx->p, dst, src);
             if (ret < 0)
                 return ret;
         } else if (dst->hw_frames_ctx) {
-            ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
+            FFHWFramesContext *ctx = (FFHWFramesContext*)dst->hw_frames_ctx->data;
 
-            ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
+            ret = ctx->hw_type->transfer_data_to(&ctx->p, dst, src);
             if (ret < 0)
                 return ret;
         } else {
@@ -504,10 +501,11 @@  int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
 
 int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
 {
-    AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
+    FFHWFramesContext *ctxi = (FFHWFramesContext*)hwframe_ref->data;
+    AVHWFramesContext *ctx  = &ctxi->p;
     int ret;
 
-    if (ctx->internal->source_frames) {
+    if (ctxi->source_frames) {
         // This is a derived frame context, so we allocate in the source
         // and map the frame immediately.
         AVFrame *src_frame;
@@ -521,7 +519,7 @@  int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
         if (!src_frame)
             return AVERROR(ENOMEM);
 
-        ret = av_hwframe_get_buffer(ctx->internal->source_frames,
+        ret = av_hwframe_get_buffer(ctxi->source_frames,
                                     src_frame, 0);
         if (ret < 0) {
             av_frame_free(&src_frame);
@@ -529,7 +527,7 @@  int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
         }
 
         ret = av_hwframe_map(frame, src_frame,
-                             ctx->internal->source_allocation_map_flags);
+                             ctxi->source_allocation_map_flags);
         if (ret) {
             av_log(ctx, AV_LOG_ERROR, "Failed to map frame into derived "
                    "frame context: %d.\n", ret);
@@ -544,7 +542,7 @@  int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
         return 0;
     }
 
-    if (!ctx->internal->hw_type->frames_get_buffer)
+    if (!ctxi->hw_type->frames_get_buffer)
         return AVERROR(ENOSYS);
 
     if (!ctx->pool)
@@ -554,7 +552,7 @@  int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
     if (!frame->hw_frames_ctx)
         return AVERROR(ENOMEM);
 
-    ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame);
+    ret = ctxi->hw_type->frames_get_buffer(ctx, frame);
     if (ret < 0) {
         av_buffer_unref(&frame->hw_frames_ctx);
         return ret;
@@ -792,19 +790,18 @@  int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
 {
     AVBufferRef    *orig_dst_frames = dst->hw_frames_ctx;
     enum AVPixelFormat orig_dst_fmt = dst->format;
-    AVHWFramesContext *src_frames, *dst_frames;
     HWMapDescriptor *hwmap;
     int ret;
 
     if (src->hw_frames_ctx && dst->hw_frames_ctx) {
-        src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data;
-        dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data;
+        FFHWFramesContext *src_frames = (FFHWFramesContext*)src->hw_frames_ctx->data;
+        FFHWFramesContext *dst_frames = (FFHWFramesContext*)dst->hw_frames_ctx->data;
 
         if ((src_frames == dst_frames &&
-             src->format == dst_frames->sw_format &&
-             dst->format == dst_frames->format) ||
-            (src_frames->internal->source_frames &&
-             src_frames->internal->source_frames->data ==
+             src->format == dst_frames->p.sw_format &&
+             dst->format == dst_frames->p.format) ||
+            (src_frames->source_frames &&
+             src_frames->source_frames->data ==
              (uint8_t*)dst_frames)) {
             // This is an unmap operation.  We don't need to directly
             // do anything here other than fill in the original frame,
@@ -821,12 +818,12 @@  int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
     }
 
     if (src->hw_frames_ctx) {
-        src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data;
+        FFHWFramesContext *src_frames = (FFHWFramesContext*)src->hw_frames_ctx->data;
 
-        if (src_frames->format == src->format &&
-            src_frames->internal->hw_type->map_from) {
-            ret = src_frames->internal->hw_type->map_from(src_frames,
-                                                          dst, src, flags);
+        if (src_frames->p.format == src->format &&
+            src_frames->hw_type->map_from) {
+            ret = src_frames->hw_type->map_from(&src_frames->p,
+                                                dst, src, flags);
             if (ret >= 0)
                 return ret;
             else if (ret != AVERROR(ENOSYS))
@@ -835,12 +832,12 @@  int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
     }
 
     if (dst->hw_frames_ctx) {
-        dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data;
+        FFHWFramesContext *dst_frames = (FFHWFramesContext*)dst->hw_frames_ctx->data;
 
-        if (dst_frames->format == dst->format &&
-            dst_frames->internal->hw_type->map_to) {
-            ret = dst_frames->internal->hw_type->map_to(dst_frames,
-                                                        dst, src, flags);
+        if (dst_frames->p.format == dst->format &&
+            dst_frames->hw_type->map_to) {
+            ret = dst_frames->hw_type->map_to(&dst_frames->p,
+                                              dst, src, flags);
             if (ret >= 0)
                 return ret;
             else if (ret != AVERROR(ENOSYS))
@@ -874,21 +871,21 @@  int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
                                   int flags)
 {
     AVBufferRef   *dst_ref = NULL;
-    AVHWFramesContext *dst = NULL;
-    AVHWFramesContext *src = (AVHWFramesContext*)source_frame_ctx->data;
+    FFHWFramesContext *dsti = NULL;
+    FFHWFramesContext *srci = (FFHWFramesContext*)source_frame_ctx->data;
+    AVHWFramesContext *dst, *src = &srci->p;
     int ret;
 
-    if (src->internal->source_frames) {
+    if (srci->source_frames) {
         AVHWFramesContext *src_src =
-            (AVHWFramesContext*)src->internal->source_frames->data;
+            (AVHWFramesContext*)srci->source_frames->data;
         AVHWDeviceContext *dst_dev =
             (AVHWDeviceContext*)derived_device_ctx->data;
 
         if (src_src->device_ctx == dst_dev) {
             // This is actually an unmapping, so we just return a
             // reference to the source frame context.
-            *derived_frame_ctx =
-                av_buffer_ref(src->internal->source_frames);
+            *derived_frame_ctx = av_buffer_ref(srci->source_frames);
             if (!*derived_frame_ctx) {
                 ret = AVERROR(ENOMEM);
                 goto fail;
@@ -903,31 +900,32 @@  int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
         goto fail;
     }
 
-    dst = (AVHWFramesContext*)dst_ref->data;
+    dsti = (FFHWFramesContext*)dst_ref->data;
+    dst  = &dsti->p;
 
     dst->format    = format;
     dst->sw_format = src->sw_format;
     dst->width     = src->width;
     dst->height    = src->height;
 
-    dst->internal->source_frames = av_buffer_ref(source_frame_ctx);
-    if (!dst->internal->source_frames) {
+    dsti->source_frames = av_buffer_ref(source_frame_ctx);
+    if (!dsti->source_frames) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
 
-    dst->internal->source_allocation_map_flags =
+    dsti->source_allocation_map_flags =
         flags & (AV_HWFRAME_MAP_READ      |
                  AV_HWFRAME_MAP_WRITE     |
                  AV_HWFRAME_MAP_OVERWRITE |
                  AV_HWFRAME_MAP_DIRECT);
 
     ret = AVERROR(ENOSYS);
-    if (src->internal->hw_type->frames_derive_from)
-        ret = src->internal->hw_type->frames_derive_from(dst, src, flags);
+    if (srci->hw_type->frames_derive_from)
+        ret = srci->hw_type->frames_derive_from(dst, src, flags);
     if (ret == AVERROR(ENOSYS) &&
-        dst->internal->hw_type->frames_derive_to)
-        ret = dst->internal->hw_type->frames_derive_to(dst, src, flags);
+        dsti->hw_type->frames_derive_to)
+        ret = dsti->hw_type->frames_derive_to(dst, src, flags);
     if (ret == AVERROR(ENOSYS))
         ret = 0;
     if (ret)
@@ -937,8 +935,8 @@  int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
     return 0;
 
 fail:
-    if (dst)
-        av_buffer_unref(&dst->internal->source_frames);
+    if (dsti)
+        av_buffer_unref(&dsti->source_frames);
     av_buffer_unref(&dst_ref);
     return ret;
 }
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index 091bceb2f9..bac30debae 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -102,8 +102,6 @@  typedef struct AVHWDeviceContext {
     void *user_opaque;
 } AVHWDeviceContext;
 
-typedef struct AVHWFramesInternal AVHWFramesInternal;
-
 /**
  * This struct describes a set or pool of "hardware" frames (i.e. those with
  * data not located in normal system memory). All the frames in the pool are
@@ -120,12 +118,6 @@  typedef struct AVHWFramesContext {
      */
     const AVClass *av_class;
 
-    /**
-     * Private data used internally by libavutil. Must not be accessed in any
-     * way by the caller.
-     */
-    AVHWFramesInternal *internal;
-
     /**
      * A reference to the parent AVHWDeviceContext. This reference is owned and
      * managed by the enclosing AVHWFramesContext, but the caller may derive
diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c
index 1c61b36d69..b430b42f62 100644
--- a/libavutil/hwcontext_cuda.c
+++ b/libavutil/hwcontext_cuda.c
@@ -165,8 +165,9 @@  static int cuda_frames_init(AVHWFramesContext *ctx)
         if (size < 0)
             return size;
 
-        ctx->internal->pool_internal = av_buffer_pool_init2(size, ctx, cuda_pool_alloc, NULL);
-        if (!ctx->internal->pool_internal)
+        ffhwframesctx(ctx)->pool_internal =
+            av_buffer_pool_init2(size, ctx, cuda_pool_alloc, NULL);
+        if (!ffhwframesctx(ctx)->pool_internal)
             return AVERROR(ENOMEM);
     }
 
diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
index 19fcf37a84..24b3546e7b 100644
--- a/libavutil/hwcontext_d3d11va.c
+++ b/libavutil/hwcontext_d3d11va.c
@@ -319,9 +319,10 @@  static int d3d11va_frames_init(AVHWFramesContext *ctx)
         return AVERROR(ENOMEM);
     s->nb_surfaces = ctx->initial_pool_size;
 
-    ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(AVD3D11FrameDescriptor),
-                                                        ctx, d3d11va_pool_alloc, NULL);
-    if (!ctx->internal->pool_internal)
+    ffhwframesctx(ctx)->pool_internal =
+        av_buffer_pool_init2(sizeof(AVD3D11FrameDescriptor),
+                             ctx, d3d11va_pool_alloc, NULL);
+    if (!ffhwframesctx(ctx)->pool_internal)
         return AVERROR(ENOMEM);
 
     return 0;
diff --git a/libavutil/hwcontext_d3d12va.c b/libavutil/hwcontext_d3d12va.c
index 16c07868f3..353807359b 100644
--- a/libavutil/hwcontext_d3d12va.c
+++ b/libavutil/hwcontext_d3d12va.c
@@ -297,10 +297,10 @@  static int d3d12va_frames_init(AVHWFramesContext *ctx)
         return AVERROR(EINVAL);
     }
 
-    ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(AVD3D12VAFrame),
+    ffhwframesctx(ctx)->pool_internal = av_buffer_pool_init2(sizeof(AVD3D12VAFrame),
         ctx, d3d12va_pool_alloc, NULL);
 
-    if (!ctx->internal->pool_internal)
+    if (!ffhwframesctx(ctx)->pool_internal)
         return AVERROR(ENOMEM);
 
     return 0;
diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c
index 0922776342..77f34919a8 100644
--- a/libavutil/hwcontext_dxva2.c
+++ b/libavutil/hwcontext_dxva2.c
@@ -208,9 +208,10 @@  static int dxva2_init_pool(AVHWFramesContext *ctx)
         return AVERROR_UNKNOWN;
     }
 
-    ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(*s->surfaces_internal),
-                                                        ctx, dxva2_pool_alloc, NULL);
-    if (!ctx->internal->pool_internal)
+    ffhwframesctx(ctx)->pool_internal =
+        av_buffer_pool_init2(sizeof(*s->surfaces_internal),
+                             ctx, dxva2_pool_alloc, NULL);
+    if (!ffhwframesctx(ctx)->pool_internal)
         return AVERROR(ENOMEM);
 
     frames_hwctx->surfaces    = s->surfaces_internal;
diff --git a/libavutil/hwcontext_internal.h b/libavutil/hwcontext_internal.h
index 1476def1d7..e32b786238 100644
--- a/libavutil/hwcontext_internal.h
+++ b/libavutil/hwcontext_internal.h
@@ -90,7 +90,12 @@  typedef struct HWContextType {
                                            AVHWFramesContext *src_ctx, int flags);
 } HWContextType;
 
-struct AVHWFramesInternal {
+typedef struct FFHWFramesContext {
+    /**
+     * The public AVHWFramesContext. See hwcontext.h for it.
+     */
+    AVHWFramesContext p;
+
     const HWContextType *hw_type;
 
     AVBufferPool *pool_internal;
@@ -105,7 +110,12 @@  struct AVHWFramesInternal {
      * frame context when trying to allocate in the derived context.
      */
     int source_allocation_map_flags;
-};
+} FFHWFramesContext;
+
+static inline FFHWFramesContext *ffhwframesctx(AVHWFramesContext *ctx)
+{
+    return (FFHWFramesContext*)ctx;
+}
 
 typedef struct HWMapDescriptor {
     /**
diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c
index c5af1aec74..b449c5c31b 100644
--- a/libavutil/hwcontext_opencl.c
+++ b/libavutil/hwcontext_opencl.c
@@ -1714,10 +1714,10 @@  static int opencl_frames_init_command_queue(AVHWFramesContext *hwfc)
 static int opencl_frames_init(AVHWFramesContext *hwfc)
 {
     if (!hwfc->pool) {
-        hwfc->internal->pool_internal =
+        ffhwframesctx(hwfc)->pool_internal =
             av_buffer_pool_init2(sizeof(cl_mem), hwfc,
                                  &opencl_pool_alloc, NULL);
-        if (!hwfc->internal->pool_internal)
+        if (!ffhwframesctx(hwfc)->pool_internal)
             return AVERROR(ENOMEM);
     }
 
diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index f524a663b1..378cd5e826 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -605,9 +605,9 @@  static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc)
         return ret;
 #endif
 
-    ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(mfxFrameSurface1),
-                                                        ctx, qsv_pool_alloc, NULL);
-    if (!ctx->internal->pool_internal)
+    ffhwframesctx(ctx)->pool_internal = av_buffer_pool_init2(sizeof(mfxFrameSurface1),
+                                                             ctx, qsv_pool_alloc, NULL);
+    if (!ffhwframesctx(ctx)->pool_internal)
         return AVERROR(ENOMEM);
 
     frames_hwctx->surfaces    = s->surfaces_internal;
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 2c75f5f5b1..56d03aa4cd 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -633,10 +633,10 @@  static int vaapi_frames_init(AVHWFramesContext *hwfc)
             avfc->surface_ids = NULL;
         }
 
-        hwfc->internal->pool_internal =
+        ffhwframesctx(hwfc)->pool_internal =
             av_buffer_pool_init2(sizeof(VASurfaceID), hwfc,
                                  &vaapi_pool_alloc, NULL);
-        if (!hwfc->internal->pool_internal) {
+        if (!ffhwframesctx(hwfc)->pool_internal) {
             av_log(hwfc, AV_LOG_ERROR, "Failed to create VAAPI surface pool.\n");
             err = AVERROR(ENOMEM);
             goto fail;
@@ -654,7 +654,7 @@  static int vaapi_frames_init(AVHWFramesContext *hwfc)
             goto fail;
         }
     } else {
-        test_surface = av_buffer_pool_get(hwfc->internal->pool_internal);
+        test_surface = av_buffer_pool_get(ffhwframesctx(hwfc)->pool_internal);
         if (!test_surface) {
             av_log(hwfc, AV_LOG_ERROR, "Unable to allocate a surface from "
                    "internal buffer pool.\n");
diff --git a/libavutil/hwcontext_vdpau.c b/libavutil/hwcontext_vdpau.c
index 0a1a33f8b1..081b863e0c 100644
--- a/libavutil/hwcontext_vdpau.c
+++ b/libavutil/hwcontext_vdpau.c
@@ -281,9 +281,10 @@  static int vdpau_frames_init(AVHWFramesContext *ctx)
     }
 
     if (!ctx->pool) {
-        ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(VdpVideoSurface), ctx,
-                                                            vdpau_pool_alloc, NULL);
-        if (!ctx->internal->pool_internal)
+        ffhwframesctx(ctx)->pool_internal =
+            av_buffer_pool_init2(sizeof(VdpVideoSurface), ctx,
+                                 vdpau_pool_alloc, NULL);
+        if (!ffhwframesctx(ctx)->pool_internal)
             return AVERROR(ENOMEM);
     }
 
diff --git a/libavutil/hwcontext_videotoolbox.c b/libavutil/hwcontext_videotoolbox.c
index 823cf9a8ee..9f82b104c3 100644
--- a/libavutil/hwcontext_videotoolbox.c
+++ b/libavutil/hwcontext_videotoolbox.c
@@ -286,9 +286,9 @@  static int vt_frames_init(AVHWFramesContext *ctx)
     }
 
     if (!ctx->pool) {
-        ctx->internal->pool_internal = av_buffer_pool_init2(
+        ffhwframesctx(ctx)->pool_internal = av_buffer_pool_init2(
                 sizeof(CVPixelBufferRef), ctx, vt_pool_alloc_buffer, NULL);
-        if (!ctx->internal->pool_internal)
+        if (!ffhwframesctx(ctx)->pool_internal)
             return AVERROR(ENOMEM);
     }
 
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 449a6a2fef..f6ecdcbfda 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2399,10 +2399,10 @@  static int vulkan_frames_init(AVHWFramesContext *hwfc)
     /* If user did not specify a pool, hwfc->pool will be set to the internal one
      * in hwcontext.c just after this gets called */
     if (!hwfc->pool) {
-        hwfc->internal->pool_internal = av_buffer_pool_init2(sizeof(AVVkFrame),
-                                                             hwfc, vulkan_pool_alloc,
-                                                             NULL);
-        if (!hwfc->internal->pool_internal)
+        ffhwframesctx(hwfc)->pool_internal = av_buffer_pool_init2(sizeof(AVVkFrame),
+                                                                  hwfc, vulkan_pool_alloc,
+                                                                  NULL);
+        if (!ffhwframesctx(hwfc)->pool_internal)
             return AVERROR(ENOMEM);
     }