[FFmpeg-devel] [PATCH 10/23] avutil/hwcontext: Allocate AVHWDevCtx jointly with its internals

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Mon Feb 12 02:03:22 EET 2024


This is possible because the lifetime of these structures coincide.
It has the advantage of allowing to remove the AVHWDeviceInternal
from the public header; given that AVHWDeviceInternal.priv is no more,
all accesses to it happen in hwcontext.c, so that this commit moves
the joint structure there.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
 libavutil/hwcontext.c          | 102 ++++++++++++++++++---------------
 libavutil/hwcontext.h          |   8 ---
 libavutil/hwcontext_internal.h |  10 ----
 3 files changed, 57 insertions(+), 63 deletions(-)

diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index 02e9668c31..c962c19f3e 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -84,6 +84,21 @@ static const char *const hw_type_names[] = {
     [AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
 };
 
+typedef struct FFHWDeviceContext {
+    /**
+     * The public AVHWDeviceContext. See hwcontext.h for it.
+     */
+    AVHWDeviceContext p;
+
+    const HWContextType *hw_type;
+
+    /**
+     * For a derived device, a reference to the original device
+     * context it was derived from.
+     */
+    AVBufferRef *source_device;
+} FFHWDeviceContext;
+
 enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
 {
     int type;
@@ -126,25 +141,26 @@ static const AVClass hwdevice_ctx_class = {
 
 static void hwdevice_ctx_free(void *opaque, uint8_t *data)
 {
-    AVHWDeviceContext *ctx = (AVHWDeviceContext*)data;
+    FFHWDeviceContext *ctxi = (FFHWDeviceContext*)data;
+    AVHWDeviceContext *ctx  = &ctxi->p;
 
     /* uninit might still want access the hw context and the user
      * free() callback might destroy it, so uninit has to be called first */
-    if (ctx->internal->hw_type->device_uninit)
-        ctx->internal->hw_type->device_uninit(ctx);
+    if (ctxi->hw_type->device_uninit)
+        ctxi->hw_type->device_uninit(ctx);
 
     if (ctx->free)
         ctx->free(ctx);
 
-    av_buffer_unref(&ctx->internal->source_device);
+    av_buffer_unref(&ctxi->source_device);
 
     av_freep(&ctx->hwctx);
-    av_freep(&ctx->internal);
     av_freep(&ctx);
 }
 
 AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
 {
+    FFHWDeviceContext *ctxi;
     AVHWDeviceContext *ctx;
     AVBufferRef *buf;
     const HWContextType *hw_type = NULL;
@@ -159,13 +175,10 @@ AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
     if (!hw_type)
         return 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->device_hwctx_size) {
         ctx->hwctx = av_mallocz(hw_type->device_hwctx_size);
@@ -182,12 +195,11 @@ AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
     ctx->type     = type;
     ctx->av_class = &hwdevice_ctx_class;
 
-    ctx->internal->hw_type = hw_type;
+    ctxi->hw_type = hw_type;
 
     return buf;
 
 fail:
-    av_freep(&ctx->internal);
     av_freep(&ctx->hwctx);
     av_freep(&ctx);
     return NULL;
@@ -195,19 +207,20 @@ fail:
 
 int av_hwdevice_ctx_init(AVBufferRef *ref)
 {
-    AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
+    FFHWDeviceContext *ctxi = (FFHWDeviceContext*)ref->data;
+    AVHWDeviceContext *ctx  = &ctxi->p;
     int ret;
 
-    if (ctx->internal->hw_type->device_init) {
-        ret = ctx->internal->hw_type->device_init(ctx);
+    if (ctxi->hw_type->device_init) {
+        ret = ctxi->hw_type->device_init(ctx);
         if (ret < 0)
             goto fail;
     }
 
     return 0;
 fail:
-    if (ctx->internal->hw_type->device_uninit)
-        ctx->internal->hw_type->device_uninit(ctx);
+    if (ctxi->hw_type->device_uninit)
+        ctxi->hw_type->device_uninit(ctx);
     return ret;
 }
 
@@ -242,8 +255,8 @@ static void hwframe_ctx_free(void *opaque, uint8_t *data)
 
 AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
 {
-    AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data;
-    const HWContextType  *hw_type = device_ctx->internal->hw_type;
+    FFHWDeviceContext *device_ctx = (FFHWDeviceContext*)device_ref_in->data;
+    const HWContextType  *hw_type = device_ctx->hw_type;
     AVHWFramesContext *ctx;
     AVBufferRef *buf, *device_ref = NULL;
 
@@ -279,7 +292,7 @@ AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
 
     ctx->av_class   = &hwframe_ctx_class;
     ctx->device_ref = device_ref;
-    ctx->device_ctx = device_ctx;
+    ctx->device_ctx = &device_ctx->p;
     ctx->format     = AV_PIX_FMT_NONE;
     ctx->sw_format  = AV_PIX_FMT_NONE;
 
@@ -563,8 +576,8 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
 
 void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
 {
-    AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
-    const HWContextType  *hw_type = ctx->internal->hw_type;
+    FFHWDeviceContext *ctx = (FFHWDeviceContext*)ref->data;
+    const HWContextType  *hw_type = ctx->hw_type;
 
     if (hw_type->device_hwconfig_size == 0)
         return NULL;
@@ -575,8 +588,8 @@ void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
 AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref,
                                                            const void *hwconfig)
 {
-    AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
-    const HWContextType  *hw_type = ctx->internal->hw_type;
+    FFHWDeviceContext *ctx = (FFHWDeviceContext*)ref->data;
+    const HWContextType  *hw_type = ctx->hw_type;
     AVHWFramesConstraints *constraints;
 
     if (!hw_type->frames_get_constraints)
@@ -589,7 +602,7 @@ AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref,
     constraints->min_width = constraints->min_height = 0;
     constraints->max_width = constraints->max_height = INT_MAX;
 
-    if (hw_type->frames_get_constraints(ctx, hwconfig, constraints) >= 0) {
+    if (hw_type->frames_get_constraints(&ctx->p, hwconfig, constraints) >= 0) {
         return constraints;
     } else {
         av_hwframe_constraints_free(&constraints);
@@ -610,7 +623,7 @@ int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type,
                            const char *device, AVDictionary *opts, int flags)
 {
     AVBufferRef *device_ref = NULL;
-    AVHWDeviceContext *device_ctx;
+    FFHWDeviceContext *device_ctx;
     int ret = 0;
 
     device_ref = av_hwdevice_ctx_alloc(type);
@@ -618,15 +631,15 @@ int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type,
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-    device_ctx = (AVHWDeviceContext*)device_ref->data;
+    device_ctx = (FFHWDeviceContext*)device_ref->data;
 
-    if (!device_ctx->internal->hw_type->device_create) {
+    if (!device_ctx->hw_type->device_create) {
         ret = AVERROR(ENOSYS);
         goto fail;
     }
 
-    ret = device_ctx->internal->hw_type->device_create(device_ctx, device,
-                                                       opts, flags);
+    ret = device_ctx->hw_type->device_create(&device_ctx->p, device,
+                                             opts, flags);
     if (ret < 0)
         goto fail;
 
@@ -648,13 +661,13 @@ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
                                         AVDictionary *options, int flags)
 {
     AVBufferRef *dst_ref = NULL, *tmp_ref;
-    AVHWDeviceContext *dst_ctx, *tmp_ctx;
+    FFHWDeviceContext *dst_ctx;
     int ret = 0;
 
     tmp_ref = src_ref;
     while (tmp_ref) {
-        tmp_ctx = (AVHWDeviceContext*)tmp_ref->data;
-        if (tmp_ctx->type == type) {
+        FFHWDeviceContext *tmp_ctx = (FFHWDeviceContext*)tmp_ref->data;
+        if (tmp_ctx->p.type == type) {
             dst_ref = av_buffer_ref(tmp_ref);
             if (!dst_ref) {
                 ret = AVERROR(ENOMEM);
@@ -662,7 +675,7 @@ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
             }
             goto done;
         }
-        tmp_ref = tmp_ctx->internal->source_device;
+        tmp_ref = tmp_ctx->source_device;
     }
 
     dst_ref = av_hwdevice_ctx_alloc(type);
@@ -670,19 +683,18 @@ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-    dst_ctx = (AVHWDeviceContext*)dst_ref->data;
+    dst_ctx = (FFHWDeviceContext*)dst_ref->data;
 
     tmp_ref = src_ref;
     while (tmp_ref) {
-        tmp_ctx = (AVHWDeviceContext*)tmp_ref->data;
-        if (dst_ctx->internal->hw_type->device_derive) {
-            ret = dst_ctx->internal->hw_type->device_derive(dst_ctx,
-                                                            tmp_ctx,
-                                                            options,
-                                                            flags);
+        FFHWDeviceContext *tmp_ctx = (FFHWDeviceContext*)tmp_ref->data;
+        if (dst_ctx->hw_type->device_derive) {
+            ret = dst_ctx->hw_type->device_derive(&dst_ctx->p,
+                                                  &tmp_ctx->p,
+                                                  options, flags);
             if (ret == 0) {
-                dst_ctx->internal->source_device = av_buffer_ref(src_ref);
-                if (!dst_ctx->internal->source_device) {
+                dst_ctx->source_device = av_buffer_ref(src_ref);
+                if (!dst_ctx->source_device) {
                     ret = AVERROR(ENOMEM);
                     goto fail;
                 }
@@ -694,7 +706,7 @@ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
             if (ret != AVERROR(ENOSYS))
                 goto fail;
         }
-        tmp_ref = tmp_ctx->internal->source_device;
+        tmp_ref = tmp_ctx->source_device;
     }
 
     ret = AVERROR(ENOSYS);
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index 2b33721a97..d91391294b 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -40,8 +40,6 @@ enum AVHWDeviceType {
     AV_HWDEVICE_TYPE_D3D12VA,
 };
 
-typedef struct AVHWDeviceInternal AVHWDeviceInternal;
-
 /**
  * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
  * i.e. state that is not tied to a concrete processing configuration.
@@ -65,12 +63,6 @@ typedef struct AVHWDeviceContext {
      */
     const AVClass *av_class;
 
-    /**
-     * Private data used internally by libavutil. Must not be accessed in any
-     * way by the caller.
-     */
-    AVHWDeviceInternal *internal;
-
     /**
      * This field identifies the underlying API used for hardware access.
      *
diff --git a/libavutil/hwcontext_internal.h b/libavutil/hwcontext_internal.h
index 374c6dde2f..3745867283 100644
--- a/libavutil/hwcontext_internal.h
+++ b/libavutil/hwcontext_internal.h
@@ -95,16 +95,6 @@ typedef struct HWContextType {
                                            AVHWFramesContext *src_ctx, int flags);
 } HWContextType;
 
-struct AVHWDeviceInternal {
-    const HWContextType *hw_type;
-
-    /**
-     * For a derived device, a reference to the original device
-     * context it was derived from.
-     */
-    AVBufferRef *source_device;
-};
-
 struct AVHWFramesInternal {
     const HWContextType *hw_type;
     void                *priv;
-- 
2.34.1



More information about the ffmpeg-devel mailing list