[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