[vlc-commits] [Git][videolan/vlc][3.0.x] 4 commits: amf_helper: add a macro to add namespace when using C++

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Jun 2 07:23:38 UTC 2024



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
bfb2084a by Steve Lhomme at 2024-05-30T09:03:41+02:00
amf_helper: add a macro to add namespace when using C++

(cherry picked from commit 7bde5ce851f21b2a3223afe46f6692a07800f66c)

- - - - -
0b65cc7f by Steve Lhomme at 2024-05-30T09:04:20+02:00
amf_helper: share DXGIToAMF()

(cherry picked from commit 957db11f12c04a2c7b2b459f71b56b4878009d5c)

- - - - -
2ab7be5d by Steve Lhomme at 2024-05-30T09:04:36+02:00
configure: detect AMD VQEnhancer.h

(cherry picked from commit 9815b7eb436aa59772e59ef63c40bb5e81590883)

- - - - -
b351cccc by Steve Lhomme at 2024-05-30T09:04:50+02:00
video_filter: add AMD VQ Enhancer filter

(cherry picked from commit 4125ad5a96a48af7007439df74aec158ad8ad73b)

- - - - -


7 changed files:

- configure.ac
- modules/hw/amf/amf_helper.h
- modules/hw/d3d11/Makefile.am
- modules/hw/d3d11/d3d11_filters.c
- modules/hw/d3d11/d3d11_filters.h
- + modules/video_filter/amf_vqenhancer.c
- modules/video_output/win32/d3d11_scaler.cpp


Changes:

=====================================
configure.ac
=====================================
@@ -1824,7 +1824,7 @@ You can get an updated one from http://www.live555.com/liveMedia .])
         other_libs="$other_libs -lws2_32"
       ])
 
-      dnl We need to check for pic because live555 don't provide shared libs
+      dnl We need to check for pic because live555 do not provide shared libs
       dnl and we want to build a plugins so we need -fPIC on some arch.
       VLC_ADD_CXXFLAGS([live555], [${CPPFLAGS_live555}])
       VLC_ADD_LDFLAGS([live555], [${LDFLAGS_live555}])
