[vlc-commits] [Git][videolan/vlc][3.0.x] 19 commits: contrib: add AMF package to enable AMF encoder in FFMPEG

Steve Lhomme (@robUx4) gitlab at videolan.org
Sat Feb 24 07:14:09 UTC 2024



Steve Lhomme pushed to branch 3.0.x at VideoLAN / VLC


Commits:
81aa273a by Steve Lhomme at 2024-02-24T06:24:03+00:00
contrib: add AMF package to enable AMF encoder in FFMPEG

(cherry picked from commit f1a2665f609d9d5bd7e662a8a2519018e1d3f61c)

- - - - -
33071b3a by Steve Lhomme at 2024-02-24T06:24:03+00:00
contrib: update AMF package to v1.4.29

(cherry picked from commit 47b62224d5847841a5651bac7ff8eee1b717b7c9)

- - - - -
d35919dd by Steve Lhomme at 2024-02-24T06:24:03+00:00
contrib: amf: update to 1.4.30 using git

It's faster to get the files from git and compress than downloading
the 400 MB+ package.

We don't use download_git which downloads the whole git history of the
given branch. We use git clone and a sparse checkout to only get the
folder we want for the giant repository.

(cherry picked from commit 7cfdd439b9ba299606456a62de15b144201176c9)

- - - - -
ac42dea9 by Steve Lhomme at 2024-02-24T06:24:03+00:00
contrib/amf: ensure to touch .sum-amf when the git hash check is successful

(cherry picked from commit cba3cbaa764887b2a68dc359ae82a0261a2d8240)

- - - - -
02bc0cf4 by Steve Lhomme at 2024-02-24T06:24:03+00:00
contrib: amf: update to 1.4.33

It contains the HQScaler

(cherry picked from commit 86c2cf55a55904917225df465075634e0482690e)

- - - - -
ebce27ec by Steve Lhomme at 2024-02-24T06:24:03+00:00
contrib: amf: fix compilation errors and warnings

Patchsets sent upstream:

- https://github.com/GPUOpen-LibrariesAndSDKs/AMF/pull/448
- https://github.com/GPUOpen-LibrariesAndSDKs/AMF/pull/449
- https://github.com/GPUOpen-LibrariesAndSDKs/AMF/pull/450
- https://github.com/GPUOpen-LibrariesAndSDKs/AMF/pull/451
- https://github.com/GPUOpen-LibrariesAndSDKs/AMF/pull/452

(cherry picked from commit d0c4704681541f205a38fc4a72ce01a0c61a982a)

- - - - -
edc77c8b by Steve Lhomme at 2024-02-24T06:24:03+00:00
configure: detect AMD HQScaler

(cherry picked from commit 803499c569ae8292bd924588f73f85c7cdf62fc1)

- - - - -
0e88576b by Steve Lhomme at 2024-02-24T06:24:03+00:00
hw/amf: add a helper to create an AMFContext

(cherry picked from commit 6f1ec768063bb8f93aeb14f23d26a4ce206c5daf) (edited)
edited:
- 3.0 doesn't have VLC_ENOTSUP

- - - - -
f6e0f7f0 by Steve Lhomme at 2024-02-24T06:24:03+00:00
dxgi_fmt: allow include from C++

Part of 6b7a6d86ae30109bed34fec0b5ffc1f013ca4a81 on 4.0.

- - - - -
a3595dc6 by Steve Lhomme at 2024-02-24T06:24:03+00:00
d3d11_scaler: add AMD HQScaler support

(cherry picked from commit ffd3f0e70a1b61d9d919387fa14558c1d4bf7881) (edited)
edited:
- 3.0 doesn't have nvdec support in D3D11
- 3.0 use D3D11_MAX_SHADER_VIEW rather than DXGI_MAX_SHADER_VIEW
- 3.0 needs assert.h

- - - - -
9b1ba53a by Steve Lhomme at 2024-02-24T06:24:03+00:00
d3d11_quad: reset the ShaderResources as soon as drawing with it is done

This may help with performance and avoid an issue when the render target is
also an input texture for another pipeline.

(cherry picked from commit cf5e665e47762bc793b87088e7edc235d4b228d2) (edited)
edited:
- on 3.0 we don't render multiple planes in this call

- - - - -
5f716112 by Steve Lhomme at 2024-02-24T06:24:03+00:00
d3d11_scaler: only recreate the HQ Scaler texture

(cherry picked from commit 2841b79dfb63a7c9b1be38cabfa56baf9f96c03f)

- - - - -
4e65d6f5 by Steve Lhomme at 2024-02-24T06:24:03+00:00
d3d11_scaler: allocate the HQ Scaler input texture with AMF API

No need to manage an extra variable, and that makes the code more generic.

(cherry picked from commit 27391019a86f2152608ff8897ff4969a1caf9702)

- - - - -
bb20e550 by Steve Lhomme at 2024-02-24T06:24:03+00:00
d3d11_scaler: report AMF errors

(cherry picked from commit e17246c5c0c9502f1d01f621d3892bcda9ce9170)

- - - - -
41a94606 by Steve Lhomme at 2024-02-24T06:24:03+00:00
d3d11_scaler: only (re)init the HQ Scaler when the output size changes

D3D11_UpscalerUpdate() is mostly called in those cases, but it's cleaner.

(cherry picked from commit 43c44f303e9a1335688e89a0b13ddf2b13fba6d5)

- - - - -
32e0f4e8 by Steve Lhomme at 2024-02-24T06:24:03+00:00
d3d11_scaler: just reinit AMF when the scaler was already initialized

(cherry picked from commit 21f2fb900ec6d0899035dea57625c56ae99d4bdf)

- - - - -
d468ec7f by Steve Lhomme at 2024-02-24T06:24:03+00:00
d3d11_scaler: ensure the AMF input/output textures matches the scaler sizes

(cherry picked from commit ef640c8b63b4ffb224faf2161dd23e40bdc0fd3b)

- - - - -
066d5b72 by Steve Lhomme at 2024-02-24T06:24:03+00:00
NEWS: add AMD Super Resolution support in 3.0.21

- - - - -
9acdb3ad by Steve Lhomme at 2024-02-24T06:24:03+00:00
contrib: AMF: improve sparse checkout

git sparse-checkout was only added in 2.25 (2020) [1]. Older git (1.7+) can
handle a sparse checkout setting the .git/info/sparse-checkout data.

We also clone with --filter=blob:none --no-checkout which downloads less from the host.

[1] https://stackoverflow.com/a/13738951

(cherry picked from commit f787acf2587de1e8b5968f8b68b931ab659e9f01) (edited)
edited:
- remove --fitler as it's not supported in git 2.11.0 used by 3.0 Dockers

- - - - -


18 changed files:

