This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

The following commit(s) were added to refs/heads/master by this push:
     new 485f195690 avutil/hwcontext_amf: Implement AMF hardware memory mapping 
support.
485f195690 is described below

commit 485f1956908ae3281b2f5e1c6298f5ee061bcfd9
Author:     Dmitrii Gershenkop <[email protected]>
AuthorDate: Tue Jun 16 15:33:25 2026 +0200
Commit:     ArazIusubov <[email protected]>
CommitDate: Wed Jun 17 12:30:56 2026 +0000

    avutil/hwcontext_amf: Implement AMF hardware memory mapping support.
---
 Changelog                 |  1 +
 libavutil/hwcontext_amf.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
 libavutil/version.h       |  2 +-
 3 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/Changelog b/Changelog
index 3c48005026..2ad3ee255f 100644
--- a/Changelog
+++ b/Changelog
@@ -17,6 +17,7 @@ version <next>:
 - Remove CELT decoding support (doesn't affect Opus CELT)
 - Remove ogg/celt parsing
 - Bitstream filter to split Dolby Vision multi-layer HEVC
+- Add AMF hardware memory mapping support.
 
 
 version 8.1:
diff --git a/libavutil/hwcontext_amf.c b/libavutil/hwcontext_amf.c
index 754b1c60a2..7d877683b4 100644
--- a/libavutil/hwcontext_amf.c
+++ b/libavutil/hwcontext_amf.c
@@ -819,6 +819,77 @@ static int amf_device_derive(AVHWDeviceContext *device_ctx,
     }
 }
 
+static void amf_unmap_frame(av_unused AVHWFramesContext *unused, 
HWMapDescriptor *hwmap)
+{
+    AMFSurface1 *surface1 = hwmap->priv;
+    AMF_IFACE_CALL(surface1, Unmap);
+    AMF_IFACE_CALL(surface1, Release);
+}
+
+static int amf_map_frame(AVHWFramesContext *device_ctx, AVFrame *dst, const 
AVFrame *src, int flags)
+{
+    AMFSurface *surface = (AMFSurface *)src->data[0];
+    AMFSurface1 *surface1 = NULL;
+    size_t *linesizes = NULL;
+    uint8_t **map = NULL;
+    int amf_mem_flags = AMF_MEMORY_CPU_NONE;
+    const AMFGuid guid = IID_AMFSurface1();
+    AMF_RESULT res = AMF_FAIL;
+    size_t plane_count = 0;
+    int ret = -1;
+
+    AMF_RETURN_IF_FALSE(device_ctx, surface != NULL, AVERROR(EINVAL) , "Source 
surface is null");
+
+    res = AMF_IFACE_CALL(surface, QueryInterface, &guid, (void**)&surface1);
+    AMF_RETURN_IF_FALSE(device_ctx, res == AMF_OK, AVERROR_UNKNOWN, 
"QueryInterface(AMFSurface1) failed with error %d\n", res);
+
+    if (flags & AV_HWFRAME_MAP_READ)
+        amf_mem_flags |= AMF_MEMORY_CPU_READ;
+
+    if (flags & AV_HWFRAME_MAP_WRITE)
+        amf_mem_flags |= AMF_MEMORY_CPU_WRITE;
+
+    plane_count = AMF_IFACE_CALL(surface, GetPlanesCount);
+    linesizes = av_malloc_array(sizeof(size_t), plane_count);
+    AMF_GOTO_FAIL_IF_FALSE(device_ctx, linesizes, AVERROR(ENOMEM), "Unable to 
allocate line sizes array\n");
+
+    map = av_malloc_array(sizeof(uint8_t *), plane_count);
+    AMF_GOTO_FAIL_IF_FALSE(device_ctx, map, AVERROR(ENOMEM), "Unable to 
allocate mapping buffer\n");
+
+    dst->format = av_amf_to_av_format(AMF_IFACE_CALL(surface, GetFormat));
+
+    res = AMF_IFACE_CALL(surface1, Map, amf_mem_flags, plane_count, linesizes, 
(void**)map);
+    AMF_GOTO_FAIL_IF_FALSE(device_ctx, res == AMF_OK, AVERROR_UNKNOWN, 
"AMFSurface1->Map() failed with error %d\n", res);
+
+    ret = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, 
&amf_unmap_frame, surface1);
+    AMF_GOTO_FAIL_IF_FALSE(device_ctx, ret >= 0, ret, "ff_hwframe_map_create 
failed with error %d\n", ret);
+
+    dst->width  = src->width;
+    dst->height = src->height;
+    av_frame_copy_props(dst, src);
+
+    // The dst frame is no longer a hardware frame, from the perspective of 
any dst frame consumer.
+    av_buffer_unref(&dst->hw_frames_ctx);
+
+    for (int plane = 0; plane < plane_count; ++plane)
+    {
+        dst->data[plane] = map[plane];
+        dst->linesize[plane] = linesizes[plane];
+    }
+
+fail:
+    if (map)
+        av_free(map);
+
+    if (linesizes)
+        av_free(linesizes);
+
+    if (ret < 0 && surface1 != NULL)
+        AMF_IFACE_CALL(surface1, Release);
+
+    return ret;
+}
+
 const HWContextType ff_hwcontext_type_amf = {
     .type                 = AV_HWDEVICE_TYPE_AMF,
     .name                 = "AMF",
@@ -836,6 +907,7 @@ const HWContextType ff_hwcontext_type_amf = {
     .transfer_get_formats = amf_transfer_get_formats,
     .transfer_data_to     = amf_transfer_data_to,
     .transfer_data_from   = amf_transfer_data_from,
+    .map_from             = amf_map_frame,
 
     .pix_fmts             = (const enum AVPixelFormat[]){ 
AV_PIX_FMT_AMF_SURFACE, AV_PIX_FMT_NONE },
 };
diff --git a/libavutil/version.h b/libavutil/version.h
index 42f2d41052..429e65d77f 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -80,7 +80,7 @@
 
 #define LIBAVUTIL_VERSION_MAJOR  60
 #define LIBAVUTIL_VERSION_MINOR  33
-#define LIBAVUTIL_VERSION_MICRO 100
+#define LIBAVUTIL_VERSION_MICRO 101
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                LIBAVUTIL_VERSION_MINOR, \

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

Reply via email to