[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