- NEWS
- configure.ac
- + contrib/src/amf/0001-Differentiate-the-AMF_NO_VTABLE-based-on-the-compile.patch
- + contrib/src/amf/0001-Don-t-cast-amf_int64-when-using-a-format-string.patch
- + contrib/src/amf/0001-Fix-const-on-return-by-value-AMF_DECLARE_IID.patch
- + contrib/src/amf/0001-Fix-warning-when-_MSC_VER-is-not-defined.patch
- + contrib/src/amf/0001-Move-AMF_UNICODE-into-Platform.h.patch
- + contrib/src/amf/0002-Define-LPRI-d-ud-x-64-as-Unicode-wide-versions-of-AM.patch
- + contrib/src/amf/0002-Fix-const-on-return-by-value-Variant-values.patch
- + contrib/src/amf/0003-Define-AMFPRI-d-ud-x-64-using-the-standard-C-format-.patch
- + contrib/src/amf/SHA512SUMS
- + contrib/src/amf/rules.mak
- + modules/hw/amf/amf_helper.c
- + modules/hw/amf/amf_helper.h
- modules/video_chroma/dxgi_fmt.h
- modules/video_output/Makefile.am
- modules/video_output/win32/d3d11_quad.c
- modules/video_output/win32/d3d11_scaler.cpp


Changes:

=====================================
NEWS
=====================================
@@ -5,6 +5,9 @@ Decoders:
  - Improve Opus ambisonic support
  - Fix some ASS subtitle rendering issues
 
+Video Output:
+ * Super Resolution scaling with AMD GPUs
+
 Audio Output:
  - Fix regression on macOS causing crashes when using audio devices
    with more than 9 channels


=====================================
configure.ac
=====================================
@@ -1941,6 +1941,20 @@ AS_IF([test "$enable_v4l2" != "no"], [
 ])
 AM_CONDITIONAL(HAVE_V4L2, [test "${have_v4l2}" != "no"])
 
+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)]))
+have_amf_scaler="no"
+AS_IF([test "$enable_amf_scaler" != "no"], [
+  AC_CHECK_HEADERS([AMF/core/PropertyStorage.h AMF/components/HQScaler.h], [
+    have_amf_scaler="yes"
+    AC_DEFINE(HAVE_AMF_SCALER, 1, AMD HQScaler supported)
+  ])
+])
+AM_CONDITIONAL([HAVE_AMF_SCALER], [test "${have_amf_scaler}" != "no"])
+
 dnl
 dnl special access module for Blackmagic SDI cards
 dnl


