[vlc-commits] [Git][videolan/vlc][master] 5 commits: amf_helper: add a macro to add namespace when using C++

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu May 30 06:48:24 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
7bde5ce8 by Steve Lhomme at 2024-05-30T06:15:46+00:00
amf_helper: add a macro to add namespace when using C++

- - - - -
957db11f by Steve Lhomme at 2024-05-30T06:15:46+00:00
amf_helper: share DXGIToAMF()

- - - - -
d068a0a3 by Steve Lhomme at 2024-05-30T06:15:46+00:00
configure: edit comment on live555

This fixes the M4 parsing in VSCode at no cost for VLC.

- - - - -
9815b7eb by Steve Lhomme at 2024-05-30T06:15:46+00:00
configure: detect AMD VQEnhancer.h

- - - - -
4125ad5a by Steve Lhomme at 2024-05-30T06:15:46+00:00
video_filter: add AMD VQ Enhancer filter

- - - - -


5 changed files:

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


Changes:

=====================================
configure.ac
=====================================
@@ -2072,7 +2072,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 does 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}])
@@ -2188,7 +2188,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], [
@@ -2198,6 +2198,16 @@ 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"
+  ])
+])
+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/video_filter/Makefile.am
=====================================
@@ -218,6 +218,18 @@ libpostproc_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(video_filterdir)'
 video_filter_LTLIBRARIES += $(LTLIBpostproc)
 EXTRA_LTLIBRARIES += libpostproc_plugin.la
 
+if HAVE_AMF_ENHANCER
+libamf_vqenhancer_plugin_la_SOURCES = video_filter/amf_vqenhancer.c \
+    hw/amf/amf_helper.c hw/amf/amf_helper.h
+if HAVE_WIN32
+libamf_vqenhancer_plugin_la_LIBADD = $(LIBCOM) libd3d11_common.la
+if HAVE_WINSTORE
+libamf_vqenhancer_plugin_la_LIBADD += -ld3d11
+endif
+video_filter_LTLIBRARIES += libamf_vqenhancer_plugin.la
+endif
+endif
+
 # misc
 libblend_plugin_la_SOURCES = video_filter/blend.cpp
 video_filter_LTLIBRARIES += libblend_plugin.la


=====================================
modules/video_filter/amf_vqenhancer.c
=====================================
@@ -0,0 +1,262 @@
+// 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 <assert.h>
+
+struct filter_sys_t
+{
+    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;
+
+    struct d3d11_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
+    if (unlikely(pic_ctx == NULL))
+        return NULL;
+
+    picture_resource_t dummy_res = { .p_sys = NULL };
+    picture_t *p_dst = picture_NewFromResource(&filter->fmt_out.video, &dummy_res);
+    if (p_dst == NULL) {
+        msg_Err(filter, "Failed to map create the temporary picture.");
+        goto done;
+    }
+    p_dst->context = &pic_ctx->s;
+
+    D3D11_PictureAttach(p_dst, out, sys->cfg);
+
+    if (unlikely(D3D11_AllocateResourceView(vlc_object_logger(filter), d3d_dev->d3ddevice, sys->cfg,
+                                            pic_ctx->picsys.texture, 0, pic_ctx->picsys.renderSrc) != VLC_SUCCESS))
+        goto done;
+
+    pic_ctx->s = (picture_context_t) {
+        d3d11_pic_context_destroy, d3d11_pic_context_copy,
+        vlc_video_context_Hold(filter->vctx_out),
+    };
+    pic_ctx->picsys.sharedHandle = INVALID_HANDLE_VALUE;
+
+    return p_dst;
+done:
+    if (p_dst != NULL)
+        picture_Release(p_dst);
+    free(pic_ctx);
+    return NULL;
+}
+
+static picture_t * Filter(filter_t *filter, picture_t *p_pic)
+{
+    struct filter_sys_t *sys = filter->p_sys;
+
+    picture_sys_d3d11_t *src_sys = ActiveD3D11PictureSys(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
+
+    d3d11_decoder_device_t *dev_sys = GetD3D11OpaqueContext( filter->vctx_in );
+
+#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(dev_sys->d3d_dev.d3dcontext, 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;
+}
+
+static void D3D11CloseAMFVQE(filter_t *filter)
+{
+    struct filter_sys_t *sys = filter->p_sys;
+    sys->amfInput->pVtbl->Release(sys->amfInput);
+    sys->amf_vqe->pVtbl->Release(sys->amf_vqe);
+    vlc_video_context_Release(filter->vctx_out);
+}
+
+static int D3D11CreateAMFVQE(filter_t *filter)
+{
+    if (!is_d3d11_opaque(filter->fmt_in.video.i_chroma))
+        return VLC_EGENERIC;
+    if ( GetD3D11ContextPrivate(filter->vctx_in) == NULL )
+        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;
+
+    d3d11_video_context_t *vctx_sys = GetD3D11ContextPrivate( filter->vctx_in );
+    DXGI_FORMAT input_format = vctx_sys->format;
+    const d3d_format_t *cfg;
+    for (cfg = DxgiGetRenderFormatList(); 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;
+    }
+
+    d3d11_decoder_device_t *dev_sys = GetD3D11OpaqueContext( filter->vctx_in );
+
+    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;
+    static const struct vlc_filter_operations filter_ops =
+    {
+        .filter_video = Filter,
+        .close = D3D11CloseAMFVQE,
+    };
+    filter->ops = &filter_ops;
+    filter->p_sys = sys;
+    filter->vctx_out = vlc_video_context_Hold(filter->vctx_in);
+
+    return VLC_SUCCESS;
+error:
+    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);
+    return VLC_EGENERIC;
+}
+
+vlc_module_begin()
+    set_description(N_("AMD VQ Enhancer"))
+    add_shortcut(N_("amf_vqenhancer"))
+    set_subcategory(SUBCAT_VIDEO_VFILTER)
+    set_callback_video_filter(D3D11CreateAMFVQE)
+vlc_module_end()


=====================================
modules/video_output/win32/d3d11_scaler.cpp
=====================================
@@ -18,20 +18,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/f84661975a8aea699d1b433ef80d92750e933763...4125ad5a96a48af7007439df74aec158ad8ad73b

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