@@ -1945,7 +1945,7 @@ dnl
 dnl  AMD Advanced Media Framework API
 dnl
 AC_ARG_ENABLE([amf-scaler], AS_HELP_STRING([--disable-amf-scaler],
-  [disable AMD AMF API (default auto)]))
+  [disable AMD Scaler API (default auto)]))
 have_amf_scaler="no"
 AS_IF([test "$enable_amf_scaler" != "no"], [
   AC_CHECK_HEADERS([AMF/core/PropertyStorage.h AMF/components/HQScaler.h], [
@@ -1955,6 +1955,17 @@ AS_IF([test "$enable_amf_scaler" != "no"], [
 ])
 AM_CONDITIONAL([HAVE_AMF_SCALER], [test "${have_amf_scaler}" != "no"])
 
+AC_ARG_ENABLE([amf-enhancer], AS_HELP_STRING([--disable-amf-enhancer],
+  [disable AMD Enhancer API (default auto)]))
+have_amf_enhancer="no"
+AS_IF([test "$enable_amf_enhancer" != "no"], [
+  AC_CHECK_HEADERS([AMF/core/PropertyStorage.h AMF/components/VQEnhancer.h], [
+    have_amf_enhancer="yes"
+    AC_DEFINE(HAVE_AMF_ENHANCER, 1, AMD VQ Enhancer supported)
+  ])
+])
+AM_CONDITIONAL([HAVE_AMF_ENHANCER], [test "${have_amf_enhancer}" != "no"])
+
 dnl
 dnl special access module for Blackmagic SDI cards
 dnl


=====================================
modules/hw/amf/amf_helper.h
=====================================
@@ -11,25 +11,46 @@
 #include <AMF/core/Context.h>
 #include <AMF/core/Factory.h>
 
+#ifdef _WIN32
+#include "../../video_chroma/d3d11_fmt.h"
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-struct vlc_amf_context
-{
 #ifdef __cplusplus
-    amf::AMFFactory *pFactory;
-    amf::AMFContext *Context;
+#define AMT_TYPE(t)  amf::t
 #else
-    AMFFactory      *pFactory;
-    AMFContext      *Context;
+#define AMT_TYPE(t)  t
 #endif
+
+struct vlc_amf_context
+{
+    AMT_TYPE(AMFFactory) *pFactory;
+    AMT_TYPE(AMFContext) *Context;
     void            *Private;
 };
 
 int vlc_AMFCreateContext(struct vlc_amf_context *);
 void vlc_AMFReleaseContext(struct vlc_amf_context *);
 
+#ifdef _WIN32
+static inline AMT_TYPE(AMF_SURFACE_FORMAT) DXGIToAMF(DXGI_FORMAT fmt)
+{
+    switch (fmt)
+    {
+        case DXGI_FORMAT_NV12: return AMT_TYPE(AMF_SURFACE_NV12);
+        case DXGI_FORMAT_P010: return AMT_TYPE(AMF_SURFACE_P010);
+        case DXGI_FORMAT_P016: return AMT_TYPE(AMF_SURFACE_P016);
+        case DXGI_FORMAT_B8G8R8A8_UNORM: return AMT_TYPE(AMF_SURFACE_BGRA);
+        case DXGI_FORMAT_R8G8B8A8_UNORM: return AMT_TYPE(AMF_SURFACE_RGBA);
+        case DXGI_FORMAT_R10G10B10A2_UNORM: return AMT_TYPE(AMF_SURFACE_R10G10B10A2);
+        default: return AMT_TYPE(AMF_SURFACE_UNKNOWN);
+    }
+}
+#endif
+
 #ifdef __cplusplus
 } // extern "C"
 #endif


=====================================
modules/hw/d3d11/Makefile.am
=====================================
@@ -11,6 +11,11 @@ if HAVE_WINSTORE
 libdirect3d11_filters_plugin_la_LIBADD += -ld3d11
 endif
 
+if HAVE_AMF_ENHANCER
+libdirect3d11_filters_plugin_la_SOURCES += video_filter/amf_vqenhancer.c \
+    hw/amf/amf_helper.c hw/amf/amf_helper.h
+endif
+
 d3d11_LTLIBRARIES = $(LTLIBdirect3d11_filters)
 EXTRA_LTLIBRARIES += libdirect3d11_filters_plugin.la
 


=====================================
modules/hw/d3d11/d3d11_filters.c
=====================================
@@ -665,6 +665,13 @@ vlc_module_begin()
     set_callbacks( D3D11OpenDeinterlace, D3D11CloseDeinterlace )
     add_shortcut ("deinterlace")
 
+#ifdef HAVE_AMF_ENHANCER
+    add_submodule()
+    set_description(N_("AMD VQ Enhancer"))
+    add_shortcut(N_("amf_vqenhancer"))
+    set_callbacks( D3D11CreateAMFVQE, D3D11CloseAMFVQE )
+#endif
+
     add_submodule()
     set_capability( "video converter", 10 )
     set_callbacks( D3D11OpenConverter, D3D11CloseConverter )


=====================================
modules/hw/d3d11/d3d11_filters.h
=====================================
@@ -33,6 +33,8 @@ int  D3D11OpenConverter(vlc_object_t *);
 void D3D11CloseConverter(vlc_object_t *);
 int  D3D11OpenCPUConverter(vlc_object_t *);
 void D3D11CloseCPUConverter(vlc_object_t *);
+int  D3D11CreateAMFVQE(vlc_object_t *);
+void D3D11CloseAMFVQE(vlc_object_t *);
 
 void D3D11_FilterHoldInstance(filter_t *, d3d11_device_t *, D3D11_TEXTURE2D_DESC *);
 void D3D11_FilterReleaseInstance(d3d11_device_t *);


=====================================
modules/video_filter/amf_vqenhancer.c
=====================================
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*****************************************************************************
+ * amf_vqenhancer: Enhance video with low bitrates
+ *****************************************************************************
+ * Copyright © 2024 Videolabs, VLC authors and VideoLAN
+ *
+ * Authors: Steve Lhomme <robux4 at videolabs.io>
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_filter.h>
+#include <vlc_plugin.h>
+
+#define COBJMACROS
+#include "../hw/amf/amf_helper.h"
+#include <AMF/components/VQEnhancer.h>
+
+#include "../video_chroma/d3d11_fmt.h"
+#include "../hw/d3d11/d3d11_filters.h"
+
+#include <assert.h>
+
+struct filter_sys_t
+{
+    d3d11_handle_t                 hd3d;
+    d3d11_device_t                 d3d_dev;
+    struct vlc_amf_context         amf;
+    AMFComponent                   *amf_vqe;
+    AMFSurface                     *amfInput;
+    const d3d_format_t             *cfg;
+};
+
+static picture_t *PictureFromTexture(filter_t *filter, d3d11_device_t *d3d_dev, ID3D11Texture2D *out)
+{
+    struct filter_sys_t *sys = filter->p_sys;
+
+    picture_t *p_outpic = filter_NewPicture( filter );
+    if( !p_outpic )
+    {
+        return NULL;
+    }
+    picture_sys_t *src_sys = ActivePictureSys(p_outpic);
+    if (unlikely(!src_sys))
+    {
+        /* the output filter configuration may have changed since the filter
+         * was opened */
+        picture_Release(p_outpic);
+        return NULL;
+    }
+
+    d3d11_device_lock( d3d_dev );
+    ID3D11DeviceContext_CopySubresourceRegion(src_sys->context,
+                                              src_sys->resource[KNOWN_DXGI_INDEX],
+                                              src_sys->slice_index,
+                                              0, 0, 0,
+                                              (ID3D11Resource*)out,
+                                              0,
+                                              NULL);
+    d3d11_device_unlock( d3d_dev );
+    return p_outpic;
+}
+
+static picture_t * Filter(filter_t *filter, picture_t *p_pic)
+{
+    struct filter_sys_t *sys = filter->p_sys;
+
+    picture_sys_t *src_sys = ActivePictureSys(p_pic);
+
+    AMF_RESULT res;
+    AMFSurface *submitSurface;
+
+    AMFPlane *packedStaging = sys->amfInput->pVtbl->GetPlane(sys->amfInput, AMF_PLANE_PACKED);
+    ID3D11Resource *amfStaging = packedStaging->pVtbl->GetNative(packedStaging);
+
+#ifndef NDEBUG
+    ID3D11Texture2D *staging = (ID3D11Texture2D *)amfStaging;
+    D3D11_TEXTURE2D_DESC stagingDesc, inputDesc;
+    ID3D11Texture2D_GetDesc(staging, &stagingDesc);
+    ID3D11Texture2D_GetDesc(src_sys->texture[KNOWN_DXGI_INDEX], &inputDesc);
+    assert(stagingDesc.Width == inputDesc.Width);
+    assert(stagingDesc.Height == inputDesc.Height);
+    assert(stagingDesc.Format == inputDesc.Format);
+#endif
+
+    struct filter_sys_t *dev_sys = sys;
+
+#if 0
+    if (src_sys->slice_index == 0)
+    sys->amf.Context->pVtbl->CreateSurfaceFromDX11Native(sys->amf.Context, )
+#endif
+    // copy source into staging as it may not be shared and we can't select a slice
+    d3d11_device_lock( &dev_sys->d3d_dev );
+    ID3D11DeviceContext_CopySubresourceRegion(src_sys->context, amfStaging,
+                                            0,
+                                            0, 0, 0,
+                                            src_sys->resource[KNOWN_DXGI_INDEX],
+                                            src_sys->slice_index,
+                                            NULL);
+    d3d11_device_unlock( &dev_sys->d3d_dev );
+    submitSurface = sys->amfInput;
+
+    res = sys->amf_vqe->pVtbl->SubmitInput(sys->amf_vqe, (AMFData*)submitSurface);
+    if (res == AMF_INPUT_FULL)
+    {
+        msg_Dbg(filter, "filter input full, skip this frame");
+        return p_pic;
+    }
+    if (res != AMF_OK)
+    {
+        msg_Err(filter, "filter input failed (err=%d)", res);
+        return p_pic;
+    }
+
+    AMFData *amfOutput = NULL;
+    res = sys->amf_vqe->pVtbl->QueryOutput(sys->amf_vqe, &amfOutput);
+    if (res != AMF_OK)
+    {
+        msg_Err(filter, "filter gave no output (err=%d)", res);
+        return p_pic;
+    }
+
+    AMFSurface *amfOutputSurface = (AMFSurface*)amfOutput;
+    AMFPlane *packed = amfOutputSurface->pVtbl->GetPlane(amfOutputSurface, AMF_PLANE_PACKED);
+
+    assert(amfOutput->pVtbl->GetMemoryType(amfOutput) == AMF_MEMORY_DX11);
+    ID3D11Texture2D *out = packed->pVtbl->GetNative(packed);
+    picture_t *dst = PictureFromTexture(filter, &dev_sys->d3d_dev, out);
+    amfOutput->pVtbl->Release(amfOutput);
+    if (dst == NULL)
+        return p_pic;
+
+    picture_CopyProperties(dst, p_pic);
+    picture_Release(p_pic);
+    return dst;
+}
+
+void D3D11CloseAMFVQE(vlc_object_t *p_this)
+{
+    filter_t *filter = container_of(p_this, filter_t, obj);
+    struct filter_sys_t *sys = filter->p_sys;
+    sys->amfInput->pVtbl->Release(sys->amfInput);
+    sys->amf_vqe->pVtbl->Release(sys->amf_vqe);
+    if (sys->d3d_dev.d3dcontext)
+        D3D11_FilterReleaseInstance(&sys->d3d_dev);
+    D3D11_Destroy(&sys->hd3d);
+}
+
+int D3D11CreateAMFVQE(vlc_object_t *p_this)
+{
+    filter_t *filter = container_of(p_this, filter_t, obj);
+    if (!is_d3d11_opaque(filter->fmt_in.video.i_chroma))
+        return VLC_EGENERIC;
+    if (!video_format_IsSimilar(&filter->fmt_in.video, &filter->fmt_out.video))
+        return VLC_EGENERIC;
+
+    struct filter_sys_t *sys = vlc_obj_calloc(VLC_OBJECT(filter), 1, sizeof(*sys));
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
+
+    if ( unlikely(D3D11_Create(filter, &sys->hd3d, false) != VLC_SUCCESS ))
+    {
+       msg_Err(filter, "Could not access the d3d11.");
+       goto error;
+    }
+
+    D3D11_TEXTURE2D_DESC dstDesc;
+    D3D11_FilterHoldInstance(filter, &sys->d3d_dev, &dstDesc);
+    if (unlikely(sys->d3d_dev.d3dcontext==NULL))
+    {
+        msg_Dbg(filter, "Filter without a context");
+        return VLC_ENOOBJ;
+    }
+
+    DXGI_FORMAT input_format = dstDesc.Format;
+    const d3d_format_t *cfg;
+    for (cfg = GetRenderFormatList(); cfg->name != NULL; ++cfg)
+    {
+        if (cfg->formatTexture == input_format &&
+            is_d3d11_opaque(cfg->fourcc))
+            break;
+    }
+    assert(cfg != NULL);
+
+    AMF_SURFACE_FORMAT amf_fmt = DXGIToAMF(input_format);
+    if (amf_fmt == AMF_SURFACE_UNKNOWN)
+    {
+        msg_Err(filter, "Unsupported DXGI format %s", cfg->name);
+        return VLC_EGENERIC;
+    }
+
+    struct filter_sys_t *dev_sys = sys;
+
+    HRESULT hr;
+    HANDLE context_lock = INVALID_HANDLE_VALUE;
+    UINT dataSize = sizeof(context_lock);
+    hr = ID3D11DeviceContext_GetPrivateData(sys->d3d_dev.d3dcontext, &GUID_CONTEXT_MUTEX, &dataSize, &context_lock);
+    if (FAILED(hr))
+        msg_Warn(filter, "No mutex found to lock the decoder");
+    sys->d3d_dev.context_mutex = context_lock;
+
+    int err = vlc_AMFCreateContext(&sys->amf);
+    if (err != VLC_SUCCESS)
+        return err;
+
+    AMF_RESULT res;
+    res = sys->amf.Context->pVtbl->InitDX11(sys->amf.Context, dev_sys->d3d_dev.d3ddevice, AMF_DX11_0);
+    if (res != AMF_OK)
+        goto error;
+
+    res = sys->amf.pFactory->pVtbl->CreateComponent(sys->amf.pFactory, sys->amf.Context, AMFVQEnhancer, &sys->amf_vqe);
+    if (res != AMF_OK || sys->amf_vqe == NULL)
+        goto error;
+
+#if 0
+    AMFVariantStruct val;
+    val.int64Value = AMF_MEMORY_DX11;
+    val.type = AMF_VARIANT_INT64;
+    res = sys->amf_vqe->pVtbl->SetProperty(sys->amf_vqe, AMF_VIDEO_ENHANCER_ENGINE_TYPE, val);
+    if (res != AMF_OK)
+        goto error;
+
+#if 0 // this parameter doesn't exist
+    val.sizeValue = AMFConstructSize(filter->fmt_in.video.i_width, filter->fmt_in.video.i_height);
+    val.type = AMF_VARIANT_SIZE;
+    res = sys->amf_vqe->pVtbl->SetProperty(sys->amf_vqe, AMF_VIDEO_ENHANCER_OUTPUT_SIZE, val);
+    if (res != AMF_OK)
+        goto error;
+#endif
+
+#if 0 // debug test
+    val.boolValue = 1;
+    val.type = AMF_VARIANT_BOOL;
+    res = sys->amf_vqe->pVtbl->SetProperty(sys->amf_vqe, AMF_VE_FCR_SPLIT_VIEW, val);
+    if (res != AMF_OK)
+        goto error;
+#endif
+#endif
+
+    res = sys->amf_vqe->pVtbl->Init(sys->amf_vqe, amf_fmt,
+                                    filter->fmt_in.video.i_width,
+                                    filter->fmt_in.video.i_height);
+    if (res != AMF_OK)
+        goto error;
+
+    res = sys->amf.Context->pVtbl->AllocSurface(sys->amf.Context, AMF_MEMORY_DX11,
+                                                amf_fmt,
+                                                filter->fmt_in.video.i_width,
+                                                filter->fmt_in.video.i_height,
+                                                &sys->amfInput);
+    if (res != AMF_OK)
+        goto error;
+
+    sys->cfg = cfg;
+    filter->pf_video_filter = Filter;
+    filter->p_sys = sys;
+
+    return VLC_SUCCESS;
+error:
+    if (sys->d3d_dev.d3dcontext)
+        D3D11_FilterReleaseInstance(&sys->d3d_dev);
+    if (sys->amfInput)
+        sys->amfInput->pVtbl->Release(sys->amfInput);
+    if (sys->amf_vqe != NULL)
+        sys->amf_vqe->pVtbl->Release(sys->amf_vqe);
+    vlc_AMFReleaseContext(&sys->amf);
+    D3D11_Destroy(&sys->hd3d);
+    return VLC_EGENERIC;
+}


=====================================
modules/video_output/win32/d3d11_scaler.cpp
=====================================
@@ -19,20 +19,6 @@
 #ifdef HAVE_AMF_SCALER
 #include "../../hw/amf/amf_helper.h"
 #include <AMF/components/HQScaler.h>
-
-amf::AMF_SURFACE_FORMAT DXGIToAMF(DXGI_FORMAT fmt)
-{
-    switch (fmt)
-    {
-        case DXGI_FORMAT_NV12: return amf::AMF_SURFACE_NV12;
-        case DXGI_FORMAT_P010: return amf::AMF_SURFACE_P010;
-        case DXGI_FORMAT_P016: return amf::AMF_SURFACE_P016;
-        case DXGI_FORMAT_B8G8R8A8_UNORM: return amf::AMF_SURFACE_BGRA;
-        case DXGI_FORMAT_R8G8B8A8_UNORM: return amf::AMF_SURFACE_RGBA;
-        case DXGI_FORMAT_R10G10B10A2_UNORM: return amf::AMF_SURFACE_R10G10B10A2;
-        default: return amf::AMF_SURFACE_UNKNOWN;
-    }
-}
 #endif
 
 #include <new>



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6ceb56b8306e5e2eec58414e22b3589afdc093d8...b351ccccc41b5807b93579614b0eb1d9ad86ce6e

-- 
This project does not include diff previews in email notifications.
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6ceb56b8306e5e2eec58414e22b3589afdc093d8...b351ccccc41b5807b93579614b0eb1d9ad86ce6e
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