=====================================
contrib/src/amf/0001-Differentiate-the-AMF_NO_VTABLE-based-on-the-compile.patch
=====================================
@@ -0,0 +1,47 @@
+From cf190d084644d3d3e2ea1ffbb740ad8e7aede760 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Fri, 16 Feb 2024 08:18:19 +0100
+Subject: [PATCH] Differentiate the AMF_NO_VTABLE based on the compiler
+
+This is a Microsoft specific extension: https://learn.microsoft.com/en-us/cpp/cpp/novtable
+Clang and gcc can compile for Windows but don't support this.
+---
+ amf/public/include/core/Platform.h | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/amf/public/include/core/Platform.h b/amf/public/include/core/Platform.h
+index d6496d4..378f789 100644
+--- a/amf/public/include/core/Platform.h
++++ b/amf/public/include/core/Platform.h
+@@ -100,6 +100,12 @@ typedef signed int HRESULT;
+ #include <stdint.h>
+ #include <string.h>
+ 
++#if defined(_MSC_VER)
++    #define AMF_NO_VTABLE           __declspec(novtable)
++#else
++    #define AMF_NO_VTABLE
++#endif
++
+ #if defined(_WIN32)
+ 
+ 
+@@ -116,7 +122,6 @@ typedef signed int HRESULT;
+     #define AMF_INLINE              __inline
+     #define AMF_FORCEINLINE         __forceinline
+ #endif
+-    #define AMF_NO_VTABLE           __declspec(novtable)
+ 
+ #else // !WIN32 - Linux and Mac
+ 
+@@ -130,7 +135,6 @@ typedef signed int HRESULT;
+     #define AMF_INLINE              __inline__
+     #define AMF_FORCEINLINE         __inline__
+ #endif
+-    #define AMF_NO_VTABLE
+ 
+ #endif // WIN32
+ 
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/amf/0001-Don-t-cast-amf_int64-when-using-a-format-string.patch
=====================================
@@ -0,0 +1,34 @@
+From e5498eb5e82c54c93fdd56127a8bb6dc96961e46 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Fri, 16 Feb 2024 08:05:13 +0100
+Subject: [PATCH] Don't cast amf_int64 when using a format string
+
+The format string is designed to match amf_int64.
+---
+ amf/public/include/core/Variant.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/amf/public/include/core/Variant.h b/amf/public/include/core/Variant.h
+index edf14ae..a44fbf5 100644
+--- a/amf/public/include/core/Variant.h
++++ b/amf/public/include/core/Variant.h
+@@ -872,14 +872,14 @@ namespace amf
+     {
+         res = AMF_OK;
+         char buff[0xFF];
+-        sprintf(buff, "%" AMFPRId64, (long long)value);
++        sprintf(buff, "%" AMFPRId64, value);
+         return buff;
+     }
+     static AMF_INLINE AMFVariant::WString AMFConvertInt64ToWString(amf_int64 value, AMF_RESULT& res)
+     {
+         res = AMF_OK;
+         wchar_t buff[0xFF];
+-        swprintf(buff, 0xFF, L"%" LPRId64, (long long)value);
++        swprintf(buff, 0xFF, L"%" LPRId64, value);
+         return buff;
+     }
+ 
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/amf/0001-Fix-const-on-return-by-value-AMF_DECLARE_IID.patch
=====================================
@@ -0,0 +1,29 @@
+From 17cc77f3185ca562c7c0aa4e439c8f4bace1360a Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Fri, 16 Feb 2024 08:12:20 +0100
+Subject: [PATCH 1/2] Fix const on return by value AMF_DECLARE_IID()
+
+The returned value won't be const in C.
+
+Fixes this kind of warning:
+include/AMF/core/../components/Component.h:326:5: warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers]
+---
+ amf/public/include/core/Interface.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/amf/public/include/core/Interface.h b/amf/public/include/core/Interface.h
+index 9ac7e41..96117f0 100644
+--- a/amf/public/include/core/Interface.h
++++ b/amf/public/include/core/Interface.h
+@@ -49,7 +49,7 @@ namespace amf
+         }
+ #else
+ #define AMF_DECLARE_IID(name, _data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48) \
+-        AMF_INLINE static const AMFGuid IID_##name(void) \
++        AMF_INLINE static AMFGuid IID_##name(void) \
+         { \
+             AMFGuid uid = {_data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48}; \
+             return uid; \
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/amf/0001-Fix-warning-when-_MSC_VER-is-not-defined.patch
=====================================
@@ -0,0 +1,52 @@
+From 6c26950f67fb07550b86f3064fb0f7b7b53eec5d Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Fri, 16 Feb 2024 08:57:46 +0100
+Subject: [PATCH] Fix warning when _MSC_VER is not defined
+
+---
+ amf/public/include/core/Variant.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/amf/public/include/core/Variant.h b/amf/public/include/core/Variant.h
+index edf14ae..879f092 100644
+--- a/amf/public/include/core/Variant.h
++++ b/amf/public/include/core/Variant.h
+@@ -365,7 +365,7 @@ namespace amf
+             operator=(p_other);
+         }
+ 
+-#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600)
++#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (defined(_MSC_VER) && _MSC_VER >= 1600)
+ #pragma warning (push)
+ #pragma warning (disable : 26439) //This kind of function may not throw. Declare it 'noexcept'.
+         String(String&& p_other) : m_Str(nullptr)
+@@ -393,7 +393,7 @@ namespace amf
+             m_Str = AMFVariantDuplicateString(p_other.m_Str);
+             return *this;
+         }
+-#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600)
++#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (defined(_MSC_VER) && _MSC_VER >= 1600)
+         String& operator=(String&& p_other)
+         {
+             Free();
+@@ -475,7 +475,7 @@ namespace amf
+         {
+             operator=(p_other);
+         }
+-#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600)
++#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (defined(_MSC_VER) && _MSC_VER >= 1600)
+         WString(WString&& p_other) : m_Str(nullptr)
+         {
+             operator=(p_other);
+@@ -492,7 +492,7 @@ namespace amf
+             m_Str = AMFVariantDuplicateWString(p_other.m_Str);
+             return *this;
+         }
+-#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600)
++#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (defined(_MSC_VER) && _MSC_VER >= 1600)
+         WString& operator=(WString&& p_other)
+         {
+             Free();
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/amf/0001-Move-AMF_UNICODE-into-Platform.h.patch
=====================================
@@ -0,0 +1,38 @@
+From a9ee7691cf2535f58695769893e92a634f810523 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Fri, 16 Feb 2024 07:43:32 +0100
+Subject: [PATCH 1/4] Move AMF_UNICODE into Platform.h
+
+It's a common macro that can be used in other places.
+---
+ amf/public/include/core/Platform.h | 14 ++++++++++++++
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/amf/public/include/core/Platform.h b/amf/public/include/core/Platform.h
+index 3f997fe..cdab1b2 100644
+--- a/amf/public/include/core/Platform.h
++++ b/amf/public/include/core/Platform.h
+@@ -66,6 +66,20 @@
+ 
+ #define AMF_TODO(_todo) (__FILE__ "(" AMF_MACRO_STRING(__LINE__) "): TODO: "_todo)
+ 
++/**
++*******************************************************************************
++*   AMF_UNICODE
++*
++*   @brief
++*       Macro to convert string constant into wide char string constant
++*
++*   Auxilary AMF_UNICODE_ macro is needed as otherwise it is not possible to use AMF_UNICODE(__FILE__)
++*   Microsoft macro _T also uses 2 passes to accomplish that
++*******************************************************************************
++*/
++#define AMF_UNICODE(s) AMF_UNICODE_(s)
++#define AMF_UNICODE_(s) L ## s
++
+ 
+  #if defined(__GNUC__) || defined(__clang__)
+      #define AMF_ALIGN(n) __attribute__((aligned(n)))
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/amf/0002-Define-LPRI-d-ud-x-64-as-Unicode-wide-versions-of-AM.patch
=====================================
@@ -0,0 +1,54 @@
+From 7a0df0c174dce8d383be26e7b96d410865c62cf1 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Fri, 16 Feb 2024 07:45:25 +0100
+Subject: [PATCH 2/4] Define LPRI(d|ud|x)64 as Unicode (wide) versions of
+ AMFPRI(d|ud|x)64
+
+It's always true for all platforms.
+---
+ amf/public/include/core/Platform.h | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/amf/public/include/core/Platform.h b/amf/public/include/core/Platform.h
+index cdab1b2..12ee75c 100644
+--- a/amf/public/include/core/Platform.h
++++ b/amf/public/include/core/Platform.h
+@@ -119,13 +119,10 @@ typedef signed int HRESULT;
+     #define AMF_NO_VTABLE           __declspec(novtable)
+ 
+     #define AMFPRId64   "I64d"
+-    #define LPRId64    L"I64d"
+ 
+     #define AMFPRIud64   "Iu64d"
+-    #define LPRIud64    L"Iu64d"
+ 
+     #define AMFPRIx64   "I64x"
+-    #define LPRIx64    L"I64x"
+ 
+ #else // !WIN32 - Linux and Mac
+ 
+@@ -143,17 +140,18 @@ typedef signed int HRESULT;
+ 
+     #if !defined(AMFPRId64)
+         #define AMFPRId64    "lld"
+-        #define LPRId64     L"lld"
+ 
+         #define AMFPRIud64    "ulld"
+-        #define LPRIud64     L"ulld"
+ 
+         #define AMFPRIx64    "llx"
+-        #define LPRIx64     L"llx"
+     #endif
+ 
+ #endif // WIN32
+ 
++#define LPRId64   AMF_UNICODE(AMFPRId64)
++#define LPRIud64  AMF_UNICODE(AMFPRIud64)
++#define LPRIx64   AMF_UNICODE(AMFPRIx64)
++
+ 
+ #if defined(_WIN32)
+ #define AMF_WEAK __declspec( selectany )
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/amf/0002-Fix-const-on-return-by-value-Variant-values.patch
=====================================
@@ -0,0 +1,49 @@
+From 18c87b557f7d5b9f1850a66705b551ac482e47e3 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Fri, 16 Feb 2024 08:50:28 +0100
+Subject: [PATCH 2/2] Fix const on return by value Variant values
+
+Fix const on return by value AMF_DECLARE_IID()
+
+The returned value won't be const in C.
+
+Fixes this kind of warning:
+include/AMF/core/Variant.h:135:23: warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers]
+---
+ amf/public/include/core/Variant.h | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/amf/public/include/core/Variant.h b/amf/public/include/core/Variant.h
+index edf14ae..a0a7eb8 100644
+--- a/amf/public/include/core/Variant.h
++++ b/amf/public/include/core/Variant.h
+@@ -132,16 +132,16 @@ namespace amf
+     static AMF_INLINE const AMFRatio&      AMF_STD_CALL AMFVariantGetRatio(const AMFVariantStruct* _variant) { return (_variant)->ratioValue; }
+     static AMF_INLINE const AMFColor&      AMF_STD_CALL AMFVariantGetColor(const AMFVariantStruct* _variant) { return (_variant)->colorValue; }
+ #else // #if defined(__cplusplus)
+-    static AMF_INLINE const AMFRect        AMF_STD_CALL AMFVariantGetRect (const AMFVariantStruct* _variant) { return (_variant)->rectValue; }
+-    static AMF_INLINE const AMFSize        AMF_STD_CALL AMFVariantGetSize (const AMFVariantStruct* _variant) { return (_variant)->sizeValue; }
+-    static AMF_INLINE const AMFPoint       AMF_STD_CALL AMFVariantGetPoint(const AMFVariantStruct* _variant) { return (_variant)->pointValue; }
+-    static AMF_INLINE const AMFFloatSize  AMF_STD_CALL AMFVariantGetFloatSize(const AMFVariantStruct* _variant) { return (_variant)->floatSizeValue; }
+-    static AMF_INLINE const AMFFloatPoint2D  AMF_STD_CALL AMFVariantGetFloatPoint2D(const AMFVariantStruct* _variant) { return (_variant)->floatPoint2DValue; }
+-    static AMF_INLINE const AMFFloatPoint3D  AMF_STD_CALL AMFVariantGetFloatPoint3D(const AMFVariantStruct* _variant) { return (_variant)->floatPoint3DValue; }
+-    static AMF_INLINE const AMFFloatVector4D  AMF_STD_CALL AMFVariantGetFloatVector4D(const AMFVariantStruct* _variant) { return (_variant)->floatVector4DValue; }
+-    static AMF_INLINE const AMFRate        AMF_STD_CALL AMFVariantGetRate (const AMFVariantStruct* _variant) { return (_variant)->rateValue; }
+-    static AMF_INLINE const AMFRatio       AMF_STD_CALL AMFVariantGetRatio(const AMFVariantStruct* _variant) { return (_variant)->ratioValue; }
+-    static AMF_INLINE const AMFColor       AMF_STD_CALL AMFVariantGetColor(const AMFVariantStruct* _variant) { return (_variant)->colorValue; }
++    static AMF_INLINE AMFRect        AMF_STD_CALL AMFVariantGetRect (const AMFVariantStruct* _variant) { return (_variant)->rectValue; }
++    static AMF_INLINE AMFSize        AMF_STD_CALL AMFVariantGetSize (const AMFVariantStruct* _variant) { return (_variant)->sizeValue; }
++    static AMF_INLINE AMFPoint       AMF_STD_CALL AMFVariantGetPoint(const AMFVariantStruct* _variant) { return (_variant)->pointValue; }
++    static AMF_INLINE AMFFloatSize  AMF_STD_CALL AMFVariantGetFloatSize(const AMFVariantStruct* _variant) { return (_variant)->floatSizeValue; }
++    static AMF_INLINE AMFFloatPoint2D  AMF_STD_CALL AMFVariantGetFloatPoint2D(const AMFVariantStruct* _variant) { return (_variant)->floatPoint2DValue; }
++    static AMF_INLINE AMFFloatPoint3D  AMF_STD_CALL AMFVariantGetFloatPoint3D(const AMFVariantStruct* _variant) { return (_variant)->floatPoint3DValue; }
++    static AMF_INLINE AMFFloatVector4D  AMF_STD_CALL AMFVariantGetFloatVector4D(const AMFVariantStruct* _variant) { return (_variant)->floatVector4DValue; }
++    static AMF_INLINE AMFRate        AMF_STD_CALL AMFVariantGetRate (const AMFVariantStruct* _variant) { return (_variant)->rateValue; }
++    static AMF_INLINE AMFRatio       AMF_STD_CALL AMFVariantGetRatio(const AMFVariantStruct* _variant) { return (_variant)->ratioValue; }
++    static AMF_INLINE AMFColor       AMF_STD_CALL AMFVariantGetColor(const AMFVariantStruct* _variant) { return (_variant)->colorValue; }
+ #endif // #if defined(__cplusplus)
+ 
+ 
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/amf/0003-Define-AMFPRI-d-ud-x-64-using-the-standard-C-format-.patch
=====================================
@@ -0,0 +1,70 @@
+From 4069f86effdc36ba3f12d120212c8f077b96cdb0 Mon Sep 17 00:00:00 2001
+From: Steve Lhomme <robux4 at videolabs.io>
+Date: Fri, 16 Feb 2024 07:50:03 +0100
+Subject: [PATCH 3/4] Define AMFPRI(d|ud|x)64 using the standard C++ format for
+ C+11 and up
+
+See https://en.cppreference.com/w/cpp/types/integer
+
+When compiled in C, it depends whether it's the Microsoft flavor or the standard C format. Not
+whether it's Win32 or not. Clang or GCC use the proper string formats on windows.
+---
+ amf/public/include/core/Platform.h | 29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/amf/public/include/core/Platform.h b/amf/public/include/core/Platform.h
+index 12ee75c..d6496d4 100644
+--- a/amf/public/include/core/Platform.h
++++ b/amf/public/include/core/Platform.h
+@@ -118,12 +118,6 @@ typedef signed int HRESULT;
+ #endif
+     #define AMF_NO_VTABLE           __declspec(novtable)
+ 
+-    #define AMFPRId64   "I64d"
+-
+-    #define AMFPRIud64   "Iu64d"
+-
+-    #define AMFPRIx64   "I64x"
+-
+ #else // !WIN32 - Linux and Mac
+ 
+     #define AMF_STD_CALL
+@@ -138,15 +132,32 @@ typedef signed int HRESULT;
+ #endif
+     #define AMF_NO_VTABLE
+ 
++#endif // WIN32
++
++#if defined(__cplusplus) && (__cplusplus >= 201103L)
++    #include <cinttypes>
++    #define AMFPRId64   PRId64
++
++    #define AMFPRIud64  PRIu64
++
++    #define AMFPRIx64   PRIx64
++#else
++#if defined(_MSC_VER)
++    #define AMFPRId64   "I64d"
++
++    #define AMFPRIud64  "Iu64d"
++
++    #define AMFPRIx64   "I64x"
++#else
+     #if !defined(AMFPRId64)
+         #define AMFPRId64    "lld"
+ 
+-        #define AMFPRIud64    "ulld"
++        #define AMFPRIud64   "ulld"
+ 
+         #define AMFPRIx64    "llx"
+     #endif
+-
+-#endif // WIN32
++#endif
++#endif
+ 
+ #define LPRId64   AMF_UNICODE(AMFPRId64)
+ #define LPRIud64  AMF_UNICODE(AMFPRIud64)
+-- 
+2.37.3.windows.1
+


=====================================
contrib/src/amf/SHA512SUMS
=====================================
@@ -0,0 +1 @@
+43d7d3c05cb385cc5b0b76562dae3f8d5fb0123300291019ddce1032eec55a664290bd9b0552073d3a5cc7036886a015d9edb1f17e2f0f8ffd07acf57360ec18  AMF-1.4.29.tar.gz


=====================================
contrib/src/amf/rules.mak
=====================================
@@ -0,0 +1,53 @@
+# AMF
+
+AMF_VERSION := 1.4.33
+AMF_URL := $(GITHUB)/GPUOpen-LibrariesAndSDKs/AMF/archive/refs/tags/v$(AMF_VERSION).tar.gz
+AMF_GITURL := $(GITHUB)/GPUOpen-LibrariesAndSDKs/AMF.git
+AMF_BRANCH := v$(AMF_VERSION)
+AMF_GITVERSION := e8c7cd7c10d4e05c1913aa8dfd2be9f9dbdb03d6
+
+ifeq ($(ARCH),x86_64)
+ifdef HAVE_WIN32
+PKGS += amf
+endif
+ifdef HAVE_LINUX
+ifndef HAVE_ANDROID
+PKGS += amf
+endif
+endif
+endif
+
+$(TARBALLS)/AMF-$(AMF_GITVERSION).tar.xz:
+	rm -rf "$@" "$(@:.tar.xz=.githash)"
+	rm -rf "$(@:.tar.xz=)"
+	mkdir "$(@:.tar.xz=)"
+	# clone the top of the branch and only checkout amf/public/include
+	cd "$(@:.tar.xz=)" && git clone -n --depth=1 --no-checkout --branch $(AMF_BRANCH) $(AMF_GITURL) "$(notdir $(@:.tar.xz=))"
+	cd "$(@:.tar.xz=)/$(notdir $(@:.tar.xz=))" && git config core.sparseCheckout true && echo "amf/public/include" >> .git/info/sparse-checkout && git checkout
+	cd "$(@:.tar.xz=)" && tar cJf "$(notdir $(@))" --exclude=$(notdir $(@:.tar.xz=))/.git $(notdir $(@:.tar.xz=))
+	cd "$(@:.tar.xz=)/$(notdir $(@:.tar.xz=))" && echo "`git rev-parse HEAD` $(@)" > "../tmp.githash"
+	mv -f -- "$(@:.tar.xz=)/tmp.githash" "$(@:.tar.xz=.githash)"
+	mv -f -- "$(@:.tar.xz=)/$(notdir $(@))" "$@"
+	rm -rf "$(@:.tar.xz=)"
+
+.sum-amf: AMF-$(AMF_GITVERSION).tar.xz
+	$(call check_githash,$(AMF_GITVERSION))
+	touch "$@"
+
+# amf: AMF-$(AMF_VERSION).tar.gz .sum-amf
+amf: AMF-$(AMF_GITVERSION).tar.xz .sum-amf
+	$(UNPACK)
+	$(APPLY) $(SRC)/amf/0001-Move-AMF_UNICODE-into-Platform.h.patch
+	$(APPLY) $(SRC)/amf/0002-Define-LPRI-d-ud-x-64-as-Unicode-wide-versions-of-AM.patch
+	$(APPLY) $(SRC)/amf/0003-Define-AMFPRI-d-ud-x-64-using-the-standard-C-format-.patch
+	$(APPLY) $(SRC)/amf/0001-Don-t-cast-amf_int64-when-using-a-format-string.patch
+	$(APPLY) $(SRC)/amf/0001-Differentiate-the-AMF_NO_VTABLE-based-on-the-compile.patch
+	$(APPLY) $(SRC)/amf/0001-Fix-const-on-return-by-value-AMF_DECLARE_IID.patch
+	$(APPLY) $(SRC)/amf/0002-Fix-const-on-return-by-value-Variant-values.patch
+	$(APPLY) $(SRC)/amf/0001-Fix-warning-when-_MSC_VER-is-not-defined.patch
+	$(MOVE)
+
+.amf: amf
+	mkdir -p $(PREFIX)/include/AMF
+	cp -R $(UNPACK_DIR)/amf/public/include/* $(PREFIX)/include/AMF
+	touch $@


=====================================
modules/hw/amf/amf_helper.c
=====================================
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+// amf_helper.c: AMD Advanced Media Framework helper
+// Copyright © 2024 VideoLabs, VLC authors and VideoLAN
+
+// Authors: Steve Lhomme <robux4 at videolabs.io>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "amf_helper.h"
+
+#include <vlc_common.h>
+
+int vlc_AMFCreateContext(struct vlc_amf_context *c)
+{
+#ifdef _WIN32
+# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+    HMODULE hLib = LoadLibraryA(AMF_DLL_NAMEA);
+    if (hLib == NULL)
+        return (-ENOTSUP);
+
+    amf_uint64 version = 0;
+    AMF_RESULT res;
+    AMFQueryVersion_Fn queryVersion = (AMFQueryVersion_Fn)GetProcAddress(hLib, AMF_QUERY_VERSION_FUNCTION_NAME);
+    if (unlikely(queryVersion == NULL))
+        goto error;
+    res = queryVersion(&version);
+    if (unlikely(res != AMF_OK))
+        goto error;
+
+    c->pFactory = NULL;
+    c->Context = NULL;
+
+    AMFInit_Fn init = (AMFInit_Fn)GetProcAddress(hLib, AMF_INIT_FUNCTION_NAME);
+    res = init(version, &c->pFactory);
+    if (unlikely(res != AMF_OK))
+        goto error;
+
+    res = c->pFactory->pVtbl->CreateContext(c->pFactory, &c->Context);
+    if (res != AMF_OK || c->Context == NULL)
+        goto error;
+
+    c->Private = hLib;
+    return VLC_SUCCESS;
+
+error:
+    FreeLibrary(hLib);
+    return (-ENOTSUP);
+
+# else // !WINAPI_PARTITION_DESKTOP
+    // we can't load external DLLs in UWP
+    return (-ENOTSUP);
+# endif // !WINAPI_PARTITION_DESKTOP
+
+#else
+    return NULL; // TODO
+#endif
+}
+
+void vlc_AMFReleaseContext(struct vlc_amf_context *c)
+{
+    c->Context->pVtbl->Terminate(c->Context);
+    c->Context->pVtbl->Release(c->Context);
+#ifdef _WIN32
+    FreeLibrary(c->Private);
+#endif
+}


=====================================
modules/hw/amf/amf_helper.h
=====================================
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+// amf_helper.h: AMD Advanced Media Framework helper
+// Copyright © 2024 VideoLabs, VLC authors and VideoLAN
+
+// Authors: Steve Lhomme <robux4 at videolabs.io>
+
+#ifndef VLC_AMF_HELPER_H
+#define VLC_AMF_HELPER_H
+
+#include <AMF/core/Context.h>
+#include <AMF/core/Factory.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct vlc_amf_context
+{
+#ifdef __cplusplus
+    amf::AMFFactory *pFactory;
+    amf::AMFContext *Context;
+#else
+    AMFFactory      *pFactory;
+    AMFContext      *Context;
+#endif
+    void            *Private;
+};
+
+int vlc_AMFCreateContext(struct vlc_amf_context *);
+void vlc_AMFReleaseContext(struct vlc_amf_context *);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // VLC_AMF_HELPER_H


=====================================
modules/video_chroma/dxgi_fmt.h
=====================================
@@ -29,6 +29,10 @@
 #include <vlc_common.h>
 #include <vlc_fourcc.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif// __cplusplus
+
 #define GPU_MANUFACTURER_AMD           0x1002
 #define GPU_MANUFACTURER_NVIDIA        0x10DE
 #define GPU_MANUFACTURER_VIA           0x1106
@@ -56,4 +60,8 @@ void DxgiFormatMask(DXGI_FORMAT format, video_format_t *);
 const char *DxgiVendorStr(int gpu_vendor);
 UINT DxgiResourceCount(const d3d_format_t *);
 
+#ifdef __cplusplus
+}
+#endif// __cplusplus
+
 #endif /* include-guard */


=====================================
modules/video_output/Makefile.am
=====================================
@@ -298,6 +298,9 @@ else
 libdirect3d11_plugin_la_LIBADD += -ld3d11
 libdirect3d11_plugin_la_LIBADD += -ld3dcompiler_47
 endif
+if HAVE_AMF_SCALER
+libdirect3d11_plugin_la_SOURCES += hw/amf/amf_helper.c hw/amf/amf_helper.h
+endif
 libdirect3d11_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
 vout_LTLIBRARIES += $(LTLIBdirect3d11)
 EXTRA_LTLIBRARIES += libdirect3d11_plugin.la


=====================================
modules/video_output/win32/d3d11_quad.c
=====================================
@@ -71,6 +71,11 @@ void D3D11_RenderQuad(d3d11_device_t *d3d_dev, d3d_quad_t *quad,
     ID3D11DeviceContext_RSSetViewports(d3d_dev->d3dcontext, 1, &quad->cropViewport);
 
     ID3D11DeviceContext_DrawIndexed(d3d_dev->d3dcontext, quad->indexCount, 0, 0);
+
+    /* force unbinding the input texture, otherwise we get:
+     * OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! */
+    ID3D11RenderTargetView *reset[D3D11_MAX_SHADER_VIEW] = { 0 };
+    ID3D11DeviceContext_PSSetShaderResources(d3d_dev->d3dcontext, 0, quad->resourceCount, reset);
 }
 
 static bool AllocQuadVertices(vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_quad_t *quad)


=====================================
modules/video_output/win32/d3d11_scaler.cpp
=====================================
@@ -12,7 +12,28 @@
 # include "config.h"
 #endif
 
+#include <vlc_common.h>
+#include <assert.h>
+
 #include "d3d11_scaler.h"
+#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>
 #include <wrl/client.h>
@@ -33,6 +54,13 @@ struct d3d11_scaler
     ComPtr<ID3D11VideoProcessor>            processor;
     ComPtr<ID3D11VideoProcessorOutputView>  outputView;
     ID3D11ShaderResourceView                *SRVs[D3D11_MAX_SHADER_VIEW] = {};
+#ifdef HAVE_AMF_SCALER
+    vlc_amf_context                 amf = {};
+    amf::AMFComponent               *amf_scaler = nullptr;
+    bool                            amf_initialized{false};
+    amf::AMFSurface                 *amfInput = nullptr;
+    d3d11_device_t                  *d3d_dev = nullptr;
+#endif
 };
 
 static const d3d_format_t *GetDirectRenderingFormat(vlc_object_t *vd, d3d11_device_t *d3d_dev, vlc_fourcc_t i_src_chroma)
@@ -44,7 +72,17 @@ static const d3d_format_t *GetDirectRenderingFormat(vlc_object_t *vd, d3d11_devi
 d3d11_scaler *D3D11_UpscalerCreate(vlc_object_t *vd, d3d11_device_t *d3d_dev, vlc_fourcc_t i_chroma,
                                    bool super_res, const d3d_format_t **out_fmt)
 {
+    if ((*out_fmt)->formatTexture == DXGI_FORMAT_UNKNOWN)
+    {
+        msg_Warn(vd, "chroma upscale of %4.4s not supported", (char*)&i_chroma);
+        return nullptr;
+    }
+
     bool canProcess = !super_res;
+#ifdef HAVE_AMF_SCALER
+    struct vlc_amf_context amf = {};
+    amf::AMFComponent *amf_scaler = nullptr;
+#endif
     // NVIDIA 530+ driver
     if (d3d_dev->adapterDesc.VendorId == GPU_MANUFACTURER_NVIDIA &&
         (d3d_dev->WDDM.revision * 10000 + d3d_dev->WDDM.build) > 153000)
@@ -57,20 +95,43 @@ d3d11_scaler *D3D11_UpscalerCreate(vlc_object_t *vd, d3d11_device_t *d3d_dev, vl
         // TODO refine which GPU and drivers can do it
         canProcess = true;
     }
+#ifdef HAVE_AMF_SCALER
+    else if (d3d_dev->adapterDesc.VendorId == GPU_MANUFACTURER_AMD && !canProcess)
+    {
+        int res = vlc_AMFCreateContext(&amf);
+        if (res == VLC_SUCCESS)
+        {
+            AMF_RESULT res = amf.pFactory->CreateComponent(amf.Context, AMFHQScaler, &amf_scaler);
+            if (res == AMF_OK && amf_scaler)
+            {
+                res = amf.Context->InitDX11(d3d_dev->d3ddevice);
+                canProcess = res == AMF_OK;
+            }
+        }
+    }
+#endif
 
+    d3d11_scaler *scaleProc = nullptr;
+    const d3d_format_t *fmt = nullptr;
     if (!canProcess)
     {
         msg_Err(vd, "Super Resolution filter not supported");
-        return nullptr;
+        goto error;
     }
 
-    if ((*out_fmt)->formatTexture == DXGI_FORMAT_UNKNOWN)
+#ifdef HAVE_AMF_SCALER
+    if (amf_scaler != nullptr)
     {
-        msg_Warn(vd, "chroma upscale of %4.4s not supported", (char*)&i_chroma);
-        return nullptr;
+        auto amf_fmt = DXGIToAMF((*out_fmt)->formatTexture);
+        if (amf_fmt == amf::AMF_SURFACE_UNKNOWN)
+        {
+            msg_Warn(vd, "upscale of DXGI %s not supported", DxgiFormatToStr((*out_fmt)->formatTexture));
+            goto error;
+        }
+        fmt = *out_fmt;
     }
-    const d3d_format_t *fmt = nullptr;
-    if ((*out_fmt)->bitsPerChannel > 10)
+#endif
+    if (fmt == nullptr && (*out_fmt)->bitsPerChannel > 10)
         fmt = GetDirectRenderingFormat(vd, d3d_dev, VLC_CODEC_RGBA64);
     if (fmt == nullptr && (*out_fmt)->bitsPerChannel > 8)
         fmt = GetDirectRenderingFormat(vd, d3d_dev, VLC_CODEC_RGBA10);
@@ -81,13 +142,23 @@ d3d11_scaler *D3D11_UpscalerCreate(vlc_object_t *vd, d3d11_device_t *d3d_dev, vl
     if (fmt == nullptr || fmt->formatTexture == DXGI_FORMAT_UNKNOWN)
     {
         msg_Warn(vd, "chroma upscale of %4.4s not supported", (char*)&i_chroma);
-        return nullptr;
+        goto error;
     }
 
-    d3d11_scaler *scaleProc = new (std::nothrow) d3d11_scaler;
+    scaleProc = new (std::nothrow) d3d11_scaler;
     if (unlikely(scaleProc == nullptr))
-        return nullptr;
+        goto error;
 
+#ifdef HAVE_AMF_SCALER
+    if (amf_scaler != nullptr)
+    {
+        scaleProc->amf = amf;
+        scaleProc->amf_scaler = amf_scaler;
+        scaleProc->d3d_dev = d3d_dev;
+    }
+    else
+    {
+#endif
     HRESULT hr;
     hr = d3d_dev->d3ddevice->QueryInterface(IID_GRAPHICS_PPV_ARGS(&scaleProc->d3dviddev));
     if (unlikely(FAILED(hr)))
@@ -102,12 +173,21 @@ d3d11_scaler *D3D11_UpscalerCreate(vlc_object_t *vd, d3d11_device_t *d3d_dev, vl
         msg_Err(vd, "Could not Query ID3D11VideoContext Interface. (hr=0x%lX)", hr);
         goto error;
     }
+#ifdef HAVE_AMF_SCALER
+    }
+#endif
 
     scaleProc->d3d_fmt = fmt;
     scaleProc->super_res = super_res;
     *out_fmt = scaleProc->d3d_fmt;
     return scaleProc;
 error:
+#ifdef HAVE_AMF_SCALER
+    if (amf_scaler)
+        amf_scaler->Release();
+    if (amf.Context)
+        vlc_AMFReleaseContext(&amf);
+#endif
     delete scaleProc;
     return nullptr;
 }
@@ -161,6 +241,9 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device
 
     scaleProc->usable = false;
 
+#ifdef HAVE_AMF_SCALER
+    if (!scaleProc->amf_scaler)
+#endif
     if (scaleProc->enumerator.Get() == nullptr)
     {
         d3d11_device_lock(d3d_dev);
@@ -207,7 +290,6 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device
         ZeroMemory(&texDesc, sizeof(texDesc));
         texDesc.MipLevels = 1;
         texDesc.SampleDesc.Count = 1;
-        texDesc.MiscFlags = 0;
         texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
         texDesc.Usage = D3D11_USAGE_DEFAULT;
         texDesc.CPUAccessFlags = 0;
@@ -215,6 +297,11 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device
         texDesc.Format = scaleProc->d3d_fmt->formatTexture;
         texDesc.Width = scaleProc->Width;
         texDesc.Height = scaleProc->Height;
+        texDesc.MiscFlags = 0;
+#ifdef HAVE_AMF_SCALER
+        if (scaleProc->amf_scaler)
+            texDesc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
+#endif
         hr = d3d_dev->d3ddevice->CreateTexture2D(&texDesc, nullptr, upscaled.GetAddressOf());
         if (FAILED(hr))
         {
@@ -226,6 +313,42 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device
         outDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
         outDesc.Texture2D.MipSlice = 0;
 
+#ifdef HAVE_AMF_SCALER
+        if (scaleProc->amf_scaler)
+        {
+            AMF_RESULT res;
+
+            texDesc.Width  = fmt->i_x_offset + fmt->i_visible_width;
+            texDesc.Height = fmt->i_y_offset + fmt->i_visible_height;
+            if (scaleProc->amfInput != nullptr)
+            {
+                D3D11_TEXTURE2D_DESC stagingDesc;
+                auto packed = scaleProc->amfInput->GetPlane(amf::AMF_PLANE_PACKED);
+                ID3D11Texture2D *amfStaging = reinterpret_cast<ID3D11Texture2D *>(packed->GetNative());
+                amfStaging->GetDesc(&stagingDesc);
+                if (stagingDesc.Width != texDesc.Width || stagingDesc.Height != texDesc.Height)
+                {
+                    scaleProc->amfInput->Release();
+                    scaleProc->amfInput = nullptr;
+                }
+            }
+
+            if (scaleProc->amfInput == nullptr)
+            {
+                res = scaleProc->amf.Context->AllocSurface(amf::AMF_MEMORY_DX11,
+                                                           DXGIToAMF(scaleProc->d3d_fmt->formatTexture),
+                                                           texDesc.Width, texDesc.Height,
+                                                           &scaleProc->amfInput);
+                if (unlikely(res != AMF_OK || scaleProc->amfInput == nullptr))
+                {
+                    msg_Err(vd, "Failed to wrap D3D11 output texture. %d", res);
+                    goto done_super;
+                }
+            }
+        }
+        else
+        {
+#endif
         hr = scaleProc->d3dviddev->CreateVideoProcessorOutputView(
                                                                 upscaled.Get(),
                                                                 scaleProc->enumerator.Get(),
@@ -236,6 +359,9 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device
             msg_Dbg(vd,"Failed to create processor output. (hr=0x%lX)", hr);
             goto done_super;
         }
+#ifdef HAVE_AMF_SCALER
+        }
+#endif
 
         ReleaseSRVs(scaleProc);
         _upscaled[0] = upscaled.Get();
@@ -245,8 +371,43 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device
         if ((D3D11_AllocateShaderView)(vd, d3d_dev->d3ddevice, scaleProc->d3d_fmt,
                                     _upscaled, 0, scaleProc->SRVs) != VLC_SUCCESS)
             goto done_super;
+
+#ifdef HAVE_AMF_SCALER
+        if (scaleProc->amf_scaler)
+        {
+            AMF_RESULT res;
+            res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_OUTPUT_SIZE, ::AMFConstructSize(out_width, out_height));
+            res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_ENGINE_TYPE, amf::AMF_MEMORY_DX11);
+            res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_ALGORITHM, AMF_HQ_SCALER_ALGORITHM_VIDEOSR1_0);
+            res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FROM_SRGB, 0);
+            res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_SHARPNESS, 0.5);
+            res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FILL, 1);
+            AMFColor black{0,0,0,255};
+            res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FILL_COLOR, black);
+            // res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FRAME_RATE, oFrameRate);
+            auto amf_fmt = DXGIToAMF(scaleProc->d3d_fmt->formatTexture);
+            if (scaleProc->amf_initialized)
+                res = scaleProc->amf_scaler->ReInit(
+                    fmt->i_x_offset + fmt->i_visible_width,
+                    fmt->i_y_offset + fmt->i_visible_height);
+            else
+                res = scaleProc->amf_scaler->Init(amf_fmt,
+                    fmt->i_x_offset + fmt->i_visible_width,
+                    fmt->i_y_offset + fmt->i_visible_height);
+            if (res != AMF_OK)
+            {
+                msg_Err(vd, "Failed to (re)initialize scaler, (err=%d)", res);
+                return false;
+            }
+            scaleProc->amf_initialized = true;
+        }
+#endif
     }
 
+#ifdef HAVE_AMF_SCALER
+    if (!scaleProc->amf_scaler)
+    {
+#endif
     RECT srcRect;
     srcRect.left   = fmt->i_x_offset;
     srcRect.top    = fmt->i_y_offset;
@@ -365,6 +526,9 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler *scaleProc, d3d11_device
         }
     }
     d3d11_device_unlock(d3d_dev);
+#ifdef HAVE_AMF_SCALER
+    }
+#endif
 
     if (scaleProc->upscaling != upscale)
     {
@@ -384,6 +548,20 @@ done_super:
 void D3D11_UpscalerDestroy(d3d11_scaler *scaleProc)
 {
     ReleaseSRVs(scaleProc);
+#ifdef HAVE_AMF_SCALER
+    if (scaleProc->amfInput != nullptr)
+    {
+        scaleProc->amfInput->Release();
+        scaleProc->amfInput = nullptr;
+    }
+    if (scaleProc->amf_scaler)
+    {
+        scaleProc->amf_scaler->Terminate();
+        scaleProc->amf_scaler->Release();
+    }
+    if (scaleProc->amf.Context)
+        vlc_AMFReleaseContext(&scaleProc->amf);
+#endif
     delete scaleProc;
 }
 
@@ -420,6 +598,86 @@ int D3D11_UpscalerScale(vlc_object_t *vd, d3d11_scaler *scaleProc, picture_sys_t
 {
     HRESULT hr;
 
+#ifdef HAVE_AMF_SCALER
+    if (scaleProc->amf_scaler)
+    {
+        AMF_RESULT res;
+        amf::AMFSurface *submitSurface;
+
+        auto packedStaging = scaleProc->amfInput->GetPlane(amf::AMF_PLANE_PACKED);
+        ID3D11Texture2D *amfStaging = reinterpret_cast<ID3D11Texture2D *>(packedStaging->GetNative());
+
+#ifndef NDEBUG
+        D3D11_TEXTURE2D_DESC stagingDesc, inputDesc;
+        amfStaging->GetDesc(&stagingDesc);
+        p_sys->texture[KNOWN_DXGI_INDEX]->GetDesc(&inputDesc);
+        assert(stagingDesc.Width == inputDesc.Width);
+        assert(stagingDesc.Height == inputDesc.Height);
+        assert(stagingDesc.Format == inputDesc.Format);
+#endif
+
+        // copy source into staging as it may not be shared
+        d3d11_device_lock( scaleProc->d3d_dev );
+        scaleProc->d3d_dev->d3dcontext->CopySubresourceRegion(amfStaging,
+                                                0,
+                                                0, 0, 0,
+                                                p_sys->texture[KNOWN_DXGI_INDEX],
+                                                p_sys->slice_index,
+                                                NULL);
+        d3d11_device_unlock( scaleProc->d3d_dev );
+        submitSurface = scaleProc->amfInput;
+
+        res = scaleProc->amf_scaler->SubmitInput(submitSurface);
+        if (res == AMF_INPUT_FULL)
+        {
+            msg_Dbg(vd, "scaler input full, skip this frame");
+            return VLC_SUCCESS;
+        }
+        if (res != AMF_OK)
+        {
+            msg_Err(vd, "scaler input failed, (err=%d)", res);
+            return VLC_EGENERIC;
+        }
+
+        amf::AMFData *amfOutput = nullptr;
+        res = scaleProc->amf_scaler->QueryOutput(&amfOutput);
+        if (res != AMF_OK)
+        {
+            msg_Err(vd, "scaler gave no output full, (err=%d)", res);
+            return VLC_EGENERIC;
+        }
+
+        assert(amfOutput->GetMemoryType() == amf::AMF_MEMORY_DX11);
+        amf::AMFSurface *amfOutputSurface = reinterpret_cast<amf::AMFSurface*>(amfOutput);
+        auto packed = amfOutputSurface->GetPlane(amf::AMF_PLANE_PACKED);
+
+        ID3D11Texture2D *out = reinterpret_cast<ID3D11Texture2D *>(packed->GetNative());
+
+#ifndef NDEBUG
+        D3D11_TEXTURE2D_DESC outDesc;
+        out->GetDesc(&outDesc);
+        assert(outDesc.Width == scaleProc->Width);
+        assert(outDesc.Height == scaleProc->Height);
+        assert(outDesc.Format == inputDesc.Format);
+#endif
+
+        ReleaseSRVs(scaleProc);
+        ID3D11Texture2D *_upscaled[D3D11_MAX_SHADER_VIEW];
+        _upscaled[0] = out;
+        _upscaled[1] = out;
+        _upscaled[2] = out;
+        _upscaled[3] = out;
+        if (D3D11_AllocateShaderView(vd, scaleProc->d3d_dev->d3ddevice, scaleProc->d3d_fmt,
+                                    _upscaled, 0, scaleProc->SRVs) != VLC_SUCCESS)
+        {
+            return (-ENOTSUP);
+        }
+
+        amfOutput->Release();
+
+        return VLC_SUCCESS;
+    }
+#endif
     if (assert_ProcessorInput(vd, scaleProc, p_sys) != VLC_SUCCESS)
     {
         msg_Err(vd, "fail to create upscaler input");



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/512e6710013e3ff85fd584a789425691bdac91ed...9acdb3addb3bee1994d14960fef5c22021baa65d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/512e6710013e3ff85fd584a789425691bdac91ed...9acdb3addb3bee1994d14960fef5c22021baa65d
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