瀏覽代碼

obs-ffmpeg: Add texture-based hardware AMD encoder

Adds support for texture-based AMD encoding, with both H264, HEVC, and
HDR support. Falls back to FFmpeg when texture-based encoding cannot be
used for whatever reason.

(Jim note: This is based upon obsproject/obs-studio#4538 by AMD/Luxoft
with fewer files, FFmpeg fallback for software encoding, and HDR
support. I also went to lengths to ensure that FFmpeg command line
parameters also works with it)

Co-authored-by: Jim <[email protected]>
OvchinnikovDmitrii 3 年之前
父節點
當前提交
4e140d2ffe
共有 56 個文件被更改,包括 11835 次插入2 次删除
  1. 5 2
      plugins/obs-ffmpeg/CMakeLists.txt
  2. 10 0
      plugins/obs-ffmpeg/data/locale/en-US.ini
  3. 79 0
      plugins/obs-ffmpeg/external/AMF/include/components/Ambisonic2SRenderer.h
  4. 86 0
      plugins/obs-ffmpeg/external/AMF/include/components/AudioCapture.h
  5. 198 0
      plugins/obs-ffmpeg/external/AMF/include/components/Capture.h
  6. 76 0
      plugins/obs-ffmpeg/external/AMF/include/components/ChromaKey.h
  7. 138 0
      plugins/obs-ffmpeg/external/AMF/include/components/ColorSpace.h
  8. 443 0
      plugins/obs-ffmpeg/external/AMF/include/components/Component.h
  9. 172 0
      plugins/obs-ffmpeg/external/AMF/include/components/ComponentCaps.h
  10. 53 0
      plugins/obs-ffmpeg/external/AMF/include/components/CursorCapture.h
  11. 81 0
      plugins/obs-ffmpeg/external/AMF/include/components/DisplayCapture.h
  12. 62 0
      plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioConverter.h
  13. 68 0
      plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioDecoder.h
  14. 66 0
      plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioEncoder.h
  15. 54 0
      plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGComponents.h
  16. 66 0
      plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileDemuxer.h
  17. 53 0
      plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileMuxer.h
  18. 53 0
      plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGVideoDecoder.h
  19. 64 0
      plugins/obs-ffmpeg/external/AMF/include/components/HQScaler.h
  20. 79 0
      plugins/obs-ffmpeg/external/AMF/include/components/MediaSource.h
  21. 110 0
      plugins/obs-ffmpeg/external/AMF/include/components/PreAnalysis.h
  22. 59 0
      plugins/obs-ffmpeg/external/AMF/include/components/PreProcessing.h
  23. 52 0
      plugins/obs-ffmpeg/external/AMF/include/components/VideoCapture.h
  24. 121 0
      plugins/obs-ffmpeg/external/AMF/include/components/VideoConverter.h
  25. 122 0
      plugins/obs-ffmpeg/external/AMF/include/components/VideoDecoderUVD.h
  26. 296 0
      plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderHEVC.h
  27. 326 0
      plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderVCE.h
  28. 124 0
      plugins/obs-ffmpeg/external/AMF/include/components/VideoStitch.h
  29. 83 0
      plugins/obs-ffmpeg/external/AMF/include/components/ZCamLiveStream.h
  30. 234 0
      plugins/obs-ffmpeg/external/AMF/include/core/AudioBuffer.h
  31. 187 0
      plugins/obs-ffmpeg/external/AMF/include/core/Buffer.h
  32. 302 0
      plugins/obs-ffmpeg/external/AMF/include/core/Compute.h
  33. 147 0
      plugins/obs-ffmpeg/external/AMF/include/core/ComputeFactory.h
  34. 786 0
      plugins/obs-ffmpeg/external/AMF/include/core/Context.h
  35. 52 0
      plugins/obs-ffmpeg/external/AMF/include/core/CurrentTime.h
  36. 44 0
      plugins/obs-ffmpeg/external/AMF/include/core/D3D12AMF.h
  37. 177 0
      plugins/obs-ffmpeg/external/AMF/include/core/Data.h
  38. 78 0
      plugins/obs-ffmpeg/external/AMF/include/core/Debug.h
  39. 112 0
      plugins/obs-ffmpeg/external/AMF/include/core/Dump.h
  40. 133 0
      plugins/obs-ffmpeg/external/AMF/include/core/Factory.h
  41. 258 0
      plugins/obs-ffmpeg/external/AMF/include/core/Interface.h
  42. 112 0
      plugins/obs-ffmpeg/external/AMF/include/core/Plane.h
  43. 547 0
      plugins/obs-ffmpeg/external/AMF/include/core/Platform.h
  44. 275 0
      plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorage.h
  45. 207 0
      plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorageEx.h
  46. 127 0
      plugins/obs-ffmpeg/external/AMF/include/core/Result.h
  47. 279 0
      plugins/obs-ffmpeg/external/AMF/include/core/Surface.h
  48. 183 0
      plugins/obs-ffmpeg/external/AMF/include/core/Trace.h
  49. 2075 0
      plugins/obs-ffmpeg/external/AMF/include/core/Variant.h
  50. 59 0
      plugins/obs-ffmpeg/external/AMF/include/core/Version.h
  51. 108 0
      plugins/obs-ffmpeg/external/AMF/include/core/VulkanAMF.h
  52. 11 0
      plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt
  53. 131 0
      plugins/obs-ffmpeg/obs-amf-test/obs-amf-test.cpp
  54. 8 0
      plugins/obs-ffmpeg/obs-ffmpeg.c
  55. 272 0
      plugins/obs-ffmpeg/texture-amf-opts.hpp
  56. 1732 0
      plugins/obs-ffmpeg/texture-amf.cpp

+ 5 - 2
plugins/obs-ffmpeg/CMakeLists.txt

@@ -63,6 +63,8 @@ target_compile_options(
 )
 
 if(OS_WINDOWS)
+  add_subdirectory(obs-amf-test)
+
   if(MSVC)
     target_link_libraries(obs-ffmpeg PRIVATE OBS::w32-pthreads)
   endif()
@@ -71,8 +73,9 @@ if(OS_WINDOWS)
   configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in
                  obs-ffmpeg.rc)
 
-  target_sources(obs-ffmpeg PRIVATE jim-nvenc.c jim-nvenc.h jim-nvenc-helpers.c
-                                    obs-ffmpeg.rc)
+  target_sources(
+    obs-ffmpeg PRIVATE texture-amf.cpp texture-amf-opts.hpp jim-nvenc.c
+                       jim-nvenc.h jim-nvenc-helpers.c obs-ffmpeg.rc)
 
 elseif(OS_POSIX AND NOT OS_MACOS)
   find_package(Libpci REQUIRED)

+ 10 - 0
plugins/obs-ffmpeg/data/locale/en-US.ini

@@ -12,6 +12,9 @@ KeyframeIntervalSec="Keyframe Interval (seconds, 0=auto)"
 Lossless="Lossless"
 Level="Level"
 
+AMFOpts="AMF/FFmpeg Options"
+AMFOpts.ToolTip="Use to specify custom AMF or FFmpeg options. For example, \"level=5.2 profile=main BPicturesPattern=3\""
+
 BFrames="Max B-frames"
 
 VAAPI.Codec="VAAPI Codec"
@@ -33,6 +36,10 @@ NVENC.CQLevel="CQ Level"
 NVENC.10bitUnsupported="Cannot perform 10-bit encode on this encoder."
 NVENC.TooManyBFrames="Max B-frames setting (%d) is more than encoder supports (%d)."
 
+AMF.Preset.speed="Speed"
+AMF.Preset.balanced="Balanced"
+AMF.Preset.quality="Quality"
+
 FFmpegSource="Media Source"
 LocalFile="Local File"
 Looping="Loop"
@@ -72,6 +79,9 @@ WarnWindowsDefender="If Windows 10 Ransomware Protection is enabled it can also
 Encoder.Error="Failed to open %1: %2"
 Encoder.Timeout="Encoder %1 is taking too long to encode (timeout: %2 seconds)"
 
+AMF.Error="Failed to open AMF codec: %1"
+AMF.GenericError="Check your video drivers are up to date. Try closing other recording software which might be using the AMD encoder such as the Radeon Software or Windows 10 Game DVR."
+
 NVENC.Error="Failed to open NVENC codec: %1"
 NVENC.GenericError="Check your video drivers are up to date. Try closing other recording software which might be using NVENC such as NVIDIA Shadowplay or Windows 10 Game DVR."
 NVENC.BadGPUIndex="You have selected GPU %1 in your output encoder settings. Set this back to 0 and try again."

+ 79 - 0
plugins/obs-ffmpeg/external/AMF/include/components/Ambisonic2SRenderer.h

@@ -0,0 +1,79 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// interface declaration;  Ambisonic to Stereo Renderer
+//-------------------------------------------------------------------------------------------------
+
+#ifndef AMF_Ambisonic2SRenderer_h
+#define AMF_Ambisonic2SRenderer_h
+#pragma once
+
+#include "public/include/components/Component.h"
+
+#define AMFAmbisonic2SRendererHW L"AMFAmbisonic2SRenderer"
+
+enum AMF_AMBISONIC2SRENDERER_MODE_ENUM 
+{
+    AMF_AMBISONIC2SRENDERER_MODE_SIMPLE            = 0,
+    AMF_AMBISONIC2SRENDERER_MODE_HRTF_AMD0         = 1,
+    AMF_AMBISONIC2SRENDERER_MODE_HRTF_MIT1         = 2,
+};
+
+
+// static properties 
+#define AMF_AMBISONIC2SRENDERER_IN_AUDIO_SAMPLE_RATE        L"InSampleRate"         // amf_int64 (default = 0)
+#define AMF_AMBISONIC2SRENDERER_IN_AUDIO_CHANNELS           L"InChannels"           // amf_int64 (only = 4)
+#define AMF_AMBISONIC2SRENDERER_IN_AUDIO_SAMPLE_FORMAT      L"InSampleFormat"       // amf_int64(AMF_AUDIO_FORMAT) (default = AMFAF_FLTP)
+
+#define AMF_AMBISONIC2SRENDERER_OUT_AUDIO_CHANNELS          L"OutChannels"          // amf_int64 (only = 2 - stereo)
+#define AMF_AMBISONIC2SRENDERER_OUT_AUDIO_SAMPLE_FORMAT     L"OutSampleFormat"      // amf_int64(AMF_AUDIO_FORMAT) (only = AMFAF_FLTP)
+#define AMF_AMBISONIC2SRENDERER_OUT_AUDIO_CHANNEL_LAYOUT    L"OutChannelLayout"     // amf_int64 (only = 3 - defalut stereo L R)
+
+#define AMF_AMBISONIC2SRENDERER_MODE                        L"StereoMode"               //TODO: AMF_AMBISONIC2SRENDERER_MODE_ENUM(default=AMF_AMBISONIC2SRENDERER_MODE_HRTF)
+
+
+// dynamic properties
+#define AMF_AMBISONIC2SRENDERER_W                           L"w"                        //amf_int64 (default=0)
+#define AMF_AMBISONIC2SRENDERER_X                           L"x"                        //amf_int64 (default=1)
+#define AMF_AMBISONIC2SRENDERER_Y                           L"y"                        //amf_int64 (default=2)
+#define AMF_AMBISONIC2SRENDERER_Z                           L"z"                        //amf_int64 (default=3)
+
+#define AMF_AMBISONIC2SRENDERER_THETA                       L"Theta"                    //double (default=0.0)
+#define AMF_AMBISONIC2SRENDERER_PHI                         L"Phi"                      //double (default=0.0)
+#define AMF_AMBISONIC2SRENDERER_RHO                         L"Rho"                      //double (default=0.0)
+
+extern "C"
+{
+    AMF_RESULT AMF_CDECL_CALL AMFCreateComponentAmbisonic(amf::AMFContext* pContext, void* reserved, amf::AMFComponent** ppComponent);
+}
+#endif //#ifndef AMF_Ambisonic2SRenderer_h

+ 86 - 0
plugins/obs-ffmpeg/external/AMF/include/components/AudioCapture.h

@@ -0,0 +1,86 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// Audio session  interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_AudioCapture_h
+#define AMF_AudioCapture_h
+
+#pragma once
+
+#include "Component.h"
+
+// Set to capture from either a microphone or desktop
+#define AUDIOCAPTURE_SOURCE                L"AudioCaptureSource"           // amf_bool true for microphone, false for desktop;
+
+// In the case of capturing a microphone, the AUDIOCAPTURE_DEVICE_ACTIVE property
+// can be set to -1 so that the active input devices are looked up. If the initialization
+// is successful then the AUDIOCAPTURE_DEVICE_NAME and AUDIOCAPTURE_DEVICE_COUNT
+// properties will be set.
+#define AUDIOCAPTURE_DEVICE_ACTIVE          L"AudioCaptureDeviceActive"   // amf_int64
+#define AUDIOCAPTURE_DEVICE_COUNT           L"AudioCaptureDeviceCount"    // amf_int64
+#define AUDIOCAPTURE_DEVICE_NAME            L"AudioCaptureDeviceName"     // String
+
+// Codec used for audio capture
+#define AUDIOCAPTURE_CODEC                  L"AudioCaptureCodec"           // amf_int64, AV_CODEC_ID_PCM_F32LE
+// Sample rate used for audio capture
+#define AUDIOCAPTURE_SAMPLERATE             L"AudioCaptureSampleRate"      // amf_int64, 44100 in samples
+// Sample count used for audio capture
+#define AUDIOCAPTURE_SAMPLES                L"AudioCaptureSampleCount"     // amf_int64, 1024
+// Bitrate used for audio capture
+#define AUDIOCAPTURE_BITRATE                L"AudioCaptureBitRate"         // amf_int64, in bits
+// Channel count used for audio capture
+#define AUDIOCAPTURE_CHANNELS               L"AudioCaptureChannelCount"    // amf_int64, 2
+// Channel layout used for audio capture
+#define AUDIOCAPTURE_CHANNEL_LAYOUT         L"AudioCaptureChannelLayout"   // amf_int64, AMF_AUDIO_CHANNEL_LAYOUT
+// Format used for audio capture
+#define AUDIOCAPTURE_FORMAT                 L"AudioCaptureFormat"          // amf_int64, AMFAF_U8
+// Block alignment
+#define AUDIOCAPTURE_BLOCKALIGN             L"AudioCaptureBlockAlign"      // amf_int64, bytes
+// Audio frame size
+#define AUDIOCAPTURE_FRAMESIZE              L"AudioCaptureFrameSize"       // amf_int64, bytes
+// Audio low latency state
+#define AUDIOCAPTURE_LOWLATENCY             L"AudioCaptureLowLatency"      // amf_int64;
+
+// Optional interface that provides current time
+#define AUDIOCAPTURE_CURRENT_TIME_INTERFACE	L"CurrentTimeInterface"        // interface to current time object
+
+extern "C"
+{
+	// Component that allows the recording of inputs such as microphones or the audio that is being
+	// rendered.  The direction that is captured is controlled by the AUDIOCAPTURE_CAPTURE property
+	//
+	AMF_RESULT AMF_CDECL_CALL AMFCreateComponentAudioCapture(amf::AMFContext* pContext, amf::AMFComponent** ppComponent);
+}
+
+#endif // #ifndef AMF_AudioCapture_h

+ 198 - 0
plugins/obs-ffmpeg/external/AMF/include/components/Capture.h

@@ -0,0 +1,198 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// Capture interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef __Capture_h__
+#define __Capture_h__
+#pragma once
+
+#include "../../../public/include/components/Component.h"
+
+typedef enum AMF_CAPTURE_DEVICE_TYPE_ENUM
+{
+    AMF_CAPTURE_DEVICE_UNKNOWN              = 0,
+    AMF_CAPTURE_DEVICE_MEDIAFOUNDATION      = 1,
+    AMF_CAPTURE_DEVICE_WASAPI               = 2,
+    AMF_CAPTURE_DEVICE_SDI                  = 3,
+    AMF_CAPTURE_DEVICE_SCREEN_DUPLICATION   = 4,
+} AMF_CAPTURE_DEVICE_TYPE_ENUM;
+
+// device properties
+#define AMF_CAPTURE_DEVICE_TYPE                     L"DeviceType"               // amf_int64( AMF_CAPTURE_DEVICE_TYPE_ENUM )
+#define AMF_CAPTURE_DEVICE_NAME                     L"DeviceName"               // wchar_t* : name of the device
+
+
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+
+    //----------------------------------------------------------------------------------------------
+    // AMFCaptureDevice interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFCaptureDevice : public AMFComponentEx
+    {
+    public:
+        AMF_DECLARE_IID (0x5bfd1b17, 0x9f2a, 0x43c4, 0x9c, 0xdd, 0x2c, 0x3, 0x88, 0x43, 0xb5, 0xf3)
+
+        virtual AMF_RESULT          AMF_STD_CALL Start() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL Stop() = 0;
+
+        // TODO add callback interface for disconnected / lost / changed device notification
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFCaptureDevice> AMFCaptureDevicePtr;
+    //----------------------------------------------------------------------------------------------
+#else // #if defined(__cplusplus)
+        AMF_DECLARE_IID(AMFCaptureDevice, 0x5bfd1b17, 0x9f2a, 0x43c4, 0x9c, 0xdd, 0x2c, 0x3, 0x88, 0x43, 0xb5, 0xf3)
+
+    typedef struct AMFCaptureDeviceVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFCaptureDevice* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFCaptureDevice* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFCaptureDevice* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFCaptureDevice* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFCaptureDevice* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFCaptureDevice* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFCaptureDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFCaptureDevice* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFCaptureDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFCaptureDevice* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFCaptureDevice* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFCaptureDevice* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFCaptureDevice* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFPropertyStorageEx interface
+
+        amf_size            (AMF_STD_CALL *GetPropertiesInfoCount)(AMFCaptureDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfoAt)(AMFCaptureDevice* pThis, amf_size index, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfo)(AMFCaptureDevice* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *ValidateProperty)(AMFCaptureDevice* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated);
+
+        // AMFComponent interface
+
+        AMF_RESULT          (AMF_STD_CALL *Init)(AMFCaptureDevice* pThis, AMF_SURFACE_FORMAT format,amf_int32 width,amf_int32 height);
+        AMF_RESULT          (AMF_STD_CALL *ReInit)(AMFCaptureDevice* pThis, amf_int32 width,amf_int32 height);
+        AMF_RESULT          (AMF_STD_CALL *Terminate)(AMFCaptureDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *Drain)(AMFCaptureDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *Flush)(AMFCaptureDevice* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *SubmitInput)(AMFCaptureDevice* pThis, AMFData* pData);
+        AMF_RESULT          (AMF_STD_CALL *QueryOutput)(AMFCaptureDevice* pThis, AMFData** ppData);
+        AMFContext*         (AMF_STD_CALL *GetContext)(AMFCaptureDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *SetOutputDataAllocatorCB)(AMFCaptureDevice* pThis, AMFDataAllocatorCB* callback);
+
+        AMF_RESULT          (AMF_STD_CALL *GetCaps)(AMFCaptureDevice* pThis, AMFCaps** ppCaps);
+        AMF_RESULT          (AMF_STD_CALL *Optimize)(AMFCaptureDevice* pThis, AMFComponentOptimizationCallback* pCallback);
+
+        // AMFComponentEx interface
+
+        amf_int32           (AMF_STD_CALL *GetInputCount)(AMFCaptureDevice* pThis);
+        amf_int32           (AMF_STD_CALL *GetOutputCount)(AMFCaptureDevice* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *GetInput)(AMFCaptureDevice* pThis, amf_int32 index, AMFInput** ppInput);
+        AMF_RESULT          (AMF_STD_CALL *GetOutput)(AMFCaptureDevice* pThis, amf_int32 index, AMFOutput** ppOutput);
+
+        // AMFCaptureDevice interface
+
+        AMF_RESULT          (AMF_STD_CALL *Start)(AMFCaptureDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *Stop)(AMFCaptureDevice* pThis);
+
+    } AMFCaptureVtbl;
+
+    struct AMFCapture
+    {
+        const AMFCaptureVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+    // AMFCaptureManager interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFCaptureManager : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID ( 0xf64d2f0d, 0xad16, 0x4ce7, 0x80, 0x5f, 0xa1, 0xe7, 0x3b, 0x0, 0xf4, 0x28)
+
+        virtual AMF_RESULT          AMF_STD_CALL Update() = 0;
+        virtual amf_int32           AMF_STD_CALL GetDeviceCount() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetDevice(amf_int32 index,AMFCaptureDevice **pDevice) = 0;
+
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFCaptureManager> AMFCaptureManagerPtr;
+    //----------------------------------------------------------------------------------------------
+#else // #if defined(__cplusplus)
+        AMF_DECLARE_IID(AMFCaptureManager, 0xf64d2f0d, 0xad16, 0x4ce7, 0x80, 0x5f, 0xa1, 0xe7, 0x3b, 0x0, 0xf4, 0x28)
+
+    typedef struct AMFCaptureManagerVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFCaptureManager* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFCaptureManager* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFCaptureManager* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+
+        // AMFCaptureManager interface
+        AMF_RESULT          (AMF_STD_CALL *Update)((AMFCaptureManager* pThis);
+        amf_int32           (AMF_STD_CALL *GetDeviceCount)(AMFCaptureManager* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetDevice)(AMFCaptureManager* pThis, amf_int32 index,AMFCaptureDevice **pDevice);
+
+    } AMFCaptureManagerVtbl;
+
+    struct AMFCaptureManager
+    {
+        const AMFCaptureManagerVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+#if defined(__cplusplus)
+} // namespace
+#endif
+
+extern "C"
+{
+    AMF_RESULT AMF_CDECL_CALL AMFCreateCaptureManager(amf::AMFContext* pContext, amf::AMFCaptureManager** ppManager);
+}
+
+#endif // __Capture_h__

+ 76 - 0
plugins/obs-ffmpeg/external/AMF/include/components/ChromaKey.h

@@ -0,0 +1,76 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+/**
+ ***************************************************************************************************
+ * @file  ChromaKey.h
+ * @brief AMFChromaKey interface declaration
+ ***************************************************************************************************
+ */
+#ifndef __AMFChromaKey_h__
+#define __AMFChromaKey_h__
+#pragma once
+
+#include "public/include/components/Component.h"
+
+#define AMFChromaKey                  L"AMFChromaKey"
+
+// static properties 
+#define AMF_CHROMAKEY_COLOR           L"ChromaKeyColor"         // amf_uint64 (default=0x992A1E), YUV Green key Color
+#define AMF_CHROMAKEY_COLOR_EX        L"ChromaKeyColorEX"       // amf_uint64 (default=0), YUV Green key Color, secondary
+#define AMF_CHROMAKEY_RANGE_MIN       L"ChromaKeyRangeMin"      // amf_uint64 (default=20)   color tolerance low, 0~255
+#define AMF_CHROMAKEY_RANGE_MAX       L"ChromaKeyRangeMax"      // amf_uint64 (default=22)   color tolerance high, 0~255
+#define AMF_CHROMAKEY_RANGE_EXT       L"ChromaKeyRangeExt"      // amf_uint64 (default=40)   color tolerance extended, 0~255
+#define AMF_CHROMAKEY_SPILL_MODE      L"ChromaKeySpillMode"     // amf_uint64 (default=0)    spill suppression mode
+#define AMF_CHROMAKEY_RANGE_SPILL     L"ChromaKeyRangeSpill"    // amf_uint64 (default=5)    spill suppression threshold
+#define AMF_CHROMAKEY_LUMA_LOW        L"ChromaKeyLumaLow"       // amf_uint64 (default=16)   minimum luma value for processing
+#define AMF_CHROMAKEY_INPUT_COUNT     L"InputCount"             // amf_uint64 (default=2)    number of inputs
+#define AMF_CHROMAKEY_COLOR_POS       L"KeyColorPos"            // amf_uint64 (default=0)    key color position from the surface
+#define AMF_CHROMAKEY_OUT_FORMAT      L"ChromaKeyOutFormat"     // amf_uint64 (default=RGBA) output format
+#define AMF_CHROMAKEY_MEMORY_TYPE     L"ChromaKeyMemoryType"    // amf_uint64 (default=DX11) mmeory type
+#define AMF_CHROMAKEY_COLOR_ADJ       L"ChromaKeyColorAdj"      // amf_uint64 (default=0)    endble color adjustment
+#define AMF_CHROMAKEY_COLOR_ADJ_THRE  L"ChromaKeyColorAdjThre"  // amf_uint64 (default=0)    color adjustment threshold
+#define AMF_CHROMAKEY_COLOR_ADJ_THRE2 L"ChromaKeyColorAdjThre2" // amf_uint64 (default=0)    color adjustment threshold
+#define AMF_CHROMAKEY_BYPASS          L"ChromaKeyBypass"        // amf_uint64 (default=0)    disable chromakey
+#define AMF_CHROMAKEY_EDGE            L"ChromaKeyEdge"          // amf_uint64 (default=0)    endble edge detection
+#define AMF_CHROMAKEY_BOKEH           L"ChromaKeyBokeh"         // amf_uint64 (default=0)    endble background bokeh
+#define AMF_CHROMAKEY_BOKEH_RADIUS    L"ChromaKeyBokehRadius"   // amf_uint64 (default=7)    background bokeh radius
+#define AMF_CHROMAKEY_DEBUG           L"ChromaKeyDebug"         // amf_uint64 (default=0)    endble debug mode
+
+#define AMF_CHROMAKEY_POSX            L"ChromaKeyPosX"          // amf_uint64 (default=0)    positionX
+#define AMF_CHROMAKEY_POSY            L"ChromaKeyPosY"          // amf_uint64 (default=0)    positionY
+
+extern "C"
+{
+    AMF_RESULT AMF_CDECL_CALL AMFCreateComponentChromaKey(amf::AMFContext* pContext, amf::AMFComponentEx** ppComponent);
+}
+#endif //#ifndef __AMFChromaKey_h__

+ 138 - 0
plugins/obs-ffmpeg/external/AMF/include/components/ColorSpace.h

@@ -0,0 +1,138 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// Color Spacedeclaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_ColorSpace_h
+#define AMF_ColorSpace_h
+#pragma once
+
+// YUV <--> RGB conversion matrix with range
+typedef enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM
+{
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN   =-1,
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_601       = 0,    // studio range 
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_709       = 1,    // studio range 
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020      = 2,    // studio range 
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_JPEG      = 3,    // full range 601
+//    AMF_VIDEO_CONVERTER_COLOR_PROFILE_G22_BT709 = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709,
+//    AMF_VIDEO_CONVERTER_COLOR_PROFILE_G10_SCRGB = 4,
+//    AMF_VIDEO_CONVERTER_COLOR_PROFILE_G10_BT709 = 5,
+//    AMF_VIDEO_CONVERTER_COLOR_PROFILE_G10_BT2020 = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020,
+//    AMF_VIDEO_CONVERTER_COLOR_PROFILE_G2084_BT2020 = 6,
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601  = AMF_VIDEO_CONVERTER_COLOR_PROFILE_JPEG,    // full range
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709  = 7,                                         // full range
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020 = 8,                                        // full range
+    AMF_VIDEO_CONVERTER_COLOR_PROFILE_COUNT
+} AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM;
+
+typedef enum AMF_COLOR_PRIMARIES_ENUM // as in VUI color_primaries AVC and HEVC
+{
+    AMF_COLOR_PRIMARIES_UNDEFINED   = 0,
+    AMF_COLOR_PRIMARIES_BT709       = 1,
+    AMF_COLOR_PRIMARIES_UNSPECIFIED = 2,
+    AMF_COLOR_PRIMARIES_RESERVED    = 3,
+    AMF_COLOR_PRIMARIES_BT470M      = 4,
+    AMF_COLOR_PRIMARIES_BT470BG     = 5,
+    AMF_COLOR_PRIMARIES_SMPTE170M   = 6,
+    AMF_COLOR_PRIMARIES_SMPTE240M   = 7,
+    AMF_COLOR_PRIMARIES_FILM        = 8,
+    AMF_COLOR_PRIMARIES_BT2020      = 9,
+    AMF_COLOR_PRIMARIES_SMPTE428    = 10,
+    AMF_COLOR_PRIMARIES_SMPTE431    = 11,
+    AMF_COLOR_PRIMARIES_SMPTE432    = 12,
+    AMF_COLOR_PRIMARIES_JEDEC_P22   = 22,
+    AMF_COLOR_PRIMARIES_CCCS        = 1000, // Common Composition Color Space or scRGB
+} AMF_COLOR_PRIMARIES_ENUM;
+
+typedef enum AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM // as in VUI transfer_characteristic AVC and HEVC
+{
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED     = 0,
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709         = 1, //BT709
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_UNSPECIFIED   = 2,
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_RESERVED      = 3,
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_GAMMA22       = 4, //BT470_M
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_GAMMA28       = 5, //BT470
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE170M     = 6, //BT601
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE240M     = 7, //SMPTE 240M
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_LINEAR        = 8,
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_LOG           = 9, //LOG10
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_LOG_SQRT      = 10,//LOG10 SQRT
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_4  = 11,
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_BT1361_ECG    = 12,
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_1  = 13,
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_BT2020_10     = 14, //BT709
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_BT2020_12     = 15, //BT709
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084     = 16, //PQ
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE428      = 17,
+    AMF_COLOR_TRANSFER_CHARACTERISTIC_ARIB_STD_B67  = 18, //HLG
+} AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM;
+
+typedef enum AMF_COLOR_BIT_DEPTH_ENUM
+{
+    AMF_COLOR_BIT_DEPTH_UNDEFINED   = 0,
+    AMF_COLOR_BIT_DEPTH_8           = 8,
+    AMF_COLOR_BIT_DEPTH_10          = 10,
+} AMF_COLOR_BIT_DEPTH_ENUM;
+
+typedef struct AMFHDRMetadata
+{
+    amf_uint16  redPrimary[2];              // normalized to 50000
+    amf_uint16  greenPrimary[2];            // normalized to 50000
+    amf_uint16  bluePrimary[2];             // normalized to 50000
+    amf_uint16  whitePoint[2];              // normalized to 50000
+    amf_uint32  maxMasteringLuminance;      // normalized to 10000
+    amf_uint32  minMasteringLuminance;      // normalized to 10000
+    amf_uint16  maxContentLightLevel;       // nit value 
+    amf_uint16  maxFrameAverageLightLevel;  // nit value 
+} AMFHDRMetadata;
+
+
+typedef enum AMF_COLOR_RANGE_ENUM
+{
+    AMF_COLOR_RANGE_UNDEFINED   = 0,
+    AMF_COLOR_RANGE_STUDIO      = 1,
+    AMF_COLOR_RANGE_FULL        = 2,
+} AMF_COLOR_RANGE_ENUM;
+
+
+// these properties can be set on input or outout surface
+// IDs are the same as in decoder properties
+// can be used to dynamically pass color data between components:
+// Decoder, Capture, Encoder. Presenter etc.
+#define AMF_VIDEO_COLOR_TRANSFER_CHARACTERISTIC         L"ColorTransferChar"    // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013 Section 7.2 See ColorSpace.h for enum 
+#define AMF_VIDEO_COLOR_PRIMARIES                       L"ColorPrimaries"       // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013 Section 7.1 See ColorSpace.h for enum 
+#define AMF_VIDEO_COLOR_RANGE                           L"ColorRange"           // amf_int64(AMF_COLOR_RANGE_ENUM) default = AMF_COLOR_RANGE_UNDEFINED
+#define AMF_VIDEO_COLOR_HDR_METADATA                    L"HdrMetadata"          // AMFBuffer containing AMFHDRMetadata; default NULL
+
+#endif //#ifndef AMF_ColorSpace_h

+ 443 - 0
plugins/obs-ffmpeg/external/AMF/include/components/Component.h

@@ -0,0 +1,443 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ ***************************************************************************************************
+ * @file  Component.h
+ * @brief AMFComponent interface declaration
+ ***************************************************************************************************
+ */
+#ifndef AMF_Component_h
+#define AMF_Component_h
+#pragma once
+
+#include "../core/Data.h"
+#include "../core/PropertyStorageEx.h"
+#include "../core/Surface.h"
+#include "../core/Context.h"
+#include "ComponentCaps.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    // AMFDataAllocatorCB interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFDataAllocatorCB : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0x4bf46198, 0x8b7b, 0x49d0, 0xaa, 0x72, 0x48, 0xd4, 0x7, 0xce, 0x24, 0xc5 )
+
+        virtual AMF_RESULT AMF_STD_CALL AllocBuffer(AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer) = 0;
+        virtual AMF_RESULT AMF_STD_CALL AllocSurface(AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format,
+            amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, AMFSurface** ppSurface) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFDataAllocatorCB> AMFDataAllocatorCBPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFDataAllocatorCB, 0x4bf46198, 0x8b7b, 0x49d0, 0xaa, 0x72, 0x48, 0xd4, 0x7, 0xce, 0x24, 0xc5 )
+    typedef struct AMFDataAllocatorCB AMFDataAllocatorCB;
+
+    typedef struct AMFDataAllocatorCBVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFDataAllocatorCB* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFDataAllocatorCB* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFDataAllocatorCB* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+        // AMFDataAllocatorCB interface 
+        AMF_RESULT (AMF_STD_CALL *AllocBuffer)(AMFDataAllocatorCB* pThis, AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer);
+        AMF_RESULT (AMF_STD_CALL *AllocSurface)(AMFDataAllocatorCB* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format,
+            amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, AMFSurface** ppSurface);
+    } AMFDataAllocatorCBVtbl;
+
+    struct AMFDataAllocatorCB
+    {
+        const AMFDataAllocatorCBVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFComponentOptimizationCallback
+    {
+    public:
+        virtual AMF_RESULT AMF_STD_CALL OnComponentOptimizationProgress(amf_uint percent) = 0;
+    };
+#else // #if defined(__cplusplus)
+    typedef struct AMFComponentOptimizationCallback AMFComponentOptimizationCallback;
+    typedef struct AMFComponentOptimizationCallbackVtbl
+    {
+        // AMFDataAllocatorCB interface 
+        AMF_RESULT (AMF_STD_CALL *OnComponentOptimizationProgress)(AMFComponentOptimizationCallback* pThis, amf_uint percent);
+    } AMFComponentOptimizationCallbackVtbl;
+
+    struct AMFComponentOptimizationCallback
+    {
+        const AMFComponentOptimizationCallbackVtbl *pVtbl;
+    };
+
+#endif //#if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // AMFComponent interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFComponent : public AMFPropertyStorageEx
+    {
+    public:
+        AMF_DECLARE_IID(0x8b51e5e4, 0x455d, 0x4034, 0xa7, 0x46, 0xde, 0x1b, 0xed, 0xc3, 0xc4, 0x6)
+
+        virtual AMF_RESULT  AMF_STD_CALL Init(AMF_SURFACE_FORMAT format,amf_int32 width,amf_int32 height) = 0;
+        virtual AMF_RESULT  AMF_STD_CALL ReInit(amf_int32 width,amf_int32 height) = 0;
+        virtual AMF_RESULT  AMF_STD_CALL Terminate() = 0;
+        virtual AMF_RESULT  AMF_STD_CALL Drain() = 0;
+        virtual AMF_RESULT  AMF_STD_CALL Flush() = 0;
+
+        virtual AMF_RESULT  AMF_STD_CALL SubmitInput(AMFData* pData) = 0;
+        virtual AMF_RESULT  AMF_STD_CALL QueryOutput(AMFData** ppData) = 0;
+        virtual AMFContext* AMF_STD_CALL GetContext() = 0;
+        virtual AMF_RESULT  AMF_STD_CALL SetOutputDataAllocatorCB(AMFDataAllocatorCB* callback) = 0;
+
+        virtual AMF_RESULT  AMF_STD_CALL GetCaps(AMFCaps** ppCaps) = 0;
+        virtual AMF_RESULT  AMF_STD_CALL Optimize(AMFComponentOptimizationCallback* pCallback) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFComponent> AMFComponentPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFComponent, 0x8b51e5e4, 0x455d, 0x4034, 0xa7, 0x46, 0xde, 0x1b, 0xed, 0xc3, 0xc4, 0x6)
+    typedef struct AMFComponent AMFComponent;
+
+    typedef struct AMFComponentVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFComponent* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFComponent* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFComponent* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFComponent* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFComponent* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFComponent* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFComponent* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFComponent* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFComponent* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFComponent* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFComponent* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFComponent* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFComponent* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFPropertyStorageEx interface
+
+        amf_size            (AMF_STD_CALL *GetPropertiesInfoCount)(AMFComponent* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfoAt)(AMFComponent* pThis, amf_size index, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfo)(AMFComponent* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *ValidateProperty)(AMFComponent* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated);
+
+        // AMFComponent interface
+
+        AMF_RESULT  (AMF_STD_CALL *Init)(AMFComponent* pThis, AMF_SURFACE_FORMAT format,amf_int32 width,amf_int32 height);
+        AMF_RESULT  (AMF_STD_CALL *ReInit)(AMFComponent* pThis, amf_int32 width,amf_int32 height);
+        AMF_RESULT  (AMF_STD_CALL *Terminate)(AMFComponent* pThis);
+        AMF_RESULT  (AMF_STD_CALL *Drain)(AMFComponent* pThis);
+        AMF_RESULT  (AMF_STD_CALL *Flush)(AMFComponent* pThis);
+
+        AMF_RESULT  (AMF_STD_CALL *SubmitInput)(AMFComponent* pThis, AMFData* pData);
+        AMF_RESULT  (AMF_STD_CALL *QueryOutput)(AMFComponent* pThis, AMFData** ppData);
+        AMFContext* (AMF_STD_CALL *GetContext)(AMFComponent* pThis);
+        AMF_RESULT  (AMF_STD_CALL *SetOutputDataAllocatorCB)(AMFComponent* pThis, AMFDataAllocatorCB* callback);
+
+        AMF_RESULT  (AMF_STD_CALL *GetCaps)(AMFComponent* pThis, AMFCaps** ppCaps);
+        AMF_RESULT  (AMF_STD_CALL *Optimize)(AMFComponent* pThis, AMFComponentOptimizationCallback* pCallback);
+    } AMFComponentVtbl;
+
+    struct AMFComponent
+    {
+        const AMFComponentVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // AMFInput interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFInput : public AMFPropertyStorageEx
+    {
+    public:
+        AMF_DECLARE_IID(0x1181eee7, 0x95f2, 0x434a, 0x9b, 0x96, 0xea, 0x55, 0xa, 0xa7, 0x84, 0x89)
+
+        virtual AMF_RESULT  AMF_STD_CALL SubmitInput(AMFData* pData) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFInput> AMFInputPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFInput, 0x1181eee7, 0x95f2, 0x434a, 0x9b, 0x96, 0xea, 0x55, 0xa, 0xa7, 0x84, 0x89)
+    typedef struct AMFInput AMFInput;
+
+    typedef struct AMFInputVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFInput* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFInput* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFInput* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFInput* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFInput* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFInput* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFInput* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFInput* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFInput* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFInput* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFInput* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFInput* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFInput* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFPropertyStorageEx interface
+
+        amf_size            (AMF_STD_CALL *GetPropertiesInfoCount)(AMFInput* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfoAt)(AMFInput* pThis, amf_size index, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfo)(AMFInput* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *ValidateProperty)(AMFInput* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated);
+
+        // AMFInput interface
+        AMF_RESULT          (AMF_STD_CALL *SubmitInput)(AMFInput* pThis, AMFData* pData);
+
+    } AMFInputVtbl;
+
+    struct AMFInput
+    {
+        const AMFInputVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+    // AMFOutput interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFOutput : public AMFPropertyStorageEx
+    {
+    public:
+        AMF_DECLARE_IID(0x86a8a037, 0x912c, 0x4698, 0xb0, 0x46, 0x7, 0x5a, 0x1f, 0xac, 0x6b, 0x97)
+
+        virtual AMF_RESULT  AMF_STD_CALL QueryOutput(AMFData** ppData) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFOutput> AMFOutputPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFOutput, 0x86a8a037, 0x912c, 0x4698, 0xb0, 0x46, 0x7, 0x5a, 0x1f, 0xac, 0x6b, 0x97)
+    typedef struct AMFOutput AMFOutput;
+
+    typedef struct AMFOutputVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFOutput* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFOutput* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFOutput* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFOutput* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFOutput* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFOutput* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFOutput* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFOutput* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFOutput* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFOutput* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFOutput* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFOutput* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFOutput* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFPropertyStorageEx interface
+
+        amf_size            (AMF_STD_CALL *GetPropertiesInfoCount)(AMFOutput* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfoAt)(AMFOutput* pThis, amf_size index, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfo)(AMFOutput* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *ValidateProperty)(AMFOutput* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated);
+
+        // AMFOutput interface
+        AMF_RESULT          (AMF_STD_CALL *QueryOutput)(AMFOutput* pThis, AMFData** ppData);
+
+    } AMFOutputVtbl;
+
+    struct AMFOutput
+    {
+        const AMFOutputVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // AMFComponent interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFComponentEx : public AMFComponent
+    {
+    public:
+        AMF_DECLARE_IID(0xfda792af, 0x8712, 0x44df, 0x8e, 0xa0, 0xdf, 0xfa, 0xad, 0x2c, 0x80, 0x93)
+
+        virtual amf_int32   AMF_STD_CALL GetInputCount() = 0;
+        virtual amf_int32   AMF_STD_CALL GetOutputCount() = 0;
+
+        virtual AMF_RESULT  AMF_STD_CALL GetInput(amf_int32 index, AMFInput** ppInput) = 0;
+        virtual AMF_RESULT  AMF_STD_CALL GetOutput(amf_int32 index, AMFOutput** ppOutput) = 0;
+
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFComponentEx> AMFComponentExPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFComponentEx, 0xfda792af, 0x8712, 0x44df, 0x8e, 0xa0, 0xdf, 0xfa, 0xad, 0x2c, 0x80, 0x93)
+    typedef struct AMFComponentEx AMFComponentEx;
+
+    typedef struct AMFComponentExVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFComponentEx* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFComponentEx* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFComponentEx* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFComponentEx* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFComponentEx* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFComponentEx* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFComponentEx* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFComponentEx* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFComponentEx* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFComponentEx* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFComponentEx* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFComponentEx* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFComponentEx* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFPropertyStorageEx interface
+
+        amf_size            (AMF_STD_CALL *GetPropertiesInfoCount)(AMFComponentEx* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfoAt)(AMFComponentEx* pThis, amf_size index, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfo)(AMFComponentEx* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *ValidateProperty)(AMFComponentEx* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated);
+
+        // AMFComponent interface
+
+        AMF_RESULT  (AMF_STD_CALL *Init)(AMFComponentEx* pThis, AMF_SURFACE_FORMAT format,amf_int32 width,amf_int32 height);
+        AMF_RESULT  (AMF_STD_CALL *ReInit)(AMFComponentEx* pThis, amf_int32 width,amf_int32 height);
+        AMF_RESULT  (AMF_STD_CALL *Terminate)(AMFComponentEx* pThis);
+        AMF_RESULT  (AMF_STD_CALL *Drain)(AMFComponentEx* pThis);
+        AMF_RESULT  (AMF_STD_CALL *Flush)(AMFComponentEx* pThis);
+
+        AMF_RESULT  (AMF_STD_CALL *SubmitInput)(AMFComponentEx* pThis, AMFData* pData);
+        AMF_RESULT  (AMF_STD_CALL *QueryOutput)(AMFComponentEx* pThis, AMFData** ppData);
+        AMFContext* (AMF_STD_CALL *GetContext)(AMFComponentEx* pThis);
+        AMF_RESULT  (AMF_STD_CALL *SetOutputDataAllocatorCB)(AMFComponentEx* pThis, AMFDataAllocatorCB* callback);
+
+        AMF_RESULT  (AMF_STD_CALL *GetCaps)(AMFComponentEx* pThis, AMFCaps** ppCaps);
+        AMF_RESULT  (AMF_STD_CALL *Optimize)(AMFComponentEx* pThis, AMFComponentOptimizationCallback* pCallback);
+
+        // AMFComponentEx interface
+
+        amf_int32   (AMF_STD_CALL *GetInputCount)(AMFComponentEx* pThis);
+        amf_int32   (AMF_STD_CALL *GetOutputCount)(AMFComponentEx* pThis);
+
+        AMF_RESULT  (AMF_STD_CALL *GetInput)(AMFComponentEx* pThis, amf_int32 index, AMFInput** ppInput);
+        AMF_RESULT  (AMF_STD_CALL *GetOutput)(AMFComponentEx* pThis, amf_int32 index, AMFOutput** ppOutput);
+
+
+    } AMFComponentExVtbl;
+
+    struct AMFComponentEx
+    {
+        const AMFComponentExVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+
+
+#if defined(__cplusplus)
+} // namespace
+#endif
+
+typedef enum AMF_STREAM_TYPE_ENUM
+{
+    AMF_STREAM_UNKNOWN              = 0,
+    AMF_STREAM_VIDEO                = 1,
+    AMF_STREAM_AUDIO                = 2,
+    AMF_STREAM_DATA                 = 3,
+} AMF_STREAM_TYPE_ENUM;
+
+typedef enum AMF_STREAM_CODEC_ID_ENUM     // matched codecs from VideoDecoxcderUVD.h
+{
+    AMF_STREAM_CODEC_ID_UNKNOWN     = 0,
+    AMF_STREAM_CODEC_ID_MPEG2       = 1,  // AMFVideoDecoderUVD_MPEG2      
+    AMF_STREAM_CODEC_ID_MPEG4       = 2,  // AMFVideoDecoderUVD_MPEG4      
+    AMF_STREAM_CODEC_ID_WMV3        = 3,  // AMFVideoDecoderUVD_WMV3       
+    AMF_STREAM_CODEC_ID_VC1         = 4,  // AMFVideoDecoderUVD_VC1        
+    AMF_STREAM_CODEC_ID_H264_AVC    = 5,  // AMFVideoDecoderUVD_H264_AVC   
+    AMF_STREAM_CODEC_ID_H264_MVC    = 6,  // AMFVideoDecoderUVD_H264_MVC   
+    AMF_STREAM_CODEC_ID_H264_SVC    = 7,  // AMFVideoDecoderUVD_H264_SVC   
+    AMF_STREAM_CODEC_ID_MJPEG       = 8,  // AMFVideoDecoderUVD_MJPEG      
+    AMF_STREAM_CODEC_ID_H265_HEVC   = 9,  // AMFVideoDecoderHW_H265_HEVC   
+    AMF_STREAM_CODEC_ID_H265_MAIN10 = 10, // AMFVideoDecoderHW_H265_MAIN10 
+    AMF_STREAM_CODEC_ID_VP9         = 11, // AMFVideoDecoderHW_VP9
+    AMF_STREAM_CODEC_ID_VP9_10BIT   = 12, // AMFVideoDecoderHW_VP9_10BIT   
+    AMF_STREAM_CODEC_ID_AV1         = 13, // AMFVideoDecoderHW_AV1 
+} AMF_STREAM_CODEC_ID_ENUM;
+
+// common stream properties
+#define AMF_STREAM_TYPE                     L"StreamType"           // amf_int64( AMF_STREAM_TYPE_ENUM )
+#define AMF_STREAM_ENABLED                  L"Enabled"              // bool( default = false )
+#define AMF_STREAM_CODEC_ID                 L"CodecID"              // amf_int64(Video: AMF_STREAM_CODEC_ID_ENUM, Audio: AVCodecID) (default = 0 - uncompressed)
+#define AMF_STREAM_BIT_RATE                 L"BitRate"              // amf_int64 (default = codec->bit_rate)
+#define AMF_STREAM_EXTRA_DATA               L"ExtraData"            // interface to AMFBuffer - as is from FFMPEG
+
+// video stream properties
+#define AMF_STREAM_VIDEO_MEMORY_TYPE        L"VideoMemoryType"      // amf_int64(AMF_MEMORY_TYPE); default = AMF_MEMORY_DX11
+#define AMF_STREAM_VIDEO_FORMAT             L"VideoFormat"          // amf_int64(AMF_SURFACE_FORMAT); default = AMF_SURFACE_NV12 (used if AMF_STREAM_CODEC_ID == 0)
+#define AMF_STREAM_VIDEO_FRAME_RATE         L"VideoFrameRate"       // AMFRate; default = (30,1) - video frame rate
+#define AMF_STREAM_VIDEO_FRAME_SIZE         L"VideoFrameSize"       // AMFSize; default = (1920,1080) - video frame rate
+#define AMF_STREAM_VIDEO_SURFACE_POOL       L"VideoSurfacePool"     // amf_int64; default = 5, number of allocated output surfaces
+//TODO support interlaced frames
+
+// audio stream properties
+#define AMF_STREAM_AUDIO_FORMAT             L"AudioFormat"          // amf_int64(AMF_AUDIO_FORMAT); default = AMFAF_S16
+#define AMF_STREAM_AUDIO_SAMPLE_RATE        L"AudioSampleRate"      // amf_int64; default = 48000
+#define AMF_STREAM_AUDIO_CHANNELS           L"AudioChannels"        // amf_int64; default = 2
+#define AMF_STREAM_AUDIO_CHANNEL_LAYOUT     L"AudioChannelLayout"   // amf_int64 (default = codec->channel_layout)
+#define AMF_STREAM_AUDIO_BLOCK_ALIGN        L"AudioBlockAlign"      // amf_int64 (default = codec->block_align)
+#define AMF_STREAM_AUDIO_FRAME_SIZE         L"AudioFrameSize"       // amf_int64 (default = codec->frame_size)
+
+
+#endif //#ifndef AMF_Component_h

+ 172 - 0
plugins/obs-ffmpeg/external/AMF/include/components/ComponentCaps.h

@@ -0,0 +1,172 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_ComponentCaps_h
+#define AMF_ComponentCaps_h
+
+#pragma once
+
+#include "../core/Interface.h"
+#include "../core/PropertyStorage.h"
+#include "../core/Surface.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    typedef enum AMF_ACCELERATION_TYPE
+    {
+        AMF_ACCEL_NOT_SUPPORTED = -1,
+        AMF_ACCEL_HARDWARE,
+        AMF_ACCEL_GPU,
+        AMF_ACCEL_SOFTWARE
+    } AMF_ACCELERATION_TYPE;
+    //----------------------------------------------------------------------------------------------
+    // AMFIOCaps interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFIOCaps : public AMFInterface
+    {
+    public:
+        //  Get supported resolution ranges in pixels/lines:
+        virtual void AMF_STD_CALL GetWidthRange(amf_int32* minWidth, amf_int32* maxWidth) const = 0;
+        virtual void AMF_STD_CALL GetHeightRange(amf_int32* minHeight, amf_int32* maxHeight) const = 0;
+
+        //  Get memory alignment in lines: Vertical aligmnent should be multiples of this number
+        virtual amf_int32 AMF_STD_CALL GetVertAlign() const = 0;
+        
+        //  Enumerate supported surface pixel formats
+        virtual amf_int32 AMF_STD_CALL GetNumOfFormats() const = 0;
+        virtual  AMF_RESULT AMF_STD_CALL GetFormatAt(amf_int32 index, AMF_SURFACE_FORMAT* format, amf_bool* native) const = 0;
+
+        //  Enumerate supported memory types
+        virtual amf_int32 AMF_STD_CALL GetNumOfMemoryTypes() const = 0;
+        virtual AMF_RESULT AMF_STD_CALL GetMemoryTypeAt(amf_int32 index, AMF_MEMORY_TYPE* memType, amf_bool* native) const = 0;
+
+        virtual amf_bool AMF_STD_CALL IsInterlacedSupported() const = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFIOCaps>    AMFIOCapsPtr;
+#else // #if defined(__cplusplus)
+    typedef struct AMFIOCaps AMFIOCaps;
+
+    typedef struct AMFIOCapsVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFIOCaps* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFIOCaps* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFIOCaps* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFIOCaps interface
+        //  Get supported resolution ranges in pixels/lines:
+        void (AMF_STD_CALL *GetWidthRange)(AMFIOCaps* pThis, amf_int32* minWidth, amf_int32* maxWidth);
+        void (AMF_STD_CALL *GetHeightRange)(AMFIOCaps* pThis, amf_int32* minHeight, amf_int32* maxHeight);
+
+        //  Get memory alignment in lines: Vertical aligmnent should be multiples of this number
+        amf_int32 (AMF_STD_CALL *GetVertAlign)(AMFIOCaps* pThis);
+        
+        //  Enumerate supported surface pixel formats
+        amf_int32 (AMF_STD_CALL *GetNumOfFormats)(AMFIOCaps* pThis);
+        AMF_RESULT (AMF_STD_CALL *GetFormatAt)(AMFIOCaps* pThis, amf_int32 index, AMF_SURFACE_FORMAT* format, amf_bool* native);
+
+        //  Enumerate supported memory types
+        amf_int32 (AMF_STD_CALL *GetNumOfMemoryTypes)(AMFIOCaps* pThis);
+        AMF_RESULT (AMF_STD_CALL *GetMemoryTypeAt)(AMFIOCaps* pThis, amf_int32 index, AMF_MEMORY_TYPE* memType, amf_bool* native);
+
+        amf_bool (AMF_STD_CALL *IsInterlacedSupported)(AMFIOCaps* pThis);
+    } AMFIOCapsVtbl;
+
+    struct AMFIOCaps
+    {
+        const AMFIOCapsVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+   
+    //----------------------------------------------------------------------------------------------
+    // AMFCaps interface - base interface for every h/w module supported by Capability Manager
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFCaps : public AMFPropertyStorage
+    {
+    public:
+        virtual AMF_ACCELERATION_TYPE AMF_STD_CALL GetAccelerationType() const = 0;
+        virtual AMF_RESULT AMF_STD_CALL GetInputCaps(AMFIOCaps** input) = 0;
+        virtual AMF_RESULT AMF_STD_CALL GetOutputCaps(AMFIOCaps** output) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFCaps>  AMFCapsPtr;
+#else // #if defined(__cplusplus)
+    typedef struct AMFCaps AMFCaps;
+
+    typedef struct AMFCapsVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFCaps* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFCaps* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFCaps* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFCaps* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFCaps* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFCaps* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFCaps* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFCaps* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFCaps* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFCaps* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFCaps* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFCaps* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFCaps* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFCaps interface
+
+        AMF_ACCELERATION_TYPE (AMF_STD_CALL *GetAccelerationType)(AMFCaps* pThis);
+        AMF_RESULT (AMF_STD_CALL *GetInputCaps)(AMFCaps* pThis, AMFIOCaps** input);
+        AMF_RESULT (AMF_STD_CALL *GetOutputCaps)(AMFCaps* pThis, AMFIOCaps** output);
+    } AMFCapsVtbl;
+
+    struct AMFCaps
+    {
+        const AMFCapsVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //#ifndef AMF_ComponentCaps_h

+ 53 - 0
plugins/obs-ffmpeg/external/AMF/include/components/CursorCapture.h

@@ -0,0 +1,53 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// Cursor capture interface declaration
+//-------------------------------------------------------------------------------------------------
+
+#ifndef AMF_CursorCapture_h
+#define AMF_CursorCapture_h
+#pragma once
+
+namespace amf
+{
+    class AMFCursorCapture : public AMFInterface
+    {
+    public:
+        virtual AMF_RESULT AMF_STD_CALL AcquireCursor(amf::AMFSurface** pSurface) = 0;
+        virtual AMF_RESULT AMF_STD_CALL Reset() = 0;
+    };
+
+    typedef AMFInterfacePtr_T<AMFCursorCapture> AMFCursorCapturePtr;
+}
+
+#endif // #ifndef AMF_CursorCapture_h

+ 81 - 0
plugins/obs-ffmpeg/external/AMF/include/components/DisplayCapture.h

@@ -0,0 +1,81 @@
+//
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+//
+// MIT license
+//
+// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// Desktop duplication interface declaration
+//-------------------------------------------------------------------------------------------------
+
+#ifndef AMF_DisplayCapture_h
+#define AMF_DisplayCapture_h
+#pragma once
+
+#include "Component.h"
+
+extern "C"
+{
+    // To create capture component with Desktop Duplication API use this function
+    AMF_RESULT AMF_CDECL_CALL AMFCreateComponentDisplayCapture(amf::AMFContext* pContext, void* reserved, amf::AMFComponent** ppComponent);
+}
+
+// To create AMD Direct Capture component use this component ID with AMFFactory::CreateComponent()
+#define AMFDisplayCapture L"AMFDisplayCapture"
+
+// Static properties
+//
+typedef enum AMF_DISPLAYCAPTURE_MODE_ENUM
+{
+    AMF_DISPLAYCAPTURE_MODE_KEEP_FRAMERATE      = 0, // capture component maintains the frame rate and returns current visible surface
+    AMF_DISPLAYCAPTURE_MODE_WAIT_FOR_PRESENT    = 1, // capture component waits for flip (present) event
+    AMF_DISPLAYCAPTURE_MODE_GET_CURRENT_SURFACE = 2, // returns current visible surface immediately
+} AMF_DISPLAYCAPTURE_MODE_ENUM;
+
+
+#define AMF_DISPLAYCAPTURE_MONITOR_INDEX            L"MonitorIndex"             // amf_int64, default = 0, Index of the display monitor; is determined by using EnumAdapters() in DXGI.
+#define AMF_DISPLAYCAPTURE_MODE                     L"CaptureMode"              // amf_int64(AMF_DISPLAYCAPTURE_MODE_ENUM), default =  AMF_DISPLAYCAPTURE_MODE_FRAMERATE, controls wait logic
+#define AMF_DISPLAYCAPTURE_FRAMERATE                L"FrameRate"                // AMFRate,  default = (0, 1) Capture framerate, if 0 - capture rate will be driven by flip event from fullscreen app or DWM
+#define AMF_DISPLAYCAPTURE_CURRENT_TIME_INTERFACE   L"CurrentTimeInterface"     // AMFInterface(AMFCurrentTime) Optional interface object for providing  timestamps.
+#define AMF_DISPLAYCAPTURE_FORMAT                   L"CurrentFormat"            // amf_int64(AMF_SURFACE_FORMAT) Capture format - read-only
+#define AMF_DISPLAYCAPTURE_RESOLUTION               L"Resolution"               // AMFSize - screen resolution - read-only
+#define AMF_DISPLAYCAPTURE_DUPLICATEOUTPUT          L"DuplicateOutput"          // amf_bool, default = false, output AMF surface is a copy of captured
+#define AMF_DISPLAYCAPTURE_DESKTOP_RECT             L"DesktopRect"              // AMFRect - rect of the capture desktop - read-only
+#define AMF_DISPLAYCAPTURE_ENABLE_DIRTY_RECTS       L"EnableDirtyRects"         // amf_bool, default = false, enable dirty rectangles attached to output as AMF_DISPLAYCAPTURE_DIRTY_RECTS
+#define AMF_DISPLAYCAPTURE_DRAW_DIRTY_RECTS         L"DrawDirtyRects"           // amf_bool, default = false, copies capture output and draws dirty rectangles with red - for debugging only
+#define AMF_DISPLAYCAPTURE_ROTATION                 L"Rotation"                 // amf_int64(AMF_ROTATION_ENUM); default = AMF_ROTATION_NONE, monitor rotation state
+
+// Properties that can be set on output AMFSurface
+#define AMF_DISPLAYCAPTURE_DIRTY_RECTS              L"DirtyRects"               // AMFInterface*(AMFBuffer*) - array of AMFRect(s)
+#define AMF_DISPLAYCAPTURE_FRAME_INDEX              L"FrameIndex"               // amf_int64; default = 0, index of presented frame since capture started
+#define AMF_DISPLAYCAPTURE_FRAME_FLIP_TIMESTAMP     L"FlipTimesamp"             // amf_int64; default = 0, flip timestmap of presented frame
+// see Surface.h
+//#define AMF_SURFACE_ROTATION         L"Rotation"    // amf_int64(AMF_ROTATION_ENUM); default = AMF_ROTATION_NONE, can be set on surfaces - the same value as AMF_DISPLAYCAPTURE_ROTATION
+
+#endif // #ifndef AMF_DisplayCapture_h

+ 62 - 0
plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioConverter.h

@@ -0,0 +1,62 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// AMFFAudioConverterFFMPEG  interface declaration
+//-------------------------------------------------------------------------------------------------
+
+#ifndef AMF_AudioConverterFFMPEG_h
+#define AMF_AudioConverterFFMPEG_h
+
+#pragma once
+
+
+#define FFMPEG_AUDIO_CONVERTER    L"AudioConverterFFMPEG"
+
+
+#define AUDIO_CONVERTER_IN_AUDIO_BIT_RATE             L"In_BitRate"                 // amf_int64 (default = 128000)
+#define AUDIO_CONVERTER_IN_AUDIO_SAMPLE_RATE          L"In_SampleRate"              // amf_int64 (default = 0)
+#define AUDIO_CONVERTER_IN_AUDIO_CHANNELS             L"In_Channels"                // amf_int64 (default = 2)
+#define AUDIO_CONVERTER_IN_AUDIO_SAMPLE_FORMAT        L"In_SampleFormat"            // amf_int64 (default = AMFAF_UNKNOWN)  (AMF_AUDIO_FORMAT)
+#define AUDIO_CONVERTER_IN_AUDIO_CHANNEL_LAYOUT       L"In_ChannelLayout"           // amf_int64 (default = 0)
+#define AUDIO_CONVERTER_IN_AUDIO_BLOCK_ALIGN          L"In_BlockAlign"              // amf_int64 (default = 0)
+
+#define AUDIO_CONVERTER_OUT_AUDIO_BIT_RATE            L"Out_BitRate"                // amf_int64 (default = 128000)
+#define AUDIO_CONVERTER_OUT_AUDIO_SAMPLE_RATE         L"Out_SampleRate"             // amf_int64 (default = 0)
+#define AUDIO_CONVERTER_OUT_AUDIO_CHANNELS            L"Out_Channels"               // amf_int64 (default = 2)
+#define AUDIO_CONVERTER_OUT_AUDIO_SAMPLE_FORMAT       L"Out_SampleFormat"           // amf_int64 (default = AMFAF_UNKNOWN)  (AMF_AUDIO_FORMAT)
+#define AUDIO_CONVERTER_OUT_AUDIO_CHANNEL_LAYOUT      L"Out_ChannelLayout"          // amf_int64 (default = 0)
+#define AUDIO_CONVERTER_OUT_AUDIO_BLOCK_ALIGN         L"Out_BlockAlign"             // amf_int64 (default = 0)
+
+
+
+#endif //#ifndef AMF_AudioConverterFFMPEG_h

+ 68 - 0
plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioDecoder.h

@@ -0,0 +1,68 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// AudioDecoderFFMPEG  interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_AudioDecoderFFMPEG_h
+#define AMF_AudioDecoderFFMPEG_h
+
+#pragma once
+
+
+#define FFMPEG_AUDIO_DECODER    L"AudioDecoderFFMPEG"
+
+
+#define AUDIO_DECODER_ENABLE_DEBUGGING              L"EnableDebug"                  // bool (default = false) - trace some debug information if set to true
+#define AUDIO_DECODER_ENABLE_DECODING               L"EnableDecoding"               // bool (default = true) - if false, component will not decode anything
+
+#define AUDIO_DECODER_IN_AUDIO_CODEC_ID             L"In_CodecID"                   // amf_int64 (default = AV_CODEC_ID_NONE) - FFMPEG codec ID
+#define AUDIO_DECODER_IN_AUDIO_BIT_RATE             L"In_BitRate"                   // amf_int64 (default = 128000)
+#define AUDIO_DECODER_IN_AUDIO_EXTRA_DATA           L"In_ExtraData"                 // interface to AMFBuffer
+#define AUDIO_DECODER_IN_AUDIO_SAMPLE_RATE          L"In_SampleRate"                // amf_int64 (default = 0)
+#define AUDIO_DECODER_IN_AUDIO_CHANNELS             L"In_Channels"                  // amf_int64 (default = 2)
+#define AUDIO_DECODER_IN_AUDIO_SAMPLE_FORMAT        L"In_SampleFormat"              // amf_int64 (default = AMFAF_UNKNOWN)  (AMF_AUDIO_FORMAT)
+#define AUDIO_DECODER_IN_AUDIO_CHANNEL_LAYOUT       L"In_ChannelLayout"             // amf_int64 (default = 0)
+#define AUDIO_DECODER_IN_AUDIO_BLOCK_ALIGN          L"In_BlockAlign"                // amf_int64 (default = 0)
+#define AUDIO_DECODER_IN_AUDIO_FRAME_SIZE           L"In_FrameSize"                 // amf_int64 (default = 0)
+#define AUDIO_DECODER_IN_AUDIO_SEEK_POSITION        L"In_SeekPosition"              // amf_int64 (default = 0)
+
+#define AUDIO_DECODER_OUT_AUDIO_BIT_RATE            L"Out_BitRate"                  // amf_int64 (default = 128000)
+#define AUDIO_DECODER_OUT_AUDIO_SAMPLE_RATE         L"Out_SampleRate"               // amf_int64 (default = 0)
+#define AUDIO_DECODER_OUT_AUDIO_CHANNELS            L"Out_Channels"                 // amf_int64 (default = 2)
+#define AUDIO_DECODER_OUT_AUDIO_SAMPLE_FORMAT       L"Out_SampleFormat"             // amf_int64 (default = AMFAF_UNKNOWN)  (AMF_AUDIO_FORMAT)
+#define AUDIO_DECODER_OUT_AUDIO_CHANNEL_LAYOUT      L"Out_ChannelLayout"            // amf_int64 (default = 0)
+#define AUDIO_DECODER_OUT_AUDIO_BLOCK_ALIGN         L"Out_BlockAlign"               // amf_int64 (default = 0)
+
+
+
+#endif //#ifndef AMF_AudioDecoderFFMPEG_h

+ 66 - 0
plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioEncoder.h

@@ -0,0 +1,66 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// AudioEncoderFFMPEG  interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_AudioEncoderFFMPEG_h
+#define AMF_AudioEncoderFFMPEG_h
+
+#pragma once
+
+
+#define FFMPEG_AUDIO_ENCODER    L"AudioEncoderFFMPEG"
+
+
+#define AUDIO_ENCODER_ENABLE_DEBUGGING              L"EnableDebug"                  // bool (default = false) - trace some debug information if set to true
+#define AUDIO_ENCODER_ENABLE_ENCODING               L"EnableEncoding"               // bool (default = true) - if false, component will not encode anything
+#define AUDIO_ENCODER_AUDIO_CODEC_ID                L"CodecID"                      // amf_int64 (default = AV_CODEC_ID_NONE) - FFMPEG codec ID
+
+#define AUDIO_ENCODER_IN_AUDIO_SAMPLE_RATE          L"In_SampleRate"                // amf_int64 (default = 44100)
+#define AUDIO_ENCODER_IN_AUDIO_CHANNELS             L"In_Channels"                  // amf_int64 (default = 2)
+#define AUDIO_ENCODER_IN_AUDIO_SAMPLE_FORMAT        L"In_SampleFormat"              // amf_int64 (default = AMFAF_S16)  (AMF_AUDIO_FORMAT)
+#define AUDIO_ENCODER_IN_AUDIO_CHANNEL_LAYOUT       L"In_ChannelLayout"             // amf_int64 (default = 3)
+#define AUDIO_ENCODER_IN_AUDIO_BLOCK_ALIGN          L"In_BlockAlign"                // amf_int64 (default = 0)
+
+#define AUDIO_ENCODER_OUT_AUDIO_BIT_RATE            L"Out_BitRate"                  // amf_int64 (default = 128000)
+#define AUDIO_ENCODER_OUT_AUDIO_EXTRA_DATA          L"Out_ExtraData"                // interface to AMFBuffer
+#define AUDIO_ENCODER_OUT_AUDIO_SAMPLE_RATE         L"Out_SampleRate"               // amf_int64 (default = 44100)
+#define AUDIO_ENCODER_OUT_AUDIO_CHANNELS            L"Out_Channels"                 // amf_int64 (default = 2)
+#define AUDIO_ENCODER_OUT_AUDIO_SAMPLE_FORMAT       L"Out_SampleFormat"             // amf_int64 (default = AMFAF_S16)  (AMF_AUDIO_FORMAT)
+#define AUDIO_ENCODER_OUT_AUDIO_CHANNEL_LAYOUT      L"Out_ChannelLayout"            // amf_int64 (default = 0)
+#define AUDIO_ENCODER_OUT_AUDIO_BLOCK_ALIGN         L"Out_BlockAlign"               // amf_int64 (default = 0)
+#define AUDIO_ENCODER_OUT_AUDIO_FRAME_SIZE          L"Out_FrameSize"                // amf_int64 (default = 0)
+
+
+
+#endif //#ifndef AMF_AudioEncoderFFMPEG_h

+ 54 - 0
plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGComponents.h

@@ -0,0 +1,54 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// FFMPEG components definitions
+//-------------------------------------------------------------------------------------------------
+ 
+#ifndef AMF_ComponentsFFMPEG_h
+#define AMF_ComponentsFFMPEG_h
+
+#pragma once
+
+
+#if defined(_WIN32)
+    #if defined(_M_AMD64)
+        #define FFMPEG_DLL_NAME    L"amf-component-ffmpeg64.dll"
+    #else
+        #define FFMPEG_DLL_NAME    L"amf-component-ffmpeg32.dll"
+    #endif
+#elif defined(__linux)
+    #define FFMPEG_DLL_NAME    L"amf-component-ffmpeg.so"
+#endif
+
+
+#endif //#ifndef AMF_ComponentsFFMPEG_h

+ 66 - 0
plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileDemuxer.h

@@ -0,0 +1,66 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// DemuxerFFMPEG  interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_FileDemuxerFFMPEG_h
+#define AMF_FileDemuxerFFMPEG_h
+
+#pragma once
+
+#define FFMPEG_DEMUXER L"DemuxerFFMPEG"
+
+
+// component properties
+#define FFMPEG_DEMUXER_PATH                     L"Path"                     // string - the file to open
+#define FFMPEG_DEMUXER_URL                      L"Url"                      // string - the stream url to open
+#define FFMPEG_DEMUXER_START_FRAME              L"StartFrame"               // amf_int64 (default = 0)
+#define FFMPEG_DEMUXER_FRAME_COUNT              L"FramesNumber"             // amf_int64 (default = 0)
+#define FFMPEG_DEMUXER_DURATION                 L"Duration"                 // amf_int64 (default = 0)
+#define FFMPEG_DEMUXER_CHECK_MVC                L"CheckMVC"                 // bool (default = true)
+//#define FFMPEG_DEMUXER_SYNC_AV                  L"SyncAV"                   // bool (default = false)
+#define FFMPEG_DEMUXER_INDIVIDUAL_STREAM_MODE   L"StreamMode"               // bool (default = true)
+#define FFMPEG_DEMUXER_LISTEN                   L"Listen"                   // bool (default = false)
+
+// for common, video and audio properties see Component.h
+
+
+// video stream properties
+#define FFMPEG_DEMUXER_VIDEO_PIXEL_ASPECT_RATIO L"PixelAspectRatio"         // double (default = calculated)
+#define FFMPEG_DEMUXER_VIDEO_CODEC              L"FFmpegCodec"              // enum (from source)
+
+
+// buffer properties
+#define FFMPEG_DEMUXER_BUFFER_TYPE              L"BufferType"               // amf_int64 ( AMF_STREAM_TYPE_ENUM )
+#define FFMPEG_DEMUXER_BUFFER_STREAM_INDEX      L"BufferStreamIndexType"    // amf_int64 ( stream index )
+#endif //#ifndef AMF_FileDemuxerFFMPEG_h

+ 53 - 0
plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileMuxer.h

@@ -0,0 +1,53 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// MuxerFFMPEG  interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_FileMuxerFFMPEG_h
+#define AMF_FileMuxerFFMPEG_h
+
+#pragma once
+
+#define FFMPEG_MUXER L"MuxerFFMPEG"
+
+
+// component properties
+#define FFMPEG_MUXER_PATH                     L"Path"                     // string - the file to open
+#define FFMPEG_MUXER_URL                      L"Url"                      // string - the stream url to open
+#define FFMPEG_MUXER_LISTEN                   L"Listen"                   // bool (default = false)
+#define FFMPEG_MUXER_ENABLE_VIDEO             L"EnableVideo"              // bool (default = true)
+#define FFMPEG_MUXER_ENABLE_AUDIO             L"EnableAudio"              // bool (default = false)
+#define FFMPEG_MUXER_CURRENT_TIME_INTERFACE   L"CurrentTimeInterface"
+#define FFMPEG_MUXER_VIDEO_ROTATION           L"VideoRotation"            // amf_int64 (0, 90, 180, 270, default = 0)
+
+#endif //#ifndef AMF_FileMuxerFFMPEG_h

+ 53 - 0
plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGVideoDecoder.h

@@ -0,0 +1,53 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// VideoDecoderFFMPEG  interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_VideoDecoderFFMPEG_h
+#define AMF_VideoDecoderFFMPEG_h
+
+#pragma once
+
+#define FFMPEG_VIDEO_DECODER    L"VideoDecoderFFMPEG"
+
+#define VIDEO_DECODER_ENABLE_DECODING      L"EnableDecoding"   // bool (default = true) - if false, component will not decode anything
+#define VIDEO_DECODER_CODEC_ID             L"CodecID"          // amf_int64 (AMF_STREAM_CODEC_ID_ENUM) codec ID
+#define VIDEO_DECODER_EXTRA_DATA           L"ExtraData"        // interface to AMFBuffer
+#define VIDEO_DECODER_RESOLUTION           L"Resolution"       // AMFSize 
+#define VIDEO_DECODER_BITRATE              L"BitRate"          // amf_int64 (default = 0)
+#define VIDEO_DECODER_FRAMERATE            L"FrameRate"        // AMFRate
+#define VIDEO_DECODER_SEEK_POSITION        L"SeekPosition"     // amf_int64 (default = 0)
+
+#define VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC L"ColorTransferChar"    // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013   7.2
+
+#endif //#ifndef AMF_VideoDecoderFFMPEG_h

+ 64 - 0
plugins/obs-ffmpeg/external/AMF/include/components/HQScaler.h

@@ -0,0 +1,64 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMFHQScaler_h
+#define AMFHQScaler_h
+
+#pragma once
+
+#define AMFHQScaler L"AMFHQScaler"
+
+
+// various types of algorithms supported by the high-quality scaler
+enum  AMF_HQ_SCALER_ALGORITHM_ENUM
+{
+    AMF_HQ_SCALER_ALGORITHM_BILINEAR = 0,
+    AMF_HQ_SCALER_ALGORITHM_BICUBIC = 1,
+    AMF_HQ_SCALER_ALGORITHM_FSR = 2,
+
+};
+
+
+// PA object properties
+#define AMF_HQ_SCALER_ALGORITHM         L"HQScalerAlgorithm"        // amf_int64(AMF_HQ_SCALER_ALGORITHM_ENUM) (Bi-linear, Bi-cubic, RCAS, Auto)"      - determines which scaling algorithm will be used
+                                                                    //                                                                                   auto will chose best option between algorithms available
+#define AMF_HQ_SCALER_ENGINE_TYPE       L"HQScalerEngineType"       // AMF_MEMORY_TYPE (DX11, DX12, OPENCL, VULKAN default : DX11)"                    - determines how the object is initialized and what kernels to use
+
+#define AMF_HQ_SCALER_OUTPUT_SIZE       L"HQSOutputSize"            // AMFSize                                                                         - output scaling width/hieight
+
+#define AMF_HQ_SCALER_KEEP_ASPECT_RATIO  L"KeepAspectRatio"         // bool (default=false) Keep aspect ratio if scaling. 
+#define AMF_HQ_SCALER_FILL               L"Fill"                    // bool (default=false) fill area out of ROI. 
+#define AMF_HQ_SCALER_FILL_COLOR         L"FillColor"               // AMFColor 
+#define AMF_HQ_SCALER_FROM_SRGB          L"FromSRGB"                   //  bool (default=true) Convert to SRGB. 
+
+
+#endif //#ifndef AMFHQScaler_h

+ 79 - 0
plugins/obs-ffmpeg/external/AMF/include/components/MediaSource.h

@@ -0,0 +1,79 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_MediaSource_h
+#define AMF_MediaSource_h
+
+#pragma once
+
+#include "public/include/core/Interface.h"
+
+namespace amf
+{
+    enum AMF_SEEK_TYPE
+    {
+        AMF_SEEK_PREV = 0,           // nearest packet before pts
+        AMF_SEEK_NEXT = 1,           // nearest packet after pts
+        AMF_SEEK_PREV_KEYFRAME = 2,  // nearest keyframe packet before pts
+        AMF_SEEK_NEXT_KEYFRAME = 3,  // nearest keyframe packet after pts
+    };
+
+    //----------------------------------------------------------------------------------------------
+    // media source interface.  
+    //----------------------------------------------------------------------------------------------
+    class AMFMediaSource : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0xb367695a, 0xdbd0, 0x4430, 0x95, 0x3b, 0xbc, 0x7d, 0xbd, 0x2a, 0xa7, 0x66)
+
+        // interface
+        virtual AMF_RESULT  AMF_STD_CALL Seek(amf_pts pos, AMF_SEEK_TYPE seekType, amf_int32 whichStream) = 0;
+        virtual amf_pts     AMF_STD_CALL GetPosition() = 0;
+        virtual amf_pts     AMF_STD_CALL GetDuration() = 0;
+
+        virtual void        AMF_STD_CALL SetMinPosition(amf_pts pts) = 0;
+        virtual amf_pts     AMF_STD_CALL GetMinPosition() = 0;
+        virtual void        AMF_STD_CALL SetMaxPosition(amf_pts pts) = 0;
+        virtual amf_pts     AMF_STD_CALL GetMaxPosition() = 0;
+
+        virtual amf_uint64  AMF_STD_CALL GetFrameFromPts(amf_pts pts) = 0;
+        virtual amf_pts     AMF_STD_CALL GetPtsFromFrame(amf_uint64 frame) = 0;
+
+        virtual bool        AMF_STD_CALL SupportFramesAccess() = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFMediaSource> AMFMediaSourcePtr;
+} //namespace amf
+
+#endif //#ifndef AMF_MediaSource_h

+ 110 - 0
plugins/obs-ffmpeg/external/AMF/include/components/PreAnalysis.h

@@ -0,0 +1,110 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2019 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMFPreAnalysis_h
+#define AMFPreAnalysis_h
+
+#pragma once
+
+#define AMFPreAnalysis L"AMFPreAnalysis"
+
+
+
+enum  AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_ENUM
+{
+    AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_LOW    = 0,
+    AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_MEDIUM = 1,
+    AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_HIGH   = 2
+};
+
+
+enum  AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_ENUM
+{	
+	AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_LOW    = 0,
+	AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_MEDIUM = 1,
+	AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_HIGH   = 2
+};
+
+
+enum  AMF_PA_ACTIVITY_TYPE_ENUM
+{
+    AMF_PA_ACTIVITY_Y   = 0,
+    AMF_PA_ACTIVITY_YUV = 1
+};
+
+
+enum  AMF_PA_CAQ_STRENGTH_ENUM
+{
+    AMF_PA_CAQ_STRENGTH_LOW    = 0,
+    AMF_PA_CAQ_STRENGTH_MEDIUM = 1,
+    AMF_PA_CAQ_STRENGTH_HIGH   = 2
+};
+
+
+
+// PA object properties
+#define AMF_PA_ENGINE_TYPE                          L"PAEngineType"                         // AMF_MEMORY_TYPE (Host, DX11, OpenCL, Vulkan, Auto default : UNKNOWN (Auto))" - determines how the object is initialized and what kernels to use
+                                                                                            //                                                                        by default it is Auto (DX11, OpenCL and Vulkan are currently available)
+
+#define AMF_PA_SCENE_CHANGE_DETECTION_ENABLE        L"PASceneChangeDetectionEnable"         // bool       (default : True)                                          - Enable Scene Change Detection GPU algorithm
+#define AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY   L"PASceneChangeDetectionSensitivity"	// AMF_PA_SCENE_CHANGE_DETECTION_SENSITIVITY_ENUM (default : Medium)    - Scene Change Detection Sensitivity
+#define AMF_PA_STATIC_SCENE_DETECTION_ENABLE        L"PAStaticSceneDetectionEnable"         // bool       (default : True)                                          - Enable Skip Detection GPU algorithm
+#define AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY   L"PAStaticSceneDetectionSensitivity"	// AMF_PA_STATIC_SCENE_DETECTION_SENSITIVITY_ENUM (default : High)      - Allowable absolute difference between pixels (sample counts)
+#define AMF_PA_FRAME_SAD_ENABLE                     L"PAFrameSadEnable"	                    // bool       (default : True)                                          - Enable Frame SAD algorithm
+#define AMF_PA_ACTIVITY_TYPE                        L"PAActivityType"                       // AMF_PA_ACTIVITY_TYPE_ENUM (default : Calculate on Y)                 - Block activity calculation mode
+#define AMF_PA_LTR_ENABLE                           L"PALongTermReferenceEnable"            // bool       (default : True)                                          - Enable Automatic Long Term Reference frame management
+
+
+
+///////////////////////////////////////////
+// the following properties are available 
+// only through the Encoder - trying to 
+// access/set them when PA is standalone
+// will fail
+
+
+#define AMF_PA_INITIAL_QP_AFTER_SCENE_CHANGE        L"PAInitialQPAfterSceneChange"          // amf_uint64 (default : 0)           Values: [0, 51]                   - Base QP to be used immediately after scene change. If this value is not set, PA will choose a proper QP value
+#define AMF_PA_MAX_QP_BEFORE_FORCE_SKIP             L"PAMaxQPBeforeForceSkip"               // amf_uint64 (default : 35)          Values: [0, 51]                   - When a static scene is detected, a skip frame is inserted only if the previous encoded frame average QP <= this value
+
+
+#define AMF_PA_CAQ_STRENGTH                         L"PACAQStrength"                        // AMF_PA_CAQ_STRENGTH_ENUM (default : Medium)                          - Content Adaptive Quantization (CAQ) strength
+
+
+
+
+//////////////////////////////////////////////////
+// properties set by PA on output buffer interface
+#define AMF_PA_ACTIVITY_MAP                         L"PAActivityMap"                        // AMFInterface* -> AMFSurface*;       Values: int32                    - When PA is standalone, there will be a 2D Activity map generated for each frame
+#define AMF_PA_SCENE_CHANGE_DETECT                  L"PASceneChangeDetect"                  // bool                                                                 - True/False - available if AMF_PA_SCENE_CHANGE_DETECTION_ENABLE was set to True
+#define AMF_PA_STATIC_SCENE_DETECT                  L"PAStaticSceneDetect"                  // bool                                                                 - True/False - available if AMF_PA_STATIC_SCENE_DETECTION_ENABLE was set to True
+
+#endif //#ifndef AMFPreAnalysis_h

+ 59 - 0
plugins/obs-ffmpeg/external/AMF/include/components/PreProcessing.h

@@ -0,0 +1,59 @@
+//
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+//
+// MIT license
+//
+// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMFPreProcessing_h
+#define AMFPreProcessing_h
+
+#pragma once
+
+#define AMFPreProcessing L"AMFPreProcessing"
+
+
+// Pre-processing object properties
+#define AMF_PP_ENGINE_TYPE                   L"PPEngineType"                   // AMF_MEMORY_TYPE (Host, DX11, OPENCL, Auto default : OPENCL)   - determines how the object is initialized and what kernels to use
+                                                                               //                                                                 by default it is OpenCL (Host, DX11 and OpenCL are currently available)
+// add a property that will determine the output format
+// by default we output in the same format as input
+// but in some cases we might need to change the output
+// format to be different than input
+#define AMF_PP_OUTPUT_MEMORY_TYPE            L"PPOutputFormat"                 // AMF_MEMORY_TYPE (Host, DX11, OPENCL    default : Unknown)     - determines format of frame going out
+
+
+#define AMF_PP_ADAPTIVE_FILTER_STRENGTH      L"PPAdaptiveFilterStrength"       // int       (default : 4)                                       - strength:    0 - 10: the higher the value, the stronger the filtering
+#define AMF_PP_ADAPTIVE_FILTER_SENSITIVITY   L"PPAdaptiveFilterSensitivity"	   // int       (default : 4)                                       - sensitivity: 0 - 10: the lower the value, the more sensitive to edge (preserve more details)
+
+// Encoder parameters used for adaptive filtering
+#define AMF_PP_TARGET_BITRATE                L"PPTargetBitrate"                // int64     (default: 2000000)                                  - target bit rate
+#define AMF_PP_FRAME_RATE                    L"PPFrameRate"                    // AMFRate   (default: 30, 1)                                    - frame rate
+#define AMF_PP_ADAPTIVE_FILTER_ENABLE        L"PPAdaptiveFilterEnable"         // bool      (default: false)                                    - turn on/off adaptive filtering
+
+#endif //#ifndef AMFPreProcessing_h

+ 52 - 0
plugins/obs-ffmpeg/external/AMF/include/components/VideoCapture.h

@@ -0,0 +1,52 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// ZCamLive  interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_VideoCapture_h
+#define AMF_VideoCapture_h
+
+#pragma once
+
+#define VIDEOCAP_DEVICE_COUNT           L"VideoCapDeviceCount"    // amf_int64, (default=2), number of video capture devices
+#define VIDEOCAP_DEVICE_NAME            L"VideoCapDeviceName"     // WString, (default=""), name of the video capture device
+#define VIDEOCAP_DEVICE_ACTIVE          L"VideoCapDeviceActive"   // WString, (default=""), name of the selected video capture device
+
+#define VIDEOCAP_CODEC                   L"CodecID"               // WString (default = "AMFVideoDecoderUVD_H264_AVC"), UVD codec ID
+#define VIDEOCAP_FRAMESIZE               L"FrameSize"             // AMFSize, (default=AMFConstructSize(1920, 1080)), frame size in pixels
+
+extern "C"
+{
+    AMF_RESULT AMF_CDECL_CALL AMFCreateComponentVideoCapture(amf::AMFContext* pContext, amf::AMFComponentEx** ppComponent);
+}
+#endif // AMF_VideoCapture_h

+ 121 - 0
plugins/obs-ffmpeg/external/AMF/include/components/VideoConverter.h

@@ -0,0 +1,121 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// AMFFVideoConverter interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_VideoConverter_h
+#define AMF_VideoConverter_h
+#pragma once
+
+#include "Component.h"
+#include "ColorSpace.h"
+
+#define AMFVideoConverter L"AMFVideoConverter"
+
+enum AMF_VIDEO_CONVERTER_SCALE_ENUM
+{
+    AMF_VIDEO_CONVERTER_SCALE_INVALID          = -1,
+    AMF_VIDEO_CONVERTER_SCALE_BILINEAR          = 0,
+    AMF_VIDEO_CONVERTER_SCALE_BICUBIC           = 1
+};
+
+enum AMF_VIDEO_CONVERTER_TONEMAPPING_ENUM
+{
+    AMF_VIDEO_CONVERTER_TONEMAPPING_COPY = 0,
+    AMF_VIDEO_CONVERTER_TONEMAPPING_AMD = 1,
+    AMF_VIDEO_CONVERTER_TONEMAPPING_LINEAR = 2,
+    AMF_VIDEO_CONVERTER_TONEMAPPING_GAMMA = 3,
+    AMF_VIDEO_CONVERTER_TONEMAPPING_REINHARD = 4,
+    AMF_VIDEO_CONVERTER_TONEMAPPING_2390 = 5,
+};
+
+
+
+#define AMF_VIDEO_CONVERTER_OUTPUT_FORMAT                   L"OutputFormat"             // Values : AMF_SURFACE_NV12 or AMF_SURFACE_BGRA or AMF_SURFACE_YUV420P
+#define AMF_VIDEO_CONVERTER_MEMORY_TYPE                     L"MemoryType"               // Values : AMF_MEMORY_DX11 or AMF_MEMORY_DX9 or AMF_MEMORY_UNKNOWN (get from input type)
+#define AMF_VIDEO_CONVERTER_COMPUTE_DEVICE                  L"ComputeDevice"            // Values : AMF_MEMORY_COMPUTE_FOR_DX9 enumeration
+
+#define AMF_VIDEO_CONVERTER_OUTPUT_SIZE                     L"OutputSize"               // AMFSize  (default=0,0) width in pixels. default means no scaling
+#define AMF_VIDEO_CONVERTER_OUTPUT_RECT                     L"OutputRect"               // AMFRect  (default=0, 0, 0, 0) rectangle in pixels. default means no rect
+#define AMF_VIDEO_CONVERTER_SCALE                           L"ScaleType"            // amf_int64(AMF_VIDEO_CONVERTER_SCALE_ENUM); default = AMF_VIDEO_CONVERTER_SCALE_BILINEAR
+#define AMF_VIDEO_CONVERTER_FORCE_OUTPUT_SURFACE_SIZE       L"ForceOutputSurfaceSize" // bool (default=false) Force output size from output surface 
+
+#define AMF_VIDEO_CONVERTER_KEEP_ASPECT_RATIO               L"KeepAspectRatio"          // bool (default=false) Keep aspect ratio if scaling. 
+#define AMF_VIDEO_CONVERTER_FILL                            L"Fill"                     // bool (default=false) fill area out of ROI. 
+#define AMF_VIDEO_CONVERTER_FILL_COLOR                      L"FillColor"                // AMFColor 
+
+//-------------------------------------------------------------------------------------------------
+// SDR color conversion
+//-------------------------------------------------------------------------------------------------
+#define AMF_VIDEO_CONVERTER_COLOR_PROFILE                   L"ColorProfile"         // amf_int64(AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM); default = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN - mean AUTO
+#define AMF_VIDEO_CONVERTER_LINEAR_RGB                      L"LinearRGB"             // bool (default=false) Convert to/from linear RGB instead of sRGB using AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC or by default AMF_VIDEO_CONVERTER_TRANSFER_CHARACTERISTIC
+
+//-------------------------------------------------------------------------------------------------
+// HDR color conversion
+//-------------------------------------------------------------------------------------------------
+// AMF_VIDEO_CONVERTER_COLOR_PROFILE is used to define color space conversion
+
+// HDR data - can be set on converter or respectively on input and output surfaces (output surface via custom allocator) 
+// if present, HDR_METADATA primary color overwrites COLOR_PRIMARIES
+
+// these properties can be set on converter component to configure input and output 
+// these properties overwrite properties set on surface - see below
+#define AMF_VIDEO_CONVERTER_INPUT_TRANSFER_CHARACTERISTIC   L"InputTransferChar"    // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013   7.2 See ColorSpace.h for enum 
+#define AMF_VIDEO_CONVERTER_INPUT_COLOR_PRIMARIES           L"InputColorPrimaries"  // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013   7.1 See ColorSpace.h for enum 
+#define AMF_VIDEO_CONVERTER_INPUT_COLOR_RANGE               L"InputColorRange"      // amf_int64(AMF_COLOR_RANGE_ENUM) default = AMF_COLOR_RANGE_UNDEFINED
+#define AMF_VIDEO_CONVERTER_INPUT_HDR_METADATA              L"InputHdrMetadata"     // AMFBuffer containing AMFHDRMetadata; default NULL
+#define AMF_VIDEO_CONVERTER_INPUT_TONEMAPPING               L"InputTonemapping"   // amf_int64(AMF_VIDEO_CONVERTER_TONEMAPPING_ENUM) default = AMF_VIDEO_CONVERTER_TONEMAPPING_LINEAR
+
+#define AMF_VIDEO_CONVERTER_OUTPUT_TRANSFER_CHARACTERISTIC  L"OutputTransferChar"   // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013   7.2 See ColorSpace.h for enum 
+#define AMF_VIDEO_CONVERTER_OUTPUT_COLOR_PRIMARIES          L"OutputColorPrimaries" // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013   7.1 See ColorSpace.h for enum 
+#define AMF_VIDEO_CONVERTER_OUTPUT_COLOR_RANGE              L"OutputColorRange"     // amf_int64(AMF_COLOR_RANGE_ENUM) default = AMF_COLOR_RANGE_UNDEFINED
+#define AMF_VIDEO_CONVERTER_OUTPUT_HDR_METADATA             L"OutputHdrMetadata"    // AMFBuffer containing AMFHDRMetadata; default NULL
+#define AMF_VIDEO_CONVERTER_OUTPUT_TONEMAPPING              L"OutputTonemapping"  // amf_int64(AMF_VIDEO_CONVERTER_TONEMAPPING_ENUM) default = AMF_VIDEO_CONVERTER_TONEMAPPING_AMD
+
+// these properties can be set on input or outout surface See ColorSpace.h
+// the same as decoder properties set on input surface - see below
+//#define AMF_VIDEO_COLOR_TRANSFER_CHARACTERISTIC         L"ColorTransferChar"      // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013   7.2 See ColorSpace.h for enum 
+//#define AMF_VIDEO_COLOR_PRIMARIES                       L"ColorPrimaries"         // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013   7.1 See ColorSpace.h for enum 
+//#define AMF_VIDEO_COLOR_RANGE                           L"ColorRange"           // amf_int64(AMF_COLOR_RANGE_ENUM) default = AMF_COLOR_RANGE_UNDEFINED
+//#define AMF_VIDEO_COLOR_HDR_METADATA                    L"HdrMetadata"            // AMFBuffer containing AMFHDRMetadata; default NULL
+
+// If decoder properties can be set on input see VideoDecoder.h
+// AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC
+// AMF_VIDEO_DECODER_COLOR_PRIMARIES
+// AMF_VIDEO_DECODER_COLOR_RANGE
+// AMF_VIDEO_DECODER_HDR_METADATA
+
+#define AMF_VIDEO_CONVERTER_USE_DECODER_HDR_METADATA    L"UseDecoderHDRMetadata" // bool (default=true) enables use of decoder / surface input color properties above
+
+
+#endif //#ifndef AMF_VideoConverter_h

+ 122 - 0
plugins/obs-ffmpeg/external/AMF/include/components/VideoDecoderUVD.h

@@ -0,0 +1,122 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+//  VideoDecoderUVD interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_VideoDecoderUVD_h
+#define AMF_VideoDecoderUVD_h
+#pragma once
+
+#include "Component.h"
+#include "ColorSpace.h"
+
+#define AMFVideoDecoderUVD_MPEG2                     L"AMFVideoDecoderUVD_MPEG2"
+#define AMFVideoDecoderUVD_MPEG4                     L"AMFVideoDecoderUVD_MPEG4"
+#define AMFVideoDecoderUVD_WMV3                      L"AMFVideoDecoderUVD_WMV3"
+#define AMFVideoDecoderUVD_VC1                       L"AMFVideoDecoderUVD_VC1"
+#define AMFVideoDecoderUVD_H264_AVC                  L"AMFVideoDecoderUVD_H264_AVC"
+#define AMFVideoDecoderUVD_H264_MVC                  L"AMFVideoDecoderUVD_H264_MVC"
+#define AMFVideoDecoderUVD_H264_SVC                  L"AMFVideoDecoderUVD_H264_SVC"
+#define AMFVideoDecoderUVD_MJPEG                     L"AMFVideoDecoderUVD_MJPEG"
+#define AMFVideoDecoderHW_H265_HEVC                  L"AMFVideoDecoderHW_H265_HEVC"
+#define AMFVideoDecoderHW_H265_MAIN10                L"AMFVideoDecoderHW_H265_MAIN10"
+#define AMFVideoDecoderHW_VP9                        L"AMFVideoDecoderHW_VP9"
+#define AMFVideoDecoderHW_VP9_10BIT                  L"AMFVideoDecoderHW_VP9_10BIT"
+#define AMFVideoDecoderHW_AV1                        L"AMFVideoDecoderHW_AV1"
+
+enum AMF_VIDEO_DECODER_MODE_ENUM
+{
+    AMF_VIDEO_DECODER_MODE_REGULAR = 0,     // DPB delay is based on number of reference frames + 1 (from SPS)
+    AMF_VIDEO_DECODER_MODE_COMPLIANT,       // DPB delay is based on profile - up to 16
+    AMF_VIDEO_DECODER_MODE_LOW_LATENCY,     // DPB delay is 0. Expect stream with no reordering in P-Frames or B-Frames. B-frames can be present as long as they do not introduce any frame re-ordering 
+};
+enum AMF_TIMESTAMP_MODE_ENUM
+{
+    AMF_TS_PRESENTATION = 0, // default. decoder will preserve timestamps from input to output
+       AMF_TS_SORT,             // decoder will resort PTS list 
+    AMF_TS_DECODE            // timestamps reflect decode order - decoder will reuse them
+};
+
+#define AMF_VIDEO_DECODER_SURFACE_COPY                 L"SurfaceCopy"           // amf_bool; default = false; return output surfaces as a copy
+#define AMF_VIDEO_DECODER_EXTRADATA                    L"ExtraData"             // AMFInterface* -> AMFBuffer* - AVCC - size length + SPS/PPS; or as Annex B. Optional if stream is Annex B
+#define AMF_VIDEO_DECODER_FRAME_RATE                   L"FrameRate"             // amf_double; default = 0.0, optional property to restore duration in the output if needed
+#define AMF_TIMESTAMP_MODE                             L"TimestampMode"         // amf_int64(AMF_TIMESTAMP_MODE_ENUM)  - default AMF_TS_PRESENTATION - how input timestamps are treated
+
+// dynamic/adaptive resolution change
+#define AMF_VIDEO_DECODER_ADAPTIVE_RESOLUTION_CHANGE   L"AdaptiveResolutionChange" // amf_bool; default = false; reuse allocated surfaces if new resolution is smaller
+#define AMF_VIDEO_DECODER_ALLOC_SIZE                   L"AllocSize"             // AMFSize; default (1920,1088); size of allocated surface if AdaptiveResolutionChange is true
+#define AMF_VIDEO_DECODER_CURRENT_SIZE                 L"CurrentSize"           // AMFSize; default = (0,0); current size of the video
+
+// reference frame management
+#define AMF_VIDEO_DECODER_REORDER_MODE                 L"ReorderMode"           // amf_int64(AMF_VIDEO_DECODER_MODE_ENUM); default = AMF_VIDEO_DECODER_MODE_REGULAR;  defines number of surfaces in DPB list.
+#define AMF_VIDEO_DECODER_SURFACE_POOL_SIZE            L"SurfacePoolSize"       // amf_int64; number of surfaces in the decode pool = DPB list size + number of surfaces for presentation
+#define AMF_VIDEO_DECODER_DPB_SIZE                     L"DPBSize"               // amf_int64; minimum number of surfaces for reordering
+
+#define AMF_VIDEO_DECODER_DEFAULT_SURFACES_FOR_TRANSIT  5                      // if AMF_VIDEO_DECODER_SURFACE_POOL_SIZE is 0 , AMF_VIDEO_DECODER_SURFACE_POOL_SIZE=AMF_VIDEO_DECODER_DEFAULT_SURFACES_FOR_TRANSIT+AMF_VIDEO_DECODER_DPB_SIZE
+
+// Decoder capabilities - exposed in AMFCaps interface
+#define AMF_VIDEO_DECODER_CAP_NUM_OF_STREAMS            L"NumOfStreams"               // amf_int64; maximum number of decode streams supported 
+
+
+// metadata information: can be set on output surface
+
+// Properties could be set on surface based on HDR SEI or VUI header
+#define AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC L"ColorTransferChar"    // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013   7.2
+#define AMF_VIDEO_DECODER_COLOR_PRIMARIES               L"ColorPrimaries"       // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013   7.1
+#define AMF_VIDEO_DECODER_HDR_METADATA                  L"HdrMetadata"          // AMFBuffer containing AMFHDRMetadata; default NULL
+
+/////// AMF_VIDEO_DECODER_FULL_RANGE_COLOR deprecated, use AMF_VIDEO_DECODER_COLOR_RANGE
+#define AMF_VIDEO_DECODER_FULL_RANGE_COLOR              L"FullRangeColor"       // bool; default = false; false =  studio range, true = full range 
+///////
+#define AMF_VIDEO_DECODER_COLOR_RANGE                   L"ColorRange"           // amf_int64(AMF_COLOR_RANGE_ENUM) default = AMF_COLOR_RANGE_UNDEFINED
+
+// can be set on output surface if YUV outout or on component to overwrite VUI
+#define AMF_VIDEO_DECODER_COLOR_PROFILE                 L"ColorProfile"         // amf_int64(AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM); default = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN - mean AUTO
+
+// properties to be set on decoder if internal converter is used
+#define AMF_VIDEO_DECODER_OUTPUT_TRANSFER_CHARACTERISTIC        L"OutColorTransferChar"     // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013   7.2 See VideoDecoderUVD.h for enum 
+#define AMF_VIDEO_DECODER_OUTPUT_COLOR_PRIMARIES                L"OutputColorPrimaries"       // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013   7.1 See ColorSpace.h for enum 
+#define AMF_VIDEO_DECODER_OUTPUT_HDR_METADATA                   L"OutHDRMetadata"           // AMFBuffer containing AMFHDRMetadata; default NULL
+
+
+#if defined(__ANDROID__)
+#define AMF_VIDEO_DECODER_NATIVEWINDOW                  L"AndroidNativeWindow"  // amf_int64; default = 0; pointer to native window
+#endif //__ANDROID__
+
+
+#if defined(__APPLE__)
+#define AMF_VIDEO_DECODER_NATIVEWINDOW                  L"AppleNativeWindow"  // amf_int64; default = 0; pointer to native window
+#endif //__APPLE__
+
+
+#endif //#ifndef AMF_VideoDecoderUVD_h

+ 296 - 0
plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderHEVC.h

@@ -0,0 +1,296 @@
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+//  VideoEncoderHW_HEVC interface declaration
+//-------------------------------------------------------------------------------------------------
+
+#ifndef AMF_VideoEncoderHEVC_h
+#define AMF_VideoEncoderHEVC_h
+#pragma once
+
+#include "Component.h"
+#include "ColorSpace.h"
+#include "PreAnalysis.h"
+
+#define AMFVideoEncoder_HEVC L"AMFVideoEncoderHW_HEVC"
+
+enum AMF_VIDEO_ENCODER_HEVC_USAGE_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING = 0, // kept for backwards compatability
+    AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING = 0, // fixed typo
+    AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY,
+    AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY,
+    AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM,
+    AMF_VIDEO_ENCODER_HEVC_USAGE_HIGH_QUALITY,
+    AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN = 1,
+    AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10 = 2
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_TIER_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_TIER_MAIN    = 0,
+    AMF_VIDEO_ENCODER_HEVC_TIER_HIGH    = 1
+};
+
+enum AMF_VIDEO_ENCODER_LEVEL_ENUM
+{
+    AMF_LEVEL_1     = 30,
+    AMF_LEVEL_2     = 60,
+    AMF_LEVEL_2_1   = 63,
+    AMF_LEVEL_3     = 90,
+    AMF_LEVEL_3_1   = 93,
+    AMF_LEVEL_4     = 120,
+    AMF_LEVEL_4_1   = 123,
+    AMF_LEVEL_5     = 150,
+    AMF_LEVEL_5_1   = 153,
+    AMF_LEVEL_5_2   = 156,
+    AMF_LEVEL_6     = 180,
+    AMF_LEVEL_6_1   = 183,
+    AMF_LEVEL_6_2   = 186
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_UNKNOWN = -1,
+    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP = 0,
+    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR,
+    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
+    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_NONE = 0,
+    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_SKIP,
+    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_IDR,
+    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_I,
+    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_P
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_IDR,
+    AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_I,
+    AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_P
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY    = 0,
+    AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED   = 5,
+    AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED      = 10
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_NONE = 0,
+    AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_GOP_ALIGNED,
+    AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_PICTURE_TRANSFER_MODE_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_PICTURE_TRANSFER_MODE_OFF = 0,
+    AMF_VIDEO_ENCODER_HEVC_PICTURE_TRANSFER_MODE_ON
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE
+{
+    AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE_STUDIO = 0,
+    AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE_FULL   = 1
+};
+
+enum AMF_VIDEO_ENCODER_HEVC_LTR_MODE_ENUM
+{
+    AMF_VIDEO_ENCODER_HEVC_LTR_MODE_RESET_UNUSED    = 0,
+    AMF_VIDEO_ENCODER_HEVC_LTR_MODE_KEEP_UNUSED
+};
+
+// Static properties - can be set before Init()
+#define AMF_VIDEO_ENCODER_HEVC_INSTANCE_INDEX                       L"HevcEncoderInstance"          // amf_int64; selected instance idx
+#define AMF_VIDEO_ENCODER_HEVC_FRAMESIZE                            L"HevcFrameSize"                // AMFSize; default = 0,0; Frame size
+
+#define AMF_VIDEO_ENCODER_HEVC_USAGE                                L"HevcUsage"                    // amf_int64(AMF_VIDEO_ENCODER_HEVC_USAGE_ENUM); default = N/A; Encoder usage type. fully configures parameter set.
+#define AMF_VIDEO_ENCODER_HEVC_PROFILE                              L"HevcProfile"                  // amf_int64(AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM) ; default = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN;
+#define AMF_VIDEO_ENCODER_HEVC_TIER                                 L"HevcTier"                     // amf_int64(AMF_VIDEO_ENCODER_HEVC_TIER_ENUM) ; default = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN;
+#define AMF_VIDEO_ENCODER_HEVC_PROFILE_LEVEL                        L"HevcProfileLevel"             // amf_int64 (AMF_VIDEO_ENCODER_LEVEL_ENUM, default depends on HW capabilities);
+#define AMF_VIDEO_ENCODER_HEVC_MAX_LTR_FRAMES                       L"HevcMaxOfLTRFrames"           // amf_int64; default = 0; Max number of LTR frames
+#define AMF_VIDEO_ENCODER_HEVC_LTR_MODE                             L"HevcLTRMode"                  // amf_int64(AMF_VIDEO_ENCODER_HEVC_LTR_MODE_ENUM); default = AMF_VIDEO_ENCODER_HEVC_LTR_MODE_RESET_UNUSED; remove/keep unused LTRs (not specified in property AMF_VIDEO_ENCODER_HEVC_FORCE_LTR_REFERENCE_BITFIELD)
+#define AMF_VIDEO_ENCODER_HEVC_MAX_NUM_REFRAMES                     L"HevcMaxNumRefFrames"          // amf_int64; default = 1; Maximum number of reference frames
+#define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET                       L"HevcQualityPreset"            // amf_int64(AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_ENUM); default = depends on USAGE; Quality Preset
+#define AMF_VIDEO_ENCODER_HEVC_EXTRADATA                            L"HevcExtraData"                // AMFInterface* - > AMFBuffer*; SPS/PPS buffer - read-only
+#define AMF_VIDEO_ENCODER_HEVC_ASPECT_RATIO                         L"HevcAspectRatio"              // AMFRatio; default = 1, 1
+#define AMF_VIDEO_ENCODER_HEVC_LOWLATENCY_MODE					    L"LowLatencyInternal"           // bool; default = false, enables low latency mode
+#define AMF_VIDEO_ENCODER_HEVC_PRE_ANALYSIS_ENABLE                  L"HevcEnablePreAnalysis"        // bool; default = false; enables the pre-analysis module. Currently only works in AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR mode. Refer to AMF Video PreAnalysis API reference for more details.
+#define AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE						L"HevcNominalRange"				// amf_int64(AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE); default = amf_int64(AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE_STUDIO); property is bool but amf_int64 also works for backward compatibility.
+
+// Picture control properties
+#define AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR                     L"HevcGOPSPerIDR"               // amf_int64; default = 1; The frequency to insert IDR as start of a GOP. 0 means no IDR will be inserted.
+#define AMF_VIDEO_ENCODER_HEVC_GOP_SIZE                             L"HevcGOPSize"                  // amf_int64; default = 60; GOP Size, in frames
+#define AMF_VIDEO_ENCODER_HEVC_DE_BLOCKING_FILTER_DISABLE           L"HevcDeBlockingFilter"         // bool; default = depends on USAGE; De-blocking Filter
+#define AMF_VIDEO_ENCODER_HEVC_SLICES_PER_FRAME                     L"HevcSlicesPerFrame"           // amf_int64; default = 1; Number of slices Per Frame
+#define AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE                L"HevcHeaderInsertionMode"      // amf_int64(AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_ENUM); default = NONE
+#define AMF_VIDEO_ENCODER_HEVC_INTRA_REFRESH_NUM_CTBS_PER_SLOT      L"HevcIntraRefreshCTBsNumberPerSlot" // amf_int64; default = depends on USAGE; Intra Refresh CTBs Number Per Slot in 64x64 CTB
+
+// Rate control properties
+#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD                  L"HevcRateControlMethod"        // amf_int64(AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_ENUM); default = depends on USAGE; Rate Control Method
+#define AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE                      L"HevcVBVBufferSize"            // amf_int64; default = depends on USAGE; VBV Buffer Size in bits
+#define AMF_VIDEO_ENCODER_HEVC_INITIAL_VBV_BUFFER_FULLNESS          L"HevcInitialVBVBufferFullness" // amf_int64; default =  64; Initial VBV Buffer Fullness 0=0% 64=100%
+#define AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ                          L"HevcEnableVBAQ"               // // bool; default = depends on USAGE; Enable auto VBAQ
+#define AMF_VIDEO_ENCODER_HEVC_HIGH_MOTION_QUALITY_BOOST_ENABLE     L"HevcHighMotionQualityBoostEnable"// bool; default = depends on USAGE; Enable High motion quality boost mode
+
+#define AMF_VIDEO_ENCODER_HEVC_PREENCODE_ENABLE                     L"HevcRateControlPreAnalysisEnable"  // bool; default =  depends on USAGE; enables pre-encode assisted rate control
+#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_PREANALYSIS_ENABLE      L"HevcRateControlPreAnalysisEnable"  // bool; default =  depends on USAGE; enables pre-encode assisted rate control. Deprecated, please use AMF_VIDEO_ENCODER_PREENCODE_ENABLE instead.
+#ifdef _MSC_VER
+    #ifndef __clang__
+        #pragma deprecated("AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_PREANALYSIS_ENABLE")
+    #endif
+#endif
+
+// Motion estimation
+#define AMF_VIDEO_ENCODER_HEVC_MOTION_HALF_PIXEL                    L"HevcHalfPixel"                // bool; default= true; Half Pixel
+#define AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL                  L"HevcQuarterPixel"             // bool; default= true; Quarter Pixel
+
+// color conversion
+#define AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH                      L"HevcColorBitDepth"            // amf_int64(AMF_COLOR_BIT_DEPTH_ENUM); default = AMF_COLOR_BIT_DEPTH_8
+
+#define AMF_VIDEO_ENCODER_HEVC_INPUT_COLOR_PROFILE                  L"HevcInColorProfile"           // amf_int64(AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM); default = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN - mean AUTO by size
+#define AMF_VIDEO_ENCODER_HEVC_INPUT_TRANSFER_CHARACTERISTIC        L"HevcInColorTransferChar"      // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013 section 7.2 See VideoDecoderUVD.h for enum
+#define AMF_VIDEO_ENCODER_HEVC_INPUT_COLOR_PRIMARIES                L"HevcInColorPrimaries"         // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013 section 7.1 See ColorSpace.h for enum
+
+#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PROFILE                 L"HevcOutColorProfile"          // amf_int64(AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM); default = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN - mean AUTO by size
+#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC       L"HevcOutColorTransferChar"     // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013 ?7.2 See VideoDecoderUVD.h for enum
+#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES               L"HevcOutColorPrimaries"        // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013 section 7.1 See ColorSpace.h for enum
+
+// Dynamic properties - can be set at any time
+
+// Rate control properties
+#define AMF_VIDEO_ENCODER_HEVC_FRAMERATE                            L"HevcFrameRate"                // AMFRate; default = depends on usage; Frame Rate
+
+#define AMF_VIDEO_ENCODER_HEVC_ENFORCE_HRD                          L"HevcEnforceHRD"               // bool; default = depends on USAGE; Enforce HRD
+#define AMF_VIDEO_ENCODER_HEVC_FILLER_DATA_ENABLE                   L"HevcFillerDataEnable"         // bool; default = depends on USAGE; Enforce HRD
+#define AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE                       L"HevcTargetBitrate"            // amf_int64; default = depends on USAGE; Target bit rate in bits
+#define AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE                         L"HevcPeakBitrate"              // amf_int64; default = depends on USAGE; Peak bit rate in bits
+
+#define AMF_VIDEO_ENCODER_HEVC_MAX_AU_SIZE                          L"HevcMaxAUSize"                // amf_int64; default = 60; Max AU Size in bits
+
+#define AMF_VIDEO_ENCODER_HEVC_MIN_QP_I                             L"HevcMinQP_I"                  // amf_int64; default = depends on USAGE; Min QP; range =
+#define AMF_VIDEO_ENCODER_HEVC_MAX_QP_I                             L"HevcMaxQP_I"                  // amf_int64; default = depends on USAGE; Max QP; range =
+#define AMF_VIDEO_ENCODER_HEVC_MIN_QP_P                             L"HevcMinQP_P"                  // amf_int64; default = depends on USAGE; Min QP; range =
+#define AMF_VIDEO_ENCODER_HEVC_MAX_QP_P                             L"HevcMaxQP_P"                  // amf_int64; default = depends on USAGE; Max QP; range =
+
+#define AMF_VIDEO_ENCODER_HEVC_QP_I                                 L"HevcQP_I"                     // amf_int64; default = 26; P-frame QP; range = 0-51
+#define AMF_VIDEO_ENCODER_HEVC_QP_P                                 L"HevcQP_P"                     // amf_int64; default = 26; P-frame QP; range = 0-51
+
+#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_SKIP_FRAME_ENABLE       L"HevcRateControlSkipFrameEnable" // bool; default =  depends on USAGE; Rate Control Based Frame Skip
+
+// color conversion
+#define AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA                   L"HevcInHDRMetadata"            // AMFBuffer containing AMFHDRMetadata; default NULL
+//#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_HDR_METADATA                  L"HevcOutHDRMetadata"            // AMFBuffer containing AMFHDRMetadata; default NULL
+
+// DPB management
+#define AMF_VIDEO_ENCODER_HEVC_PICTURE_TRANSFER_MODE                L"HevcPicTransferMode"          // amf_int64(AMF_VIDEO_ENCODER_HEVC_PICTURE_TRANSFER_MODE_ENUM); default = AMF_VIDEO_ENCODER_HEVC_PICTURE_TRANSFER_MODE_OFF - whether to exchange reference/reconstructed pic between encoder and application
+
+// misc
+#define AMF_VIDEO_ENCODER_HEVC_QUERY_TIMEOUT                        L"HevcQueryTimeout"             // amf_int64; default = 0 (no wait); timeout for QueryOutput call in ms.
+
+// Per-submittion properties - can be set on input surface interface
+#define AMF_VIDEO_ENCODER_HEVC_END_OF_SEQUENCE                      L"HevcEndOfSequence"            // bool; default = false; generate end of sequence
+#define AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE                   L"HevcForcePictureType"         // amf_int64(AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_ENUM); default = AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_NONE; generate particular picture type
+#define AMF_VIDEO_ENCODER_HEVC_INSERT_AUD                           L"HevcInsertAUD"                // bool; default = false; insert AUD
+#define AMF_VIDEO_ENCODER_HEVC_INSERT_HEADER                        L"HevcInsertHeader"             // bool; default = false; insert header(SPS, PPS, VPS)
+
+#define AMF_VIDEO_ENCODER_HEVC_MARK_CURRENT_WITH_LTR_INDEX          L"HevcMarkCurrentWithLTRIndex"  // amf_int64; default = N/A; Mark current frame with LTR index
+#define AMF_VIDEO_ENCODER_HEVC_FORCE_LTR_REFERENCE_BITFIELD         L"HevcForceLTRReferenceBitfield"// amf_int64; default = 0; force LTR bit-field
+#define AMF_VIDEO_ENCODER_HEVC_ROI_DATA                             L"HevcROIData"					// 2D AMFSurface, surface format: AMF_SURFACE_GRAY32
+#define AMF_VIDEO_ENCODER_HEVC_REFERENCE_PICTURE                    L"HevcReferencePicture"         // AMFInterface(AMFSurface); surface used for frame injection
+#define AMF_VIDEO_ENCODER_HEVC_PSNR_FEEDBACK                        L"HevcPSNRFeedback"             // amf_bool; default = false; Signal encoder to calculate PSNR score
+#define AMF_VIDEO_ENCODER_HEVC_SSIM_FEEDBACK                        L"HevcSSIMFeedback"             // amf_bool; default = false; Signal encoder to calculate SSIM score
+#define AMF_VIDEO_ENCODER_HEVC_STATISTICS_FEEDBACK                  L"HevcStatisticsFeedback"       // amf_bool; default = false; Signal encoder to collect and feedback encoder statistics
+#define AMF_VIDEO_ENCODER_HEVC_BLOCK_QP_FEEDBACK                    L"HevcBlockQpFeedback"          // amf_bool; default = false; Signal encoder to collect and feedback block level QP values
+
+// Properties set by encoder on output buffer interface
+#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE                     L"HevcOutputDataType"           // amf_int64(AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_ENUM); default = N/A
+#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_MARKED_LTR_INDEX              L"HevcMarkedLTRIndex"           // amf_int64; default = -1; Marked LTR index
+#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_REFERENCED_LTR_INDEX_BITFIELD L"HevcReferencedLTRIndexBitfield"// amf_int64; default = 0; referenced LTR bit-field
+#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_TEMPORAL_LAYER                L"HevcOutputTemporalLayer"      // amf_int64; Temporal layer
+#define AMF_VIDEO_ENCODER_HEVC_RECONSTRUCTED_PICTURE                L"HevcReconstructedPicture"     // AMFInterface(AMFSurface); returns reconstructed picture as an AMFSurface attached to the output buffer as property AMF_VIDEO_ENCODER_RECONSTRUCTED_PICTURE of AMFInterface type
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_PSNR_Y                     L"PSNRY"                        // double; PSNR Y
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_PSNR_U                     L"PSNRU"                        // double; PSNR U
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_PSNR_V                     L"PSNRV"                        // double; PSNR V
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_PSNR_ALL                   L"PSNRALL"                      // double; PSNR All
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_SSIM_Y                     L"SSIMY"                        // double; SSIM Y
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_SSIM_U                     L"SSIMU"                        // double; SSIM U
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_SSIM_V                     L"SSIMV"                        // double; SSIM V
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_SSIM_ALL                   L"SSIMALL"                      // double; SSIM ALL
+
+    // Encoder statistics feedback
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_FRAME_QP                   L"HevcStatisticsFeedbackFrameQP"                // amf_int64; Rate control base frame/initial QP
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_AVERAGE_QP                 L"HevcStatisticsFeedbackAvgQP"                  // amf_int64; Average QP of all encoded CTBs in a picture. Value may be different from the one reported by bitstream analyzer when there are skipped CTBs.
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_MAX_QP                     L"HevcStatisticsFeedbackMaxQP"                  // amf_int64; Max QP among all encoded CTBs in a picture. Value may be different from the one reported by bitstream analyzer when there are skipped CTBs.
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_MIN_QP                     L"HevcStatisticsFeedbackMinQP"                  // amf_int64; Min QP among all encoded CTBs in a picture. Value may be different from the one reported by bitstream analyzer when there are skipped CTBs.
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_PIX_NUM_INTRA              L"HevcStatisticsFeedbackPixNumIntra"            // amf_int64; Number of the intra encoded pixels
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_PIX_NUM_INTER              L"HevcStatisticsFeedbackPixNumInter"            // amf_int64; Number of the inter encoded pixels
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_PIX_NUM_SKIP               L"HevcStatisticsFeedbackPixNumSkip"             // amf_int64; Number of the skip mode pixels
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_BITCOUNT_RESIDUAL          L"HevcStatisticsFeedbackBitcountResidual"       // amf_int64; The bit count that corresponds to residual data
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_BITCOUNT_MOTION            L"HevcStatisticsFeedbackBitcountMotion"         // amf_int64; The bit count that corresponds to motion vectors
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_BITCOUNT_INTER             L"HevcStatisticsFeedbackBitcountInter"          // amf_int64; The bit count that are assigned to inter CTBs
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_BITCOUNT_INTRA             L"HevcStatisticsFeedbackBitcountIntra"          // amf_int64; The bit count that are assigned to intra CTBs
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_BITCOUNT_ALL_MINUS_HEADER  L"HevcStatisticsFeedbackBitcountAllMinusHeader" // amf_int64; The bit count of the bitstream excluding header
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_MV_X                       L"HevcStatisticsFeedbackMvX"                    // amf_int64; Accumulated absolute values of horizontal MV's
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_MV_Y                       L"HevcStatisticsFeedbackMvY"                    // amf_int64; Accumulated absolute values of vertical MV's
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_RD_COST_FINAL              L"HevcStatisticsFeedbackRdCostFinal"            // amf_int64; Frame level final RD cost for full encoding
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_RD_COST_INTRA              L"HevcStatisticsFeedbackRdCostIntra"            // amf_int64; Frame level intra RD cost for full encoding
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_RD_COST_INTER              L"HevcStatisticsFeedbackRdCostInter"            // amf_int64; Frame level inter RD cost for full encoding
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_SAD_FINAL                  L"HevcStatisticsFeedbackSadFinal"               // amf_int64; Frame level final SAD for full encoding
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_SAD_INTRA                  L"HevcStatisticsFeedbackSadIntra"               // amf_int64; Frame level intra SAD for full encoding
+#define AMF_VIDEO_ENCODER_HEVC_STATISTIC_SAD_INTER                  L"HevcStatisticsFeedbackSadInter"               // amf_int64; Frame level inter SAD for full encoding
+
+    // Encoder block level feedback
+#define AMF_VIDEO_ENCODER_HEVC_BLOCK_QP_MAP                         L"HevcBlockQpMap"                               // AMFInterface(AMFSurface); AMFSurface of format AMF_SURFACE_GRAY32 containing block level QP values
+
+// HEVC Encoder capabilities - exposed in AMFCaps interface
+#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_BITRATE                      L"HevcMaxBitrate"               // amf_int64; Maximum bit rate in bits
+#define AMF_VIDEO_ENCODER_HEVC_CAP_NUM_OF_STREAMS                   L"HevcNumOfStreams"             // amf_int64; maximum number of encode streams supported
+#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_PROFILE                      L"HevcMaxProfile"               // amf_int64(AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM)
+#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_TIER                         L"HevcMaxTier"                  // amf_int64(AMF_VIDEO_ENCODER_HEVC_TIER_ENUM) maximum profile tier
+#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_LEVEL                        L"HevcMaxLevel"                 // amf_int64 maximum profile level
+#define AMF_VIDEO_ENCODER_HEVC_CAP_MIN_REFERENCE_FRAMES             L"HevcMinReferenceFrames"       // amf_int64 minimum number of reference frames
+#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_REFERENCE_FRAMES             L"HevcMaxReferenceFrames"       // amf_int64 maximum number of reference frames
+#define AMF_VIDEO_ENCODER_HEVC_CAP_NUM_OF_HW_INSTANCES              L"HevcNumOfHwInstances"         // amf_int64 number of HW encoder instances
+#define AMF_VIDEO_ENCODER_HEVC_CAP_COLOR_CONVERSION                 L"HevcColorConversion"          // amf_int64(AMF_ACCELERATION_TYPE) - type of supported color conversion. default AMF_ACCEL_GPU
+#define AMF_VIDEO_ENCODER_HEVC_CAP_PRE_ANALYSIS                     L"HevcPreAnalysis"              // amf_bool - pre analysis module is available for HEVC UVE encoder, n/a for the other encoders
+#define AMF_VIDEO_ENCODER_HEVC_CAP_ROI                              L"HevcROIMap"                   // amf_bool - ROI map support is available for HEVC UVE encoder, n/a for the other encoders
+#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_THROUGHPUT                   L"HevcMaxThroughput"            // amf_int64 - MAX throughput for HEVC encoder in MB (16 x 16 pixel)
+#define AMF_VIDEO_ENCODER_HEVC_CAP_REQUESTED_THROUGHPUT             L"HevcRequestedThroughput"      // amf_int64 - Currently total requested throughput for HEVC encode in MB (16 x 16 pixel)
+#define AMF_VIDEO_ENCODER_CAPS_HEVC_QUERY_TIMEOUT_SUPPORT           L"HevcQueryTimeoutSupport"      // amf_bool - Timeout supported for QueryOutout call
+
+// properties set on AMFComponent to control component creation
+#define AMF_VIDEO_ENCODER_HEVC_MEMORY_TYPE                          L"HevcEncoderMemoryType"        // amf_int64(AMF_MEMORY_TYPE) , default is AMF_MEMORY_UNKNOWN, Values : AMF_MEMORY_DX11, AMF_MEMORY_DX9, AMF_MEMORY_UNKNOWN (auto)
+
+#endif //#ifndef AMF_VideoEncoderHEVC_h

+ 326 - 0
plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderVCE.h

@@ -0,0 +1,326 @@
+//
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+//
+// MIT license
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// AMFVideoEncoderHW_AVC interface declaration
+//-------------------------------------------------------------------------------------------------
+
+#ifndef AMF_VideoEncoderVCE_h
+#define AMF_VideoEncoderVCE_h
+#pragma once
+
+#include "Component.h"
+#include "ColorSpace.h"
+#include "PreAnalysis.h"
+
+#define AMFVideoEncoderVCE_AVC L"AMFVideoEncoderVCE_AVC"
+#define AMFVideoEncoderVCE_SVC L"AMFVideoEncoderVCE_SVC"
+
+enum AMF_VIDEO_ENCODER_USAGE_ENUM
+{
+    AMF_VIDEO_ENCODER_USAGE_TRANSCONDING = 0, // kept for backwards compatability
+    AMF_VIDEO_ENCODER_USAGE_TRANSCODING = 0, // fixed typo
+    AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY,
+    AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY,
+    AMF_VIDEO_ENCODER_USAGE_WEBCAM,
+    AMF_VIDEO_ENCODER_USAGE_HIGH_QUALITY,
+    AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY
+};
+
+enum AMF_VIDEO_ENCODER_PROFILE_ENUM
+{
+    AMF_VIDEO_ENCODER_PROFILE_UNKNOWN = 0,
+    AMF_VIDEO_ENCODER_PROFILE_BASELINE = 66,
+    AMF_VIDEO_ENCODER_PROFILE_MAIN = 77,
+    AMF_VIDEO_ENCODER_PROFILE_HIGH = 100,
+    AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE = 256,
+    AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH = 257
+};
+
+enum AMF_VIDEO_ENCODER_SCANTYPE_ENUM
+{
+    AMF_VIDEO_ENCODER_SCANTYPE_PROGRESSIVE = 0,
+    AMF_VIDEO_ENCODER_SCANTYPE_INTERLACED
+};
+
+enum AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM
+{
+    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN = -1,
+    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP = 0,
+    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR,
+    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
+    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR,
+    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_QUALITY_VBR
+};
+
+enum AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM
+{
+    AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED = 0,
+    AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED,
+    AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY
+};
+
+enum AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_ENUM
+{
+    AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_NONE = 0,
+    AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_FRAME,
+    AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_TOP_FIELD,
+    AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_BOTTOM_FIELD
+};
+
+enum AMF_VIDEO_ENCODER_PICTURE_TYPE_ENUM
+{
+    AMF_VIDEO_ENCODER_PICTURE_TYPE_NONE = 0,
+    AMF_VIDEO_ENCODER_PICTURE_TYPE_SKIP,
+    AMF_VIDEO_ENCODER_PICTURE_TYPE_IDR,
+    AMF_VIDEO_ENCODER_PICTURE_TYPE_I,
+    AMF_VIDEO_ENCODER_PICTURE_TYPE_P,
+    AMF_VIDEO_ENCODER_PICTURE_TYPE_B
+};
+
+enum AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM
+{
+    AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR,
+    AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_I,
+    AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_P,
+    AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_B
+};
+
+enum AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM
+{
+    AMF_VIDEO_ENCODER_PREENCODE_DISABLED = 0,
+    AMF_VIDEO_ENCODER_PREENCODE_ENABLED  = 1,
+};
+
+enum AMF_VIDEO_ENCODER_CODING_ENUM
+{
+    AMF_VIDEO_ENCODER_UNDEFINED = 0, // BASELINE = CALV; MAIN, HIGH = CABAC
+    AMF_VIDEO_ENCODER_CABAC,
+    AMF_VIDEO_ENCODER_CALV,
+
+};
+
+enum AMF_VIDEO_ENCODER_PICTURE_TRANSFER_MODE_ENUM
+{
+    AMF_VIDEO_ENCODER_PICTURE_TRANSFER_MODE_OFF = 0,
+    AMF_VIDEO_ENCODER_PICTURE_TRANSFER_MODE_ON
+};
+
+enum AMF_VIDEO_ENCODER_LTR_MODE_ENUM
+{
+    AMF_VIDEO_ENCODER_LTR_MODE_RESET_UNUSED = 0,
+    AMF_VIDEO_ENCODER_LTR_MODE_KEEP_UNUSED
+};
+
+
+// Static properties - can be set before Init()
+#define AMF_VIDEO_ENCODER_INSTANCE_INDEX                        L"EncoderInstance"          // amf_int64; selected HW instance idx
+#define AMF_VIDEO_ENCODER_FRAMESIZE                             L"FrameSize"                // AMFSize; default = 0,0; Frame size
+
+#define AMF_VIDEO_ENCODER_EXTRADATA                             L"ExtraData"                // AMFInterface* - > AMFBuffer*; SPS/PPS buffer in Annex B format - read-only
+#define AMF_VIDEO_ENCODER_USAGE                                 L"Usage"                    // amf_int64(AMF_VIDEO_ENCODER_USAGE_ENUM); default = N/A; Encoder usage type. fully configures parameter set.
+#define AMF_VIDEO_ENCODER_PROFILE                               L"Profile"                  // amf_int64(AMF_VIDEO_ENCODER_PROFILE_ENUM) ; default = AMF_VIDEO_ENCODER_PROFILE_MAIN;  H264 profile
+#define AMF_VIDEO_ENCODER_PROFILE_LEVEL                         L"ProfileLevel"             // amf_int64; default = 42; H264 profile level
+#define AMF_VIDEO_ENCODER_MAX_LTR_FRAMES                        L"MaxOfLTRFrames"           // amf_int64; default = 0; Max number of LTR frames
+#define AMF_VIDEO_ENCODER_LTR_MODE                              L"LTRMode"                  // amf_int64(AMF_VIDEO_ENCODER_LTR_MODE_ENUM); default = AMF_VIDEO_ENCODER_LTR_MODE_RESET_UNUSED; remove/keep unused LTRs (not specified in property AMF_VIDEO_ENCODER_FORCE_LTR_REFERENCE_BITFIELD)
+#define AMF_VIDEO_ENCODER_SCANTYPE                              L"ScanType"                 // amf_int64(AMF_VIDEO_ENCODER_SCANTYPE_ENUM); default = AMF_VIDEO_ENCODER_SCANTYPE_PROGRESSIVE; indicates input stream type
+#define AMF_VIDEO_ENCODER_MAX_NUM_REFRAMES                      L"MaxNumRefFrames"          // amf_int64; Maximum number of reference frames
+#define AMF_VIDEO_ENCODER_MAX_CONSECUTIVE_BPICTURES             L"MaxConsecutiveBPictures"  // amf_int64; Maximum number of consecutive B Pictures
+#define AMF_VIDEO_ENCODER_ADAPTIVE_MINIGOP                      L"AdaptiveMiniGOP"          // bool; default = false; Disable/Enable Adaptive MiniGOP
+#define AMF_VIDEO_ENCODER_ASPECT_RATIO                          L"AspectRatio"              // AMFRatio; default = 1, 1
+#define AMF_VIDEO_ENCODER_FULL_RANGE_COLOR                      L"FullRangeColor"           // bool; default = false; inidicates that YUV input is (0,255)
+#define AMF_VIDEO_ENCODER_LOWLATENCY_MODE                       L"LowLatencyInternal"       // bool; default = false, enables low latency mode and POC mode 2 in the encoder
+#define AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE                   L"EnablePreAnalysis"        // bool; default = false; enables the pre-analysis module. Currently only works in AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR mode. Refer to AMF Video PreAnalysis API reference for more details.
+#define AMF_VIDEO_ENCODER_PREENCODE_ENABLE                      L"RateControlPreanalysisEnable"     // amf_int64(AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM); default =  AMF_VIDEO_ENCODER_PREENCODE_DISABLED; enables pre-encode assisted rate control
+#define AMF_VIDEO_ENCODER_RATE_CONTROL_PREANALYSIS_ENABLE       L"RateControlPreanalysisEnable"     // amf_int64(AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM); default =  AMF_VIDEO_ENCODER_PREENCODE_DISABLED; enables pre-encode assisted rate control. Deprecated, please use AMF_VIDEO_ENCODER_PREENCODE_ENABLE instead.
+#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD                   L"RateControlMethod"        // amf_int64(AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM); default = depends on USAGE; Rate Control Method
+#define AMF_VIDEO_ENCODER_QVBR_QUALITY_LEVEL                    L"QvbrQualityLevel"         // amf_int64; default = 23; QVBR quality level; range = 1-51
+#if !defined(__GNUC__) && !defined(__clang__)
+    #pragma deprecated("AMF_VIDEO_ENCODER_RATE_CONTROL_PREANALYSIS_ENABLE")
+#endif
+
+
+    // Quality preset property
+#define AMF_VIDEO_ENCODER_QUALITY_PRESET                        L"QualityPreset"            // amf_int64(AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM); default = depends on USAGE; Quality Preset
+
+    // color conversion
+#define AMF_VIDEO_ENCODER_COLOR_BIT_DEPTH                       L"ColorBitDepth"            // amf_int64(AMF_COLOR_BIT_DEPTH_ENUM); default = AMF_COLOR_BIT_DEPTH_8
+
+#define AMF_VIDEO_ENCODER_INPUT_COLOR_PROFILE                   L"InColorProfile"           // amf_int64(AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM); default = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN - mean AUTO by size
+#define AMF_VIDEO_ENCODER_INPUT_TRANSFER_CHARACTERISTIC         L"InColorTransferChar"      // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013 ?7.2 See VideoDecoderUVD.h for enum
+#define AMF_VIDEO_ENCODER_INPUT_COLOR_PRIMARIES                 L"InColorPrimaries"         // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013 Section 7.1 See ColorSpace.h for enum
+#define AMF_VIDEO_ENCODER_INPUT_HDR_METADATA                    L"InHDRMetadata"            // AMFBuffer containing AMFHDRMetadata; default NULL
+
+#define AMF_VIDEO_ENCODER_OUTPUT_COLOR_PROFILE                  L"OutColorProfile"          // amf_int64(AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM); default = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN - mean AUTO by size
+#define AMF_VIDEO_ENCODER_OUTPUT_TRANSFER_CHARACTERISTIC        L"OutColorTransferChar"     // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013 Section 7.2 See VideoDecoderUVD.h for enum
+#define AMF_VIDEO_ENCODER_OUTPUT_COLOR_PRIMARIES                L"OutColorPrimaries"        // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013 Section 7.1 See ColorSpace.h for enum
+#define AMF_VIDEO_ENCODER_OUTPUT_HDR_METADATA                   L"OutHDRMetadata"           // AMFBuffer containing AMFHDRMetadata; default NULL
+
+
+// Dynamic properties - can be set at any time
+   // Rate control properties
+#define AMF_VIDEO_ENCODER_FRAMERATE                             L"FrameRate"                // AMFRate; default = depends on usage; Frame Rate
+#define AMF_VIDEO_ENCODER_B_PIC_DELTA_QP                        L"BPicturesDeltaQP"         // amf_int64; default = depends on USAGE; B-picture Delta
+#define AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP                    L"ReferenceBPicturesDeltaQP"// amf_int64; default = depends on USAGE; Reference B-picture Delta
+
+#define AMF_VIDEO_ENCODER_ENFORCE_HRD                           L"EnforceHRD"               // bool; default = depends on USAGE; Enforce HRD
+#define AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE                    L"FillerDataEnable"         // bool; default = false; Filler Data Enable
+#define AMF_VIDEO_ENCODER_ENABLE_VBAQ                           L"EnableVBAQ"               // bool; default = depends on USAGE; Enable VBAQ
+#define AMF_VIDEO_ENCODER_HIGH_MOTION_QUALITY_BOOST_ENABLE      L"HighMotionQualityBoostEnable"// bool; default = depends on USAGE; Enable High motion quality boost mode
+
+
+#define AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE                       L"VBVBufferSize"            // amf_int64; default = depends on USAGE; VBV Buffer Size in bits
+#define AMF_VIDEO_ENCODER_INITIAL_VBV_BUFFER_FULLNESS           L"InitialVBVBufferFullness" // amf_int64; default =  64; Initial VBV Buffer Fullness 0=0% 64=100%
+
+#define AMF_VIDEO_ENCODER_MAX_AU_SIZE                           L"MaxAUSize"                // amf_int64; default = 0; Max AU Size in bits
+
+#define AMF_VIDEO_ENCODER_MIN_QP                                L"MinQP"                    // amf_int64; default = depends on USAGE; Min QP; range = 0-51
+#define AMF_VIDEO_ENCODER_MAX_QP                                L"MaxQP"                    // amf_int64; default = depends on USAGE; Max QP; range = 0-51
+#define AMF_VIDEO_ENCODER_QP_I                                  L"QPI"                      // amf_int64; default = 22; I-frame QP; range = 0-51
+#define AMF_VIDEO_ENCODER_QP_P                                  L"QPP"                      // amf_int64; default = 22; P-frame QP; range = 0-51
+#define AMF_VIDEO_ENCODER_QP_B                                  L"QPB"                      // amf_int64; default = 22; B-frame QP; range = 0-51
+#define AMF_VIDEO_ENCODER_TARGET_BITRATE                        L"TargetBitrate"            // amf_int64; default = depends on USAGE; Target bit rate in bits
+#define AMF_VIDEO_ENCODER_PEAK_BITRATE                          L"PeakBitrate"              // amf_int64; default = depends on USAGE; Peak bit rate in bits
+#define AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE        L"RateControlSkipFrameEnable"   // bool; default =  depends on USAGE; Rate Control Based Frame Skip
+
+    // Picture control properties
+#define AMF_VIDEO_ENCODER_HEADER_INSERTION_SPACING              L"HeaderInsertionSpacing"   // amf_int64; default = depends on USAGE; Header Insertion Spacing; range 0-1000
+#define AMF_VIDEO_ENCODER_B_PIC_PATTERN                         L"BPicturesPattern"         // amf_int64; default = 3; B-picture Pattern (number of B-Frames)
+#define AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER                    L"DeBlockingFilter"         // bool; default = depends on USAGE; De-blocking Filter
+#define AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE                    L"BReferenceEnable"         // bool; default = true; Enable Refrence to B-frames
+#define AMF_VIDEO_ENCODER_IDR_PERIOD                            L"IDRPeriod"                // amf_int64; default = depends on USAGE; IDR Period in frames
+#define AMF_VIDEO_ENCODER_INTRA_REFRESH_NUM_MBS_PER_SLOT        L"IntraRefreshMBsNumberPerSlot" // amf_int64; default = depends on USAGE; Intra Refresh MBs Number Per Slot in Macroblocks
+#define AMF_VIDEO_ENCODER_SLICES_PER_FRAME                      L"SlicesPerFrame"           // amf_int64; default = 1; Number of slices Per Frame
+#define AMF_VIDEO_ENCODER_CABAC_ENABLE                          L"CABACEnable"              // amf_int64(AMF_VIDEO_ENCODER_CODING_ENUM) default = AMF_VIDEO_ENCODER_UNDEFINED
+
+    // Motion estimation
+#define AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL                     L"HalfPixel"                // bool; default= true; Half Pixel
+#define AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL                   L"QuarterPixel"             // bool; default= true; Quarter Pixel
+
+    // SVC
+#define AMF_VIDEO_ENCODER_NUM_TEMPORAL_ENHANCMENT_LAYERS        L"NumOfTemporalEnhancmentLayers" // amf_int64; default = 1; range = 1-MaxTemporalLayers; Number of temporal Layers (SVC)
+
+
+    // DPB management
+#define AMF_VIDEO_ENCODER_PICTURE_TRANSFER_MODE                 L"PicTransferMode"               // amf_int64(AMF_VIDEO_ENCODER_PICTURE_TRANSFER_MODE_ENUM); default = AMF_VIDEO_ENCODER_PICTURE_TRANSFER_MODE_OFF - whether to exchange reference/reconstructed pic between encoder and application
+    // misc
+#define AMF_VIDEO_ENCODER_QUERY_TIMEOUT                         L"QueryTimeout"             // amf_int64; default = 0 (no wait); timeout for QueryOutput call in ms.
+
+// Per-submittion properties - can be set on input surface interface
+#define AMF_VIDEO_ENCODER_END_OF_SEQUENCE                       L"EndOfSequence"            // bool; default = false; generate end of sequence
+#define AMF_VIDEO_ENCODER_END_OF_STREAM                         L"EndOfStream"              // bool; default = false; generate end of stream
+#define AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE                    L"ForcePictureType"         // amf_int64(AMF_VIDEO_ENCODER_PICTURE_TYPE_ENUM); default = AMF_VIDEO_ENCODER_PICTURE_TYPE_NONE; generate particular picture type
+#define AMF_VIDEO_ENCODER_INSERT_AUD                            L"InsertAUD"                // bool; default = false; insert AUD
+#define AMF_VIDEO_ENCODER_INSERT_SPS                            L"InsertSPS"                // bool; default = false; insert SPS
+#define AMF_VIDEO_ENCODER_INSERT_PPS                            L"InsertPPS"                // bool; default = false; insert PPS
+#define AMF_VIDEO_ENCODER_PICTURE_STRUCTURE                     L"PictureStructure"         // amf_int64(AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_ENUM); default = AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_FRAME; indicate picture type
+#define AMF_VIDEO_ENCODER_MARK_CURRENT_WITH_LTR_INDEX           L"MarkCurrentWithLTRIndex"  // //amf_int64; default = N/A; Mark current frame with LTR index
+#define AMF_VIDEO_ENCODER_FORCE_LTR_REFERENCE_BITFIELD          L"ForceLTRReferenceBitfield"// amf_int64; default = 0; force LTR bit-field
+#define AMF_VIDEO_ENCODER_ROI_DATA                              L"ROIData"                  // 2D AMFSurface, surface format: AMF_SURFACE_GRAY32
+#define AMF_VIDEO_ENCODER_REFERENCE_PICTURE                     L"ReferencePicture"         // AMFInterface(AMFSurface); surface used for frame injection
+#define AMF_VIDEO_ENCODER_PSNR_FEEDBACK                         L"PSNRFeedback"             // amf_bool; default = false; Signal encoder to calculate PSNR score
+#define AMF_VIDEO_ENCODER_SSIM_FEEDBACK                         L"SSIMFeedback"             // amf_bool; default = false; Signal encoder to calculate SSIM score
+#define AMF_VIDEO_ENCODER_STATISTICS_FEEDBACK                   L"StatisticsFeedback"       // amf_bool; default = false; Signal encoder to collect and feedback statistics
+#define AMF_VIDEO_ENCODER_BLOCK_QP_FEEDBACK                     L"BlockQpFeedback"          // amf_bool; default = false; Signal encoder to collect and feedback block level QP values
+
+
+// properties set by encoder on output buffer interface
+#define AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE                      L"OutputDataType"           // amf_int64(AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM); default = N/A
+#define AMF_VIDEO_ENCODER_OUTPUT_MARKED_LTR_INDEX               L"MarkedLTRIndex"           //amf_int64; default = -1; Marked LTR index
+#define AMF_VIDEO_ENCODER_OUTPUT_REFERENCED_LTR_INDEX_BITFIELD  L"ReferencedLTRIndexBitfield" // amf_int64; default = 0; referenced LTR bit-field
+#define AMF_VIDEO_ENCODER_OUTPUT_TEMPORAL_LAYER                 L"OutputTemporalLayer"      // amf_int64; Temporal layer
+#define AMF_VIDEO_ENCODER_PRESENTATION_TIME_STAMP               L"PresentationTimeStamp"    // amf_int64; Presentation time stamp (PTS)
+#define AMF_VIDEO_ENCODER_RECONSTRUCTED_PICTURE                 L"ReconstructedPicture"     // AMFInterface(AMFSurface); returns reconstructed picture as an AMFSurface attached to the output buffer as property AMF_VIDEO_ENCODER_RECONSTRUCTED_PICTURE of AMFInterface type
+#define AMF_VIDEO_ENCODER_STATISTIC_PSNR_Y                      L"PSNRY"                    // double; PSNR Y
+#define AMF_VIDEO_ENCODER_STATISTIC_PSNR_U                      L"PSNRU"                    // double; PSNR U
+#define AMF_VIDEO_ENCODER_STATISTIC_PSNR_V                      L"PSNRV"                    // double; PSNR V
+#define AMF_VIDEO_ENCODER_STATISTIC_PSNR_ALL                    L"PSNRALL"                  // double; PSNR All
+#define AMF_VIDEO_ENCODER_STATISTIC_SSIM_Y                      L"SSIMY"                    // double; SSIM Y
+#define AMF_VIDEO_ENCODER_STATISTIC_SSIM_U                      L"SSIMU"                    // double; SSIM U
+#define AMF_VIDEO_ENCODER_STATISTIC_SSIM_V                      L"SSIMV"                    // double; SSIM V
+#define AMF_VIDEO_ENCODER_STATISTIC_SSIM_ALL                    L"SSIMALL"                  // double; SSIM ALL
+
+    // Encoder statistics feedback
+#define AMF_VIDEO_ENCODER_STATISTIC_FRAME_QP                    L"StatisticsFeedbackFrameQP"                // amf_int64; Rate control base frame/initial QP
+#define AMF_VIDEO_ENCODER_STATISTIC_AVERAGE_QP                  L"StatisticsFeedbackAvgQP"                  // amf_int64; Average calculated QP of all encoded MBs in a picture. Value may be different from the one reported by bitstream analyzer when there are skipped MBs.
+#define AMF_VIDEO_ENCODER_STATISTIC_MAX_QP                      L"StatisticsFeedbackMaxQP"                  // amf_int64; Max calculated QP among all encoded MBs in a picture. Value may be different from the one reported by bitstream analyzer when there are skipped MBs.
+#define AMF_VIDEO_ENCODER_STATISTIC_MIN_QP                      L"StatisticsFeedbackMinQP"                  // amf_int64; Min calculated QP among all encoded MBs in a picture. Value may be different from the one reported by bitstream analyzer when there are skipped MBs.
+#define AMF_VIDEO_ENCODER_STATISTIC_PIX_NUM_INTRA               L"StatisticsFeedbackPixNumIntra"            // amf_int64; Number of the intra encoded pixels
+#define AMF_VIDEO_ENCODER_STATISTIC_PIX_NUM_INTER               L"StatisticsFeedbackPixNumInter"            // amf_int64; Number of the inter encoded pixels
+#define AMF_VIDEO_ENCODER_STATISTIC_PIX_NUM_SKIP                L"StatisticsFeedbackPixNumSkip"             // amf_int64; Number of the skip mode pixels
+#define AMF_VIDEO_ENCODER_STATISTIC_BITCOUNT_RESIDUAL           L"StatisticsFeedbackBitcountResidual"       // amf_int64; The bit count that corresponds to residual data
+#define AMF_VIDEO_ENCODER_STATISTIC_BITCOUNT_MOTION             L"StatisticsFeedbackBitcountMotion"         // amf_int64; The bit count that corresponds to motion vectors
+#define AMF_VIDEO_ENCODER_STATISTIC_BITCOUNT_INTER              L"StatisticsFeedbackBitcountInter"          // amf_int64; The bit count that are assigned to inter MBs
+#define AMF_VIDEO_ENCODER_STATISTIC_BITCOUNT_INTRA              L"StatisticsFeedbackBitcountIntra"          // amf_int64; The bit count that are assigned to intra MBs
+#define AMF_VIDEO_ENCODER_STATISTIC_BITCOUNT_ALL_MINUS_HEADER   L"StatisticsFeedbackBitcountAllMinusHeader" // amf_int64; The bit count of the bitstream excluding header
+#define AMF_VIDEO_ENCODER_STATISTIC_MV_X                        L"StatisticsFeedbackMvX"                    // amf_int64; Accumulated absolute values of horizontal MV's
+#define AMF_VIDEO_ENCODER_STATISTIC_MV_Y                        L"StatisticsFeedbackMvY"                    // amf_int64; Accumulated absolute values of vertical MV's
+#define AMF_VIDEO_ENCODER_STATISTIC_RD_COST_FINAL               L"StatisticsFeedbackRdCostFinal"            // amf_int64; Frame level final RD cost for full encoding
+#define AMF_VIDEO_ENCODER_STATISTIC_RD_COST_INTRA               L"StatisticsFeedbackRdCostIntra"            // amf_int64; Frame level intra RD cost for full encoding
+#define AMF_VIDEO_ENCODER_STATISTIC_RD_COST_INTER               L"StatisticsFeedbackRdCostInter"            // amf_int64; Frame level inter RD cost for full encoding
+#define AMF_VIDEO_ENCODER_STATISTIC_SATD_FINAL                  L"StatisticsFeedbackSatdFinal"              // amf_int64; Frame level final SATD for full encoding
+#define AMF_VIDEO_ENCODER_STATISTIC_SATD_INTRA                  L"StatisticsFeedbackSatdIntra"              // amf_int64; Frame level intra SATD for full encoding
+#define AMF_VIDEO_ENCODER_STATISTIC_SATD_INTER                  L"StatisticsFeedbackSatdInter"              // amf_int64; Frame level inter SATD for full encoding
+
+    // Encoder block level feedback
+#define AMF_VIDEO_ENCODER_BLOCK_QP_MAP                          L"BlockQpMap"                               // AMFInterface(AMFSurface); AMFSurface of format AMF_SURFACE_GRAY32 containing block level QP values
+
+#define AMF_VIDEO_ENCODER_HDCP_COUNTER                          L"HDCPCounter"              //  const void*
+
+// Properties for multi-instance cloud gaming
+#define AMF_VIDEO_ENCODER_MAX_INSTANCES                         L"EncoderMaxInstances"      // deprecated.  amf_int64; default = 1; max number of encoder instances
+#define AMF_VIDEO_ENCODER_MULTI_INSTANCE_MODE                   L"MultiInstanceMode"        // deprecated.  bool; default = false;
+#define AMF_VIDEO_ENCODER_CURRENT_QUEUE                         L"MultiInstanceCurrentQueue"// deprecated.  amf_int64; default = 0;
+
+
+// VCE Encoder capabilities - exposed in AMFCaps interface
+#define AMF_VIDEO_ENCODER_CAP_MAX_BITRATE                       L"MaxBitrate"               // amf_int64; Maximum bit rate in bits
+#define AMF_VIDEO_ENCODER_CAP_NUM_OF_STREAMS                    L"NumOfStreams"             // amf_int64; maximum number of encode streams supported
+#define AMF_VIDEO_ENCODER_CAP_MAX_PROFILE                       L"MaxProfile"               // AMF_VIDEO_ENCODER_PROFILE_ENUM
+#define AMF_VIDEO_ENCODER_CAP_MAX_LEVEL                         L"MaxLevel"                 // amf_int64 maximum profile level
+#define AMF_VIDEO_ENCODER_CAP_BFRAMES                           L"BFrames"                  // bool  is B-Frames supported
+#define AMF_VIDEO_ENCODER_CAP_MIN_REFERENCE_FRAMES              L"MinReferenceFrames"       // amf_int64 minimum number of reference frames
+#define AMF_VIDEO_ENCODER_CAP_MAX_REFERENCE_FRAMES              L"MaxReferenceFrames"       // amf_int64 maximum number of reference frames
+#define AMF_VIDEO_ENCODER_CAP_MAX_TEMPORAL_LAYERS               L"MaxTemporalLayers"        // amf_int64 maximum number of temporal layers
+#define AMF_VIDEO_ENCODER_CAP_FIXED_SLICE_MODE                  L"FixedSliceMode"           // bool  is fixed slice mode supported
+#define AMF_VIDEO_ENCODER_CAP_NUM_OF_HW_INSTANCES               L"NumOfHwInstances"         // amf_int64 number of HW encoder instances
+#define AMF_VIDEO_ENCODER_CAP_COLOR_CONVERSION                  L"ColorConversion"          // amf_int64(AMF_ACCELERATION_TYPE) - type of supported color conversion. default AMF_ACCEL_GPU
+#define AMF_VIDEO_ENCODER_CAP_PRE_ANALYSIS                      L"PreAnalysis"              // amf_bool - pre analysis module is available for H264 UVE encoder, n/a for the other encoders
+#define AMF_VIDEO_ENCODER_CAP_ROI                               L"ROIMap"                   // amf_bool - ROI map support is available for H264 UVE encoder, n/a for the other encoders
+#define AMF_VIDEO_ENCODER_CAP_MAX_THROUGHPUT                    L"MaxThroughput"            // amf_int64 - MAX throughput for H264 encoder in MB (16 x 16 pixel)
+#define AMF_VIDEO_ENCODER_CAP_REQUESTED_THROUGHPUT              L"RequestedThroughput"      // amf_int64 - Currently total requested throughput for H264 encoder in MB (16 x 16 pixel)
+#define AMF_VIDEO_ENCODER_CAPS_QUERY_TIMEOUT_SUPPORT            L"QueryTimeoutSupport"      // amf_bool - Timeout supported for QueryOutout call
+
+// properties set on AMFComponent to control component creation
+#define AMF_VIDEO_ENCODER_MEMORY_TYPE                           L"EncoderMemoryType"        // amf_int64(AMF_MEMORY_TYPE) , default is AMF_MEMORY_UNKNOWN, Values : AMF_MEMORY_DX11, AMF_MEMORY_DX9, AMF_MEMORY_VULKAN or AMF_MEMORY_UNKNOWN (auto)
+
+#endif //#ifndef AMF_VideoEncoderVCE_h

+ 124 - 0
plugins/obs-ffmpeg/external/AMF/include/components/VideoStitch.h

@@ -0,0 +1,124 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+//
+// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ ***************************************************************************************************
+ * @file  VideoStitch.h
+ * @brief AMFVideoStitch interface declaration
+ ***************************************************************************************************
+ */
+#ifndef AMF_VideoStitch_h
+#define AMF_VideoStitch_h
+#pragma once
+
+#include "public/include/components/Component.h"
+
+#define AMFVideoStitch       L"AMFVideoStitch"                  //Component name
+
+// static properties 
+#define AMF_VIDEO_STITCH_OUTPUT_FORMAT       L"OutputFormat"    // Values, AMF_SURFACE_BGRA or AMF_SURFACE_RGBA
+#define AMF_VIDEO_STITCH_MEMORY_TYPE         L"MemoryType"      // Values, only AMF_MEMORY_DX11 is supported for now.
+#define AMF_VIDEO_STITCH_OUTPUT_SIZE         L"OutputSize"      // AMFSize, (width, height) in pixels. default= (0,0), will be the same size as input.
+#define AMF_VIDEO_STITCH_INPUTCOUNT          L"InputCount"      // amf_uint64, number of camera inputs.
+
+// individual camera direction and location
+#define AMF_VIDEO_CAMERA_ANGLE_PITCH        L"CameraPitch"      // double, in radians, default = 0, camera pitch orientation 
+#define AMF_VIDEO_CAMERA_ANGLE_YAW          L"CameraYaw"        // double, in radians, default = 0, camera yaw orientation 
+#define AMF_VIDEO_CAMERA_ANGLE_ROLL         L"CameraRoll"       // double, in radians, default = 0, camera roll orientation 
+
+#define AMF_VIDEO_CAMERA_OFFSET_X           L"CameraOffsetX"    // double, in pixels, default = 0, X offset of camera center of the lens from the center of the rig.
+#define AMF_VIDEO_CAMERA_OFFSET_Y           L"CameraOffsetY"    // double, in pixels, default = 0, Y offset of camera center of the lens from the center of the rig.
+#define AMF_VIDEO_CAMERA_OFFSET_Z           L"CameraOffsetZ"    // double, in pixels, default = 0, Z offset of camera center of the lens from the center of the rig.
+#define AMF_VIDEO_CAMERA_HFOV               L"CameraHFOV"       // double, in radians, default = PI, - horizontal field of view
+#define AMF_VIDEO_CAMERA_SCALE              L"CameraScale"      // double, default = 1, scale coeff
+
+// lens correction parameters
+#define AMF_VIDEO_STITCH_LENS_CORR_K1       L"LensK1"           // double, default = 0.
+#define AMF_VIDEO_STITCH_LENS_CORR_K2       L"LensK2"           // double, default = 0.
+#define AMF_VIDEO_STITCH_LENS_CORR_K3       L"LensK3"           // double, default = 0.
+#define AMF_VIDEO_STITCH_LENS_CORR_OFFX     L"LensOffX"         // double, default = 0.
+#define AMF_VIDEO_STITCH_LENS_CORR_OFFY     L"LensOffY"         // double, default = 0.
+#define AMF_VIDEO_STITCH_CROP               L"Crop"             //AMFRect, in pixels default = (0,0,0,0).
+
+#define AMF_VIDEO_STITCH_LENS_MODE          L"LensMode"         // Values, AMF_VIDEO_STITCH_LENS_CORR_MODE_ENUM, (default = AMF_VIDEO_STITCH_LENS_CORR_MODE_RADIAL)
+
+#define AMF_VIDEO_STITCH_OUTPUT_MODE        L"OutputMode"       // AMF_VIDEO_STITCH_OUTPUT_MODE_ENUM (default=AMF_VIDEO_STITCH_OUTPUT_MODE_PREVIEW) 
+#define AMF_VIDEO_STITCH_COMBINED_SOURCE    L"CombinedSource"   // bool, (default=false) video sources are combined in one stream
+
+#define AMF_VIDEO_STITCH_COMPUTE_DEVICE     L"ComputeDevice"    // amf_int64(AMF_MEMORY_TYPE) Values, AMF_MEMORY_DX11, AMF_MEMORY_COMPUTE_FOR_DX11, AMF_MEMORY_OPENCL
+
+//for debug
+#define AMF_VIDEO_STITCH_WIRE_RENDER        L"Wire"             // bool (default=false) reder wireframe
+
+//view angle 
+#define AMF_VIDEO_STITCH_VIEW_ROTATE_X      L"AngleX"           // double, in radians, default = 0 - delta from current position / automatilcally reset to 0 inside SetProperty() call
+#define AMF_VIDEO_STITCH_VIEW_ROTATE_Y      L"AngleY"           // double, in radians, default = 0 - delta from current position / automatilcally reset to 0 inside SetProperty() call
+#define AMF_VIDEO_STITCH_VIEW_ROTATE_Z      L"AngleZ"           // double, in radians, default = 0 - delta from current position / automatilcally reset to 0 inside SetProperty() call
+
+#define AMF_VIDEO_STITCH_COLOR_BALANCE      L"ColorBalance"     // bool (default=true) enables color balance
+
+//lens mode
+enum AMF_VIDEO_STITCH_LENS_ENUM
+{
+    AMF_VIDEO_STITCH_LENS_RECTILINEAR        = 0,   //rect linear lens
+    AMF_VIDEO_STITCH_LENS_FISHEYE_FULLFRAME  = 1,   //fisheye full frame
+    AMF_VIDEO_STITCH_LENS_FISHEYE_CIRCULAR   = 2,   //fisheye, circular
+};
+
+//Output Mode
+enum AMF_VIDEO_STITCH_OUTPUT_MODE_ENUM
+{
+    AMF_VIDEO_STITCH_OUTPUT_MODE_PREVIEW          = 0,    //preview mode
+    AMF_VIDEO_STITCH_OUTPUT_MODE_EQUIRECTANGULAR  = 1,    //equirectangular mode
+    AMF_VIDEO_STITCH_OUTPUT_MODE_CUBEMAP          = 2,    //cubemap mode
+    AMF_VIDEO_STITCH_OUTPUT_MODE_LAST = AMF_VIDEO_STITCH_OUTPUT_MODE_CUBEMAP,
+};
+
+//audio mode
+enum AMF_VIDEO_STITCH_AUDIO_MODE_ENUM
+{
+    AMF_VIDEO_STITCH_AUDIO_MODE_NONE        = 0,    //no audio
+    AMF_VIDEO_STITCH_AUDIO_MODE_VIDEO       = 1,    //using audio from video stream
+    AMF_VIDEO_STITCH_AUDIO_MODE_FILE        = 2,    //using audio from file
+    AMF_VIDEO_STITCH_AUDIO_MODE_CAPTURE     = 3,    //using audio from capture device
+    AMF_VIDEO_STITCH_AUDIO_MODE_INVALID = -1,       //invalid
+};
+
+
+#if defined(_M_AMD64)
+    #define STITCH_DLL_NAME    L"amf-stitch-64.dll"
+#else
+    #define STITCH_DLL_NAME    L"amf-stitch-32.dll"
+#endif
+
+#endif //#ifndef AMF_VideoStitch_h

+ 83 - 0
plugins/obs-ffmpeg/external/AMF/include/components/ZCamLiveStream.h

@@ -0,0 +1,83 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+//-------------------------------------------------------------------------------------------------
+// ZCamLive  interface declaration
+//-------------------------------------------------------------------------------------------------
+#ifndef AMF_ZCamLiveStream_h
+#define AMF_ZCamLiveStream_h
+
+#pragma once
+#define ZCAMLIVE_STREAMCOUNT             L"StreamCount"          // amf_int64 (default = 4),  number of streams
+#define ZCAMLIVE_VIDEO_FRAMESIZE         L"FrameSize"            // AMFSize   (default = AMFConstructSize(2704, 1520)), frame size
+#define ZCAMLIVE_VIDEO_FRAMERATE         L"FrameRate"            // AMFRate   (default = 30.0), video frame rate
+#define ZCAMLIVE_VIDEO_BIT_RATE          L"BitRate"              // amf_int64 (default = 3000000), video bitrate
+#define ZCAMLIVE_STREAM_ACTIVE_CAMERA    L"ActiveCamera"         // amf_int64 (default = -1, all the cameras), the index of the camera to capture
+#define ZCAMLIVE_STREAM_FRAMECOUNT       L"FrameCount"           // amf_int64 (default = 0), number of frames captured
+#define ZCAMLIVE_CODEC_ID                L"CodecID"              // WString (default = "AMFVideoDecoderUVD_H264_AVC"), UVD codec ID
+#define ZCAMLIVE_VIDEO_MODE              L"VideoMode"            // Enum (default = 0, 2K7P30), ZCam mode
+#define ZCAMLIVE_AUDIO_MODE              L"AudioMode"            // Enum (default = 0, Silent) - Audio mode
+#define ZCAMLIVE_LOWLATENCY              L"LowLatency"           // amf_int64 (default = 1, LowLatency), low latency flag
+#define ZCAMLIVE_IP_0                    L"ZCamIP_00"               // WString, IP address of the #1 stream, default "10.98.32.1"
+#define ZCAMLIVE_IP_1                    L"ZCamIP_01"             // WString, IP address of the #2 stream, default "10.98.32.2"
+#define ZCAMLIVE_IP_2                    L"ZCamIP_02"             // WString, IP address of the #3 stream, default "10.98.32.3"
+#define ZCAMLIVE_IP_3                    L"ZCamIP_03"             // WString, IP address of the #4 stream, default "10.98.32.4"
+
+//Camera live capture Mode
+enum CAMLIVE_MODE_ENUM
+{
+    CAMLIVE_MODE_ZCAM_1080P24 = 0,  //1920x1080, 24FPS
+    CAMLIVE_MODE_ZCAM_1080P30,      //1920x1080, 30FPS
+    CAMLIVE_MODE_ZCAM_1080P60,      //1920x1080, 60FPS
+    CAMLIVE_MODE_ZCAM_2K7P24,       //2704x1520, 24FPS
+    CAMLIVE_MODE_ZCAM_2K7P30,       //2704x1520, 24FPS
+    CAMLIVE_MODE_ZCAM_2K7P60,       //2704x1520, 24FPS
+    CAMLIVE_MODE_ZCAM_2544P24,      //3392x2544, 24FPS
+    CAMLIVE_MODE_ZCAM_2544P30,      //3392x2544, 24FPS
+    CAMLIVE_MODE_ZCAM_2544P60,      //3392x2544, 24FPS
+    CAMLIVE_MODE_THETAS,            //Ricoh TheataS
+    CAMLIVE_MODE_THETAV,            //Ricoh TheataV
+    CAMLIVE_MODE_INVALID = -1,
+};
+ 
+enum CAM_AUDIO_MODE_ENUM
+{
+    CAM_AUDIO_MODE_NONE = 0,   //None
+    CAM_AUDIO_MODE_SILENT,     //Silent audio
+    CAM_AUDIO_MODE_CAMERA      //Capture from camera, not supported yet
+};
+
+extern "C"
+{
+    AMF_RESULT AMF_CDECL_CALL AMFCreateComponentZCamLiveStream(amf::AMFContext* pContext, amf::AMFComponentEx** ppComponent);
+}
+#endif // AMF_ZCamLiveStream_h

+ 234 - 0
plugins/obs-ffmpeg/external/AMF/include/core/AudioBuffer.h

@@ -0,0 +1,234 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_AudioBuffer_h
+#define AMF_AudioBuffer_h
+#pragma once
+
+#include "Data.h"
+#if defined(_MSC_VER)
+    #pragma warning( push )
+    #pragma warning(disable : 4263)
+    #pragma warning(disable : 4264)
+#endif
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    typedef enum AMF_AUDIO_FORMAT
+    {
+        AMFAF_UNKNOWN   =-1,
+        AMFAF_U8        = 0,               // amf_uint8
+        AMFAF_S16       = 1,               // amf_int16
+        AMFAF_S32       = 2,               // amf_int32
+        AMFAF_FLT       = 3,               // amf_float
+        AMFAF_DBL       = 4,               // amf_double
+
+        AMFAF_U8P       = 5,               // amf_uint8
+        AMFAF_S16P      = 6,               // amf_int16
+        AMFAF_S32P      = 7,               // amf_int32
+        AMFAF_FLTP      = 8,               // amf_float
+        AMFAF_DBLP      = 9,               // amf_double
+        AMFAF_FIRST     = AMFAF_U8,
+        AMFAF_LAST      = AMFAF_DBLP,
+    } AMF_AUDIO_FORMAT;
+
+    typedef enum AMF_AUDIO_CHANNEL_LAYOUT
+    {
+        AMFACL_SPEAKER_FRONT_LEFT            = 0x1,
+        AMFACL_SPEAKER_FRONT_RIGHT           = 0x2,
+        AMFACL_SPEAKER_FRONT_CENTER          = 0x4,
+        AMFACL_SPEAKER_LOW_FREQUENCY         = 0x8,
+        AMFACL_SPEAKER_BACK_LEFT             = 0x10,
+        AMFACL_SPEAKER_BACK_RIGHT            = 0x20,
+        AMFACL_SPEAKER_FRONT_LEFT_OF_CENTER  = 0x40,
+        AMFACL_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80,
+        AMFACL_SPEAKER_BACK_CENTER           = 0x100,
+        AMFACL_SPEAKER_SIDE_LEFT             = 0x200,
+        AMFACL_SPEAKER_SIDE_RIGHT            = 0x400,
+        AMFACL_SPEAKER_TOP_CENTER            = 0x800,
+        AMFACL_SPEAKER_TOP_FRONT_LEFT        = 0x1000,
+        AMFACL_SPEAKER_TOP_FRONT_CENTER      = 0x2000,
+        AMFACL_SPEAKER_TOP_FRONT_RIGHT       = 0x4000,
+        AMFACL_SPEAKER_TOP_BACK_LEFT         = 0x8000,
+        AMFACL_SPEAKER_TOP_BACK_CENTER       = 0x10000,
+        AMFACL_SPEAKER_TOP_BACK_RIGHT        = 0x20000
+    } AMF_AUDIO_CHANNEL_LAYOUT;
+
+    // get the most common layout for a given number of speakers
+    inline int GetDefaultChannelLayout(int channels)
+    {
+        switch (channels)
+        {
+        case 1:
+            return (AMFACL_SPEAKER_FRONT_CENTER);
+        case 2:
+            return (AMFACL_SPEAKER_FRONT_LEFT | AMFACL_SPEAKER_FRONT_RIGHT);
+        case 4:
+            return (AMFACL_SPEAKER_FRONT_LEFT | AMFACL_SPEAKER_FRONT_RIGHT | AMFACL_SPEAKER_BACK_LEFT | AMFACL_SPEAKER_BACK_RIGHT);
+        case 6:
+            return (AMFACL_SPEAKER_FRONT_LEFT | AMFACL_SPEAKER_FRONT_RIGHT | AMFACL_SPEAKER_FRONT_CENTER | AMFACL_SPEAKER_LOW_FREQUENCY | AMFACL_SPEAKER_BACK_LEFT | AMFACL_SPEAKER_BACK_RIGHT);
+        case 8:
+            return (AMFACL_SPEAKER_FRONT_LEFT | AMFACL_SPEAKER_FRONT_RIGHT | AMFACL_SPEAKER_FRONT_CENTER | AMFACL_SPEAKER_LOW_FREQUENCY | AMFACL_SPEAKER_BACK_LEFT | AMFACL_SPEAKER_BACK_RIGHT | AMFACL_SPEAKER_FRONT_LEFT_OF_CENTER | AMFACL_SPEAKER_FRONT_RIGHT_OF_CENTER);
+        }
+
+        return AMFACL_SPEAKER_FRONT_LEFT | AMFACL_SPEAKER_FRONT_RIGHT;
+    }
+
+    //----------------------------------------------------------------------------------------------
+    // AMFAudioBufferObserver interface - callback
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMFAudioBuffer;
+    class AMF_NO_VTABLE AMFAudioBufferObserver
+    {
+    public:
+        virtual void                AMF_STD_CALL OnBufferDataRelease(AMFAudioBuffer* pBuffer) = 0;
+    };
+#else // #if defined(__cplusplus)
+    typedef struct AMFAudioBuffer AMFAudioBuffer;
+    typedef struct AMFAudioBufferObserver AMFAudioBufferObserver;
+    typedef struct AMFAudioBufferObserverVtbl
+    {
+        void                (AMF_STD_CALL *OnBufferDataRelease)(AMFAudioBufferObserver* pThis, AMFAudioBuffer* pBuffer);
+    } AMFAudioBufferObserverVtbl;
+
+    struct AMFAudioBufferObserver
+    {
+        const AMFAudioBufferObserverVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // AudioBuffer interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFAudioBuffer : public AMFData
+    {
+    public:
+        AMF_DECLARE_IID(0x2212ff8, 0x6107, 0x430b, 0xb6, 0x3c, 0xc7, 0xe5, 0x40, 0xe5, 0xf8, 0xeb)
+
+        virtual amf_int32           AMF_STD_CALL GetSampleCount() = 0;
+        virtual amf_int32           AMF_STD_CALL GetSampleRate() = 0;
+        virtual amf_int32           AMF_STD_CALL GetChannelCount() = 0;
+        virtual AMF_AUDIO_FORMAT    AMF_STD_CALL GetSampleFormat() = 0;
+        virtual amf_int32           AMF_STD_CALL GetSampleSize() = 0;
+        virtual amf_uint32          AMF_STD_CALL GetChannelLayout() = 0;
+        virtual void*               AMF_STD_CALL GetNative() = 0;
+        virtual amf_size            AMF_STD_CALL GetSize() = 0;
+
+        // Observer management
+#ifdef __clang__
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Woverloaded-virtual"
+#endif
+        virtual void                AMF_STD_CALL AddObserver(AMFAudioBufferObserver* pObserver) = 0;
+        virtual void                AMF_STD_CALL RemoveObserver(AMFAudioBufferObserver* pObserver) = 0;
+#ifdef __clang__
+    #pragma clang diagnostic pop
+#endif
+
+
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFAudioBuffer> AMFAudioBufferPtr;
+    //----------------------------------------------------------------------------------------------
+#else // #if defined(__cplusplus)
+        AMF_DECLARE_IID(AMFAudioBuffer, 0x2212ff8, 0x6107, 0x430b, 0xb6, 0x3c, 0xc7, 0xe5, 0x40, 0xe5, 0xf8, 0xeb)
+
+    typedef struct AMFAudioBufferVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFAudioBuffer* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFAudioBuffer* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFAudioBuffer* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFAudioBuffer* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFAudioBuffer* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFAudioBuffer* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFAudioBuffer* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFAudioBuffer* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFAudioBuffer* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFAudioBuffer* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFAudioBuffer* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFAudioBuffer* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFAudioBuffer* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFData interface
+
+        AMF_MEMORY_TYPE     (AMF_STD_CALL *GetMemoryType)(AMFAudioBuffer* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *Duplicate)(AMFAudioBuffer* pThis, AMF_MEMORY_TYPE type, AMFData** ppData);
+        AMF_RESULT          (AMF_STD_CALL *Convert)(AMFAudioBuffer* pThis, AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through host memory if needed
+        AMF_RESULT          (AMF_STD_CALL *Interop)(AMFAudioBuffer* pThis, AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy through host memory for GPU objects
+
+        AMF_DATA_TYPE       (AMF_STD_CALL *GetDataType)(AMFAudioBuffer* pThis);
+
+        amf_bool            (AMF_STD_CALL *IsReusable)(AMFAudioBuffer* pThis);
+
+        void                (AMF_STD_CALL *SetPts)(AMFAudioBuffer* pThis, amf_pts pts);
+        amf_pts             (AMF_STD_CALL *GetPts)(AMFAudioBuffer* pThis);
+        void                (AMF_STD_CALL *SetDuration)(AMFAudioBuffer* pThis, amf_pts duration);
+        amf_pts             (AMF_STD_CALL *GetDuration)(AMFAudioBuffer* pThis);
+
+        // AMFAudioBuffer interface
+
+        amf_int32           (AMF_STD_CALL *GetSampleCount)(AMFAudioBuffer* pThis);
+        amf_int32           (AMF_STD_CALL *GetSampleRate)(AMFAudioBuffer* pThis);
+        amf_int32           (AMF_STD_CALL *GetChannelCount)(AMFAudioBuffer* pThis);
+        AMF_AUDIO_FORMAT    (AMF_STD_CALL *GetSampleFormat)(AMFAudioBuffer* pThis);
+        amf_int32           (AMF_STD_CALL *GetSampleSize)(AMFAudioBuffer* pThis);
+        amf_uint32          (AMF_STD_CALL *GetChannelLayout)(AMFAudioBuffer* pThis);
+        void*               (AMF_STD_CALL *GetNative)(AMFAudioBuffer* pThis);
+        amf_size            (AMF_STD_CALL *GetSize)(AMFAudioBuffer* pThis);
+
+        // Observer management
+        void                (AMF_STD_CALL *AddObserver_AudioBuffer)(AMFAudioBuffer* pThis, AMFAudioBufferObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver_AudioBuffer)(AMFAudioBuffer* pThis, AMFAudioBufferObserver* pObserver);
+
+    } AMFAudioBufferVtbl;
+
+    struct AMFAudioBuffer
+    {
+        const AMFAudioBufferVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+#if defined(__cplusplus)
+} // namespace
+#endif
+#if defined(_MSC_VER)
+    #pragma warning( pop )
+#endif
+#endif //#ifndef AMF_AudioBuffer_h

+ 187 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Buffer.h

@@ -0,0 +1,187 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Buffer_h
+#define AMF_Buffer_h
+#pragma once
+
+#include "Data.h"
+
+#if defined(_MSC_VER)
+    #pragma warning( push )
+    #pragma warning(disable : 4263)
+    #pragma warning(disable : 4264)
+#endif
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+
+    //----------------------------------------------------------------------------------------------
+    // AMF_BUFFER_USAGE translates to D3D11_BIND_FLAG or VkBufferUsageFlagBits
+    // bit mask
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_BUFFER_USAGE_BITS
+    {                                                      // D3D11                         D3D12                                       Vulkan 
+        AMF_BUFFER_USAGE_DEFAULT           = 0x80000000,   // D3D11_USAGE_STAGING,                                                      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT 
+        AMF_BUFFER_USAGE_NONE              = 0x00000000,   // 0                  ,          D3D12_RESOURCE_FLAG_NONE,                   0
+        AMF_BUFFER_USAGE_CONSTANT          = 0x00000001,   // D3D11_BIND_CONSTANT_BUFFER,   											VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT 
+        AMF_BUFFER_USAGE_SHADER_RESOURCE   = 0x00000002,   // D3D11_BIND_SHADER_RESOURCE,   D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET,    VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
+        AMF_BUFFER_USAGE_UNORDERED_ACCESS  = 0x00000004,   // D3D11_BIND_UNORDERED_ACCESS,  D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
+        AMF_BUFFER_USAGE_TRANSFER_SRC      = 0x00000008,   //                               								            VK_BUFFER_USAGE_TRANSFER_SRC_BIT
+        AMF_BUFFER_USAGE_TRANSFER_DST      = 0x00000010,   //                               								            VK_BUFFER_USAGE_TRANSFER_DST_BIT
+    } AMF_BUFFER_USAGE_BITS;
+    typedef amf_flags AMF_BUFFER_USAGE;
+    //----------------------------------------------------------------------------------------------
+
+
+    //----------------------------------------------------------------------------------------------
+    // AMFBufferObserver interface - callback
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMFBuffer;
+    class AMF_NO_VTABLE AMFBufferObserver
+    {
+    public:
+        virtual void                AMF_STD_CALL OnBufferDataRelease(AMFBuffer* pBuffer) = 0;
+    };
+#else // #if defined(__cplusplus)
+    typedef struct AMFBuffer AMFBuffer;
+    typedef struct AMFBufferObserver AMFBufferObserver;
+
+    typedef struct AMFBufferObserverVtbl
+    {
+        void                (AMF_STD_CALL *OnBufferDataRelease)(AMFBufferObserver* pThis, AMFBuffer* pBuffer);
+    } AMFBufferObserverVtbl;
+
+    struct AMFBufferObserver
+    {
+        const AMFBufferObserverVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+    // AMFBuffer interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFBuffer : public AMFData
+    {
+    public:
+        AMF_DECLARE_IID(0xb04b7248, 0xb6f0, 0x4321, 0xb6, 0x91, 0xba, 0xa4, 0x74, 0xf, 0x9f, 0xcb)
+
+        virtual AMF_RESULT          AMF_STD_CALL SetSize(amf_size newSize) = 0;
+        virtual amf_size            AMF_STD_CALL GetSize() = 0;
+        virtual void*               AMF_STD_CALL GetNative() = 0;
+
+        // Observer management
+#ifdef __clang__
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Woverloaded-virtual"
+#endif
+        virtual void                AMF_STD_CALL AddObserver(AMFBufferObserver* pObserver) = 0;
+        virtual void                AMF_STD_CALL RemoveObserver(AMFBufferObserver* pObserver) = 0;
+#ifdef __clang__
+    #pragma clang diagnostic pop
+#endif
+
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFBuffer> AMFBufferPtr;
+    //----------------------------------------------------------------------------------------------
+
+#else // #if defined(__cplusplus)
+        AMF_DECLARE_IID(AMFBuffer, 0xb04b7248, 0xb6f0, 0x4321, 0xb6, 0x91, 0xba, 0xa4, 0x74, 0xf, 0x9f, 0xcb)
+
+    typedef struct AMFBufferVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFBuffer* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFBuffer* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFBuffer* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFBuffer* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFBuffer* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFBuffer* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFBuffer* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFBuffer* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFBuffer* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFBuffer* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFBuffer* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFBuffer* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFBuffer* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFData interface
+
+        AMF_MEMORY_TYPE     (AMF_STD_CALL *GetMemoryType)(AMFBuffer* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *Duplicate)(AMFBuffer* pThis, AMF_MEMORY_TYPE type, AMFData** ppData);
+        AMF_RESULT          (AMF_STD_CALL *Convert)(AMFBuffer* pThis, AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through host memory if needed
+        AMF_RESULT          (AMF_STD_CALL *Interop)(AMFBuffer* pThis, AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy through host memory for GPU objects
+
+        AMF_DATA_TYPE       (AMF_STD_CALL *GetDataType)(AMFBuffer* pThis);
+
+        amf_bool            (AMF_STD_CALL *IsReusable)(AMFBuffer* pThis);
+
+        void                (AMF_STD_CALL *SetPts)(AMFBuffer* pThis, amf_pts pts);
+        amf_pts             (AMF_STD_CALL *GetPts)(AMFBuffer* pThis);
+        void                (AMF_STD_CALL *SetDuration)(AMFBuffer* pThis, amf_pts duration);
+        amf_pts             (AMF_STD_CALL *GetDuration)(AMFBuffer* pThis);
+
+        // AMFBuffer interface
+
+        AMF_RESULT          (AMF_STD_CALL *SetSize)(AMFBuffer* pThis, amf_size newSize);
+        amf_size            (AMF_STD_CALL *GetSize)(AMFBuffer* pThis);
+        void*               (AMF_STD_CALL *GetNative)(AMFBuffer* pThis);
+
+        // Observer management
+        void                (AMF_STD_CALL *AddObserver_Buffer)(AMFBuffer* pThis, AMFBufferObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver_Buffer)(AMFBuffer* pThis, AMFBufferObserver* pObserver);
+
+    } AMFBufferVtbl;
+
+    struct AMFBuffer
+    {
+        const AMFBufferVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+#if defined(__cplusplus)
+} // namespace
+#endif
+#if defined(_MSC_VER)
+    #pragma warning( pop )
+#endif
+#endif //#ifndef AMF_Buffer_h

+ 302 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Compute.h

@@ -0,0 +1,302 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+ ***************************************************************************************************
+ * @file  Compute.h
+ * @brief AMFCompute interface declaration
+ ***************************************************************************************************
+ */
+#ifndef AMF_Compute_h
+#define AMF_Compute_h
+#pragma once
+
+#include "Buffer.h"
+#include "Surface.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    typedef amf_uint64 AMF_KERNEL_ID;
+
+    //----------------------------------------------------------------------------------------------
+    // enumerations for plane conversion
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_CHANNEL_ORDER
+    {
+        AMF_CHANNEL_ORDER_INVALID       = 0,
+        AMF_CHANNEL_ORDER_R             = 1,
+        AMF_CHANNEL_ORDER_RG            = 2,
+        AMF_CHANNEL_ORDER_BGRA          = 3,
+        AMF_CHANNEL_ORDER_RGBA          = 4,
+        AMF_CHANNEL_ORDER_ARGB          = 5,
+        AMF_CHANNEL_ORDER_YUY2          = 6,
+    } AMF_CHANNEL_ORDER;
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_CHANNEL_TYPE
+    {
+        AMF_CHANNEL_INVALID             = 0,
+        AMF_CHANNEL_UNSIGNED_INT8       = 1,
+        AMF_CHANNEL_UNSIGNED_INT32      = 2,
+        AMF_CHANNEL_UNORM_INT8          = 3,
+        AMF_CHANNEL_UNORM_INT16         = 4,
+        AMF_CHANNEL_SNORM_INT16         = 5,
+        AMF_CHANNEL_FLOAT               = 6,
+        AMF_CHANNEL_FLOAT16             = 7,
+        AMF_CHANNEL_UNSIGNED_INT16      = 8,
+        AMF_CHANNEL_UNORM_INT_101010    = 9,
+} AMF_CHANNEL_TYPE;
+    //----------------------------------------------------------------------------------------------
+#define AMF_STRUCTURED_BUFFER_FORMAT        L"StructuredBufferFormat"                                                             // amf_int64(AMF_CHANNEL_TYPE), default - AMF_CHANNEL_UNSIGNED_INT32; to be set on AMFBuffer objects
+#if defined(_WIN32)
+    AMF_WEAK GUID  AMFStructuredBufferFormatGUID = { 0x90c5d674, 0xe90, 0x4181, {0xbd, 0xef, 0x26, 0x13, 0xc1, 0xdf, 0xa3, 0xbd} }; // UINT(DXGI_FORMAT), default - DXGI_FORMAT_R32_UINT; to be set on ID3D11Buffer or ID3D11Texture2D objects when used natively
+#endif
+    //----------------------------------------------------------------------------------------------
+    // enumeration argument type
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_ARGUMENT_ACCESS_TYPE
+    {
+        AMF_ARGUMENT_ACCESS_READ        = 0,
+        AMF_ARGUMENT_ACCESS_WRITE       = 1,
+        AMF_ARGUMENT_ACCESS_READWRITE   = 2,
+        AMF_ARGUMENT_ACCESS_READWRITE_MASK  = 0xFFFF,
+        //Sampler parameters
+        AMF_ARGUMENT_SAMPLER_LINEAR        = 0x10000000, 
+        AMF_ARGUMENT_SAMPLER_NORM_COORD    = 0x20000000, 
+        AMF_ARGUMENT_SAMPLER_POINT         = 0x40000000,
+        AMF_ARGUMENT_SAMPLER_MASK          = 0xFFFF0000,
+    } AMF_ARGUMENT_ACCESS_TYPE;
+    //----------------------------------------------------------------------------------------------
+    // AMFComputeKernel interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFComputeKernel : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0x94815701, 0x6c84, 0x4ba6, 0xa9, 0xfe, 0xe9, 0xad, 0x40, 0xf8, 0x8, 0x8)
+
+        virtual void*               AMF_STD_CALL GetNative() = 0;
+        virtual const wchar_t*      AMF_STD_CALL GetIDName() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL SetArgPlaneNative(amf_size index, void* pPlane, AMF_ARGUMENT_ACCESS_TYPE eAccess) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL SetArgBufferNative(amf_size index, void* pBuffer, AMF_ARGUMENT_ACCESS_TYPE eAccess) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL SetArgPlane(amf_size index, AMFPlane* pPlane, AMF_ARGUMENT_ACCESS_TYPE eAccess) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL SetArgBuffer(amf_size index, AMFBuffer* pBuffer, AMF_ARGUMENT_ACCESS_TYPE eAccess) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL SetArgInt32(amf_size index, amf_int32 data) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL SetArgInt64(amf_size index, amf_int64 data) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL SetArgFloat(amf_size index, amf_float data) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL SetArgBlob(amf_size index, amf_size dataSize, const void* pData) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL GetCompileWorkgroupSize(amf_size workgroupSize[3]) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL Enqueue(amf_size dimension, amf_size globalOffset[3], amf_size globalSize[3], amf_size localSize[3]) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFComputeKernel> AMFComputeKernelPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFComputeKernel, 0x94815701, 0x6c84, 0x4ba6, 0xa9, 0xfe, 0xe9, 0xad, 0x40, 0xf8, 0x8, 0x8)
+    typedef struct AMFComputeKernel AMFComputeKernel;
+
+    typedef struct AMFComputeKernelVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFComputeKernel* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFComputeKernel* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFComputeKernel* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFComputeKernel interface 
+
+    } AMFComputeKernelVtbl;
+
+    struct AMFComputeKernel
+    {
+        const AMFComputeKernelVtbl *pVtbl;
+    };
+
+#endif //#if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+    // AMFComputeSyncPoint interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFComputeSyncPoint : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0x66f33fe6, 0xaae, 0x4e65, 0xba, 0x3, 0xea, 0x8b, 0xa3, 0x60, 0x11, 0x2)
+
+        virtual amf_bool            AMF_STD_CALL IsCompleted() = 0;
+        virtual void                AMF_STD_CALL Wait() = 0;
+    };
+    typedef AMFInterfacePtr_T<AMFComputeSyncPoint> AMFComputeSyncPointPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFComputeSyncPoint, 0x66f33fe6, 0xaae, 0x4e65, 0xba, 0x3, 0xea, 0x8b, 0xa3, 0x60, 0x11, 0x2)
+    typedef struct AMFComputeSyncPoint AMFComputeSyncPoint;
+
+    typedef struct AMFComputeSyncPointVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFComputeSyncPoint* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFComputeSyncPoint* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFComputeSyncPoint* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFComputeSyncPoint interface 
+        amf_bool            (AMF_STD_CALL *IsCompleted)(AMFComputeSyncPoint* pThis);
+        void                (AMF_STD_CALL *Wait)(AMFComputeSyncPoint* pThis);
+
+    } AMFComputeSyncPointVtbl;
+
+    struct AMFComputeSyncPoint
+    {
+        const AMFComputeSyncPointVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+    // AMFCompute interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFCompute : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0x3846233a, 0x3f43, 0x443f, 0x8a, 0x45, 0x75, 0x22, 0x11, 0xa9, 0xfb, 0xd5)
+
+        virtual AMF_MEMORY_TYPE     AMF_STD_CALL GetMemoryType() = 0;
+
+        virtual void*               AMF_STD_CALL GetNativeContext() = 0;
+        virtual void*               AMF_STD_CALL GetNativeDeviceID() = 0;
+        virtual void*               AMF_STD_CALL GetNativeCommandQueue() = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL GetKernel(AMF_KERNEL_ID kernelID, AMFComputeKernel** kernel) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL PutSyncPoint(AMFComputeSyncPoint** ppSyncPoint) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL FinishQueue() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL FlushQueue() = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL FillPlane(AMFPlane *pPlane, const amf_size origin[3], const amf_size region[3], const void* pColor) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL FillBuffer(AMFBuffer* pBuffer, amf_size dstOffset, amf_size dstSize, const void* pSourcePattern, amf_size patternSize) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL ConvertPlaneToBuffer(AMFPlane *pSrcPlane, AMFBuffer** ppDstBuffer) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL CopyBuffer(AMFBuffer* pSrcBuffer, amf_size srcOffset, amf_size size, AMFBuffer* pDstBuffer, amf_size dstOffset) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CopyPlane(AMFPlane *pSrcPlane, const amf_size srcOrigin[3], const amf_size region[3], AMFPlane *pDstPlane, const amf_size dstOrigin[3]) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL CopyBufferToHost(AMFBuffer* pSrcBuffer, amf_size srcOffset, amf_size size, void* pDest, amf_bool blocking) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CopyBufferFromHost(const void* pSource, amf_size size, AMFBuffer* pDstBuffer, amf_size dstOffsetInBytes, amf_bool blocking) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL CopyPlaneToHost(AMFPlane *pSrcPlane, const amf_size origin[3], const amf_size region[3], void* pDest, amf_size dstPitch, amf_bool blocking) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CopyPlaneFromHost(void* pSource, const amf_size origin[3], const amf_size region[3], amf_size srcPitch, AMFPlane *pDstPlane, amf_bool blocking) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL ConvertPlaneToPlane(AMFPlane* pSrcPlane, AMFPlane** ppDstPlane, AMF_CHANNEL_ORDER order, AMF_CHANNEL_TYPE type) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFCompute> AMFComputePtr;
+#else // #if defined(__cplusplus)
+        AMF_DECLARE_IID(AMFCompute, 0x3846233a, 0x3f43, 0x443f, 0x8a, 0x45, 0x75, 0x22, 0x11, 0xa9, 0xfb, 0xd5)
+    typedef struct AMFCompute AMFCompute;
+
+    typedef struct AMFComputeVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFCompute* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFCompute* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFCompute* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFCompute interface 
+        AMF_MEMORY_TYPE     (AMF_STD_CALL *GetMemoryType)(AMFCompute* pThis);
+        void*               (AMF_STD_CALL *GetNativeContext)(AMFCompute* pThis);
+        void*               (AMF_STD_CALL *GetNativeDeviceID)(AMFCompute* pThis);
+        void*               (AMF_STD_CALL *GetNativeCommandQueue)(AMFCompute* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetKernel)(AMFCompute* pThis, AMF_KERNEL_ID kernelID, AMFComputeKernel** kernel);
+        AMF_RESULT          (AMF_STD_CALL *PutSyncPoint)(AMFCompute* pThis, AMFComputeSyncPoint** ppSyncPoint);
+        AMF_RESULT          (AMF_STD_CALL *FinishQueue)(AMFCompute* pThis);
+        AMF_RESULT          (AMF_STD_CALL *FlushQueue)(AMFCompute* pThis);
+        AMF_RESULT          (AMF_STD_CALL *FillPlane)(AMFCompute* pThis, AMFPlane *pPlane, const amf_size origin[3], const amf_size region[3], const void* pColor);
+        AMF_RESULT          (AMF_STD_CALL *FillBuffer)(AMFCompute* pThis, AMFBuffer* pBuffer, amf_size dstOffset, amf_size dstSize, const void* pSourcePattern, amf_size patternSize);
+        AMF_RESULT          (AMF_STD_CALL *ConvertPlaneToBuffer)(AMFCompute* pThis, AMFPlane *pSrcPlane, AMFBuffer** ppDstBuffer);
+        AMF_RESULT          (AMF_STD_CALL *CopyBuffer)(AMFCompute* pThis, AMFBuffer* pSrcBuffer, amf_size srcOffset, amf_size size, AMFBuffer* pDstBuffer, amf_size dstOffset);
+        AMF_RESULT          (AMF_STD_CALL *CopyPlane)(AMFCompute* pThis, AMFPlane *pSrcPlane, const amf_size srcOrigin[3], const amf_size region[3], AMFPlane *pDstPlane, const amf_size dstOrigin[3]);
+        AMF_RESULT          (AMF_STD_CALL *CopyBufferToHost)(AMFCompute* pThis, AMFBuffer* pSrcBuffer, amf_size srcOffset, amf_size size, void* pDest, amf_bool blocking);
+        AMF_RESULT          (AMF_STD_CALL *CopyBufferFromHost)(AMFCompute* pThis, const void* pSource, amf_size size, AMFBuffer* pDstBuffer, amf_size dstOffsetInBytes, amf_bool blocking);
+        AMF_RESULT          (AMF_STD_CALL *CopyPlaneToHost)(AMFCompute* pThis, AMFPlane *pSrcPlane, const amf_size origin[3], const amf_size region[3], void* pDest, amf_size dstPitch, amf_bool blocking);
+        AMF_RESULT          (AMF_STD_CALL *CopyPlaneFromHost)(AMFCompute* pThis, void* pSource, const amf_size origin[3], const amf_size region[3], amf_size srcPitch, AMFPlane *pDstPlane, amf_bool blocking);
+        AMF_RESULT          (AMF_STD_CALL *ConvertPlaneToPlane)(AMFCompute* pThis, AMFPlane* pSrcPlane, AMFPlane** ppDstPlane, AMF_CHANNEL_ORDER order, AMF_CHANNEL_TYPE type);
+    } AMFComputeVtbl;
+
+    struct AMFCompute
+    {
+        const AMFComputeVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+    // AMFPrograms interface - singleton
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFPrograms
+    {
+    public:
+        virtual AMF_RESULT          AMF_STD_CALL RegisterKernelSourceFile(AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, const wchar_t* filepath, const char* options) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL RegisterKernelSource(AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL RegisterKernelBinary(AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL RegisterKernelSource1(AMF_MEMORY_TYPE eMemoryType, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL RegisterKernelBinary1(AMF_MEMORY_TYPE eMemoryType, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options) = 0;
+    };
+#else // #if defined(__cplusplus)
+    typedef struct AMFPrograms AMFPrograms;
+    typedef struct AMFProgramsVtbl
+    {
+        AMF_RESULT          (AMF_STD_CALL *RegisterKernelSourceFile)(AMFPrograms* pThis, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, const wchar_t* filepath, const char* options);
+        AMF_RESULT          (AMF_STD_CALL *RegisterKernelSource)(AMFPrograms* pThis, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options);
+        AMF_RESULT          (AMF_STD_CALL *RegisterKernelBinary)(AMFPrograms* pThis, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options);
+        AMF_RESULT          (AMF_STD_CALL *RegisterKernelSource1)(AMFPrograms* pThis, AMF_MEMORY_TYPE eMemoryType, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options);
+        AMF_RESULT          (AMF_STD_CALL *RegisterKernelBinary1)(AMFPrograms* pThis, AMF_MEMORY_TYPE eMemoryType, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options);
+    } AMFProgramsVtbl;
+
+    struct AMFPrograms
+    {
+        const AMFProgramsVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+
+
+#if defined(__cplusplus)
+} // namespace amf
+#endif
+
+#endif // AMF_Compute_h

+ 147 - 0
plugins/obs-ffmpeg/external/AMF/include/core/ComputeFactory.h

@@ -0,0 +1,147 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_ComputeFactory_h
+#define AMF_ComputeFactory_h
+#pragma once
+
+#include "Compute.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+// compute device audio capabilities accessed via GetProperties() from AMFComputeDevice
+#define AMF_DEVICE_NAME                         L"DeviceName"                       // char*, string, device name
+#define AMF_DRIVER_VERSION_NAME                 L"DriverVersion"                       // char*, string, driver version
+#define AMF_AUDIO_CONVOLUTION_MAX_STREAMS       L"ConvolutionMaxStreams"            // amf_int64, maximum number of audio streams supported in realtime
+#define AMF_AUDIO_CONVOLUTION_LENGTH            L"ConvolutionLength"                // amf_int64, length of convolution in samples
+#define AMF_AUDIO_CONVOLUTION_BUFFER_SIZE       L"ConvolutionBufferSize"            // amf_int64, buffer size in samples
+#define AMF_AUDIO_CONVOLUTION_SAMPLE_RATE       L"ConvolutionSampleRate"            // amf_int64, sample rate
+
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFComputeDevice  : public AMFPropertyStorage
+    {
+    public:
+        AMF_DECLARE_IID(0xb79d7cf6, 0x2c5c, 0x4deb, 0xb8, 0x96, 0xa2, 0x9e, 0xbe, 0xa6, 0xe3, 0x97)
+
+        virtual void*               AMF_STD_CALL GetNativePlatform() = 0;
+        virtual void*               AMF_STD_CALL GetNativeDeviceID() = 0;
+        virtual void*               AMF_STD_CALL GetNativeContext() = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL CreateCompute(void *reserved, AMFCompute **ppCompute) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateComputeEx(void* pCommandQueue, AMFCompute **ppCompute) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFComputeDevice> AMFComputeDevicePtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFComputeDevice, 0xb79d7cf6, 0x2c5c, 0x4deb, 0xb8, 0x96, 0xa2, 0x9e, 0xbe, 0xa6, 0xe3, 0x97)
+    typedef struct AMFComputeDevice AMFComputeDevice;
+
+    typedef struct AMFComputeDeviceVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFComputeDevice* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFComputeDevice* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFComputeDevice* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFComputeDevice* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFComputeDevice* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFComputeDevice* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFComputeDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFComputeDevice* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFComputeDevice* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFComputeDevice* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFComputeDevice* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFComputeDevice* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFComputeDevice* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFComputeDevice interface
+       void*               (AMF_STD_CALL *GetNativePlatform)(AMFComputeDevice* pThis);
+       void*               (AMF_STD_CALL *GetNativeDeviceID)(AMFComputeDevice* pThis);
+       void*               (AMF_STD_CALL *GetNativeContext)(AMFComputeDevice* pThis);
+
+       AMF_RESULT          (AMF_STD_CALL *CreateCompute)(AMFComputeDevice* pThis, void *reserved, AMFCompute **ppCompute);
+       AMF_RESULT          (AMF_STD_CALL *CreateComputeEx)(AMFComputeDevice* pThis, void* pCommandQueue, AMFCompute **ppCompute);
+
+    } AMFComputeDeviceVtbl;
+
+    struct AMFComputeDevice
+    {
+        const AMFComputeDeviceVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFComputeFactory : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0xe3c24bd7, 0x2d83, 0x416c, 0x8c, 0x4e, 0xfd, 0x13, 0xca, 0x86, 0xf4, 0xd0)
+
+        virtual amf_int32           AMF_STD_CALL GetDeviceCount() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetDeviceAt(amf_int32 index, AMFComputeDevice **ppDevice) = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFComputeFactory> AMFComputeFactoryPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFComputeFactory, 0xe3c24bd7, 0x2d83, 0x416c, 0x8c, 0x4e, 0xfd, 0x13, 0xca, 0x86, 0xf4, 0xd0)
+    typedef struct AMFComputeFactory AMFComputeFactory;
+
+    typedef struct AMFComputeFactoryVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFComputeFactory* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFComputeFactory* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFComputeFactory* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFComputeFactory interface
+        amf_int32           (AMF_STD_CALL *GetDeviceCount)(AMFComputeFactory* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetDeviceAt)(AMFComputeFactory* pThis, amf_int32 index, AMFComputeDevice **ppDevice);
+    } AMFComputeFactoryVtbl;
+
+    struct AMFComputeFactory
+    {
+        const AMFComputeFactoryVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+} // namespace amf
+#endif
+
+#endif // AMF_ComputeFactory_h

+ 786 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Context.h

@@ -0,0 +1,786 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Context_h
+#define AMF_Context_h
+#pragma once
+
+#include "Buffer.h"
+#include "AudioBuffer.h"
+#include "Surface.h"
+#include "Compute.h"
+#include "ComputeFactory.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    // AMFContext interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFContext : public AMFPropertyStorage
+    {
+    public:
+        AMF_DECLARE_IID(0xa76a13f0, 0xd80e, 0x4fcc, 0xb5, 0x8, 0x65, 0xd0, 0xb5, 0x2e, 0xd9, 0xee)
+        
+        // Cleanup
+        virtual AMF_RESULT          AMF_STD_CALL Terminate() = 0;
+
+        // DX9
+        virtual AMF_RESULT          AMF_STD_CALL InitDX9(void* pDX9Device) = 0;
+        virtual void*               AMF_STD_CALL GetDX9Device(AMF_DX_VERSION dxVersionRequired = AMF_DX9) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL LockDX9() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL UnlockDX9() = 0;
+        class AMFDX9Locker;
+
+        // DX11
+        virtual AMF_RESULT          AMF_STD_CALL InitDX11(void* pDX11Device, AMF_DX_VERSION dxVersionRequired = AMF_DX11_0) = 0;
+        virtual void*               AMF_STD_CALL GetDX11Device(AMF_DX_VERSION dxVersionRequired = AMF_DX11_0) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL LockDX11() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL UnlockDX11() = 0;
+        class AMFDX11Locker;
+
+        // OpenCL
+        virtual AMF_RESULT          AMF_STD_CALL InitOpenCL(void* pCommandQueue = NULL) = 0;
+        virtual void*               AMF_STD_CALL GetOpenCLContext() = 0;
+        virtual void*               AMF_STD_CALL GetOpenCLCommandQueue() = 0;
+        virtual void*               AMF_STD_CALL GetOpenCLDeviceID() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetOpenCLComputeFactory(AMFComputeFactory **ppFactory) = 0; // advanced compute - multiple queries
+        virtual AMF_RESULT          AMF_STD_CALL InitOpenCLEx(AMFComputeDevice *pDevice) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL LockOpenCL() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL UnlockOpenCL() = 0;
+        class AMFOpenCLLocker;
+
+        // OpenGL
+        virtual AMF_RESULT          AMF_STD_CALL InitOpenGL(amf_handle hOpenGLContext, amf_handle hWindow, amf_handle hDC) = 0;
+        virtual amf_handle          AMF_STD_CALL GetOpenGLContext() = 0;
+        virtual amf_handle          AMF_STD_CALL GetOpenGLDrawable() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL LockOpenGL() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL UnlockOpenGL() = 0;
+        class AMFOpenGLLocker;
+
+        // XV - Linux
+        virtual AMF_RESULT          AMF_STD_CALL InitXV(void* pXVDevice) = 0;
+        virtual void*               AMF_STD_CALL GetXVDevice() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL LockXV() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL UnlockXV() = 0;
+        class AMFXVLocker;
+
+        // Gralloc - Android
+        virtual AMF_RESULT          AMF_STD_CALL InitGralloc(void* pGrallocDevice) = 0;
+        virtual void*               AMF_STD_CALL GetGrallocDevice() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL LockGralloc() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL UnlockGralloc() = 0;
+        class AMFGrallocLocker;
+
+        // Allocation
+        virtual AMF_RESULT          AMF_STD_CALL AllocBuffer(AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL AllocSurface(AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMFSurface** ppSurface) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL AllocAudioBuffer(AMF_MEMORY_TYPE type, AMF_AUDIO_FORMAT format, amf_int32 samples, amf_int32 sampleRate, amf_int32 channels, 
+                                                    AMFAudioBuffer** ppAudioBuffer) = 0;
+
+        // Wrap existing objects
+        virtual AMF_RESULT          AMF_STD_CALL CreateBufferFromHostNative(void* pHostBuffer, amf_size size, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateSurfaceFromHostNative(AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, void* pData, 
+                                                     AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateSurfaceFromDX9Native(void* pDX9Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateSurfaceFromDX11Native(void* pDX11Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateSurfaceFromOpenGLNative(AMF_SURFACE_FORMAT format, amf_handle hGLTextureID, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateSurfaceFromGrallocNative(amf_handle hGrallocSurface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateSurfaceFromOpenCLNative(AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, void** pClPlanes, 
+                                                     AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateBufferFromOpenCLNative(void* pCLBuffer, amf_size size, AMFBuffer** ppBuffer) = 0;
+
+        // Access to AMFCompute interface - AMF_MEMORY_OPENCL, AMF_MEMORY_COMPUTE_FOR_DX9, AMF_MEMORY_COMPUTE_FOR_DX11 are currently supported
+        virtual AMF_RESULT          AMF_STD_CALL GetCompute(AMF_MEMORY_TYPE eMemType, AMFCompute** ppCompute) = 0;
+    };
+
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFContext> AMFContextPtr;
+
+    //----------------------------------------------------------------------------------------------
+    // AMFContext1 interface
+    //----------------------------------------------------------------------------------------------
+
+    class AMF_NO_VTABLE AMFContext1 : public AMFContext
+    {
+    public:
+        AMF_DECLARE_IID(0xd9e9f868, 0x6220, 0x44c6, 0xa2, 0x2f, 0x7c, 0xd6, 0xda, 0xc6, 0x86, 0x46)
+
+        virtual AMF_RESULT          AMF_STD_CALL CreateBufferFromDX11Native(void* pHostBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL AllocBufferEx(AMF_MEMORY_TYPE type, amf_size size, AMF_BUFFER_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFBuffer** ppBuffer) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL AllocSurfaceEx(AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMF_SURFACE_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFSurface** ppSurface) = 0;
+
+        // Vulkan - Windows, Linux
+        virtual AMF_RESULT          AMF_STD_CALL InitVulkan(void* pVulkanDevice) = 0;
+        virtual void*               AMF_STD_CALL GetVulkanDevice() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL LockVulkan() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL UnlockVulkan() = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL CreateSurfaceFromVulkanNative(void* pVulkanImage, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateBufferFromVulkanNative(void* pVulkanBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetVulkanDeviceExtensions(amf_size *pCount, const char **ppExtensions) = 0;
+
+        
+        class AMFVulkanLocker;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFContext1> AMFContext1Ptr;
+
+    class AMF_NO_VTABLE AMFContext2 : public AMFContext1
+    {
+    public:
+        AMF_DECLARE_IID(0x726241d3, 0xbd46, 0x4e90, 0x99, 0x68, 0x93, 0xe0, 0x7e, 0xa2, 0x98, 0x4d)
+
+        // DX12
+        virtual AMF_RESULT          AMF_STD_CALL InitDX12(void* pDX11Device, AMF_DX_VERSION dxVersionRequired = AMF_DX12) = 0;
+        virtual void*               AMF_STD_CALL GetDX12Device(AMF_DX_VERSION dxVersionRequired = AMF_DX12) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL LockDX12() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL UnlockDX12() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateSurfaceFromDX12Native(void* pResourceTexture, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateBufferFromDX12Native(void* pResourceBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver) = 0;
+
+        class AMFDX12Locker;
+    };
+    typedef AMFInterfacePtr_T<AMFContext2> AMFContext2Ptr;
+#else
+    typedef struct AMFContext AMFContext;
+    AMF_DECLARE_IID(AMFContext, 0xa76a13f0, 0xd80e, 0x4fcc, 0xb5, 0x8, 0x65, 0xd0, 0xb5, 0x2e, 0xd9, 0xee)
+
+    typedef struct AMFContextVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFContext* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFContext* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFContext* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+        
+        // AMFInterface AMFPropertyStorage
+
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFContext* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFContext* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFContext* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFContext* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFContext* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFContext* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFContext* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFContext* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFContext interface
+       
+        // Cleanup
+        AMF_RESULT          (AMF_STD_CALL *Terminate)(AMFContext* pThis);
+
+        // DX9
+        AMF_RESULT          (AMF_STD_CALL *InitDX9)(AMFContext* pThis, void* pDX9Device);
+        void*               (AMF_STD_CALL *GetDX9Device)(AMFContext* pThis, AMF_DX_VERSION dxVersionRequired);
+        AMF_RESULT          (AMF_STD_CALL *LockDX9)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockDX9)(AMFContext* pThis);
+        // DX11
+        AMF_RESULT          (AMF_STD_CALL *InitDX11)(AMFContext* pThis, void* pDX11Device, AMF_DX_VERSION dxVersionRequired);
+        void*               (AMF_STD_CALL *GetDX11Device)(AMFContext* pThis, AMF_DX_VERSION dxVersionRequired);
+        AMF_RESULT          (AMF_STD_CALL *LockDX11)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockDX11)(AMFContext* pThis);
+
+        // OpenCL
+        AMF_RESULT          (AMF_STD_CALL *InitOpenCL)(AMFContext* pThis, void* pCommandQueue);
+        void*               (AMF_STD_CALL *GetOpenCLContext)(AMFContext* pThis);
+        void*               (AMF_STD_CALL *GetOpenCLCommandQueue)(AMFContext* pThis);
+        void*               (AMF_STD_CALL *GetOpenCLDeviceID)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetOpenCLComputeFactory)(AMFContext* pThis, AMFComputeFactory **ppFactory); // advanced compute - multiple queries
+        AMF_RESULT          (AMF_STD_CALL *InitOpenCLEx)(AMFContext* pThis, AMFComputeDevice *pDevice);
+        AMF_RESULT          (AMF_STD_CALL *LockOpenCL)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockOpenCL)(AMFContext* pThis);
+
+        // OpenGL
+        AMF_RESULT          (AMF_STD_CALL *InitOpenGL)(AMFContext* pThis, amf_handle hOpenGLContext, amf_handle hWindow, amf_handle hDC);
+        amf_handle          (AMF_STD_CALL *GetOpenGLContext)(AMFContext* pThis);
+        amf_handle          (AMF_STD_CALL *GetOpenGLDrawable)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockOpenGL)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockOpenGL)(AMFContext* pThis);
+        // XV - Linux
+        AMF_RESULT          (AMF_STD_CALL *InitXV)(AMFContext* pThis, void* pXVDevice);
+        void*               (AMF_STD_CALL *GetXVDevice)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockXV)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockXV)(AMFContext* pThis);
+
+        // Gralloc - Android
+        AMF_RESULT          (AMF_STD_CALL *InitGralloc)(AMFContext* pThis, void* pGrallocDevice);
+        void*               (AMF_STD_CALL *GetGrallocDevice)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockGralloc)(AMFContext* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockGralloc)(AMFContext* pThis);
+        // Allocation
+        AMF_RESULT          (AMF_STD_CALL *AllocBuffer)(AMFContext* pThis, AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer);
+        AMF_RESULT          (AMF_STD_CALL *AllocSurface)(AMFContext* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMFSurface** ppSurface);
+        AMF_RESULT          (AMF_STD_CALL *AllocAudioBuffer)(AMFContext* pThis, AMF_MEMORY_TYPE type, AMF_AUDIO_FORMAT format, amf_int32 samples, amf_int32 sampleRate, amf_int32 channels, 
+                                                    AMFAudioBuffer** ppAudioBuffer);
+
+        // Wrap existing objects
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromHostNative)(AMFContext* pThis, void* pHostBuffer, amf_size size, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromHostNative)(AMFContext* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, void* pData, 
+                                                     AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromDX9Native)(AMFContext* pThis, void* pDX9Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromDX11Native)(AMFContext* pThis, void* pDX11Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromOpenGLNative)(AMFContext* pThis, AMF_SURFACE_FORMAT format, amf_handle hGLTextureID, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromGrallocNative)(AMFContext* pThis, amf_handle hGrallocSurface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromOpenCLNative)(AMFContext* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, void** pClPlanes, 
+                                                     AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromOpenCLNative)(AMFContext* pThis, void* pCLBuffer, amf_size size, AMFBuffer** ppBuffer);
+
+        // Access to AMFCompute interface - AMF_MEMORY_OPENCL, AMF_MEMORY_COMPUTE_FOR_DX9, AMF_MEMORY_COMPUTE_FOR_DX11 are currently supported
+        AMF_RESULT          (AMF_STD_CALL *GetCompute)(AMFContext* pThis, AMF_MEMORY_TYPE eMemType, AMFCompute** ppCompute);
+
+    } AMFContextVtbl;
+
+    struct AMFContext
+    {
+        const AMFContextVtbl *pVtbl;
+    };
+
+
+    typedef struct AMFContext1 AMFContext1;
+    AMF_DECLARE_IID(AMFContext1, 0xd9e9f868, 0x6220, 0x44c6, 0xa2, 0x2f, 0x7c, 0xd6, 0xda, 0xc6, 0x86, 0x46)
+
+    typedef struct AMFContext1Vtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFContext1* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFContext1* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFContext1* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+        
+        // AMFInterface AMFPropertyStorage
+
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFContext1* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFContext1* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFContext1* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFContext1* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFContext1* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFContext1* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFContext1* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFContext1* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFContext interface
+       
+        // Cleanup
+        AMF_RESULT          (AMF_STD_CALL *Terminate)(AMFContext1* pThis);
+
+        // DX9
+        AMF_RESULT          (AMF_STD_CALL *InitDX9)(AMFContext1* pThis, void* pDX9Device);
+        void*               (AMF_STD_CALL *GetDX9Device)(AMFContext1* pThis, AMF_DX_VERSION dxVersionRequired);
+        AMF_RESULT          (AMF_STD_CALL *LockDX9)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockDX9)(AMFContext1* pThis);
+        // DX11
+        AMF_RESULT          (AMF_STD_CALL *InitDX11)(AMFContext1* pThis, void* pDX11Device, AMF_DX_VERSION dxVersionRequired);
+        void*               (AMF_STD_CALL *GetDX11Device)(AMFContext1* pThis, AMF_DX_VERSION dxVersionRequired);
+        AMF_RESULT          (AMF_STD_CALL *LockDX11)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockDX11)(AMFContext1* pThis);
+
+        // OpenCL
+        AMF_RESULT          (AMF_STD_CALL *InitOpenCL)(AMFContext1* pThis, void* pCommandQueue);
+        void*               (AMF_STD_CALL *GetOpenCLContext)(AMFContext1* pThis);
+        void*               (AMF_STD_CALL *GetOpenCLCommandQueue)(AMFContext1* pThis);
+        void*               (AMF_STD_CALL *GetOpenCLDeviceID)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetOpenCLComputeFactory)(AMFContext1* pThis, AMFComputeFactory **ppFactory); // advanced compute - multiple queries
+        AMF_RESULT          (AMF_STD_CALL *InitOpenCLEx)(AMFContext1* pThis, AMFComputeDevice *pDevice);
+        AMF_RESULT          (AMF_STD_CALL *LockOpenCL)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockOpenCL)(AMFContext1* pThis);
+
+        // OpenGL
+        AMF_RESULT          (AMF_STD_CALL *InitOpenGL)(AMFContext1* pThis, amf_handle hOpenGLContext, amf_handle hWindow, amf_handle hDC);
+        amf_handle          (AMF_STD_CALL *GetOpenGLContext)(AMFContext1* pThis);
+        amf_handle          (AMF_STD_CALL *GetOpenGLDrawable)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockOpenGL)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockOpenGL)(AMFContext1* pThis);
+        // XV - Linux
+        AMF_RESULT          (AMF_STD_CALL *InitXV)(AMFContext1* pThis, void* pXVDevice);
+        void*               (AMF_STD_CALL *GetXVDevice)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockXV)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockXV)(AMFContext1* pThis);
+
+        // Gralloc - Android
+        AMF_RESULT          (AMF_STD_CALL *InitGralloc)(AMFContext1* pThis, void* pGrallocDevice);
+        void*               (AMF_STD_CALL *GetGrallocDevice)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockGralloc)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockGralloc)(AMFContext1* pThis);
+        // Allocation
+        AMF_RESULT          (AMF_STD_CALL *AllocBuffer)(AMFContext1* pThis, AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer);
+        AMF_RESULT          (AMF_STD_CALL *AllocSurface)(AMFContext1* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMFSurface** ppSurface);
+        AMF_RESULT          (AMF_STD_CALL *AllocAudioBuffer)(AMFContext1* pThis, AMF_MEMORY_TYPE type, AMF_AUDIO_FORMAT format, amf_int32 samples, amf_int32 sampleRate, amf_int32 channels, 
+                                                    AMFAudioBuffer** ppAudioBuffer);
+
+        // Wrap existing objects
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromHostNative)(AMFContext1* pThis, void* pHostBuffer, amf_size size, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromHostNative)(AMFContext1* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, void* pData, 
+                                                     AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromDX9Native)(AMFContext1* pThis, void* pDX9Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromDX11Native)(AMFContext1* pThis, void* pDX11Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromOpenGLNative)(AMFContext1* pThis, AMF_SURFACE_FORMAT format, amf_handle hGLTextureID, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromGrallocNative)(AMFContext1* pThis, amf_handle hGrallocSurface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromOpenCLNative)(AMFContext1* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, void** pClPlanes, 
+                                                     AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromOpenCLNative)(AMFContext1* pThis, void* pCLBuffer, amf_size size, AMFBuffer** ppBuffer);
+
+        // Access to AMFCompute interface - AMF_MEMORY_OPENCL, AMF_MEMORY_COMPUTE_FOR_DX9, AMF_MEMORY_COMPUTE_FOR_DX11 are currently supported
+        AMF_RESULT          (AMF_STD_CALL *GetCompute)(AMFContext1* pThis, AMF_MEMORY_TYPE eMemType, AMFCompute** ppCompute);
+
+        // AMFContext1 interface
+
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromDX11Native)(AMFContext1* pThis, void* pHostBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *AllocBufferEx)(AMFContext1* pThis, AMF_MEMORY_TYPE type, amf_size size, AMF_BUFFER_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFBuffer** ppBuffer);
+        AMF_RESULT          (AMF_STD_CALL *AllocSurfaceEx)(AMFContext1* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMF_SURFACE_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFSurface** ppSurface);
+
+        // Vulkan - Windows, Linux
+        AMF_RESULT          (AMF_STD_CALL *InitVulkan)(AMFContext1* pThis, void* pVulkanDevice);
+        void*               (AMF_STD_CALL *GetVulkanDevice)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockVulkan)(AMFContext1* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockVulkan)(AMFContext1* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromVulkanNative)(AMFContext1* pThis, void* pVulkanImage, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromVulkanNative)(AMFContext1* pThis, void* pVulkanBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *GetVulkanDeviceExtensions)(AMFContext1* pThis, amf_size *pCount, const char **ppExtensions);
+
+    } AMFContext1Vtbl;
+
+    struct AMFContext1
+    {
+        const AMFContext1Vtbl *pVtbl;
+    };
+
+    typedef struct AMFContext2 AMFContext2;
+    AMF_DECLARE_IID(AMFContext2, 0xd9e9f868, 0x6220, 0x44c6, 0xa2, 0x2f, 0x7c, 0xd6, 0xda, 0xc6, 0x86, 0x46)
+
+        typedef struct AMFContext2Vtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFContext2* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFContext2* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFContext2* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFInterface AMFPropertyStorage
+
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFContext2* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFContext2* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFContext2* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFContext2* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFContext2* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFContext2* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFContext2* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFContext2* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFContext interface
+
+        // Cleanup
+        AMF_RESULT          (AMF_STD_CALL *Terminate)(AMFContext2* pThis);
+
+        // DX9
+        AMF_RESULT          (AMF_STD_CALL *InitDX9)(AMFContext2* pThis, void* pDX9Device);
+        void*                         (AMF_STD_CALL *GetDX9Device)(AMFContext2* pThis, AMF_DX_VERSION dxVersionRequired);
+        AMF_RESULT          (AMF_STD_CALL *LockDX9)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockDX9)(AMFContext2* pThis);
+        // DX11
+        AMF_RESULT          (AMF_STD_CALL *InitDX11)(AMFContext2* pThis, void* pDX11Device, AMF_DX_VERSION dxVersionRequired);
+        void*                         (AMF_STD_CALL *GetDX11Device)(AMFContext2* pThis, AMF_DX_VERSION dxVersionRequired);
+        AMF_RESULT          (AMF_STD_CALL *LockDX11)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockDX11)(AMFContext2* pThis);
+
+        // OpenCL
+        AMF_RESULT          (AMF_STD_CALL *InitOpenCL)(AMFContext2* pThis, void* pCommandQueue);
+        void*               (AMF_STD_CALL *GetOpenCLContext)(AMFContext2* pThis);
+        void*               (AMF_STD_CALL *GetOpenCLCommandQueue)(AMFContext2* pThis);
+        void*               (AMF_STD_CALL *GetOpenCLDeviceID)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetOpenCLComputeFactory)(AMFContext2* pThis, AMFComputeFactory **ppFactory); // advanced compute - multiple queries
+        AMF_RESULT          (AMF_STD_CALL *InitOpenCLEx)(AMFContext2* pThis, AMFComputeDevice *pDevice);
+        AMF_RESULT          (AMF_STD_CALL *LockOpenCL)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockOpenCL)(AMFContext2* pThis);
+
+        // OpenGL
+        AMF_RESULT          (AMF_STD_CALL *InitOpenGL)(AMFContext2* pThis, amf_handle hOpenGLContext, amf_handle hWindow, amf_handle hDC);
+        amf_handle          (AMF_STD_CALL *GetOpenGLContext)(AMFContext2* pThis);
+        amf_handle          (AMF_STD_CALL *GetOpenGLDrawable)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockOpenGL)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockOpenGL)(AMFContext2* pThis);
+        // XV - Linux
+        AMF_RESULT          (AMF_STD_CALL *InitXV)(AMFContext2* pThis, void* pXVDevice);
+        void*               (AMF_STD_CALL *GetXVDevice)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockXV)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockXV)(AMFContext2* pThis);
+
+        // Gralloc - Android
+        AMF_RESULT          (AMF_STD_CALL *InitGralloc)(AMFContext2* pThis, void* pGrallocDevice);
+        void*               (AMF_STD_CALL *GetGrallocDevice)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockGralloc)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockGralloc)(AMFContext2* pThis);
+        // Allocation
+        AMF_RESULT          (AMF_STD_CALL *AllocBuffer)(AMFContext2* pThis, AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer);
+        AMF_RESULT          (AMF_STD_CALL *AllocSurface)(AMFContext2* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMFSurface** ppSurface);
+        AMF_RESULT          (AMF_STD_CALL *AllocAudioBuffer)(AMFContext2* pThis, AMF_MEMORY_TYPE type, AMF_AUDIO_FORMAT format, amf_int32 samples, amf_int32 sampleRate, amf_int32 channels, AMFAudioBuffer** ppAudioBuffer);
+
+        // Wrap existing objects
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromHostNative)(AMFContext2* pThis, void* pHostBuffer, amf_size size, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromHostNative)(AMFContext2* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, void* pData,AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromDX9Native)(AMFContext2* pThis, void* pDX9Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromDX11Native)(AMFContext2* pThis, void* pDX11Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromOpenGLNative)(AMFContext2* pThis, AMF_SURFACE_FORMAT format, amf_handle hGLTextureID, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromGrallocNative)(AMFContext2* pThis, amf_handle hGrallocSurface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromOpenCLNative)(AMFContext2* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, void** pClPlanes, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromOpenCLNative)(AMFContext2* pThis, void* pCLBuffer, amf_size size, AMFBuffer** ppBuffer);
+
+        // Access to AMFCompute interface - AMF_MEMORY_OPENCL, AMF_MEMORY_COMPUTE_FOR_DX9, AMF_MEMORY_COMPUTE_FOR_DX11 are currently supported
+        AMF_RESULT          (AMF_STD_CALL *GetCompute)(AMFContext2* pThis, AMF_MEMORY_TYPE eMemType, AMFCompute** ppCompute);
+
+        // AMFContext1 interface
+
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromDX11Native)(AMFContext2* pThis, void* pHostBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *AllocBufferEx)(AMFContext2* pThis, AMF_MEMORY_TYPE type, amf_size size, AMF_BUFFER_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFBuffer** ppBuffer);
+        AMF_RESULT          (AMF_STD_CALL *AllocSurfaceEx)(AMFContext2* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMF_SURFACE_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFSurface** ppSurface);
+
+        // Vulkan - Windows, Linux
+        AMF_RESULT          (AMF_STD_CALL *InitVulkan)(AMFContext2* pThis, void* pVulkanDevice);
+        void*               (AMF_STD_CALL *GetVulkanDevice)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *LockVulkan)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockVulkan)(AMFContext2* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromVulkanNative)(AMFContext2* pThis, void* pVulkanImage, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromVulkanNative)(AMFContext2* pThis, void* pVulkanBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *GetVulkanDeviceExtensions)(AMFContext2* pThis, amf_size *pCount, const char **ppExtensions);
+
+        // AMFContext2 interface
+        AMF_RESULT          (AMF_STD_CALL *InitDX12)(AMFContext2* pThis, void* pDX11Device, AMF_DX_VERSION dxVersionRequired);
+        void*               (AMF_STD_CALL *GetDX12Device)(AMFContext2* pThis, AMF_DX_VERSION dxVersionRequired);
+        AMF_RESULT          (AMF_STD_CALL *LockDX12)(AMFContext2* pThis);
+        AMF_RESULT          (AMF_STD_CALL *UnlockDX12)(AMFContext2* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *CreateSurfaceFromDX12Native)(AMFContext2* pThis, void* pResourceTexture, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
+        AMF_RESULT          (AMF_STD_CALL *CreateBufferFromDX12Native)(AMFContext2* pThis, void* pResourceBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver);
+
+
+    } AMFContext2Vtbl;
+
+    struct AMFContext2
+    {
+        const AMFContext2Vtbl *pVtbl;
+    };
+#endif
+
+#if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // Lockers
+    //----------------------------------------------------------------------------------------------
+    class AMFContext::AMFDX9Locker
+    {
+    public:
+        AMFDX9Locker() : m_Context(NULL)
+        {}
+        AMFDX9Locker(AMFContext* resources) : m_Context(NULL)
+        {
+            Lock(resources);
+        }
+        ~AMFDX9Locker()
+        {
+            if(m_Context != NULL)
+            {
+                m_Context->UnlockDX9();
+            }
+        }
+        void Lock(AMFContext* resources)
+        {
+            if(m_Context != NULL)
+            {
+                m_Context->UnlockDX9();
+            }
+            m_Context = resources;
+            if(m_Context != NULL)
+            {
+                m_Context->LockDX9();
+            }
+        }
+    protected:
+        AMFContext* m_Context;
+
+    private:
+        AMFDX9Locker(const AMFDX9Locker&);
+        AMFDX9Locker& operator=(const AMFDX9Locker&);
+    };
+    //----------------------------------------------------------------------------------------------
+    class AMFContext::AMFDX11Locker
+    {
+    public:
+        AMFDX11Locker() : m_Context(NULL)
+        {}
+        AMFDX11Locker(AMFContext* resources) : m_Context(NULL)
+        {
+            Lock(resources);
+        }
+        ~AMFDX11Locker()
+        {
+            if(m_Context != NULL)
+            {
+                m_Context->UnlockDX11();
+            }
+        }
+        void Lock(AMFContext* resources)
+        {
+            if(m_Context != NULL)
+            {
+                m_Context->UnlockDX11();
+            }
+            m_Context = resources;
+            if(m_Context != NULL)
+            {
+                m_Context->LockDX11();
+            }
+        }
+    protected:
+        AMFContext* m_Context;
+
+    private:
+        AMFDX11Locker(const AMFDX11Locker&);
+        AMFDX11Locker& operator=(const AMFDX11Locker&);
+    };
+    //----------------------------------------------------------------------------------------------
+    class AMFContext::AMFOpenCLLocker
+    {
+    public:
+        AMFOpenCLLocker() : m_Context(NULL)
+        {}
+        AMFOpenCLLocker(AMFContext* resources) : m_Context(NULL)
+        {
+            Lock(resources);
+        }
+        ~AMFOpenCLLocker()
+        {
+            if(m_Context != NULL)
+            {
+                m_Context->UnlockOpenCL();
+            }
+        }
+        void Lock(AMFContext* resources)
+        {
+            if(m_Context != NULL)
+            {
+                m_Context->UnlockOpenCL();
+            }
+            m_Context = resources;
+            if(m_Context != NULL)
+            {
+                m_Context->LockOpenCL();
+            }
+        }
+    protected:
+        AMFContext* m_Context;
+    private:
+        AMFOpenCLLocker(const AMFOpenCLLocker&);
+        AMFOpenCLLocker& operator=(const AMFOpenCLLocker&);
+    };
+    //----------------------------------------------------------------------------------------------
+    class AMFContext::AMFOpenGLLocker
+    {
+    public:
+        AMFOpenGLLocker(AMFContext* pContext) : m_pContext(pContext),
+            m_GLLocked(false)
+        {
+            if(m_pContext != NULL)
+            {
+                if(m_pContext->LockOpenGL() == AMF_OK)
+                {
+                    m_GLLocked = true;
+                }
+            }
+        }
+        ~AMFOpenGLLocker()
+        {
+            if(m_GLLocked)
+            {
+                m_pContext->UnlockOpenGL();
+            }
+        }
+    private:
+        AMFContext* m_pContext;
+        amf_bool m_GLLocked; ///< AMFOpenGLLocker can be called when OpenGL is not initialized yet
+                             ///< in this case don't call UnlockOpenGL
+        AMFOpenGLLocker(const AMFOpenGLLocker&);
+        AMFOpenGLLocker& operator=(const AMFOpenGLLocker&);
+    };
+    //----------------------------------------------------------------------------------------------
+    class AMFContext::AMFXVLocker
+    {
+    public:
+        AMFXVLocker() : m_pContext(NULL)
+        {}
+        AMFXVLocker(AMFContext* pContext) : m_pContext(NULL)
+        {
+            Lock(pContext);
+        }
+        ~AMFXVLocker()
+        {
+            if(m_pContext != NULL)
+            {
+                m_pContext->UnlockXV();
+            }
+        }
+        void Lock(AMFContext* pContext)
+        {
+            if((pContext != NULL) && (pContext->GetXVDevice() != NULL))
+            {
+                m_pContext = pContext;
+                m_pContext->LockXV();
+            }
+        }
+    protected:
+        AMFContext* m_pContext;
+    private:
+        AMFXVLocker(const AMFXVLocker&);
+        AMFXVLocker& operator=(const AMFXVLocker&);
+    };
+    //----------------------------------------------------------------------------------------------
+    class AMFContext::AMFGrallocLocker
+    {
+    public:
+        AMFGrallocLocker() : m_pContext(NULL)
+        {}
+        AMFGrallocLocker(AMFContext* pContext) : m_pContext(NULL)
+        {
+            Lock(pContext);
+        }
+        ~AMFGrallocLocker()
+        {
+            if(m_pContext != NULL)
+            {
+                m_pContext->UnlockGralloc();
+            }
+        }
+        void Lock(AMFContext* pContext)
+        {
+            if((pContext != NULL) && (pContext->GetGrallocDevice() != NULL))
+            {
+                m_pContext = pContext;
+                m_pContext->LockGralloc();
+            }
+        }
+    protected:
+        AMFContext* m_pContext;
+    private:
+        AMFGrallocLocker(const AMFGrallocLocker&);
+        AMFGrallocLocker& operator=(const AMFGrallocLocker&);
+    };
+    //----------------------------------------------------------------------------------------------
+    class AMFContext1::AMFVulkanLocker
+    {
+    public:
+        AMFVulkanLocker() : m_pContext(NULL)
+        {}
+        AMFVulkanLocker(AMFContext1* pContext) : m_pContext(NULL)
+        {
+            Lock(pContext);
+        }
+        ~AMFVulkanLocker()
+        {
+            if(m_pContext != NULL)
+            {
+                m_pContext->UnlockVulkan();
+            }
+        }
+        void Lock(AMFContext1* pContext)
+        {
+            if((pContext != NULL) && (pContext->GetVulkanDevice() != NULL))
+            {
+                m_pContext = pContext;
+                m_pContext->LockVulkan();
+            }
+        }
+    protected:
+        AMFContext1* m_pContext;
+    private:
+        AMFVulkanLocker(const AMFVulkanLocker&);
+        AMFVulkanLocker& operator=(const AMFVulkanLocker&);
+    };
+    //----------------------------------------------------------------------------------------------
+    class AMFContext2::AMFDX12Locker
+    {
+    public:
+        AMFDX12Locker() : m_Context(NULL)
+        {}
+        AMFDX12Locker(AMFContext2* resources) : m_Context(NULL)
+        {
+            Lock(resources);
+        }
+        ~AMFDX12Locker()
+        {
+            if (m_Context != NULL)
+            {
+                m_Context->UnlockDX12();
+            }
+        }
+        void Lock(AMFContext2* resources)
+        {
+            if (m_Context != NULL)
+            {
+                m_Context->UnlockDX12();
+            }
+            m_Context = resources;
+            if (m_Context != NULL)
+            {
+                m_Context->LockDX12();
+            }
+        }
+    protected:
+        AMFContext2* m_Context;
+
+    private:
+        AMFDX12Locker(const AMFDX12Locker&);
+        AMFDX12Locker& operator=(const AMFDX12Locker&);
+    };
+    //----------------------------------------------------------------------------------------------
+    //----------------------------------------------------------------------------------------------
+    //----------------------------------------------------------------------------------------------
+#endif
+#if defined(__cplusplus)
+}
+#endif
+enum AMF_CONTEXT_DEVICETYPE_ENUM
+{
+    AMF_CONTEXT_DEVICE_TYPE_GPU = 0,
+    AMF_CONTEXT_DEVICE_TYPE_CPU
+};
+#define AMF_CONTEXT_DEVICE_TYPE  L"AMF_Context_DeviceType" //Value type: amf_int64; Values : AMF_CONTEXT_DEVICE_TYPE_GPU for GPU (default) , AMF_CONTEXT_DEVICE_TYPE_CPU for CPU.
+#endif //#ifndef AMF_Context_h

+ 52 - 0
plugins/obs-ffmpeg/external/AMF/include/core/CurrentTime.h

@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_CurrentTime_h
+#define AMF_CurrentTime_h
+
+#include "Platform.h"
+#include "Interface.h"
+
+namespace amf
+{
+	// Current time interface class. This interface object can be passed
+	// as a property to components requiring synchronized timing. The
+	// implementation is:
+	// - first call to Get() starts time and returns 0
+	// - subsequent calls to Get() returns values relative to 0
+	// - Reset() puts time back at 0 at next Get() call
+	//
+	class AMF_NO_VTABLE AMFCurrentTime : public AMFInterface
+	{
+	public:
+		virtual amf_pts AMF_STD_CALL Get() = 0;
+
+		virtual void AMF_STD_CALL Reset() = 0;
+	};
+
+	//----------------------------------------------------------------------------------------------
+	// smart pointer
+	//----------------------------------------------------------------------------------------------
+	typedef AMFInterfacePtr_T<AMFCurrentTime> AMFCurrentTimePtr;
+	//----------------------------------------------------------------------------------------------}
+}
+#endif // AMF_CurrentTime_h

+ 44 - 0
plugins/obs-ffmpeg/external/AMF/include/core/D3D12AMF.h

@@ -0,0 +1,44 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef __D3D12AMF_h__
+#define __D3D12AMF_h__
+#pragma once 
+#include "Platform.h"
+#if defined(_WIN32)||(defined(__linux) && defined(AMF_WSL))
+// syncronization properties set via SetPrivateData()
+AMF_WEAK GUID  AMFResourceStateGUID = { 0x452da9bf, 0x4ad7, 0x47a5, { 0xa6, 0x9b, 0x96, 0xd3, 0x23, 0x76, 0xf2, 0xf3 } };   // Current resource state value (D3D12_RESOURCE_STATES ), sizeof(UINT), set on ID3D12Resource 
+AMF_WEAK GUID  AMFFenceGUID         = { 0x910a7928, 0x57bd, 0x4b04, { 0x91, 0xa3, 0xe7, 0xb8, 0x04, 0x12, 0xcd, 0xa5 } };   // IUnknown (ID3D12Fence), set on ID3D12Resource  syncronization fence for this resource
+AMF_WEAK GUID  AMFFenceValueGUID    = { 0x62a693d3, 0xbb4a, 0x46c9, { 0xa5, 0x04, 0x9a, 0x8e, 0x97, 0xbf, 0xf0, 0x56 } };   // The last value to wait on the fence from AMFFenceGUID; sizeof(UINT64), set on ID3D12Fence 
+#endif
+
+#endif // __D3D12AMF_h__

+ 177 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Data.h

@@ -0,0 +1,177 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Data_h
+#define AMF_Data_h
+#pragma once
+
+#include "PropertyStorage.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_DATA_TYPE
+    {
+        AMF_DATA_BUFFER             = 0,
+        AMF_DATA_SURFACE            = 1,
+        AMF_DATA_AUDIO_BUFFER       = 2,
+        AMF_DATA_USER               = 1000,
+        // all extensions will be AMF_DATA_USER+i
+    } AMF_DATA_TYPE;
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_MEMORY_TYPE
+    {
+        AMF_MEMORY_UNKNOWN          = 0,
+        AMF_MEMORY_HOST             = 1,
+        AMF_MEMORY_DX9              = 2,
+        AMF_MEMORY_DX11             = 3,
+		AMF_MEMORY_OPENCL           = 4,
+        AMF_MEMORY_OPENGL           = 5,
+        AMF_MEMORY_XV               = 6,
+        AMF_MEMORY_GRALLOC          = 7,
+        AMF_MEMORY_COMPUTE_FOR_DX9  = 8, // deprecated, the same as AMF_MEMORY_OPENCL
+        AMF_MEMORY_COMPUTE_FOR_DX11 = 9, // deprecated, the same as AMF_MEMORY_OPENCL
+        AMF_MEMORY_VULKAN           = 10,
+        AMF_MEMORY_DX12             = 11,
+    } AMF_MEMORY_TYPE;
+
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_DX_VERSION
+    {
+        AMF_DX9                     = 90,
+        AMF_DX9_EX                  = 91,
+        AMF_DX11_0                  = 110,
+        AMF_DX11_1                  = 111,
+		AMF_DX12                    = 120,
+    } AMF_DX_VERSION;
+
+    //----------------------------------------------------------------------------------------------
+    // AMF_MEMORY_CPU_ACCESS translates to D3D11_CPU_ACCESS_FLAG or VkImageUsageFlags
+    // bit mask
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_MEMORY_CPU_ACCESS_BITS
+    {                                           // D3D11                    D3D12                      Vulkan 
+        AMF_MEMORY_CPU_DEFAULT  = 0x80000000,   // 0                     ,  D3D12_HEAP_TYPE_DEFAULT ,  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
+        AMF_MEMORY_CPU_NONE     = 0x00000000,   // 0                     ,  D3D12_HEAP_TYPE_DEFAULT ,
+        AMF_MEMORY_CPU_READ     = 0x00000001,   // D3D11_CPU_ACCESS_READ ,  D3D12_HEAP_TYPE_READBACK,  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
+        AMF_MEMORY_CPU_WRITE    = 0x00000002,   // D3D11_CPU_ACCESS_WRITE,  D3D12_HEAP_TYPE_UPLOAD  ,  VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
+        AMF_MEMORY_CPU_LOCAL    = 0x00000004,   //                       ,  D3D12_HEAP_TYPE_DEFAULT ,  VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
+        AMF_MEMORY_CPU_PINNED   = 0x00000008,   //                       ,                          ,  VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR
+    } AMF_MEMORY_CPU_ACCESS_BITS;
+    typedef amf_flags AMF_MEMORY_CPU_ACCESS;
+    //----------------------------------------------------------------------------------------------
+    // AMFData interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFData : public AMFPropertyStorage
+    {
+    public:
+        AMF_DECLARE_IID(0xa1159bf6, 0x9104, 0x4107, 0x8e, 0xaa, 0xc5, 0x3d, 0x5d, 0xba, 0xc5, 0x11)
+
+        virtual AMF_MEMORY_TYPE     AMF_STD_CALL GetMemoryType() = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL Duplicate(AMF_MEMORY_TYPE type, AMFData** ppData) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL Convert(AMF_MEMORY_TYPE type) = 0; // optimal interop if possilble. Copy through host memory if needed
+        virtual AMF_RESULT          AMF_STD_CALL Interop(AMF_MEMORY_TYPE type) = 0; // only optimal interop if possilble. No copy through host memory for GPU objects
+
+        virtual AMF_DATA_TYPE       AMF_STD_CALL GetDataType() = 0;
+
+        virtual amf_bool            AMF_STD_CALL IsReusable() = 0;
+
+        virtual void                AMF_STD_CALL SetPts(amf_pts pts) = 0;
+        virtual amf_pts             AMF_STD_CALL GetPts() = 0;
+        virtual void                AMF_STD_CALL SetDuration(amf_pts duration) = 0;
+        virtual amf_pts             AMF_STD_CALL GetDuration() = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFData> AMFDataPtr;
+    //----------------------------------------------------------------------------------------------
+
+#else // #if defined(__cplusplus)
+    typedef struct AMFData AMFData;
+    AMF_DECLARE_IID(AMFData, 0xa1159bf6, 0x9104, 0x4107, 0x8e, 0xaa, 0xc5, 0x3d, 0x5d, 0xba, 0xc5, 0x11)
+
+    typedef struct AMFDataVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFData* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFData* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFData* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFData* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFData* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFData* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFData* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFData* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFData* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFData* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFData* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFData* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFData* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFData interface
+
+        AMF_MEMORY_TYPE     (AMF_STD_CALL *GetMemoryType)(AMFData* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *Duplicate)(AMFData* pThis, AMF_MEMORY_TYPE type, AMFData** ppData);
+        AMF_RESULT          (AMF_STD_CALL *Convert)(AMFData* pThis, AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through host memory if needed
+        AMF_RESULT          (AMF_STD_CALL *Interop)(AMFData* pThis, AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy through host memory for GPU objects
+
+        AMF_DATA_TYPE       (AMF_STD_CALL *GetDataType)(AMFData* pThis);
+
+        amf_bool            (AMF_STD_CALL *IsReusable)(AMFData* pThis);
+
+        void                (AMF_STD_CALL *SetPts)(AMFData* pThis, amf_pts pts);
+        amf_pts             (AMF_STD_CALL *GetPts)(AMFData* pThis);
+        void                (AMF_STD_CALL *SetDuration)(AMFData* pThis, amf_pts duration);
+        amf_pts             (AMF_STD_CALL *GetDuration)(AMFData* pThis);
+
+    } AMFDataVtbl;
+
+    struct AMFData
+    {
+        const AMFDataVtbl *pVtbl;
+    };
+
+
+#endif // #if defined(__cplusplus)
+
+#if defined(__cplusplus)
+} // namespace
+#endif
+
+#endif //#ifndef AMF_Data_h

+ 78 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Debug.h

@@ -0,0 +1,78 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Debug_h
+#define AMF_Debug_h
+#pragma once
+
+#include "Platform.h"
+#include "Result.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    // AMFDebug interface - singleton
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFDebug
+    {
+    public:
+        virtual  void               AMF_STD_CALL EnablePerformanceMonitor(amf_bool enable) = 0;
+        virtual  amf_bool           AMF_STD_CALL PerformanceMonitorEnabled() = 0;
+        virtual  void               AMF_STD_CALL AssertsEnable(amf_bool enable) = 0;
+        virtual  amf_bool           AMF_STD_CALL AssertsEnabled() = 0;
+    };
+#else // #if defined(__cplusplus)
+    typedef struct AMFDebug AMFDebug;
+    typedef struct AMFDebugVtbl
+    {
+        // AMFDebug interface
+        void               (AMF_STD_CALL *EnablePerformanceMonitor)(AMFDebug* pThis, amf_bool enable);
+        amf_bool           (AMF_STD_CALL *PerformanceMonitorEnabled)(AMFDebug* pThis);
+        void               (AMF_STD_CALL *AssertsEnable)(AMFDebug* pThis, amf_bool enable);
+        amf_bool           (AMF_STD_CALL *AssertsEnabled)(AMFDebug* pThis);
+    } AMFDebugVtbl;
+
+    struct AMFDebug
+    {
+        const AMFDebugVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // AMF_Debug_h

+ 112 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Dump.h

@@ -0,0 +1,112 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Dump_h
+#define AMF_Dump_h
+#pragma once
+
+#include "Platform.h"
+#include "Result.h"
+#include "Interface.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFDump : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0x75366ad4, 0x504c, 0x430b, 0xbb, 0xe2, 0xad, 0x21, 0x82, 0x8, 0xf, 0x72);
+
+
+        virtual const wchar_t*  AMF_STD_CALL GetDumpBasePath() const = 0;             //  Get application dump base path
+        virtual AMF_RESULT      AMF_STD_CALL SetDumpBasePath(const wchar_t* path) = 0;    //  Set application dump base path
+
+        //  Enable/disable input and/or output stream dumps
+        virtual bool            AMF_STD_CALL IsInputDumpEnabled() const = 0;
+        virtual AMF_RESULT      AMF_STD_CALL EnableInputDump(bool enabled) = 0;     
+        virtual const wchar_t*  AMF_STD_CALL GetInputDumpFullName() const = 0;  //  Get full name of dump file
+
+        //  Enable/disable input and/or output stream dumps
+        virtual bool            AMF_STD_CALL IsOutputDumpEnabled() const = 0;
+        virtual AMF_RESULT      AMF_STD_CALL EnableOutputDump(bool enabled) = 0;     
+        virtual const wchar_t*  AMF_STD_CALL GetOutputDumpFullName() const = 0;  //  Get full name of dump file
+
+        //  When enabled, each new application session will create a subfolder with a time stamp in the base path tree (disabled by default)
+        virtual bool            AMF_STD_CALL IsPerSessionDumpEnabled() const = 0;
+        virtual void            AMF_STD_CALL EnablePerSessionDump(bool enabled) = 0;      
+    };
+    typedef AMFInterfacePtr_T<AMFDump> AMFDumpPtr;
+#else // #if defined(__cplusplus)
+        AMF_DECLARE_IID(AMFDump, 0x75366ad4, 0x504c, 0x430b, 0xbb, 0xe2, 0xad, 0x21, 0x82, 0x8, 0xf, 0x72);
+    typedef struct AMFDump AMFDump;
+
+    typedef struct AMFDumpVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFDump* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFDump* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFDump* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+        
+        // AMFDump interface
+        const wchar_t*  (AMF_STD_CALL *GetDumpBasePath)(AMFDump* pThis) const;             //  Get application dump base path
+        AMF_RESULT      (AMF_STD_CALL *SetDumpBasePath)(AMFDump* pThis, const wchar_t* path);    //  Set application dump base path
+        
+        //  Enable/disable input and/or output stream dumps
+        bool            (AMF_STD_CALL *IsInputDumpEnabled)(AMFDump* pThis) const;
+        AMF_RESULT      (AMF_STD_CALL *EnableInputDump)(AMFDump* pThis, bool enabled);     
+        const wchar_t*  (AMF_STD_CALL *GetInputDumpFullName)(AMFDump* pThis) const;  //  Get full name of dump file
+
+        //  Enable/disable input and/or output stream dumps
+        bool            (AMF_STD_CALL *IsOutputDumpEnabled)(AMFDump* pThis) const;
+        AMF_RESULT      (AMF_STD_CALL *EnableOutputDump)(AMFDump* pThis, bool enabled);     
+        const wchar_t*  (AMF_STD_CALL *GetOutputDumpFullName)(AMFDump* pThis) const;  //  Get full name of dump file
+
+        //  When enabled, each new application session will create a subfolder with a time stamp in the base path tree (disabled by default)
+        bool            (AMF_STD_CALL *IsPerSessionDumpEnabled)(AMFDump* pThis) const;
+        void            (AMF_STD_CALL *EnablePerSessionDump)(AMFDump* pThis, bool enabled);      
+
+    } AMFDumpVtbl;
+
+    struct AMFDump
+    {
+        const AMFDumpVtbl *pVtbl;
+    };
+
+
+#endif // #if defined(__cplusplus)
+#if defined(__cplusplus)
+} // namespace
+#endif
+
+#endif //AMF_Dump_h

+ 133 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Factory.h

@@ -0,0 +1,133 @@
+//
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+//
+// MIT license
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Factory_h
+#define AMF_Factory_h
+#pragma once
+
+#include "Platform.h"
+#include "Version.h"
+#include "Result.h"
+#include "Context.h"
+#include "Debug.h"
+#include "Trace.h"
+#include "Compute.h"
+
+#include "../components/Component.h"
+
+#if defined(__cplusplus)
+
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    // AMFFactory interface - singleton
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFFactory
+    {
+    public:
+        virtual AMF_RESULT          AMF_STD_CALL CreateContext(AMFContext** ppContext) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CreateComponent(AMFContext* pContext, const wchar_t* id, AMFComponent** ppComponent) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL SetCacheFolder(const wchar_t* path) = 0;
+        virtual const wchar_t*      AMF_STD_CALL GetCacheFolder() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetDebug(AMFDebug** ppDebug) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetTrace(AMFTrace** ppTrace) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetPrograms(AMFPrograms** ppPrograms) = 0;
+   };
+#else
+    typedef struct AMFFactory AMFFactory;
+
+    typedef struct AMFFactoryVtbl
+    {
+        AMF_RESULT          (AMF_STD_CALL *CreateContext)(AMFFactory* pThis, AMFContext** ppContext);
+        AMF_RESULT          (AMF_STD_CALL *CreateComponent)(AMFFactory* pThis, AMFContext* pContext, const wchar_t* id, AMFComponent** ppComponent);
+        AMF_RESULT          (AMF_STD_CALL *SetCacheFolder)(AMFFactory* pThis, const wchar_t* path);
+        const wchar_t*      (AMF_STD_CALL *GetCacheFolder)(AMFFactory* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetDebug)(AMFFactory* pThis, AMFDebug** ppDebug);
+        AMF_RESULT          (AMF_STD_CALL *GetTrace)(AMFFactory* pThis, AMFTrace** ppTrace);
+        AMF_RESULT          (AMF_STD_CALL *GetPrograms)(AMFFactory* pThis, AMFPrograms** ppPrograms);
+    } AMFFactoryVtbl;
+
+    struct AMFFactory
+    {
+        const AMFFactoryVtbl *pVtbl;
+    };
+
+#endif
+#if defined(__cplusplus)
+}
+#endif
+
+//----------------------------------------------------------------------------------------------
+// DLL entry points
+//----------------------------------------------------------------------------------------------
+
+#define AMF_INIT_FUNCTION_NAME             "AMFInit"
+#define AMF_QUERY_VERSION_FUNCTION_NAME    "AMFQueryVersion"
+
+#if defined(__cplusplus)
+extern "C"
+{
+    typedef AMF_RESULT             (AMF_CDECL_CALL *AMFInit_Fn)(amf_uint64 version, amf::AMFFactory **ppFactory);
+    typedef AMF_RESULT             (AMF_CDECL_CALL *AMFQueryVersion_Fn)(amf_uint64 *pVersion);
+}
+#else
+    typedef AMF_RESULT             (AMF_CDECL_CALL *AMFInit_Fn)(amf_uint64 version, AMFFactory **ppFactory);
+    typedef AMF_RESULT             (AMF_CDECL_CALL *AMFQueryVersion_Fn)(amf_uint64 *pVersion);
+#endif
+
+#if defined(_WIN32)
+    #if defined(_M_AMD64)
+        #define AMF_DLL_NAME    L"amfrt64.dll"
+        #define AMF_DLL_NAMEA   "amfrt64.dll"
+#else
+        #define AMF_DLL_NAME    L"amfrt32.dll"
+        #define AMF_DLL_NAMEA   "amfrt32.dll"
+    #endif
+#elif defined(__ANDROID__)
+    #define AMF_DLL_NAME    L"libamf.so"
+    #define AMF_DLL_NAMEA    "libamf.so"
+#elif defined(__APPLE__)
+    #define AMF_DLL_NAME    L"libamfrt.framework/libamfrt"
+    #define AMF_DLL_NAMEA   "libamfrt.framework/libamfrt"
+#elif defined(__linux__)
+    #if defined(__x86_64__) || defined(__aarch64__)
+        #define AMF_DLL_NAME    L"libamfrt64.so.1"
+        #define AMF_DLL_NAMEA   "libamfrt64.so.1"
+    #else
+        #define AMF_DLL_NAME    L"libamfrt32.so.1"
+        #define AMF_DLL_NAMEA   "libamfrt32.so.1"
+    #endif
+#endif
+//----------------------------------------------------------------------------------------------
+#endif   // AMF_Factory_h

+ 258 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Interface.h

@@ -0,0 +1,258 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Interface_h
+#define AMF_Interface_h
+#pragma once
+
+#include "Result.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+#if defined(__cplusplus)
+    #define AMF_DECLARE_IID(_data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48) \
+        static AMF_INLINE const amf::AMFGuid IID() \
+        { \
+            amf::AMFGuid uid = {_data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48}; \
+            return uid; \
+        }
+#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) \
+        { \
+            AMFGuid uid = {_data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48}; \
+            return uid; \
+        }
+#endif
+
+    //------------------------------------------------------------------------
+    // AMFInterface interface  - base class for all AMF interfaces
+    //------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0x9d872f34, 0x90dc, 0x4b93, 0xb6, 0xb2, 0x6c, 0xa3, 0x7c, 0x85, 0x25, 0xdb)
+
+        virtual amf_long            AMF_STD_CALL Acquire() = 0;
+        virtual amf_long            AMF_STD_CALL Release() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL QueryInterface(const AMFGuid& interfaceID, void** ppInterface) = 0;
+    };
+#else
+    AMF_DECLARE_IID(AMFInterface, 0x9d872f34, 0x90dc, 0x4b93, 0xb6, 0xb2, 0x6c, 0xa3, 0x7c, 0x85, 0x25, 0xdb)
+    typedef struct AMFInterface AMFInterface;
+
+    typedef struct AMFInterfaceVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFInterface* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFInterface* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFInterface* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+    } AMFInterfaceVtbl;
+
+    struct AMFInterface
+    {
+        const AMFInterfaceVtbl *pVtbl;
+    };
+#endif
+    //------------------------------------------------------------------------
+    // template for AMF smart pointer
+    //------------------------------------------------------------------------
+#if defined(__cplusplus)
+    template<class _Interf>
+    class AMFInterfacePtr_T
+    {
+    private:
+        _Interf* m_pInterf;
+
+        void InternalAcquire()
+        {
+            if(m_pInterf != NULL)
+            {
+                m_pInterf->Acquire();
+            }
+        }
+        void InternalRelease()
+        {
+            if(m_pInterf != NULL)
+            {
+                m_pInterf->Release();
+            }
+        }
+    public:
+        AMFInterfacePtr_T() : m_pInterf(NULL)
+        {}
+
+        AMFInterfacePtr_T(const AMFInterfacePtr_T<_Interf>& p) : m_pInterf(p.m_pInterf)
+        {
+            InternalAcquire();
+        }
+
+        AMFInterfacePtr_T(_Interf* pInterface) : m_pInterf(pInterface)
+        {
+            InternalAcquire();
+        }
+
+        template<class _OtherInterf>
+        explicit AMFInterfacePtr_T(const AMFInterfacePtr_T<_OtherInterf>& cp) : m_pInterf(NULL)
+        {
+            void* pInterf = NULL;
+            if((cp == NULL) || (cp->QueryInterface(_Interf::IID(), &pInterf) != AMF_OK))
+            {
+                pInterf = NULL;
+            }
+            m_pInterf = static_cast<_Interf*>(pInterf);
+        }
+
+        template<class _OtherInterf>
+        explicit AMFInterfacePtr_T(_OtherInterf* cp) : m_pInterf(NULL)
+        {
+            void* pInterf = NULL;
+            if((cp == NULL) || (cp->QueryInterface(_Interf::IID(), &pInterf) != AMF_OK))
+            {
+                pInterf = NULL;
+            }
+            m_pInterf = static_cast<_Interf*>(pInterf);
+        }
+
+        ~AMFInterfacePtr_T()
+        {
+            InternalRelease();
+        }
+
+        AMFInterfacePtr_T& operator=(_Interf* pInterface)
+        {
+            if(m_pInterf != pInterface)
+            {
+                _Interf* pOldInterface = m_pInterf;
+                m_pInterf = pInterface;
+                InternalAcquire();
+                if(pOldInterface != NULL)
+                {
+                    pOldInterface->Release();
+                }
+            }
+            return *this;
+        }
+
+        AMFInterfacePtr_T& operator=(const AMFInterfacePtr_T<_Interf>& cp)
+        {
+            return operator=(cp.m_pInterf);
+        }
+
+        void Attach(_Interf* pInterface)
+        {
+            InternalRelease();
+            m_pInterf = pInterface;
+        }
+
+        _Interf* Detach()
+        {
+            _Interf* const pOld = m_pInterf;
+            m_pInterf = NULL;
+            return pOld;
+        }
+        void Release()
+        {
+            InternalRelease();
+            m_pInterf = NULL;
+        }
+
+        operator _Interf*() const
+        {
+            return m_pInterf;
+        }
+
+        _Interf& operator*() const
+        {
+            return *m_pInterf;
+        }
+
+        // Returns the address of the interface pointer contained in this
+        // class. This is required for initializing from C-style factory function to
+        // avoid getting an incorrect ref count at the beginning.
+
+        _Interf** operator&()
+        {
+            InternalRelease();
+            m_pInterf = 0;
+            return &m_pInterf;
+        }
+
+        _Interf* operator->() const
+        {
+            return m_pInterf;
+        }
+
+        bool operator==(const AMFInterfacePtr_T<_Interf>& p)
+        {
+            return (m_pInterf == p.m_pInterf);
+        }
+
+        bool operator==(_Interf* p)
+        {
+            return (m_pInterf == p);
+        }
+
+        bool operator!=(const AMFInterfacePtr_T<_Interf>& p)
+        {
+            return !(operator==(p));
+        }
+        bool operator!=(_Interf* p)
+        {
+            return !(operator==(p));
+        }
+
+        _Interf* GetPtr()
+        {
+            return m_pInterf;
+        }
+
+        const _Interf* GetPtr() const
+        {
+            return m_pInterf;
+        }
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFInterface> AMFInterfacePtr;
+    //----------------------------------------------------------------------------------------------
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //#ifndef AMF_Interface_h

+ 112 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Plane.h

@@ -0,0 +1,112 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Plane_h
+#define AMF_Plane_h
+#pragma once
+
+#include "Interface.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //---------------------------------------------------------------------------------------------
+    typedef enum AMF_PLANE_TYPE
+    {
+        AMF_PLANE_UNKNOWN       = 0,
+        AMF_PLANE_PACKED        = 1,             // for all packed formats: BGRA, YUY2, etc
+        AMF_PLANE_Y             = 2,
+        AMF_PLANE_UV            = 3,
+        AMF_PLANE_U             = 4,
+        AMF_PLANE_V             = 5,
+    } AMF_PLANE_TYPE;
+    //---------------------------------------------------------------------------------------------
+    // AMFPlane interface
+    //---------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFPlane : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0xbede1aa6, 0xd8fa, 0x4625, 0x94, 0x65, 0x6c, 0x82, 0xc4, 0x37, 0x71, 0x2e)
+
+        virtual AMF_PLANE_TYPE      AMF_STD_CALL GetType() = 0;
+        virtual void*               AMF_STD_CALL GetNative() = 0;
+        virtual amf_int32           AMF_STD_CALL GetPixelSizeInBytes() = 0;
+        virtual amf_int32           AMF_STD_CALL GetOffsetX() = 0;
+        virtual amf_int32           AMF_STD_CALL GetOffsetY() = 0;
+        virtual amf_int32           AMF_STD_CALL GetWidth() = 0;
+        virtual amf_int32           AMF_STD_CALL GetHeight() = 0;
+        virtual amf_int32           AMF_STD_CALL GetHPitch() = 0;
+        virtual amf_int32           AMF_STD_CALL GetVPitch() = 0;
+        virtual bool                AMF_STD_CALL IsTiled() = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFPlane> AMFPlanePtr;
+    //----------------------------------------------------------------------------------------------
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFPlane, 0xbede1aa6, 0xd8fa, 0x4625, 0x94, 0x65, 0x6c, 0x82, 0xc4, 0x37, 0x71, 0x2e)
+    typedef struct AMFPlane AMFPlane;
+    typedef struct AMFPlaneVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFPlane* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFPlane* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFPlane* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPlane interface
+        AMF_PLANE_TYPE      (AMF_STD_CALL *GetType)(AMFPlane* pThis);
+        void*               (AMF_STD_CALL *GetNative)(AMFPlane* pThis);
+        amf_int32           (AMF_STD_CALL *GetPixelSizeInBytes)(AMFPlane* pThis);
+        amf_int32           (AMF_STD_CALL *GetOffsetX)(AMFPlane* pThis);
+        amf_int32           (AMF_STD_CALL *GetOffsetY)(AMFPlane* pThis);
+        amf_int32           (AMF_STD_CALL *GetWidth)(AMFPlane* pThis);
+        amf_int32           (AMF_STD_CALL *GetHeight)(AMFPlane* pThis);
+        amf_int32           (AMF_STD_CALL *GetHPitch)(AMFPlane* pThis);
+        amf_int32           (AMF_STD_CALL *GetVPitch)(AMFPlane* pThis);
+        amf_bool            (AMF_STD_CALL *IsTiled)(AMFPlane* pThis);
+
+    } AMFPlaneVtbl;
+
+    struct AMFPlane
+    {
+        const AMFPlaneVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+
+#if defined(__cplusplus)
+} // namespace amf
+#endif
+
+#endif //#ifndef AMF_Plane_h

+ 547 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Platform.h

@@ -0,0 +1,547 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Platform_h
+#define AMF_Platform_h
+#pragma once
+
+//----------------------------------------------------------------------------------------------
+// export declaration
+//----------------------------------------------------------------------------------------------
+#if defined(_WIN32)
+    #if defined(AMF_CORE_STATIC)
+        #define AMF_CORE_LINK
+    #else
+        #if defined(AMF_CORE_EXPORTS)
+            #define AMF_CORE_LINK __declspec(dllexport)
+        #else
+            #define AMF_CORE_LINK __declspec(dllimport)
+        #endif
+    #endif
+#elif defined(__linux)        
+        #if defined(AMF_CORE_EXPORTS)
+            #define AMF_CORE_LINK __attribute__((visibility("default")))
+        #else
+            #define AMF_CORE_LINK
+        #endif
+#else 
+    #define AMF_CORE_LINK
+#endif // #ifdef _WIN32
+
+#define AMF_MACRO_STRING2(x) #x
+#define AMF_MACRO_STRING(x) AMF_MACRO_STRING2(x)
+
+#define AMF_TODO(_todo) (__FILE__ "(" AMF_MACRO_STRING(__LINE__) "): TODO: "_todo)
+
+
+ #if defined(__GNUC__) || defined(__clang__)
+     #define AMF_ALIGN(n) __attribute__((aligned(n)))
+ #elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
+     #define AMF_ALIGN(n) __declspec(align(n))
+ #else
+    #define AMF_ALIGN(n)
+//     #error Need to define AMF_ALIGN
+ #endif
+
+#if defined(__linux) || (__clang__)
+typedef signed int HRESULT;
+#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
+#define FAILED(hr) (((HRESULT)(hr)) < 0)
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#if defined(_WIN32)
+
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+    #define AMF_STD_CALL            __stdcall
+    #define AMF_CDECL_CALL          __cdecl
+    #define AMF_FAST_CALL           __fastcall
+#if defined(__GNUC__) || defined(__clang__)
+    #define AMF_INLINE              inline
+    #define AMF_FORCEINLINE         inline
+#else
+    #define AMF_INLINE              __inline
+    #define AMF_FORCEINLINE         __forceinline
+#endif
+    #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
+
+    #define AMF_STD_CALL
+    #define AMF_CDECL_CALL
+    #define AMF_FAST_CALL
+#if defined(__GNUC__) || defined(__clang__)
+    #define AMF_INLINE              inline
+    #define AMF_FORCEINLINE         inline
+#else
+    #define AMF_INLINE              __inline__
+    #define AMF_FORCEINLINE         __inline__
+#endif
+    #define AMF_NO_VTABLE           
+
+    #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
+
+
+#if defined(_WIN32)
+#define AMF_WEAK __declspec( selectany ) 
+#elif defined (__GNUC__) || defined (__GCC__) || defined(__clang__)//GCC or CLANG
+#define AMF_WEAK __attribute__((weak))
+#endif
+
+#define amf_countof(x) (sizeof(x) / sizeof(x[0]))
+
+//-------------------------------------------------------------------------------------------------
+// basic data types
+//-------------------------------------------------------------------------------------------------
+typedef     int64_t             amf_int64;
+typedef     int32_t             amf_int32;
+typedef     int16_t             amf_int16;
+typedef     int8_t              amf_int8;
+
+typedef     uint64_t            amf_uint64;
+typedef     uint32_t            amf_uint32;
+typedef     uint16_t            amf_uint16;
+typedef     uint8_t             amf_uint8;
+typedef     size_t              amf_size;
+
+typedef     void*               amf_handle;
+typedef     double              amf_double;
+typedef     float               amf_float;
+
+typedef     void                amf_void;
+
+#if defined(__cplusplus)
+typedef     bool                amf_bool;
+#else
+typedef     amf_uint8           amf_bool;
+#define     true                1 
+#define     false               0 
+#endif
+
+typedef     long                amf_long; 
+typedef     int                 amf_int; 
+typedef     unsigned long       amf_ulong; 
+typedef     unsigned int        amf_uint; 
+
+typedef     amf_int64           amf_pts;     // in 100 nanosecs
+
+typedef amf_uint32              amf_flags;
+
+#define AMF_SECOND          10000000L    // 1 second in 100 nanoseconds
+#define AMF_MILLISECOND		(AMF_SECOND / 1000)
+
+#define AMF_MIN(a, b) ((a) < (b) ? (a) : (b))
+#define AMF_MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define AMF_BITS_PER_BYTE 8
+
+#if defined(_WIN32)
+    #define PATH_SEPARATOR_WSTR         L"\\"
+    #define PATH_SEPARATOR_WCHAR        L'\\'
+#elif defined(__linux) || defined(__APPLE__) // Linux & Apple
+    #define PATH_SEPARATOR_WSTR          L"/"
+    #define PATH_SEPARATOR_WCHAR         L'/'
+#endif
+
+typedef struct AMFRect
+{
+    amf_int32 left;
+    amf_int32 top;
+    amf_int32 right;
+    amf_int32 bottom;
+#if defined(__cplusplus)
+    bool operator==(const AMFRect& other) const
+    {
+         return left == other.left && top == other.top && right == other.right && bottom == other.bottom; 
+    }
+    AMF_INLINE bool operator!=(const AMFRect& other) const { return !operator==(other); }
+    amf_int32 Width() const { return right - left; }
+    amf_int32 Height() const { return bottom - top; }
+#endif
+} AMFRect;
+
+static AMF_INLINE struct AMFRect AMFConstructRect(amf_int32 left, amf_int32 top, amf_int32 right, amf_int32 bottom)
+{
+    struct AMFRect object = {left, top, right, bottom};
+    return object;
+}
+
+typedef struct AMFSize
+{
+    amf_int32 width;
+    amf_int32 height;
+#if defined(__cplusplus)
+    bool operator==(const AMFSize& other) const
+    {
+         return width == other.width && height == other.height; 
+    }
+    AMF_INLINE bool operator!=(const AMFSize& other) const { return !operator==(other); }
+#endif
+} AMFSize;
+
+static AMF_INLINE struct AMFSize AMFConstructSize(amf_int32 width, amf_int32 height)
+{
+    struct AMFSize object = {width, height};
+    return object;
+}
+
+typedef struct AMFPoint
+{
+    amf_int32 x;
+    amf_int32 y;
+#if defined(__cplusplus)
+    bool operator==(const AMFPoint& other) const
+    {
+         return x == other.x && y == other.y; 
+    }
+    AMF_INLINE bool operator!=(const AMFPoint& other) const { return !operator==(other); }
+#endif
+} AMFPoint;
+
+static AMF_INLINE struct AMFPoint AMFConstructPoint(amf_int32 x, amf_int32 y)
+{
+    struct AMFPoint object = { x, y };
+    return object;
+}
+
+typedef struct AMFFloatPoint2D
+{
+    amf_float x;
+    amf_float y;
+#if defined(__cplusplus)
+    bool operator==(const AMFFloatPoint2D& other) const
+    {
+        return x == other.x && y == other.y;
+    }
+    AMF_INLINE bool operator!=(const AMFFloatPoint2D& other) const { return !operator==(other); }
+#endif
+} AMFFloatPoint2D;
+
+static AMF_INLINE struct AMFFloatPoint2D AMFConstructFloatPoint2D(amf_float x, amf_float y)
+{
+    struct AMFFloatPoint2D object = {x, y};
+    return object;
+}
+typedef struct AMFFloatSize
+{
+    amf_float width;
+    amf_float height;
+#if defined(__cplusplus)
+    bool operator==(const AMFFloatSize& other) const
+    {
+        return width == other.width && height == other.height;
+    }
+    AMF_INLINE bool operator!=(const AMFFloatSize& other) const { return !operator==(other); }
+#endif
+} AMFFloatSize;
+
+static AMF_INLINE struct AMFFloatSize AMFConstructFloatSize(amf_float w, amf_float h)
+{
+    struct AMFFloatSize object = { w, h };
+    return object;
+}
+
+
+typedef struct AMFFloatPoint3D
+{
+    amf_float x;
+    amf_float y;
+    amf_float z;
+#if defined(__cplusplus)
+    bool operator==(const AMFFloatPoint3D& other) const
+    {
+        return x == other.x && y == other.y && z == other.z;
+    }
+    AMF_INLINE bool operator!=(const AMFFloatPoint3D& other) const { return !operator==(other); }
+#endif
+} AMFFloatPoint3D;
+
+static AMF_INLINE struct AMFFloatPoint3D AMFConstructFloatPoint3D(amf_float x, amf_float y, amf_float z)
+{
+    struct AMFFloatPoint3D object = { x, y, z };
+    return object;
+}
+
+typedef struct AMFFloatVector4D
+{
+    amf_float x;
+    amf_float y;
+    amf_float z;
+    amf_float w;
+#if defined(__cplusplus)
+    bool operator==(const AMFFloatVector4D& other) const
+    {
+        return x == other.x && y == other.y && z == other.z && w == other.w;
+    }
+    AMF_INLINE bool operator!=(const AMFFloatVector4D& other) const { return !operator==(other); }
+#endif
+} AMFFloatVector4D;
+
+static AMF_INLINE struct AMFFloatVector4D AMFConstructFloatVector4D(amf_float x, amf_float y, amf_float z, amf_float w)
+{
+    struct AMFFloatVector4D object = { x, y, z, w };
+    return object;
+}
+
+
+typedef struct AMFRate
+{
+    amf_uint32 num;
+    amf_uint32 den;
+#if defined(__cplusplus)
+    bool operator==(const AMFRate& other) const
+    {
+         return num == other.num && den == other.den; 
+    }
+    AMF_INLINE bool operator!=(const AMFRate& other) const { return !operator==(other); }
+#endif
+} AMFRate;
+
+static AMF_INLINE struct AMFRate AMFConstructRate(amf_uint32 num, amf_uint32 den)
+{
+    struct AMFRate object = {num, den};
+    return object;
+}
+
+typedef struct AMFRatio
+{
+    amf_uint32 num;
+    amf_uint32 den;
+#if defined(__cplusplus)
+    bool operator==(const AMFRatio& other) const
+    {
+         return num == other.num && den == other.den; 
+    }
+    AMF_INLINE bool operator!=(const AMFRatio& other) const { return !operator==(other); }
+#endif
+} AMFRatio;
+
+static AMF_INLINE struct AMFRatio AMFConstructRatio(amf_uint32 num, amf_uint32 den)
+{
+    struct AMFRatio object = {num, den};
+    return object;
+}
+
+#pragma pack(push, 1)
+#if defined(_MSC_VER)
+    #pragma warning( push )
+#endif
+#if defined(WIN32)
+#if defined(_MSC_VER)
+    #pragma warning(disable : 4200)
+    #pragma warning(disable : 4201)
+#endif
+#endif
+typedef struct AMFColor
+{
+    union
+    {
+        struct
+        {
+            amf_uint8 r;
+            amf_uint8 g;
+            amf_uint8 b;
+            amf_uint8 a;
+        };
+        amf_uint32 rgba;
+    };
+#if defined(__cplusplus)
+    bool operator==(const AMFColor& other) const
+    {
+         return r == other.r && g == other.g && b == other.b && a == other.a; 
+    }
+    AMF_INLINE bool operator!=(const AMFColor& other) const { return !operator==(other); }
+#endif
+} AMFColor;
+#if defined(_MSC_VER)
+    #pragma warning( pop )
+#endif
+#pragma pack(pop)
+
+
+static AMF_INLINE struct AMFColor AMFConstructColor(amf_uint8 r, amf_uint8 g, amf_uint8 b, amf_uint8 a)
+{
+    struct AMFColor object;
+    object.r = r;
+    object.g = g;
+    object.b = b;
+    object.a = a;
+    return object;
+}
+
+#if defined(_WIN32)
+    #include <combaseapi.h>
+
+    #if defined(__cplusplus)
+    extern "C"
+    {
+    #endif
+        // allocator
+        static AMF_INLINE void* AMF_CDECL_CALL amf_variant_alloc(amf_size count)
+        {
+            return CoTaskMemAlloc(count);
+        }
+        static AMF_INLINE void AMF_CDECL_CALL amf_variant_free(void* ptr)
+        {
+            CoTaskMemFree(ptr);
+        }
+    #if defined(__cplusplus)
+    }
+    #endif
+
+#else // defined(_WIN32)
+    #include <stdlib.h>
+    #if defined(__cplusplus)
+    extern "C"
+    {
+    #endif
+        // allocator
+        static AMF_INLINE void* AMF_CDECL_CALL amf_variant_alloc(amf_size count)
+        {
+            return malloc(count);
+        }
+        static AMF_INLINE void AMF_CDECL_CALL amf_variant_free(void* ptr)
+        {
+            free(ptr);
+        }
+    #if defined(__cplusplus)
+    }
+    #endif
+#endif // defined(_WIN32)
+
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    typedef struct AMFGuid
+    {
+        amf_uint32 data1;
+        amf_uint16 data2;
+        amf_uint16 data3;
+        amf_uint8 data41;
+        amf_uint8 data42;
+        amf_uint8 data43;
+        amf_uint8 data44;
+        amf_uint8 data45;
+        amf_uint8 data46;
+        amf_uint8 data47;
+        amf_uint8 data48;
+#if defined(__cplusplus)
+        AMFGuid(amf_uint32 _data1, amf_uint16 _data2, amf_uint16 _data3,
+                amf_uint8 _data41, amf_uint8 _data42, amf_uint8 _data43, amf_uint8 _data44,
+                amf_uint8 _data45, amf_uint8 _data46, amf_uint8 _data47, amf_uint8 _data48)
+            : data1 (_data1),
+            data2 (_data2),
+            data3 (_data3),
+            data41(_data41),
+            data42(_data42),
+            data43(_data43),
+            data44(_data44),
+            data45(_data45),
+            data46(_data46),
+            data47(_data47),
+            data48(_data48)
+        {}
+
+        bool operator==(const AMFGuid& other) const
+        {
+            return
+                data1 == other.data1 &&
+                data2 == other.data2 &&
+                data3 == other.data3 &&
+                data41 == other.data41 &&
+                data42 == other.data42 &&
+                data43 == other.data43 &&
+                data44 == other.data44 &&
+                data45 == other.data45 &&
+                data46 == other.data46 &&
+                data47 == other.data47 &&
+                data48 == other.data48;
+        }
+        AMF_INLINE bool operator!=(const AMFGuid& other) const { return !operator==(other); }
+#endif
+    } AMFGuid;
+
+#if defined(__cplusplus)
+    static AMF_INLINE bool AMFCompareGUIDs(const AMFGuid& guid1, const AMFGuid& guid2)
+    {
+        return guid1 == guid2;
+    }
+#else
+    static AMF_INLINE amf_bool AMFCompareGUIDs(const struct AMFGuid guid1, const struct AMFGuid guid2)
+    {
+        return memcmp(&guid1, &guid2, sizeof(guid1)) == 0;
+    }
+#endif
+#if defined(__cplusplus)
+}
+#endif
+
+#if defined(__APPLE__)
+//#include <MacTypes.h>
+
+#define media_status_t int
+#define ANativeWindow void
+#define JNIEnv void
+#define jobject int
+#define JavaVM void
+
+#endif
+
+#endif //#ifndef AMF_Platform_h

+ 275 - 0
plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorage.h

@@ -0,0 +1,275 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_PropertyStorage_h
+#define AMF_PropertyStorage_h
+#pragma once
+
+#include "Variant.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    // AMFPropertyStorageObserver interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+
+    class AMF_NO_VTABLE AMFPropertyStorageObserver
+    {
+    public:
+        virtual void                AMF_STD_CALL OnPropertyChanged(const wchar_t* name) = 0;
+    };
+#else //#if defined(__cplusplus)
+    typedef struct AMFPropertyStorageObserver AMFPropertyStorageObserver;
+    typedef struct AMFPropertyStorageObserverVtbl
+    {
+        void                (AMF_STD_CALL *OnPropertyChanged)(AMFPropertyStorageObserver *pThis, const wchar_t* name);
+    } AMFPropertyStorageObserverVtbl;
+
+    struct AMFPropertyStorageObserver
+    {
+        const AMFPropertyStorageObserverVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+#if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // AMFPropertyStorage interface
+    //----------------------------------------------------------------------------------------------
+    class AMF_NO_VTABLE AMFPropertyStorage : public AMFInterface
+    {
+    public:
+        AMF_DECLARE_IID(0xc7cec05b, 0xcfb9, 0x48af, 0xac, 0xe3, 0xf6, 0x8d, 0xf8, 0x39, 0x5f, 0xe3)
+
+        virtual AMF_RESULT          AMF_STD_CALL SetProperty(const wchar_t* name, AMFVariantStruct value) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetProperty(const wchar_t* name, AMFVariantStruct* pValue) const = 0;
+
+        virtual amf_bool            AMF_STD_CALL HasProperty(const wchar_t* name) const = 0;
+        virtual amf_size            AMF_STD_CALL GetPropertyCount() const = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetPropertyAt(amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue) const = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL Clear() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL AddTo(AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep) const= 0;
+        virtual AMF_RESULT          AMF_STD_CALL CopyTo(AMFPropertyStorage* pDest, amf_bool deep) const = 0;
+
+        virtual void                AMF_STD_CALL AddObserver(AMFPropertyStorageObserver* pObserver) = 0;
+        virtual void                AMF_STD_CALL RemoveObserver(AMFPropertyStorageObserver* pObserver) = 0;
+
+        template<typename _T>
+        AMF_RESULT                  AMF_STD_CALL SetProperty(const wchar_t* name, const _T& value);
+        template<typename _T>
+        AMF_RESULT                  AMF_STD_CALL GetProperty(const wchar_t* name, _T* pValue) const;
+        template<typename _T>
+        AMF_RESULT                  AMF_STD_CALL GetPropertyString(const wchar_t* name, _T* pValue) const;
+        template<typename _T>
+        AMF_RESULT                  AMF_STD_CALL GetPropertyWString(const wchar_t* name, _T* pValue) const;
+
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFPropertyStorage> AMFPropertyStoragePtr;
+    //----------------------------------------------------------------------------------------------
+
+#else // #if defined(__cplusplus)
+    typedef struct AMFPropertyStorage AMFPropertyStorage;
+        AMF_DECLARE_IID(AMFPropertyStorage, 0xc7cec05b, 0xcfb9, 0x48af, 0xac, 0xe3, 0xf6, 0x8d, 0xf8, 0x39, 0x5f, 0xe3)
+
+    typedef struct AMFPropertyStorageVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFPropertyStorage* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFPropertyStorage* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFPropertyStorage* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFPropertyStorage* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFPropertyStorage* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFPropertyStorage* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFPropertyStorage* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFPropertyStorage* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFPropertyStorage* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFPropertyStorage* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFPropertyStorage* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFPropertyStorage* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFPropertyStorage* pThis, AMFPropertyStorageObserver* pObserver);
+
+    } AMFPropertyStorageVtbl;
+
+    struct AMFPropertyStorage
+    {
+        const AMFPropertyStorageVtbl *pVtbl;
+    };
+
+    #define AMF_ASSIGN_PROPERTY_DATA(res, varType, pThis, name, val ) \
+    { \
+        AMFVariantStruct var = {0}; \
+        AMFVariantAssign##varType(&var, val); \
+        res = pThis->pVtbl->SetProperty(pThis, name, var ); \
+    }
+
+    #define AMF_QUERY_INTERFACE(res, from, InterfaceTypeTo, to) \
+    { \
+        AMFGuid guid_##InterfaceTypeTo = IID_##InterfaceTypeTo(); \
+        res = from->pVtbl->QueryInterface(from, &guid_##InterfaceTypeTo, (void**)&to); \
+    }
+
+    #define AMF_ASSIGN_PROPERTY_INTERFACE(res, pThis, name, val) \
+    { \
+        AMFInterface *amf_interface; \
+        AMFVariantStruct var; \
+        res = AMFVariantInit(&var); \
+        if (res == AMF_OK) \
+        { \
+            AMF_QUERY_INTERFACE(res, val, AMFInterface, amf_interface)\
+            if (res == AMF_OK) \
+            { \
+                res = AMFVariantAssignInterface(&var, amf_interface); \
+                amf_interface->pVtbl->Release(amf_interface); \
+                if (res == AMF_OK) \
+                { \
+                    res = pThis->pVtbl->SetProperty(pThis, name, var); \
+                } \
+            } \
+            AMFVariantClear(&var); \
+        } \
+    }
+
+    #define AMF_GET_PROPERTY_INTERFACE(res, pThis, name, TargetType, val) \
+    { \
+        AMFVariantStruct var; \
+        res = AMFVariantInit(&var); \
+        if (res != AMF_OK) \
+        { \
+            res = pThis->pVtbl->GetProperty(pThis, name, &var); \
+            if (res == AMF_OK) \
+            { \
+                if (var.type == AMF_VARIANT_INTERFACE && AMFVariantInterface(&var)) \
+                { \
+                    AMF_QUERY_INTERFACE(res, AMFVariantInterface(&var), TargetType, val); \
+                } \
+                else \
+                { \
+                    res = AMF_INVALID_DATA_TYPE; \
+                } \
+            } \
+        } \
+        AMFVariantClear(&var); \
+    }
+
+    #define AMF_ASSIGN_PROPERTY_TYPE(res, varType, dataType , pThis, name, val )  AMF_ASSIGN_PROPERTY_DATA(res, varType, pThis, name, (dataType)val)
+
+    #define AMF_ASSIGN_PROPERTY_INT64(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_TYPE(res, Int64, amf_int64, pThis, name, val)
+    #define AMF_ASSIGN_PROPERTY_DOUBLE(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_TYPE(res, Double, amf_double, pThis, name, val)
+    #define AMF_ASSIGN_PROPERTY_BOOL(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_TYPE(res, Bool, amf_bool, pThis, name, val)
+    #define AMF_ASSIGN_PROPERTY_RECT(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Rect, pThis, name, &val)
+    #define AMF_ASSIGN_PROPERTY_SIZE(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Size, pThis, name, &val)
+    #define AMF_ASSIGN_PROPERTY_POINT(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Point, pThis, name, &val)
+    #define AMF_ASSIGN_PROPERTY_RATE(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Rate, pThis, name, &val)
+    #define AMF_ASSIGN_PROPERTY_RATIO(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Ratio, pThis, name, &val)
+    #define AMF_ASSIGN_PROPERTY_COLOR(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Color, pThis, name, &val)
+
+#endif // #if defined(__cplusplus)
+
+
+#if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // template methods implementations
+    //----------------------------------------------------------------------------------------------
+    template<typename _T> inline
+    AMF_RESULT AMF_STD_CALL AMFPropertyStorage::SetProperty(const wchar_t* name, const _T& value)
+    {
+        AMF_RESULT err = SetProperty(name, static_cast<const AMFVariantStruct&>(AMFVariant(value)));
+        return err;
+    }
+    //----------------------------------------------------------------------------------------------
+    template<typename _T> inline
+    AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetProperty(const wchar_t* name, _T* pValue) const
+    {
+        AMFVariant var;
+        AMF_RESULT err = GetProperty(name, static_cast<AMFVariantStruct*>(&var));
+        if(err == AMF_OK)
+        {
+            *pValue = static_cast<_T>(var);
+        }
+        return err;
+    }
+    //----------------------------------------------------------------------------------------------
+    template<typename _T> inline
+    AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetPropertyString(const wchar_t* name, _T* pValue) const
+    {
+        AMFVariant var;
+        AMF_RESULT err = GetProperty(name, static_cast<AMFVariantStruct*>(&var));
+        if(err == AMF_OK)
+        {
+            *pValue = var.ToString().c_str();
+        }
+        return err;
+    }
+    //----------------------------------------------------------------------------------------------
+    template<typename _T> inline
+    AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetPropertyWString(const wchar_t* name, _T* pValue) const
+    {
+        AMFVariant var;
+        AMF_RESULT err = GetProperty(name, static_cast<AMFVariantStruct*>(&var));
+        if(err == AMF_OK)
+        {
+            *pValue = var.ToWString().c_str();
+        }
+        return err;
+    }
+    //----------------------------------------------------------------------------------------------
+    template<> inline
+    AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetProperty(const wchar_t* name,
+            AMFInterface** ppValue) const
+    {
+        AMFVariant var;
+        AMF_RESULT err = GetProperty(name, static_cast<AMFVariantStruct*>(&var));
+        if(err == AMF_OK)
+        {
+            *ppValue = static_cast<AMFInterface*>(var);
+        }
+        if(*ppValue)
+        {
+            (*ppValue)->Acquire();
+        }
+        return err;
+    }
+#endif // #if defined(__cplusplus)
+
+#if defined(__cplusplus)
+} //namespace amf
+#endif
+
+#endif // #ifndef AMF_PropertyStorage_h

+ 207 - 0
plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorageEx.h

@@ -0,0 +1,207 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_PropertyStorageEx_h
+#define AMF_PropertyStorageEx_h
+#pragma once
+
+#include "PropertyStorage.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_PROPERTY_CONTENT_ENUM
+    {
+        AMF_PROPERTY_CONTENT_DEFAULT = 0,
+        AMF_PROPERTY_CONTENT_XML,               // m_eType is AMF_VARIANT_STRING
+
+        AMF_PROPERTY_CONTENT_FILE_OPEN_PATH,    // m_eType AMF_VARIANT_WSTRING
+        AMF_PROPERTY_CONTENT_FILE_SAVE_PATH,    // m_eType AMF_VARIANT_WSTRING
+
+        AMF_PROPERTY_CONTENT_INTEGER_ARRAY,     // m_eType AMF_VARIANT_INTERFACE
+        AMF_PROPERTY_CONTENT_FLOAT_ARRAY        // m_eType AMF_VARIANT_INTERFACE
+    } AMF_PROPERTY_CONTENT_ENUM;
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_PROPERTY_ACCESS_TYPE
+    {
+        AMF_PROPERTY_ACCESS_PRIVATE             = 0,
+        AMF_PROPERTY_ACCESS_READ                = 0x1,
+        AMF_PROPERTY_ACCESS_WRITE               = 0x2,
+        AMF_PROPERTY_ACCESS_READ_WRITE          = (AMF_PROPERTY_ACCESS_READ | AMF_PROPERTY_ACCESS_WRITE),
+        AMF_PROPERTY_ACCESS_WRITE_RUNTIME       = 0x4,
+        AMF_PROPERTY_ACCESS_FULL                = 0xFF,
+		AMF_PROPERTY_ACCESS_NON_PERSISTANT		= 0x4000,
+		AMF_PROPERTY_ACCESS_NON_PERSISTANT_READ = (AMF_PROPERTY_ACCESS_NON_PERSISTANT | AMF_PROPERTY_ACCESS_READ),
+		AMF_PROPERTY_ACCESS_NON_PERSISTANT_READ_WRITE = (AMF_PROPERTY_ACCESS_NON_PERSISTANT | AMF_PROPERTY_ACCESS_READ_WRITE),
+		AMF_PROPERTY_ACCESS_NON_PERSISTANT_FULL = (AMF_PROPERTY_ACCESS_NON_PERSISTANT | AMF_PROPERTY_ACCESS_FULL),
+		AMF_PROPERTY_ACCESS_INVALID				= 0x8000
+    } AMF_PROPERTY_ACCESS_TYPE;
+
+    //----------------------------------------------------------------------------------------------
+    typedef struct AMFEnumDescriptionEntry
+    {
+        amf_int             value;
+        const wchar_t*      name;
+    } AMFEnumDescriptionEntry;
+    //----------------------------------------------------------------------------------------------
+    typedef amf_uint32 AMF_PROPERTY_CONTENT_TYPE;
+
+    typedef struct AMFPropertyInfo
+    {
+        const wchar_t*                  name;
+        const wchar_t*                  desc;
+        AMF_VARIANT_TYPE                type;
+        AMF_PROPERTY_CONTENT_TYPE       contentType;
+
+        AMFVariantStruct                defaultValue;
+        AMFVariantStruct                minValue;
+        AMFVariantStruct                maxValue;
+        AMF_PROPERTY_ACCESS_TYPE        accessType;
+        const AMFEnumDescriptionEntry*  pEnumDescription;
+
+#if defined(__cplusplus)
+        AMFPropertyInfo() :
+            name(NULL),
+            desc(NULL),
+            type(),
+            contentType(),
+            defaultValue(),
+            minValue(),
+            maxValue(),
+            accessType(AMF_PROPERTY_ACCESS_FULL),
+            pEnumDescription(NULL)
+        {}
+        AMFPropertyInfo(const AMFPropertyInfo& propery) : name(propery.name),
+            desc(propery.desc),
+            type(propery.type),
+            contentType(propery.contentType),
+            defaultValue(propery.defaultValue),
+            minValue(propery.minValue),
+            maxValue(propery.maxValue),
+            accessType(propery.accessType),
+            pEnumDescription(propery.pEnumDescription)
+        {}
+        virtual ~AMFPropertyInfo(){}
+
+        amf_bool AMF_STD_CALL AllowedRead() const
+        {
+            return (accessType & AMF_PROPERTY_ACCESS_READ) != 0;
+        }
+        amf_bool AMF_STD_CALL AllowedWrite() const
+        {
+            return (accessType & AMF_PROPERTY_ACCESS_WRITE) != 0;
+        }
+        amf_bool AMF_STD_CALL AllowedChangeInRuntime() const
+        {
+            return (accessType & AMF_PROPERTY_ACCESS_WRITE_RUNTIME) != 0;
+        }
+
+        AMFPropertyInfo& operator=(const AMFPropertyInfo& propery)
+        {
+            name = propery.name;
+            desc = propery.desc;
+            type = propery.type;
+            contentType = propery.contentType;
+            defaultValue = propery.defaultValue;
+            minValue = propery.minValue;
+            maxValue = propery.maxValue;
+            accessType = propery.accessType;
+            pEnumDescription = propery.pEnumDescription;
+
+            return *this;
+        }
+#endif // #if defined(__cplusplus)
+    } AMFPropertyInfo;
+    //----------------------------------------------------------------------------------------------
+    // AMFPropertyStorageEx interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFPropertyStorageEx : public AMFPropertyStorage
+    {
+    public:
+        AMF_DECLARE_IID(0x16b8958d, 0xe943, 0x4a33, 0xa3, 0x5a, 0x88, 0x5a, 0xd8, 0x28, 0xf2, 0x67)
+
+        virtual amf_size            AMF_STD_CALL GetPropertiesInfoCount() const = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetPropertyInfo(amf_size index, const AMFPropertyInfo** ppInfo) const = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetPropertyInfo(const wchar_t* name, const AMFPropertyInfo** ppInfo) const = 0;
+        virtual AMF_RESULT          AMF_STD_CALL ValidateProperty(const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated) const = 0;
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFPropertyStorageEx> AMFPropertyStorageExPtr;
+#else // #if defined(__cplusplus)
+    AMF_DECLARE_IID(AMFPropertyStorageEx, 0x16b8958d, 0xe943, 0x4a33, 0xa3, 0x5a, 0x88, 0x5a, 0xd8, 0x28, 0xf2, 0x67)
+    typedef struct AMFPropertyStorageEx AMFPropertyStorageEx;
+
+    typedef struct AMFPropertyStorageExVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFPropertyStorageEx* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFPropertyStorageEx* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFPropertyStorageEx* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFPropertyStorageEx* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFPropertyStorageEx* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFPropertyStorageEx* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFPropertyStorageEx* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFPropertyStorageEx* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFPropertyStorageEx* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFPropertyStorageEx* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFPropertyStorageEx* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFPropertyStorageEx* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFPropertyStorageEx* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFPropertyStorageEx interface
+
+        amf_size            (AMF_STD_CALL *GetPropertiesInfoCount)(AMFPropertyStorageEx* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfoAt)(AMFPropertyStorageEx* pThis, amf_size index, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyInfo)(AMFPropertyStorageEx* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo);
+        AMF_RESULT          (AMF_STD_CALL *ValidateProperty)(AMFPropertyStorageEx* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated);
+
+    } AMFPropertyStorageExVtbl;
+
+    struct AMFPropertyStorageEx
+    {
+        const AMFPropertyStorageExVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+} //namespace amf
+#endif
+
+
+#endif //#ifndef AMF_PropertyStorageEx_h

+ 127 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Result.h

@@ -0,0 +1,127 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Result_h
+#define AMF_Result_h
+#pragma once
+
+#include "Platform.h"
+
+//----------------------------------------------------------------------------------------------
+// result codes
+//----------------------------------------------------------------------------------------------
+
+typedef enum AMF_RESULT
+{
+    AMF_OK                                   = 0,
+    AMF_FAIL                                    ,
+
+// common errors
+    AMF_UNEXPECTED                              ,
+
+    AMF_ACCESS_DENIED                           ,
+    AMF_INVALID_ARG                             ,
+    AMF_OUT_OF_RANGE                            ,
+
+    AMF_OUT_OF_MEMORY                           ,
+    AMF_INVALID_POINTER                         ,
+
+    AMF_NO_INTERFACE                            ,
+    AMF_NOT_IMPLEMENTED                         ,
+    AMF_NOT_SUPPORTED                           ,
+    AMF_NOT_FOUND                               ,
+
+    AMF_ALREADY_INITIALIZED                     ,
+    AMF_NOT_INITIALIZED                         ,
+
+    AMF_INVALID_FORMAT                          ,// invalid data format
+
+    AMF_WRONG_STATE                             ,
+    AMF_FILE_NOT_OPEN                           ,// cannot open file
+
+// device common codes
+    AMF_NO_DEVICE                               ,
+
+// device directx
+    AMF_DIRECTX_FAILED                          ,
+// device opencl 
+    AMF_OPENCL_FAILED                           ,
+// device opengl 
+    AMF_GLX_FAILED                              ,//failed to use GLX
+// device XV 
+    AMF_XV_FAILED                               , //failed to use Xv extension
+// device alsa
+    AMF_ALSA_FAILED                             ,//failed to use ALSA
+
+// component common codes
+
+    //result codes
+    AMF_EOF                                     ,
+    AMF_REPEAT                                  ,
+    AMF_INPUT_FULL                              ,//returned by AMFComponent::SubmitInput if input queue is full
+    AMF_RESOLUTION_CHANGED                      ,//resolution changed client needs to Drain/Terminate/Init
+    AMF_RESOLUTION_UPDATED                      ,//resolution changed in adaptive mode. New ROI will be set on output on newly decoded frames
+
+    //error codes
+    AMF_INVALID_DATA_TYPE                       ,//invalid data type
+    AMF_INVALID_RESOLUTION                      ,//invalid resolution (width or height)
+    AMF_CODEC_NOT_SUPPORTED                     ,//codec not supported
+    AMF_SURFACE_FORMAT_NOT_SUPPORTED            ,//surface format not supported
+    AMF_SURFACE_MUST_BE_SHARED                  ,//surface should be shared (DX11: (MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0, DX9: No shared handle found)
+
+// component video decoder
+    AMF_DECODER_NOT_PRESENT                     ,//failed to create the decoder
+    AMF_DECODER_SURFACE_ALLOCATION_FAILED       ,//failed to create the surface for decoding
+    AMF_DECODER_NO_FREE_SURFACES                ,
+
+// component video encoder
+    AMF_ENCODER_NOT_PRESENT                     ,//failed to create the encoder
+
+// component video processor
+
+// component video conveter
+
+// component dem
+    AMF_DEM_ERROR                               ,
+    AMF_DEM_PROPERTY_READONLY                   ,
+    AMF_DEM_REMOTE_DISPLAY_CREATE_FAILED        ,
+    AMF_DEM_START_ENCODING_FAILED               ,
+    AMF_DEM_QUERY_OUTPUT_FAILED                 ,
+
+// component TAN
+    AMF_TAN_CLIPPING_WAS_REQUIRED               , // Resulting data was truncated to meet output type's value limits.
+    AMF_TAN_UNSUPPORTED_VERSION                 , // Not supported version requested, solely for TANCreateContext().
+
+    AMF_NEED_MORE_INPUT                         ,//returned by AMFComponent::SubmitInput did not produce a buffer because more input submissions are required.
+} AMF_RESULT;
+
+#endif //#ifndef AMF_Result_h

+ 279 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Surface.h

@@ -0,0 +1,279 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Surface_h
+#define AMF_Surface_h
+#pragma once
+
+#include "Data.h"
+#include "Plane.h"
+
+#if defined(_MSC_VER)
+    #pragma warning( push )
+    #pragma warning(disable : 4263)
+    #pragma warning(disable : 4264)
+#endif
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_SURFACE_FORMAT
+    {
+        AMF_SURFACE_UNKNOWN     = 0,
+        AMF_SURFACE_NV12,               ///< 1  - planar 4:2:0 Y width x height + packed UV width/2 x height/2 - 8 bit per component
+        AMF_SURFACE_YV12,               ///< 2  - planar 4:2:0 Y width x height + V width/2 x height/2 + U width/2 x height/2 - 8 bit per component
+        AMF_SURFACE_BGRA,               ///< 3  - packed 4:4:4 - 8 bit per component
+        AMF_SURFACE_ARGB,               ///< 4  - packed 4:4:4 - 8 bit per component
+        AMF_SURFACE_RGBA,               ///< 5  - packed 4:4:4 - 8 bit per component
+        AMF_SURFACE_GRAY8,              ///< 6  - single component - 8 bit
+        AMF_SURFACE_YUV420P,            ///< 7  - planar 4:2:0 Y width x height + U width/2 x height/2 + V width/2 x height/2 - 8 bit per component
+        AMF_SURFACE_U8V8,               ///< 8  - packed double component - 8 bit per component
+        AMF_SURFACE_YUY2,               ///< 9  - packed 4:2:2 Byte 0=8-bit Y'0; Byte 1=8-bit Cb; Byte 2=8-bit Y'1; Byte 3=8-bit Cr
+        AMF_SURFACE_P010,               ///< 10 - planar 4:2:0 Y width x height + packed UV width/2 x height/2 - 10 bit per component (16 allocated, upper 10 bits are used)
+        AMF_SURFACE_RGBA_F16,           ///< 11 - packed 4:4:4 - 16 bit per component float
+        AMF_SURFACE_UYVY,               ///< 12 - packed 4:2:2 the similar to YUY2 but Y and UV swapped: Byte 0=8-bit Cb; Byte 1=8-bit Y'0; Byte 2=8-bit Cr Byte 3=8-bit Y'1; (used the same DX/CL/Vulkan storage as YUY2)
+        AMF_SURFACE_R10G10B10A2,        ///< 13 - packed 4:4:4 to 4 bytes, 10 bit per RGB component, 2 bits per A 
+        AMF_SURFACE_Y210,               ///< 14 - packed 4:2:2 - Word 0=10-bit Y'0; Word 1=10-bit Cb; Word 2=10-bit Y'1; Word 3=10-bit Cr
+        AMF_SURFACE_AYUV,               ///< 15 - packed 4:4:4 - 8 bit per component YUVA
+        AMF_SURFACE_Y410,               ///< 16 - packed 4:4:4 - 10 bit per YUV component, 2 bits per A, AVYU 
+        AMF_SURFACE_Y416,               ///< 16 - packed 4:4:4 - 16 bit per component 4 bytes, AVYU
+        AMF_SURFACE_GRAY32,             ///< 17 - single component - 32 bit
+
+        AMF_SURFACE_FIRST = AMF_SURFACE_NV12,
+        AMF_SURFACE_LAST = AMF_SURFACE_GRAY32
+    } AMF_SURFACE_FORMAT;
+    //----------------------------------------------------------------------------------------------
+    // AMF_SURFACE_USAGE translates to D3D11_BIND_FLAG or VkImageUsageFlags
+    // bit mask
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_SURFACE_USAGE_BITS
+    {                                                       // D3D11                        D3D12                                       Vulkan 
+        AMF_SURFACE_USAGE_DEFAULT           = 0x80000000,   // will apply default           D3D12_RESOURCE_FLAG_NONE                    VK_IMAGE_USAGE_TRANSFER_SRC_BIT| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
+        AMF_SURFACE_USAGE_NONE              = 0x00000000,   // 0,                           D3D12_RESOURCE_FLAG_NONE,                   0
+        AMF_SURFACE_USAGE_SHADER_RESOURCE   = 0x00000001,   // D3D11_BIND_SHADER_RESOURCE,	D3D12_RESOURCE_FLAG_NONE					VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
+        AMF_SURFACE_USAGE_RENDER_TARGET     = 0x00000002,   // D3D11_BIND_RENDER_TARGET,    D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET,    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
+        AMF_SURFACE_USAGE_UNORDERED_ACCESS  = 0x00000004,   // D3D11_BIND_UNORDERED_ACCESS, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
+        AMF_SURFACE_USAGE_TRANSFER_SRC      = 0x00000008,   //								D3D12_RESOURCE_FLAG_NONE    	            VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+        AMF_SURFACE_USAGE_TRANSFER_DST      = 0x00000010,   //								D3D12_RESOURCE_FLAG_NONE		            VK_IMAGE_USAGE_TRANSFER_DST_BIT
+        AMF_SURFACE_USAGE_LINEAR            = 0x00000020    
+    } AMF_SURFACE_USAGE_BITS;
+    typedef amf_flags AMF_SURFACE_USAGE;
+    //----------------------------------------------------------------------------------------------
+
+#if defined(_WIN32)
+    AMF_WEAK GUID  AMFFormatGUID = { 0x8cd592d0, 0x8063, 0x4af8, {0xa7, 0xd0, 0x32, 0x5b, 0xc5, 0xf7, 0x48, 0xab}}; // UINT(AMF_SURFACE_FORMAT), default - AMF_SURFACE_UNKNOWN; to be set on ID3D11Texture2D objects when used natively (i.e. force UYVY on DXGI_FORMAT_YUY2 texture)
+#endif
+
+    //----------------------------------------------------------------------------------------------
+    // frame type
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_FRAME_TYPE
+    {
+        // flags
+        AMF_FRAME_STEREO_FLAG                           = 0x10000000,
+        AMF_FRAME_LEFT_FLAG                             = AMF_FRAME_STEREO_FLAG | 0x20000000,
+        AMF_FRAME_RIGHT_FLAG                            = AMF_FRAME_STEREO_FLAG | 0x40000000,
+        AMF_FRAME_BOTH_FLAG                             = AMF_FRAME_LEFT_FLAG | AMF_FRAME_RIGHT_FLAG,
+        AMF_FRAME_INTERLEAVED_FLAG                      = 0x01000000,
+        AMF_FRAME_FIELD_FLAG                            = 0x02000000,
+        AMF_FRAME_EVEN_FLAG                             = 0x04000000,
+        AMF_FRAME_ODD_FLAG                              = 0x08000000,
+
+        // values
+        AMF_FRAME_UNKNOWN                               =-1,
+        AMF_FRAME_PROGRESSIVE                           = 0,
+
+        AMF_FRAME_INTERLEAVED_EVEN_FIRST                = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG,
+        AMF_FRAME_INTERLEAVED_ODD_FIRST                 = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG,
+        AMF_FRAME_FIELD_SINGLE_EVEN                     = AMF_FRAME_FIELD_FLAG | AMF_FRAME_EVEN_FLAG,
+        AMF_FRAME_FIELD_SINGLE_ODD                      = AMF_FRAME_FIELD_FLAG | AMF_FRAME_ODD_FLAG,
+
+        AMF_FRAME_STEREO_LEFT                           = AMF_FRAME_LEFT_FLAG,
+        AMF_FRAME_STEREO_RIGHT                          = AMF_FRAME_RIGHT_FLAG,
+        AMF_FRAME_STEREO_BOTH                           = AMF_FRAME_BOTH_FLAG,
+
+        AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_LEFT    = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG | AMF_FRAME_LEFT_FLAG,
+        AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_RIGHT   = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG | AMF_FRAME_RIGHT_FLAG,
+        AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_BOTH    = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG | AMF_FRAME_BOTH_FLAG,
+
+        AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_LEFT     = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG | AMF_FRAME_LEFT_FLAG,
+        AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_RIGHT    = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG | AMF_FRAME_RIGHT_FLAG,
+        AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_BOTH     = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG | AMF_FRAME_BOTH_FLAG,
+    } AMF_FRAME_TYPE;
+
+    typedef enum AMF_ROTATION_ENUM
+    {
+        AMF_ROTATION_NONE   = 0,
+        AMF_ROTATION_90     = 1,
+        AMF_ROTATION_180    = 2,
+        AMF_ROTATION_270    = 3,
+    } AMF_ROTATION_ENUM;
+
+    #define AMF_SURFACE_ROTATION         L"Rotation"    // amf_int64(AMF_ROTATION_ENUM); default = AMF_ROTATION_NONE, can be set on surfaces
+
+    //----------------------------------------------------------------------------------------------
+    // AMFSurfaceObserver interface - callback; is called before internal release resources.
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMFSurface;
+    class AMF_NO_VTABLE AMFSurfaceObserver
+    {
+    public:
+        virtual void AMF_STD_CALL OnSurfaceDataRelease(AMFSurface* pSurface) = 0;
+    };
+#else // #if defined(__cplusplus)
+    typedef struct AMFSurface AMFSurface;
+    typedef struct AMFSurfaceObserver AMFSurfaceObserver;
+
+    typedef struct AMFSurfaceObserverVtbl
+    {
+        void                (AMF_STD_CALL *OnSurfaceDataRelease)(AMFSurfaceObserver* pThis, AMFSurface* pSurface);
+    } AMFSurfaceObserverVtbl;
+
+    struct AMFSurfaceObserver
+    {
+        const AMFSurfaceObserverVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+    // AMFSurface interface
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFSurface : public AMFData
+    {
+    public:
+        AMF_DECLARE_IID(0x3075dbe3, 0x8718, 0x4cfa, 0x86, 0xfb, 0x21, 0x14, 0xc0, 0xa5, 0xa4, 0x51)
+
+        virtual AMF_SURFACE_FORMAT  AMF_STD_CALL GetFormat() = 0;
+
+        // do not store planes outside. should be used together with Surface
+        virtual amf_size            AMF_STD_CALL GetPlanesCount() = 0;
+        virtual AMFPlane*           AMF_STD_CALL GetPlaneAt(amf_size index) = 0;
+        virtual AMFPlane*           AMF_STD_CALL GetPlane(AMF_PLANE_TYPE type) = 0;
+
+        virtual AMF_FRAME_TYPE      AMF_STD_CALL GetFrameType() = 0;
+        virtual void                AMF_STD_CALL SetFrameType(AMF_FRAME_TYPE type) = 0;
+
+        virtual AMF_RESULT          AMF_STD_CALL SetCrop(amf_int32 x,amf_int32 y, amf_int32 width, amf_int32 height) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL CopySurfaceRegion(AMFSurface* pDest, amf_int32 dstX, amf_int32 dstY, amf_int32 srcX, amf_int32 srcY, amf_int32 width, amf_int32 height) = 0;
+
+        // Observer management
+#ifdef __clang__
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Woverloaded-virtual"
+#endif
+        virtual void                AMF_STD_CALL AddObserver(AMFSurfaceObserver* pObserver) = 0;
+        virtual void                AMF_STD_CALL RemoveObserver(AMFSurfaceObserver* pObserver) = 0;
+#ifdef __clang__
+    #pragma clang diagnostic pop
+#endif
+
+    };
+    //----------------------------------------------------------------------------------------------
+    // smart pointer
+    //----------------------------------------------------------------------------------------------
+    typedef AMFInterfacePtr_T<AMFSurface> AMFSurfacePtr;
+    //----------------------------------------------------------------------------------------------
+#else // #if defined(__cplusplus)
+        AMF_DECLARE_IID(AMFSurface, 0x3075dbe3, 0x8718, 0x4cfa, 0x86, 0xfb, 0x21, 0x14, 0xc0, 0xa5, 0xa4, 0x51)
+    typedef struct AMFSurfaceVtbl
+    {
+        // AMFInterface interface
+        amf_long            (AMF_STD_CALL *Acquire)(AMFSurface* pThis);
+        amf_long            (AMF_STD_CALL *Release)(AMFSurface* pThis);
+        enum AMF_RESULT     (AMF_STD_CALL *QueryInterface)(AMFSurface* pThis, const struct AMFGuid *interfaceID, void** ppInterface);
+
+        // AMFPropertyStorage interface
+        AMF_RESULT          (AMF_STD_CALL *SetProperty)(AMFSurface* pThis, const wchar_t* name, AMFVariantStruct value);
+        AMF_RESULT          (AMF_STD_CALL *GetProperty)(AMFSurface* pThis, const wchar_t* name, AMFVariantStruct* pValue);
+        amf_bool            (AMF_STD_CALL *HasProperty)(AMFSurface* pThis, const wchar_t* name);
+        amf_size            (AMF_STD_CALL *GetPropertyCount)(AMFSurface* pThis);
+        AMF_RESULT          (AMF_STD_CALL *GetPropertyAt)(AMFSurface* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
+        AMF_RESULT          (AMF_STD_CALL *Clear)(AMFSurface* pThis);
+        AMF_RESULT          (AMF_STD_CALL *AddTo)(AMFSurface* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
+        AMF_RESULT          (AMF_STD_CALL *CopyTo)(AMFSurface* pThis, AMFPropertyStorage* pDest, amf_bool deep);
+        void                (AMF_STD_CALL *AddObserver)(AMFSurface* pThis, AMFPropertyStorageObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver)(AMFSurface* pThis, AMFPropertyStorageObserver* pObserver);
+
+        // AMFData interface
+
+        AMF_MEMORY_TYPE     (AMF_STD_CALL *GetMemoryType)(AMFSurface* pThis);
+
+        AMF_RESULT          (AMF_STD_CALL *Duplicate)(AMFSurface* pThis, AMF_MEMORY_TYPE type, AMFData** ppData);
+        AMF_RESULT          (AMF_STD_CALL *Convert)(AMFSurface* pThis, AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through host memory if needed
+        AMF_RESULT          (AMF_STD_CALL *Interop)(AMFSurface* pThis, AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy through host memory for GPU objects
+
+        AMF_DATA_TYPE       (AMF_STD_CALL *GetDataType)(AMFSurface* pThis);
+
+        amf_bool            (AMF_STD_CALL *IsReusable)(AMFSurface* pThis);
+
+        void                (AMF_STD_CALL *SetPts)(AMFSurface* pThis, amf_pts pts);
+        amf_pts             (AMF_STD_CALL *GetPts)(AMFSurface* pThis);
+        void                (AMF_STD_CALL *SetDuration)(AMFSurface* pThis, amf_pts duration);
+        amf_pts             (AMF_STD_CALL *GetDuration)(AMFSurface* pThis);
+
+        // AMFSurface interface
+
+        AMF_SURFACE_FORMAT  (AMF_STD_CALL *GetFormat)(AMFSurface* pThis);
+
+        // do not store planes outside. should be used together with Surface
+        amf_size            (AMF_STD_CALL *GetPlanesCount)(AMFSurface* pThis);
+        AMFPlane*           (AMF_STD_CALL *GetPlaneAt)(AMFSurface* pThis, amf_size index);
+        AMFPlane*           (AMF_STD_CALL *GetPlane)(AMFSurface* pThis, AMF_PLANE_TYPE type);
+
+        AMF_FRAME_TYPE      (AMF_STD_CALL *GetFrameType)(AMFSurface* pThis);
+        void                (AMF_STD_CALL *SetFrameType)(AMFSurface* pThis, AMF_FRAME_TYPE type);
+
+        AMF_RESULT          (AMF_STD_CALL *SetCrop)(AMFSurface* pThis, amf_int32 x,amf_int32 y, amf_int32 width, amf_int32 height);
+        AMF_RESULT          (AMF_STD_CALL *CopySurfaceRegion)(AMFSurface* pThis, AMFSurface* pDest, amf_int32 dstX, amf_int32 dstY, amf_int32 srcX, amf_int32 srcY, amf_int32 width, amf_int32 height);
+
+
+        // Observer management
+        void                (AMF_STD_CALL *AddObserver_Surface)(AMFSurface* pThis, AMFSurfaceObserver* pObserver);
+        void                (AMF_STD_CALL *RemoveObserver_Surface)(AMFSurface* pThis, AMFSurfaceObserver* pObserver);
+
+    } AMFSurfaceVtbl;
+
+    struct AMFSurface
+    {
+        const AMFSurfaceVtbl *pVtbl;
+    };
+#endif // #if defined(__cplusplus)
+#if defined(__cplusplus)
+}
+#endif
+#if defined(_MSC_VER)
+    #pragma warning( pop )
+#endif
+#endif //#ifndef AMF_Surface_h

+ 183 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Trace.h

@@ -0,0 +1,183 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Trace_h
+#define AMF_Trace_h
+#pragma once
+
+#include "Platform.h"
+#include "Result.h"
+#include "Surface.h"
+#include "AudioBuffer.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    // trace levels
+    //----------------------------------------------------------------------------------------------
+    #define AMF_TRACE_ERROR     0
+    #define AMF_TRACE_WARNING   1
+    #define AMF_TRACE_INFO      2 // default in sdk
+    #define AMF_TRACE_DEBUG     3
+    #define AMF_TRACE_TRACE     4
+
+    #define AMF_TRACE_TEST      5
+    #define AMF_TRACE_NOLOG     100
+
+    //----------------------------------------------------------------------------------------------
+    // available trace writers
+    //----------------------------------------------------------------------------------------------
+    #define AMF_TRACE_WRITER_CONSOLE            L"Console"
+    #define AMF_TRACE_WRITER_DEBUG_OUTPUT       L"DebugOutput"
+    #define AMF_TRACE_WRITER_FILE               L"File"
+
+    //----------------------------------------------------------------------------------------------
+    // AMFTraceWriter interface - callback
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFTraceWriter
+    {
+    public:
+        virtual void AMF_CDECL_CALL Write(const wchar_t* scope, const wchar_t* message) = 0;
+        virtual void AMF_CDECL_CALL Flush() = 0;
+    };
+#else // #if defined(__cplusplus)
+    typedef struct AMFTraceWriter AMFTraceWriter;
+
+    typedef struct AMFTraceWriterVtbl
+    {
+        // AMFTraceWriter interface
+        void (AMF_CDECL_CALL *Write)(AMFTraceWriter* pThis, const wchar_t* scope, const wchar_t* message);
+        void (AMF_CDECL_CALL *Flush)(AMFTraceWriter* pThis);
+    } AMFTraceWriterVtbl;
+
+    struct AMFTraceWriter
+    {
+        const AMFTraceWriterVtbl *pVtbl;
+    };
+
+#endif // #if defined(__cplusplus)
+
+    //----------------------------------------------------------------------------------------------
+    // AMFTrace interface - singleton
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    class AMF_NO_VTABLE AMFTrace
+    {
+    public:
+        virtual  void               AMF_STD_CALL TraceW(const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope,amf_int32 countArgs, const wchar_t* format, ...) = 0;
+        virtual  void               AMF_STD_CALL Trace(const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope, const wchar_t* message, va_list* pArglist) = 0;
+
+        virtual amf_int32           AMF_STD_CALL SetGlobalLevel(amf_int32 level) = 0;
+        virtual amf_int32           AMF_STD_CALL GetGlobalLevel() = 0;
+
+        virtual amf_bool            AMF_STD_CALL EnableWriter(const wchar_t* writerID, bool enable) = 0;
+        virtual amf_bool            AMF_STD_CALL WriterEnabled(const wchar_t* writerID) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL TraceEnableAsync(amf_bool enable) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL TraceFlush() = 0;
+        virtual AMF_RESULT          AMF_STD_CALL SetPath(const wchar_t* path) = 0;
+        virtual AMF_RESULT          AMF_STD_CALL GetPath(wchar_t* path, amf_size* pSize) = 0;
+        virtual amf_int32           AMF_STD_CALL SetWriterLevel(const wchar_t* writerID, amf_int32 level) = 0;
+        virtual amf_int32           AMF_STD_CALL GetWriterLevel(const wchar_t* writerID) = 0;
+        virtual amf_int32           AMF_STD_CALL SetWriterLevelForScope(const wchar_t* writerID, const wchar_t* scope, amf_int32 level) = 0;
+        virtual amf_int32           AMF_STD_CALL GetWriterLevelForScope(const wchar_t* writerID, const wchar_t* scope) = 0;
+
+        virtual amf_int32           AMF_STD_CALL GetIndentation() = 0;
+        virtual void                AMF_STD_CALL Indent(amf_int32 addIndent) = 0;
+
+        virtual void                AMF_STD_CALL RegisterWriter(const wchar_t* writerID, AMFTraceWriter* pWriter, amf_bool enable) = 0;
+        virtual void                AMF_STD_CALL UnregisterWriter(const wchar_t* writerID) = 0;
+
+        virtual const wchar_t*      AMF_STD_CALL GetResultText(AMF_RESULT res) = 0;
+        virtual const wchar_t*      AMF_STD_CALL SurfaceGetFormatName(const AMF_SURFACE_FORMAT eSurfaceFormat) = 0;
+        virtual AMF_SURFACE_FORMAT  AMF_STD_CALL SurfaceGetFormatByName(const wchar_t* name) = 0;
+
+        virtual const wchar_t*      AMF_STD_CALL GetMemoryTypeName(const AMF_MEMORY_TYPE memoryType) = 0;
+        virtual AMF_MEMORY_TYPE     AMF_STD_CALL GetMemoryTypeByName(const wchar_t* name) = 0;
+
+        virtual const wchar_t*      AMF_STD_CALL GetSampleFormatName(const AMF_AUDIO_FORMAT eFormat) = 0;
+        virtual AMF_AUDIO_FORMAT    AMF_STD_CALL GetSampleFormatByName(const wchar_t* name) = 0;
+    };
+#else // #if defined(__cplusplus)
+    typedef struct AMFTrace AMFTrace;
+
+    typedef struct AMFTraceVtbl
+    {
+        // AMFTrace interface
+         void               (AMF_STD_CALL *TraceW)(AMFTrace* pThis, const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope,amf_int32 countArgs, const wchar_t* format, ...);
+         void               (AMF_STD_CALL *Trace)(AMFTrace* pThis, const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope, const wchar_t* message, va_list* pArglist);
+
+        amf_int32           (AMF_STD_CALL *SetGlobalLevel)(AMFTrace* pThis, amf_int32 level);
+        amf_int32           (AMF_STD_CALL *GetGlobalLevel)(AMFTrace* pThis);
+
+        amf_bool            (AMF_STD_CALL *EnableWriter)(AMFTrace* pThis, const wchar_t* writerID, amf_bool enable);
+        amf_bool            (AMF_STD_CALL *WriterEnabled)(AMFTrace* pThis, const wchar_t* writerID);
+        AMF_RESULT          (AMF_STD_CALL *TraceEnableAsync)(AMFTrace* pThis, amf_bool enable);
+        AMF_RESULT          (AMF_STD_CALL *TraceFlush)(AMFTrace* pThis);
+        AMF_RESULT          (AMF_STD_CALL *SetPath)(AMFTrace* pThis, const wchar_t* path);
+        AMF_RESULT          (AMF_STD_CALL *GetPath)(AMFTrace* pThis, wchar_t* path, amf_size* pSize);
+        amf_int32           (AMF_STD_CALL *SetWriterLevel)(AMFTrace* pThis, const wchar_t* writerID, amf_int32 level);
+        amf_int32           (AMF_STD_CALL *GetWriterLevel)(AMFTrace* pThis, const wchar_t* writerID);
+        amf_int32           (AMF_STD_CALL *SetWriterLevelForScope)(AMFTrace* pThis, const wchar_t* writerID, const wchar_t* scope, amf_int32 level);
+        amf_int32           (AMF_STD_CALL *GetWriterLevelForScope)(AMFTrace* pThis, const wchar_t* writerID, const wchar_t* scope);
+
+        amf_int32           (AMF_STD_CALL *GetIndentation)(AMFTrace* pThis);
+        void                (AMF_STD_CALL *Indent)(AMFTrace* pThis, amf_int32 addIndent);
+
+        void                (AMF_STD_CALL *RegisterWriter)(AMFTrace* pThis, const wchar_t* writerID, AMFTraceWriter* pWriter, amf_bool enable);
+        void                (AMF_STD_CALL *UnregisterWriter)(AMFTrace* pThis, const wchar_t* writerID);
+
+        const wchar_t*      (AMF_STD_CALL *GetResultText)(AMFTrace* pThis, AMF_RESULT res);
+        const wchar_t*      (AMF_STD_CALL *SurfaceGetFormatName)(AMFTrace* pThis, const AMF_SURFACE_FORMAT eSurfaceFormat);
+        AMF_SURFACE_FORMAT  (AMF_STD_CALL *SurfaceGetFormatByName)(AMFTrace* pThis, const wchar_t* name);
+
+        const wchar_t*      (AMF_STD_CALL *GetMemoryTypeName)(AMFTrace* pThis, const AMF_MEMORY_TYPE memoryType);
+        AMF_MEMORY_TYPE     (AMF_STD_CALL *GetMemoryTypeByName)(AMFTrace* pThis, const wchar_t* name);
+
+        const wchar_t*      (AMF_STD_CALL *GetSampleFormatName)(AMFTrace* pThis, const AMF_AUDIO_FORMAT eFormat);
+        AMF_AUDIO_FORMAT    (AMF_STD_CALL *GetSampleFormatByName)(AMFTrace* pThis, const wchar_t* name);
+    } AMFTraceVtbl;
+
+    struct AMFTrace
+    {
+        const AMFTraceVtbl *pVtbl;
+    };
+
+#endif
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif // AMF_Trace_h

+ 2075 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Variant.h

@@ -0,0 +1,2075 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef AMF_Variant_h
+#define AMF_Variant_h
+#pragma once
+#if defined(_MSC_VER)
+    #pragma warning(disable: 4996)
+#endif
+
+#include "Interface.h"
+#include <locale.h>
+#include <wchar.h>
+#include <string.h>
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    //----------------------------------------------------------------------------------------------
+    // variant types
+    //----------------------------------------------------------------------------------------------
+    typedef enum AMF_VARIANT_TYPE
+    {
+        AMF_VARIANT_EMPTY           = 0,
+
+        AMF_VARIANT_BOOL            = 1,
+        AMF_VARIANT_INT64           = 2,
+        AMF_VARIANT_DOUBLE          = 3,
+
+        AMF_VARIANT_RECT            = 4,
+        AMF_VARIANT_SIZE            = 5,
+        AMF_VARIANT_POINT           = 6,
+        AMF_VARIANT_RATE            = 7,
+        AMF_VARIANT_RATIO           = 8,
+        AMF_VARIANT_COLOR           = 9,
+
+        AMF_VARIANT_STRING          = 10,  // value is char*
+        AMF_VARIANT_WSTRING         = 11,  // value is wchar_t*
+        AMF_VARIANT_INTERFACE       = 12,  // value is AMFInterface*
+        AMF_VARIANT_FLOAT           = 13,
+
+        AMF_VARIANT_FLOAT_SIZE      = 14,
+        AMF_VARIANT_FLOAT_POINT2D   = 15,
+        AMF_VARIANT_FLOAT_POINT3D   = 16,
+        AMF_VARIANT_FLOAT_VECTOR4D  = 17
+    } AMF_VARIANT_TYPE;
+    //----------------------------------------------------------------------------------------------
+    // variant struct
+   //----------------------------------------------------------------------------------------------
+    typedef struct AMFVariantStruct
+    {
+        AMF_VARIANT_TYPE            type;
+        union
+        {
+            amf_bool                boolValue;
+            amf_int64               int64Value;
+            amf_double              doubleValue;
+            char*                   stringValue;
+            wchar_t*                wstringValue;
+            AMFInterface*           pInterface;
+            struct AMFRect          rectValue;
+            struct AMFSize          sizeValue;
+            struct AMFPoint         pointValue;
+            struct AMFRate          rateValue;
+            struct AMFRatio         ratioValue;
+            struct AMFColor         colorValue;
+            amf_float               floatValue;
+            struct AMFFloatSize     floatSizeValue;
+            struct AMFFloatPoint2D  floatPoint2DValue;
+            struct AMFFloatPoint3D  floatPoint3DValue;
+            struct AMFFloatVector4D floatVector4DValue;
+        };
+    } AMFVariantStruct;
+    //----------------------------------------------------------------------------------------------
+    // variant accessors
+    //----------------------------------------------------------------------------------------------
+
+    static AMF_INLINE AMF_VARIANT_TYPE     AMF_STD_CALL AMFVariantGetType(const AMFVariantStruct* _variant) { return (_variant)->type; }
+#if defined(__cplusplus)
+    static AMF_INLINE AMF_VARIANT_TYPE&    AMF_STD_CALL AMFVariantGetType(AMFVariantStruct* _variant) { return (_variant)->type; }
+#endif
+    static AMF_INLINE amf_bool             AMF_STD_CALL AMFVariantGetBool(const AMFVariantStruct* _variant) { return (_variant)->boolValue; }
+    static AMF_INLINE amf_int64            AMF_STD_CALL AMFVariantGetInt64(const AMFVariantStruct* _variant) { return (_variant)->int64Value; }
+    static AMF_INLINE amf_double           AMF_STD_CALL AMFVariantGetDouble(const AMFVariantStruct* _variant) { return (_variant)->doubleValue; }
+    static AMF_INLINE amf_float            AMF_STD_CALL AMFVariantGetFloat(const AMFVariantStruct* _variant) { return (_variant)->floatValue; }
+    static AMF_INLINE const char*          AMF_STD_CALL AMFVariantGetString(const AMFVariantStruct* _variant) { return (_variant)->stringValue; }
+    static AMF_INLINE const wchar_t*       AMF_STD_CALL AMFVariantGetWString(const AMFVariantStruct* _variant) { return (_variant)->wstringValue; }
+#if defined(__cplusplus)
+    static AMF_INLINE const AMFInterface*  AMF_STD_CALL AMFVariantGetInterface(const AMFVariantStruct* _variant) { return (_variant)->pInterface; }
+#endif
+    static AMF_INLINE AMFInterface*        AMF_STD_CALL AMFVariantGetInterface(AMFVariantStruct* _variant) { return (_variant)->pInterface; }
+
+#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; }
+#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; }
+#endif // #if defined(__cplusplus)
+
+
+    #define AMFVariantEmpty(_variant)     0
+    #define AMFVariantBool(_variant)      (_variant)->boolValue
+    #define AMFVariantInt64(_variant)     (_variant)->int64Value
+    #define AMFVariantDouble(_variant)    (_variant)->doubleValue
+    #define AMFVariantFloat(_variant)    (_variant)->floatValue
+
+    #define AMFVariantRect(_variant)      (_variant)->rectValue
+    #define AMFVariantSize(_variant)      (_variant)->sizeValue
+    #define AMFVariantPoint(_variant)     (_variant)->pointValue
+    #define AMFVariantFloatSize(_variant)     (_variant)->floatSizeValue
+    #define AMFVariantFloatPoint2D(_variant)     (_variant)->floatPoint2DValue
+    #define AMFVariantFloatPoint3D(_variant)     (_variant)->floatPoint3DValue
+    #define AMFVariantFloatVector4D(_variant)     (_variant)->floatVector4DValue
+    #define AMFVariantRate(_variant)      (_variant)->rateValue
+    #define AMFVariantRatio(_variant)     (_variant)->ratioValue
+    #define AMFVariantColor(_variant)     (_variant)->colorValue
+
+    #define AMFVariantString(_variant)    (_variant)->stringValue
+    #define AMFVariantWString(_variant)   (_variant)->wstringValue
+    #define AMFVariantInterface(_variant) (_variant)->pInterface
+    //----------------------------------------------------------------------------------------------
+    // variant hleper functions
+    //----------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantInit(AMFVariantStruct* pVariant);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantClear(AMFVariantStruct* pVariant);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantCompare(const AMFVariantStruct* pFirst, const AMFVariantStruct* pSecond, amf_bool* equal);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantCopy(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignBool(AMFVariantStruct* pDest, amf_bool value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignInt64(AMFVariantStruct* pDest, amf_int64 value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignDouble(AMFVariantStruct* pDest, amf_double value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloat(AMFVariantStruct* pDest, amf_float value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignString(AMFVariantStruct* pDest, const char* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignWString(AMFVariantStruct* pDest, const wchar_t* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignInterface(AMFVariantStruct* pDest, AMFInterface* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignRect(AMFVariantStruct* pDest, const AMFRect* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignSize(AMFVariantStruct* pDest, const AMFSize* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloatSize(AMFVariantStruct* pDest, const AMFFloatSize* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloatPoint2D(AMFVariantStruct* pDest, const AMFFloatPoint2D* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloatPoint3D(AMFVariantStruct* pDest, const AMFFloatPoint3D* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloatVector4D(AMFVariantStruct* pDest, const AMFFloatVector4D* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignRate(AMFVariantStruct* pDest, const AMFRate* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio* value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor* value);
+
+#if defined(__cplusplus)
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignRect(AMFVariantStruct* pDest, const AMFRect& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignSize(AMFVariantStruct* pDest, const AMFSize& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloatSize(AMFVariantStruct* pDest, const AMFFloatSize& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloatPoint2D(AMFVariantStruct* pDest, const AMFFloatPoint2D& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloatPoint3D(AMFVariantStruct* pDest, const AMFFloatPoint3D& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignFloatVector4D(AMFVariantStruct* pDest, const AMFFloatVector4D& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignRate(AMFVariantStruct* pDest, const AMFRate& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio& value);
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor& value);
+
+    static AMF_INLINE AMF_RESULT       AMF_CDECL_CALL AMFVariantChangeType(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc, AMF_VARIANT_TYPE newType);
+#endif
+    static AMF_INLINE char*            AMF_CDECL_CALL AMFVariantDuplicateString(const char* from);
+    static AMF_INLINE void             AMF_CDECL_CALL AMFVariantFreeString(char* from);
+    static AMF_INLINE wchar_t*         AMF_CDECL_CALL AMFVariantDuplicateWString(const wchar_t* from);
+    static AMF_INLINE void             AMF_CDECL_CALL AMFVariantFreeWString(wchar_t* from);
+
+#if defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // AMF_INLINE Variant helper class
+    //----------------------------------------------------------------------------------------------
+    class AMFVariant : public AMFVariantStruct
+    {
+    public:
+        class String;
+        class WString;
+
+    public:
+        AMFVariant() {  AMFVariantInit(this); }
+        explicit AMFVariant(const AMFVariantStruct& other) { AMFVariantInit(this); AMFVariantCopy(this, const_cast<AMFVariantStruct*>(&other)); }
+
+        explicit AMFVariant(const AMFVariantStruct* pOther);
+        template<typename T>
+        explicit AMFVariant(const AMFInterfacePtr_T<T>& pValue);
+
+        AMFVariant(const AMFVariant& other) { AMFVariantInit(this); AMFVariantCopy(this, const_cast<AMFVariantStruct*>(static_cast<const AMFVariantStruct*>(&other))); }
+
+        explicit AMF_INLINE AMFVariant(amf_bool value)          { AMFVariantInit(this); AMFVariantAssignBool(this, value); }
+        explicit AMF_INLINE AMFVariant(amf_int64 value)         { AMFVariantInit(this); AMFVariantAssignInt64(this, value); }
+        explicit AMF_INLINE AMFVariant(amf_uint64 value)        { AMFVariantInit(this); AMFVariantAssignInt64(this, (amf_int64)value); }
+        explicit AMF_INLINE AMFVariant(amf_int32 value)         { AMFVariantInit(this); AMFVariantAssignInt64(this, value); }
+        explicit AMF_INLINE AMFVariant(amf_uint32 value)        { AMFVariantInit(this); AMFVariantAssignInt64(this, value); }
+        explicit AMF_INLINE AMFVariant(amf_double value)        { AMFVariantInit(this); AMFVariantAssignDouble(this, value); }
+        explicit AMF_INLINE AMFVariant(amf_float value)         { AMFVariantInit(this); AMFVariantAssignFloat(this, value); }
+        explicit AMF_INLINE AMFVariant(const AMFRect & value)   { AMFVariantInit(this); AMFVariantAssignRect(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFSize & value)   { AMFVariantInit(this); AMFVariantAssignSize(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFPoint& value)   { AMFVariantInit(this); AMFVariantAssignPoint(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFFloatSize& value) { AMFVariantInit(this); AMFVariantAssignFloatSize(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFFloatPoint2D& value) { AMFVariantInit(this); AMFVariantAssignFloatPoint2D(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFFloatPoint3D& value) { AMFVariantInit(this); AMFVariantAssignFloatPoint3D(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFFloatVector4D& value) { AMFVariantInit(this); AMFVariantAssignFloatVector4D(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFRate & value)   { AMFVariantInit(this); AMFVariantAssignRate(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFRatio& value)   { AMFVariantInit(this); AMFVariantAssignRatio(this, &value); }
+        explicit AMF_INLINE AMFVariant(const AMFColor& value)   { AMFVariantInit(this); AMFVariantAssignColor(this, &value); }
+        explicit AMF_INLINE AMFVariant(const char* value)       { AMFVariantInit(this); AMFVariantAssignString(this, value); }
+        explicit AMF_INLINE AMFVariant(const wchar_t* value)    { AMFVariantInit(this); AMFVariantAssignWString(this, value); }
+        explicit AMF_INLINE AMFVariant(AMFInterface* pValue)    { AMFVariantInit(this); AMFVariantAssignInterface(this, pValue); }
+
+        ~AMFVariant() { AMFVariantClear(this); }
+
+        AMFVariant& operator=(const AMFVariantStruct& other);
+        AMFVariant& operator=(const AMFVariantStruct* pOther);
+        AMFVariant& operator=(const AMFVariant& other);
+
+        AMFVariant& operator=(amf_bool          value)      { AMFVariantAssignBool(this, value); return *this;}
+        AMFVariant& operator=(amf_int64         value)      { AMFVariantAssignInt64(this, value); return *this;}
+        AMFVariant& operator=(amf_uint64        value)      { AMFVariantAssignInt64(this, (amf_int64)value);  return *this;}
+        AMFVariant& operator=(amf_int32         value)      { AMFVariantAssignInt64(this, value);  return *this;}
+        AMFVariant& operator=(amf_uint32        value)      { AMFVariantAssignInt64(this, value);  return *this;}
+        AMFVariant& operator=(amf_double        value)      { AMFVariantAssignDouble(this, value);  return *this;}
+        AMFVariant& operator=(amf_float        value)       { AMFVariantAssignFloat(this, value);  return *this; }
+        AMFVariant& operator=(const AMFRect &   value)      { AMFVariantAssignRect(this, &value);  return *this;}
+        AMFVariant& operator=(const AMFSize &   value)      { AMFVariantAssignSize(this, &value);  return *this;}
+        AMFVariant& operator=(const AMFPoint&   value)      { AMFVariantAssignPoint(this, &value);  return *this;}
+        AMFVariant& operator=(const AMFFloatSize&   value) { AMFVariantAssignFloatSize(this, &value);  return *this; }
+        AMFVariant& operator=(const AMFFloatPoint2D&   value) { AMFVariantAssignFloatPoint2D(this, &value);  return *this; }
+        AMFVariant& operator=(const AMFFloatPoint3D&   value) { AMFVariantAssignFloatPoint3D(this, &value);  return *this; }
+        AMFVariant& operator=(const AMFFloatVector4D&   value) { AMFVariantAssignFloatVector4D(this, &value);  return *this; }
+        AMFVariant& operator=(const AMFRate &   value)      { AMFVariantAssignRate(this, &value);  return *this;}
+        AMFVariant& operator=(const AMFRatio&   value)      { AMFVariantAssignRatio(this, &value);  return *this;}
+        AMFVariant& operator=(const AMFColor&   value)      { AMFVariantAssignColor(this, &value);  return *this;}
+        AMFVariant& operator=(const char*       value)      { AMFVariantAssignString(this, value);  return *this;}
+        AMFVariant& operator=(const wchar_t*    value)      { AMFVariantAssignWString(this, value);  return *this;}
+        AMFVariant& operator=(AMFInterface*     value)      { AMFVariantAssignInterface(this, value);  return *this;}
+
+        template<typename T> AMFVariant& operator=(const AMFInterfacePtr_T<T>& value);
+
+        operator amf_bool() const           { return ToBool();       }
+        operator amf_int64() const          { return ToInt64();      }
+        operator amf_uint64() const         { return ToUInt64();     }
+        operator amf_int32() const          { return ToInt32();      }
+        operator amf_uint32() const         { return ToUInt32();     }
+        operator amf_double() const         { return ToDouble();     }
+        operator amf_float() const          { return ToFloat();      }
+        operator AMFRect () const           { return ToRect ();      }
+        operator AMFSize () const           { return ToSize ();      }
+        operator AMFPoint() const           { return ToPoint();      }
+        operator AMFFloatSize() const       { return ToFloatSize(); }
+        operator AMFFloatPoint2D() const    { return ToFloatPoint2D(); }
+        operator AMFFloatPoint3D() const    { return ToFloatPoint3D(); }
+        operator AMFFloatVector4D() const   { return ToFloatVector4D(); }
+        operator AMFRate () const           { return ToRate ();      }
+        operator AMFRatio() const           { return ToRatio();      }
+        operator AMFColor() const           { return ToColor();      }
+        operator AMFInterface*() const      { return ToInterface();  }
+
+        AMF_INLINE amf_bool         ToBool() const      { return Empty() ? false        : GetValue<amf_bool,   AMF_VARIANT_BOOL>(AMFVariantGetBool); }
+        AMF_INLINE amf_int64        ToInt64() const     { return Empty() ? 0            : GetValue<amf_int64,  AMF_VARIANT_INT64>(AMFVariantGetInt64); }
+        AMF_INLINE amf_uint64       ToUInt64() const    { return Empty() ? 0            : GetValue<amf_uint64, AMF_VARIANT_INT64>(AMFVariantGetInt64); }
+        AMF_INLINE amf_int32        ToInt32() const     { return Empty() ? 0            : GetValue<amf_int32,  AMF_VARIANT_INT64>(AMFVariantGetInt64); }
+        AMF_INLINE amf_uint32       ToUInt32() const    { return Empty() ? 0            : GetValue<amf_uint32, AMF_VARIANT_INT64>(AMFVariantGetInt64); }
+        AMF_INLINE amf_double       ToDouble() const    { return Empty() ? 0            : GetValue<amf_double, AMF_VARIANT_DOUBLE>(AMFVariantGetDouble); }
+        AMF_INLINE amf_float        ToFloat() const     { return Empty() ? 0            : GetValue<amf_float,  AMF_VARIANT_FLOAT>(AMFVariantGetFloat); }
+        AMF_INLINE AMFRect          ToRect () const     { return Empty() ? AMFRect()    : GetValue<AMFRect,  AMF_VARIANT_RECT>(AMFVariantGetRect); }
+        AMF_INLINE AMFSize          ToSize () const     { return Empty() ? AMFSize()    : GetValue<AMFSize,  AMF_VARIANT_SIZE>(AMFVariantGetSize); }
+        AMF_INLINE AMFPoint         ToPoint() const     { return Empty() ? AMFPoint()   : GetValue<AMFPoint, AMF_VARIANT_POINT>(AMFVariantGetPoint); }
+        AMF_INLINE AMFFloatSize     ToFloatSize() const { return Empty() ? AMFFloatSize() : GetValue<AMFFloatSize, AMF_VARIANT_FLOAT_SIZE>(AMFVariantGetFloatSize); }
+        AMF_INLINE AMFFloatPoint2D  ToFloatPoint2D() const { return Empty() ? AMFFloatPoint2D() : GetValue<AMFFloatPoint2D, AMF_VARIANT_FLOAT_POINT2D>(AMFVariantGetFloatPoint2D); }
+        AMF_INLINE AMFFloatPoint3D  ToFloatPoint3D() const { return Empty() ? AMFFloatPoint3D() : GetValue<AMFFloatPoint3D, AMF_VARIANT_FLOAT_POINT3D>(AMFVariantGetFloatPoint3D); }
+        AMF_INLINE AMFFloatVector4D ToFloatVector4D() const { return Empty() ? AMFFloatVector4D() : GetValue<AMFFloatVector4D, AMF_VARIANT_FLOAT_VECTOR4D>(AMFVariantGetFloatVector4D); }
+        AMF_INLINE AMFRate          ToRate () const     { return Empty() ? AMFRate()    : GetValue<AMFRate,  AMF_VARIANT_RATE>(AMFVariantGetRate); }
+        AMF_INLINE AMFRatio         ToRatio() const     { return Empty() ? AMFRatio()   : GetValue<AMFRatio, AMF_VARIANT_RATIO>(AMFVariantGetRatio); }
+        AMF_INLINE AMFColor         ToColor() const     { return Empty() ? AMFColor()   : GetValue<AMFColor, AMF_VARIANT_COLOR>(AMFVariantGetColor); }
+        AMF_INLINE AMFInterface*    ToInterface() const { return AMFVariantGetType(this) == AMF_VARIANT_INTERFACE ? this->pInterface : NULL; }
+        AMF_INLINE String           ToString() const;
+        AMF_INLINE WString          ToWString() const;
+
+        bool operator==(const AMFVariantStruct& other) const;
+        bool operator==(const AMFVariantStruct* pOther) const;
+
+        bool operator!=(const AMFVariantStruct& other) const;
+        bool operator!=(const AMFVariantStruct* pOther) const;
+
+        void Clear() { AMFVariantClear(this); }
+
+        void Attach(AMFVariantStruct& variant);
+        AMFVariantStruct Detach();
+
+        AMFVariantStruct& GetVariant();
+
+        void ChangeType(AMF_VARIANT_TYPE type, const AMFVariant* pSrc = NULL);
+
+        bool Empty() const;
+    private:
+        template<class ReturnType, AMF_VARIANT_TYPE variantType, typename Getter>
+        ReturnType GetValue(Getter getter) const;
+    };
+    //----------------------------------------------------------------------------------------------
+    // helper String class
+    //----------------------------------------------------------------------------------------------
+    class AMFVariant::String
+    {
+        friend class AMFVariant;
+    private:
+        void Free()
+        {
+            if (m_Str != NULL)
+            {
+                AMFVariantFreeString(m_Str);
+                m_Str = NULL;
+            }
+        }
+    public:
+        String() :m_Str(NULL){}
+        String(const char* str) : m_Str(NULL)
+        {
+            m_Str = AMFVariantDuplicateString(str);
+        }
+        String(const String& p_other) : m_Str(NULL)
+        {
+            operator=(p_other);
+        }
+
+#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600)
+        String(String&& p_other) : m_Str(NULL)
+        {
+            operator=(p_other);
+        }
+#endif
+        ~String()
+        {
+            Free();
+        }
+
+        char& operator[](size_t index)
+        {
+            if (index >= size())
+            {
+                resize(index);
+            }
+            return m_Str[index];
+        }
+
+        String& operator=(const String& p_other)
+        {
+            Free();
+            m_Str = AMFVariantDuplicateString(p_other.m_Str);
+            return *this;
+        }
+#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600)
+        String& operator=(String&& p_other)
+        {
+            Free();
+            m_Str = p_other.m_Str;
+            p_other.m_Str = NULL;    //    Transfer the ownership
+            return *this;
+        }
+#endif
+        bool operator==(const String& p_other) const
+        {
+            if (m_Str == NULL && p_other.m_Str == NULL)
+            {
+                return true;
+            }
+            else if ((m_Str == NULL && p_other.m_Str != NULL) || (m_Str != NULL && p_other.m_Str == NULL))
+            {
+                return false;
+            }
+            return strcmp(c_str(), p_other.c_str()) == 0;
+        }
+        const char* c_str() const { return m_Str; }
+        size_t size() const
+        {
+            if(m_Str == NULL)
+            {
+                return 0;
+            }
+            return (size_t)strlen(m_Str);
+        }
+
+        AMF_INLINE size_t length() const { return size(); }
+        
+        void resize(size_t sizeAlloc)
+        {
+            if(sizeAlloc == 0)
+            {
+                Free();
+                return;
+            }
+            char* str = (char*)amf_variant_alloc(sizeof(char)*(sizeAlloc + 1));
+            if(m_Str != NULL)
+            {
+                size_t copySize = sizeAlloc;
+                if(copySize > size())
+                {
+                    copySize = size();
+                }
+                memcpy(str, m_Str, copySize * sizeof(char));
+                Free();
+                str[sizeAlloc] = 0;
+            }
+            m_Str = str;
+        }
+    private:
+        char*    m_Str;
+    };
+    //----------------------------------------------------------------------------------------------
+    // helper WString class
+    //----------------------------------------------------------------------------------------------
+    class AMFVariant::WString
+    {
+        friend class AMFVariant;
+    private:
+        void Free()
+        {
+            if (m_Str != NULL)
+            {
+                AMFVariantFreeWString(m_Str);
+                m_Str = NULL;
+            }
+        }
+    public:
+        WString() :m_Str(NULL){}
+        WString(const wchar_t* str) : m_Str(NULL)
+        {
+            m_Str = AMFVariantDuplicateWString(str);
+        }
+        WString(const WString& p_other) : m_Str(NULL)
+        {
+            operator=(p_other);
+        }
+#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600)
+        WString(WString&& p_other) : m_Str(NULL)
+        {
+            operator=(p_other);
+        }
+#endif
+        ~WString()
+        {
+            Free();
+        }
+
+        WString& operator=(const WString& p_other)
+        {
+            Free();
+            m_Str = AMFVariantDuplicateWString(p_other.m_Str);
+            return *this;
+        }
+#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600)
+        WString& operator=(WString&& p_other)
+        {
+            Free();
+            m_Str = p_other.m_Str;
+            p_other.m_Str = NULL;    //    Transfer the ownership
+            return *this;
+        }
+#endif
+        wchar_t& operator[](size_t index)
+        {
+            if (index >= size())
+            {
+                resize(index);
+            }
+            return m_Str[index];
+        }
+
+        bool operator==(const WString& p_other) const
+        {
+            if (m_Str == NULL && p_other.m_Str == NULL)
+            {
+                return true;
+            }
+            else if ((m_Str == NULL && p_other.m_Str != NULL) || (m_Str != NULL && p_other.m_Str == NULL))
+            {
+                return false;
+            }
+            return wcscmp(c_str(), p_other.c_str()) == 0;
+        }
+
+        const wchar_t* c_str() const { return m_Str; }
+        size_t size()  const
+        {
+            if(m_Str == NULL)
+            {
+                return 0;
+            }
+            return (size_t)wcslen(m_Str);
+        }
+
+        AMF_INLINE size_t length() const { return size(); }
+        
+        void resize(size_t sizeAlloc)
+        {
+            if(sizeAlloc == 0)
+            {
+                Free();
+                return;
+            }
+            wchar_t* str = (wchar_t*)amf_variant_alloc(sizeof(wchar_t)*(sizeAlloc + 1));
+            if(m_Str != NULL)
+            {
+                size_t copySize = sizeAlloc;
+                if(copySize > size())
+                {
+                    copySize = size();
+                }
+                memcpy(str, m_Str, copySize * sizeof(wchar_t));
+                Free();
+                str[sizeAlloc] = 0;
+            }
+            m_Str = str;
+        }
+    private:
+        wchar_t*    m_Str;
+    };
+    //-------------------------------------------------------------------------------------------------
+    AMFVariant::String       AMFVariant::ToString() const
+    {
+        String temp = GetValue<String, AMF_VARIANT_STRING>(AMFVariantGetString); 
+        return String(temp.c_str());
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMFVariant::WString      AMFVariant::ToWString() const
+    {
+        WString temp = GetValue<WString, AMF_VARIANT_WSTRING>(AMFVariantGetWString);
+        return WString(temp.c_str());
+    }
+#endif // defined(__cplusplus)
+    //----------------------------------------------------------------------------------------------
+    // AMF_INLINE implementation of helper functions 
+    //----------------------------------------------------------------------------------------------
+    #define AMF_VARIANT_RETURN_IF_INVALID_POINTER(p) \
+       { \
+            if(p == NULL) \
+                    { \
+                 return AMF_INVALID_POINTER; \
+            } \
+       }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantInit(AMFVariantStruct* pVariant)
+    {
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pVariant);
+        pVariant->type = AMF_VARIANT_EMPTY;
+        return AMF_OK;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantClear(AMFVariantStruct* pVariant)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pVariant);
+
+        switch(AMFVariantGetType(pVariant))
+        {
+        case AMF_VARIANT_STRING:
+            amf_variant_free(AMFVariantString(pVariant));
+            pVariant->type = AMF_VARIANT_EMPTY;
+            break;
+
+        case AMF_VARIANT_WSTRING:
+            amf_variant_free(AMFVariantWString(pVariant));
+            pVariant->type = AMF_VARIANT_EMPTY;
+            break;
+
+        case AMF_VARIANT_INTERFACE:
+            if(AMFVariantInterface(pVariant) != NULL)
+            {
+#if defined(__cplusplus)
+                AMFVariantInterface(pVariant)->Release();
+#else
+                AMFVariantInterface(pVariant)->pVtbl->Release(AMFVariantInterface(pVariant));
+#endif
+                AMFVariantInterface(pVariant) = NULL;
+            }
+            pVariant->type = AMF_VARIANT_EMPTY;
+            break;
+
+        default:
+            pVariant->type = AMF_VARIANT_EMPTY;
+            break;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantCompare(const AMFVariantStruct* pFirst, const AMFVariantStruct* pSecond, amf_bool* bEqual)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pFirst);
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pSecond);
+    
+        if(pFirst == pSecond)
+        {
+            *bEqual = true;
+        }
+        else if(AMFVariantGetType(pFirst) != AMFVariantGetType(pSecond))
+        {
+            *bEqual = false;
+        }
+        else
+        {
+            switch(AMFVariantGetType(pFirst))
+            {
+            case AMF_VARIANT_EMPTY:
+                *bEqual = true;
+                break;
+            case AMF_VARIANT_BOOL:
+                *bEqual = AMFVariantGetBool(pFirst) == AMFVariantBool(pSecond);
+                break;
+            case AMF_VARIANT_INT64:
+                *bEqual = AMFVariantGetInt64(pFirst) == AMFVariantInt64(pSecond);
+                break;
+            case AMF_VARIANT_DOUBLE:
+                *bEqual = AMFVariantGetDouble(pFirst) == AMFVariantDouble(pSecond);
+                break;
+            case AMF_VARIANT_FLOAT:
+                *bEqual = AMFVariantGetFloat(pFirst) == AMFVariantFloat(pSecond);
+                break;
+            case AMF_VARIANT_RECT:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetRect(pFirst) == AMFVariantGetRect(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->rectValue, &pSecond->rectValue, sizeof(AMFRect)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_SIZE:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetSize(pFirst) == AMFVariantGetSize(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->sizeValue, &pSecond->sizeValue, sizeof(AMFSize)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_POINT:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetPoint(pFirst) == AMFVariantGetPoint(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->pointValue, &pSecond->pointValue, sizeof(AMFPoint)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_FLOAT_SIZE:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetFloatSize(pFirst) == AMFVariantGetFloatSize(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->floatSizeValue, &pSecond->floatSizeValue, sizeof(AMFFloatPoint2D)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_FLOAT_POINT2D:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetFloatPoint2D(pFirst) == AMFVariantGetFloatPoint2D(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->floatPoint2DValue, &pSecond->floatPoint2DValue, sizeof(AMFFloatPoint2D)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_FLOAT_POINT3D:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetFloatPoint3D(pFirst) == AMFVariantGetFloatPoint3D(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->floatPoint3DValue, &pSecond->floatPoint3DValue, sizeof(AMFFloatPoint3D)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_FLOAT_VECTOR4D:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetFloatVector4D(pFirst) == AMFVariantGetFloatVector4D(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->floatVector4DValue, &pSecond->floatVector4DValue, sizeof(AMFFloatPoint3D)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_RATE:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetRate(pFirst) == AMFVariantGetRate(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->rateValue, &pSecond->rateValue, sizeof(AMFRate)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_RATIO:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetRatio(pFirst) == AMFVariantGetRatio(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->ratioValue, &pSecond->ratioValue, sizeof(AMFRatio)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_COLOR:
+#if defined(__cplusplus)
+                *bEqual = AMFVariantGetColor(pFirst) == AMFVariantGetColor(pSecond);
+#else
+                *bEqual = memcmp(&pFirst->colorValue, &pSecond->colorValue, sizeof(AMFColor)) == 0;
+#endif
+                break;
+            case AMF_VARIANT_STRING:
+                *bEqual = strcmp(AMFVariantString(pFirst), AMFVariantString(pSecond)) == 0;
+                break;
+            case AMF_VARIANT_WSTRING:
+                *bEqual = wcscmp(AMFVariantWString(pFirst), AMFVariantWString(pSecond)) == 0;
+                break;
+            case AMF_VARIANT_INTERFACE:
+                *bEqual = AMFVariantInterface(pFirst) == AMFVariantInterface(pSecond);
+                break;
+            default:
+                errRet = AMF_INVALID_ARG;
+                break;
+            }
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantCopy(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pSrc);
+        if(pDest != pSrc)
+        {
+            switch(AMFVariantGetType(pSrc))
+            {
+            case AMF_VARIANT_EMPTY:
+                errRet = AMFVariantClear(pDest);
+                break;
+            case AMF_VARIANT_BOOL:
+                errRet = AMFVariantAssignBool(pDest, AMFVariantBool(pSrc));
+                break;
+            case AMF_VARIANT_INT64:
+                errRet = AMFVariantAssignInt64(pDest, AMFVariantInt64(pSrc));
+                break;
+            case AMF_VARIANT_DOUBLE:
+                errRet = AMFVariantAssignDouble(pDest, AMFVariantDouble(pSrc));
+                break;
+            case AMF_VARIANT_FLOAT:
+                errRet = AMFVariantAssignFloat(pDest, AMFVariantFloat(pSrc));
+                break;
+            case AMF_VARIANT_RECT:
+                errRet = AMFVariantAssignRect(pDest, &pSrc->rectValue);
+                break;
+            case AMF_VARIANT_SIZE:
+                errRet = AMFVariantAssignSize(pDest, &pSrc->sizeValue);
+                break;
+            case AMF_VARIANT_POINT:
+                errRet = AMFVariantAssignPoint(pDest, &pSrc->pointValue);
+                break;
+            case AMF_VARIANT_FLOAT_SIZE:
+                errRet = AMFVariantAssignFloatSize(pDest, &pSrc->floatSizeValue);
+                break;
+            case AMF_VARIANT_FLOAT_POINT2D:
+                errRet = AMFVariantAssignFloatPoint2D(pDest, &pSrc->floatPoint2DValue);
+                break;
+            case AMF_VARIANT_FLOAT_POINT3D:
+                errRet = AMFVariantAssignFloatPoint3D(pDest, &pSrc->floatPoint3DValue);
+                break;
+            case AMF_VARIANT_FLOAT_VECTOR4D:
+                errRet = AMFVariantAssignFloatVector4D(pDest, &pSrc->floatVector4DValue);
+                break;
+            case AMF_VARIANT_RATE:
+                errRet = AMFVariantAssignRate(pDest, &pSrc->rateValue);
+                break;
+            case AMF_VARIANT_RATIO:
+                errRet = AMFVariantAssignRatio(pDest, &pSrc->ratioValue);
+                break;
+            case AMF_VARIANT_COLOR:
+                errRet = AMFVariantAssignColor(pDest, &pSrc->colorValue);
+                break;
+            case AMF_VARIANT_STRING:
+                errRet = AMFVariantAssignString(pDest, AMFVariantString(pSrc));
+                break;
+            case AMF_VARIANT_WSTRING:
+                errRet = AMFVariantAssignWString(pDest, AMFVariantWString(pSrc));
+                break;
+            case AMF_VARIANT_INTERFACE:
+                errRet = AMFVariantAssignInterface(pDest, AMFVariantInterface(pSrc));
+                break;
+            default:
+                errRet = AMF_INVALID_ARG;
+                break;
+            }
+        }
+        return errRet;
+    }
+    #define AMFVariantTypeEmpty         AMF_VARIANT_EMPTY
+
+    #define AMFVariantTypeBool          AMF_VARIANT_BOOL
+    #define AMFVariantTypeInt64         AMF_VARIANT_INT64
+    #define AMFVariantTypeDouble        AMF_VARIANT_DOUBLE
+    #define AMFVariantTypeFloat         AMF_VARIANT_FLOAT
+
+    #define AMFVariantTypeRect          AMF_VARIANT_RECT
+    #define AMFVariantTypeSize          AMF_VARIANT_SIZE
+    #define AMFVariantTypePoint         AMF_VARIANT_POINT
+    #define AMFVariantTypeFloatPoint2D  AMF_VARIANT_FLOAT_POINT2D
+    #define AMFVariantTypeFloatPoint3D  AMF_VARIANT_FLOAT_POINT3D
+    #define AMFVariantTypeFloatVector4D AMF_VARIANT_FLOAT_VECTOR4D
+    
+    #define AMFVariantTypeRate          AMF_VARIANT_RATE
+    #define AMFVariantTypeRatio         AMF_VARIANT_RATIO
+    #define AMFVariantTypeColor         AMF_VARIANT_COLOR
+
+    #define AMFVariantTypeString        AMF_VARIANT_STRING
+    #define AMFVariantTypeWString       AMF_VARIANT_WSTRING
+    #define AMFVariantTypeInterface     AMF_VARIANT_INTERFACE
+
+#if defined(__cplusplus)
+    
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignString(AMFVariantStruct* pDest, const AMFVariant::String& value)
+    {
+        return AMFVariantAssignString(pDest, value.c_str());
+    }
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignWString(AMFVariantStruct* pDest, const AMFVariant::WString& value)
+    {
+        return AMFVariantAssignWString(pDest, value.c_str());
+    }
+        
+    static AMF_INLINE amf_bool AMFConvertEmptyToBool(void*, AMF_RESULT& res) { res = AMF_OK; return false; }
+    static AMF_INLINE amf_int64 AMFConvertEmptyToInt64(void*, AMF_RESULT& res) {res = AMF_OK; return 0; }
+    static AMF_INLINE amf_double AMFConvertEmptyToDouble(void*, AMF_RESULT& res) {res = AMF_OK; return 0; }
+    static AMF_INLINE amf_float AMFConvertEmptyToFloat(void*, AMF_RESULT& res) { res = AMF_OK; return 0; }
+
+    
+    static AMF_INLINE AMFVariant::String AMFConvertEmptyToString(void*, AMF_RESULT& res) {res = AMF_OK; return ""; }
+    static AMF_INLINE AMFVariant::WString AMFConvertEmptyToWString(void*, AMF_RESULT& res) {res = AMF_OK; return L""; }
+    static AMF_INLINE amf_int64 AMFConvertBoolToInt64(bool value, AMF_RESULT& res){res = AMF_OK; return value ? 1 : 0;}
+    static AMF_INLINE amf_double AMFConvertBoolToDouble(bool value, AMF_RESULT& res){res = AMF_OK; return value ? 1.0 : 0.0;}
+    static AMF_INLINE amf_float AMFConvertBoolToFloat(bool value, AMF_RESULT& res) { res = AMF_OK; return value ? 1.0f : 0.0f; }
+    static AMF_INLINE AMFVariant::String AMFConvertBoolToString(bool value, AMF_RESULT& res){res = AMF_OK; return value ? "true" : "false";}
+    static AMF_INLINE AMFVariant::WString AMFConvertBoolToWString(bool value, AMF_RESULT& res){res = AMF_OK; return value ? L"true" : L"false";}
+    static AMF_INLINE bool AMFConvertInt64ToBool(amf_int64 value, AMF_RESULT& res){res = AMF_OK;return value != 0;}
+    static AMF_INLINE amf_double AMFConvertInt64ToDouble(amf_int64 value, AMF_RESULT& res){res = AMF_OK;return (amf_double)value;}
+    static AMF_INLINE amf_float AMFConvertInt64ToFloat(amf_int64 value, AMF_RESULT& res) { res = AMF_OK; return (amf_float)value; }
+    static AMF_INLINE AMFVariant::String AMFConvertInt64ToString(amf_int64 value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%" AMFPRId64, (long long)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);
+        return buff;
+    }
+
+    static AMF_INLINE bool AMFConvertDoubleToBool(amf_double value, AMF_RESULT& res){res = AMF_OK;return value != 0;}
+    static AMF_INLINE bool AMFConvertFloatToBool(amf_float value, AMF_RESULT& res) { res = AMF_OK; return value != 0; }
+    static AMF_INLINE amf_int64 AMFConvertDoubleToInt64(amf_double value, AMF_RESULT& res){res = AMF_OK;return amf_int64(value);}
+    static AMF_INLINE amf_int64 AMFConvertFloatToInt64(amf_float value, AMF_RESULT& res) { res = AMF_OK; return amf_int64(value); }
+    static AMF_INLINE AMFVariant::String AMFConvertDoubleToString(amf_double value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%lf", value);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMFConvertFloatToString(amf_float value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%f", value);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::WString AMFConvertDoubleToWString(amf_double value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        wchar_t buff[0xFF];
+        swprintf(buff, 0xFF, L"%lf", value);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::WString AMFConvertFloatToWString(amf_float value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        wchar_t buff[0xFF];
+        swprintf(buff, 0xFF, L"%f", value);
+        return buff;
+    }
+
+    static AMF_INLINE bool AMFConvertStringToBool(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFVariant::String tmp = value;
+        if(( tmp == "true") || ( tmp == "True") || ( tmp == "TRUE") || ( tmp == "1") )
+        {
+            return true;
+        }
+        else
+        {
+            if(( tmp == "false") || ( tmp == "False") || ( tmp == "FALSE") || ( tmp == "0") )
+            {
+                return false;
+            }
+        }
+        res = AMF_INVALID_ARG;
+        return false;
+    }
+
+    static AMF_INLINE amf_int64 AMFConvertStringToInt64(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        long long tmp = 0;
+        int readElements = 0;
+
+        if(value.size() > 2 && ( value.c_str()[0] == '0') && ( value.c_str()[1] == 'x') )
+        {
+            readElements = sscanf(value.c_str(), "0x%" AMFPRIx64, &tmp);
+        }
+        else if(value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%" AMFPRId64, &tmp);
+        }
+        if(readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return 0;
+    }
+
+    static AMF_INLINE amf_double AMFConvertStringToDouble(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        amf_double tmp = 0;
+        int readElements = 0;
+        if(value.size() > 0)
+        { 
+            readElements = sscanf(value.c_str(), "%lf", &tmp);
+        }
+        if(readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return 0;
+    }
+    static AMF_INLINE amf_float AMFConvertStringToFloat(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        amf_float tmp = 0;
+        int readElements = 0;
+        if (value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%f", &tmp);
+        }
+        if (readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return 0;
+    }
+
+    static AMF_INLINE AMFVariant::WString AMFConvertStringToWString(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+//        return amf_from_utf8_to_unicode(value);
+        AMFVariant::WString result;
+        if(0 == value.size())
+        {
+            return result;
+        }
+        const char* pUtf8Buff = value.c_str();
+
+#if defined(_WIN32)
+        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
+        int UnicodeBuffSize = ::MultiByteToWideChar(CP_UTF8, 0, pUtf8Buff, -1, NULL, 0);
+        if(0 == UnicodeBuffSize)
+        {
+            return result;
+        }
+        UnicodeBuffSize += 8; // get some extra space
+        result.resize(UnicodeBuffSize);
+        UnicodeBuffSize = ::MultiByteToWideChar(CP_UTF8, 0, pUtf8Buff, -1, (LPWSTR)result.c_str(), UnicodeBuffSize);
+        UnicodeBuffSize--;
+
+#elif defined(__ANDROID__)
+        // on android mbstowcs cannot be used to define length
+        char* old_locale = setlocale(LC_CTYPE, "en_US.UTF8");
+
+        mbstate_t mbs;
+        mbrlen(NULL, 0, &mbs);
+        int len = value.size();
+        const char* pt = pUtf8Buff;
+        int UnicodeBuffSize = 0;
+        while(len > 0)
+        {
+            size_t length = mbrlen (pt, len, &mbs); //MM TODO Android always return 1
+            if((length == 0) || (length > len))
+            {
+                break;
+            }
+            UnicodeBuffSize++;
+            len -= length;
+            pt += length;
+        }
+        UnicodeBuffSize += 8; // get some extra space
+        result.resize(UnicodeBuffSize);
+
+        mbrlen (NULL, 0, &mbs);
+        len = value.size();
+        pt = pUtf8Buff;
+        UnicodeBuffSize = 0;
+        while(len > 0)                            
+        {
+            size_t length = mbrlen (pt, len, &mbs);
+            if((length == 0) || (length > len))
+            {
+                break;
+            }
+            mbrtowc(&((wchar_t*)(result.c_str()))[UnicodeBuffSize], pt, length, &mbs);     //MM TODO Android always return 1 char
+            UnicodeBuffSize++;
+            len -= length;
+            pt += length;
+        }
+        setlocale(LC_CTYPE, old_locale);
+
+ #else
+        char* old_locale = setlocale(LC_CTYPE, "en_US.UTF8");
+        size_t UnicodeBuffSize = mbstowcs(NULL, pUtf8Buff, 0);
+        if(0 == UnicodeBuffSize)
+        {
+            return result;
+        }
+        UnicodeBuffSize += 8; // get some extra space
+        result.resize(UnicodeBuffSize);
+        UnicodeBuffSize = mbstowcs((wchar_t*)result.c_str(), pUtf8Buff, UnicodeBuffSize + 1);
+        setlocale(LC_CTYPE, old_locale);
+#endif
+        result.resize(UnicodeBuffSize);
+        return result;
+    }
+    static AMF_INLINE AMFVariant::String AMFConvertWStringToString(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+//      return amf_from_unicode_to_utf8(value);
+        AMFVariant::String result;
+        if(0 == value.size())
+        {
+            return result;
+        }
+
+        const wchar_t* pwBuff = value.c_str();
+
+#if defined(_WIN32)
+        _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
+        int Utf8BuffSize = ::WideCharToMultiByte(CP_UTF8, 0, pwBuff, -1, NULL, 0, NULL, NULL);
+        if(0 == Utf8BuffSize)
+        {
+            return result;
+        }
+        Utf8BuffSize += 8; // get some extra space
+        result.resize(Utf8BuffSize);
+        Utf8BuffSize = ::WideCharToMultiByte(CP_UTF8, 0, pwBuff, -1, (LPSTR)result.c_str(), Utf8BuffSize, NULL, NULL);
+        Utf8BuffSize--;
+#elif defined(__ANDROID__)
+        char* old_locale = setlocale(LC_CTYPE, "en_US.UTF8");
+        int Utf8BuffSize = value.length();
+        if(0 == Utf8BuffSize)
+        {
+            return result;
+        }
+        Utf8BuffSize += 8; // get some extra space
+        result.resize(Utf8BuffSize);
+
+        mbstate_t mbs;
+        mbrlen(NULL, 0, &mbs);
+
+        Utf8BuffSize = 0;
+        for( int i = 0; i < value.length(); i++)
+        {
+            //MM TODO Android - not implemented
+            //int written = wcrtomb(&result[Utf8BuffSize], pwBuff[i], &mbs);
+            ((char*)(result.c_str()))[Utf8BuffSize] = (char)(pwBuff[i]);
+            int written = 1;
+            // temp replacement
+            Utf8BuffSize += written;
+        }
+        setlocale(LC_CTYPE, old_locale);
+
+#else
+        char* old_locale = setlocale(LC_CTYPE, "en_US.UTF8");
+        size_t Utf8BuffSize = wcstombs(NULL, pwBuff, 0);
+        if(0 == Utf8BuffSize)
+        {
+            return result;
+        }
+        Utf8BuffSize += 8; // get some extra space
+        result.resize(Utf8BuffSize);
+        Utf8BuffSize = wcstombs((char*)result.c_str(), pwBuff, Utf8BuffSize + 1);
+
+        setlocale(LC_CTYPE, old_locale);
+#endif
+        result.resize(Utf8BuffSize);
+        return result;
+    }
+
+
+    static AMF_INLINE bool AMFConvertWStringToBool(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToBool(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE amf_int64 AMFConvertWStringToInt64(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToInt64(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE amf_double AMFConvertWStringToDouble(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToDouble(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE amf_float AMFConvertWStringToFloat(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToFloat(AMFConvertWStringToString(value, res), res);
+    }
+
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRectToString(const AMFRect& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%d,%d,%d,%d", value.left, value.top, value.right, value.bottom);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertSizeToString(const AMFSize& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%d,%d", value.width, value.height);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertPointToString(const AMFPoint& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%d,%d", value.x, value.y);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertFloatSizeToString(const AMFFloatSize& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%f,%f", value.width, value.height);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertFloatPoint2DToString(const AMFFloatPoint2D& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%f,%f", value.x, value.y);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertFloatPoint3DToString(const AMFFloatPoint3D& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%f,%f,%f", value.x, value.y, value.z);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertFloatVector4DToString(const AMFFloatVector4D& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%f,%f,%f,%f", value.x, value.y, value.z, value.w);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRateToString(const AMFRate& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%d,%d", value.num, value.den);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRatioToString(const AMFRatio& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%d,%d", value.num, value.den);
+        return buff;
+    }
+    static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertColorToString(const AMFColor& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        char buff[0xFF];
+        sprintf(buff, "%d,%d,%d,%d", value.r, value.g, value.b, value.a);
+        return buff;
+    }
+
+    static AMF_INLINE AMFRect  AMF_STD_CALL AMFConvertStringToRect(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFRect tmp = {};
+        int readElements = 0;
+        if(value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%d,%d,%d,%d", &tmp.left, &tmp.top, &tmp.right, &tmp.bottom);
+        }
+        if(readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+
+    static AMF_INLINE AMFSize  AMF_STD_CALL AMFConvertStringToSize(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFSize tmp = {};
+        int readElements = 0;
+        if(value.size() > 0)
+        {
+          if(strchr(value.c_str(), ',') != nullptr)
+          {
+            readElements = sscanf(value.c_str(), "%d,%d", &tmp.width, &tmp.height);
+          } 
+          else if (strchr(value.c_str(), 'x') != nullptr) 
+          {
+            readElements = sscanf(value.c_str(), "%dx%d", &tmp.width, &tmp.height);
+          }
+        }
+        if(readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+    static AMF_INLINE AMFPoint AMF_STD_CALL AMFConvertStringToPoint(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFPoint tmp = {};
+        int readElements = 0;
+        if(value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%d,%d", &tmp.x, &tmp.y);
+        }
+        if(readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+    static AMF_INLINE AMFFloatSize AMF_STD_CALL AMFConvertStringToFloatSize(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFFloatSize tmp = {};
+        int readElements = 0;
+        if (value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%f,%f", &tmp.width, &tmp.height);
+        }
+        if (readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+    static AMF_INLINE AMFFloatPoint2D AMF_STD_CALL AMFConvertStringToFloatPoint2D(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFFloatPoint2D tmp = {};
+        int readElements = 0;
+        if (value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%f,%f", &tmp.x, &tmp.y);
+        }
+        if (readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+    static AMF_INLINE AMFFloatPoint3D AMF_STD_CALL AMFConvertStringToFloatPoint3D(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFFloatPoint3D tmp = {};
+        int readElements = 0;
+        if (value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%f,%f,%f", &tmp.x, &tmp.y, &tmp.z);
+        }
+        if (readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+    static AMF_INLINE AMFFloatVector4D AMF_STD_CALL AMFConvertStringToFloatVector4D(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFFloatVector4D tmp = {};
+        int readElements = 0;
+        if (value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%f,%f,%f,%f", &tmp.x, &tmp.y, &tmp.z, &tmp.w);
+        }
+        if (readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+    static AMF_INLINE AMFRate  AMF_STD_CALL AMFConvertStringToRate(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFRate tmp = {};
+        int readElements = 0;
+        if(value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%d,%d", &tmp.num, &tmp.den);
+        }
+        if(readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+    static AMF_INLINE AMFRatio AMF_STD_CALL AMFConvertStringToRatio(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        AMFRatio tmp = {};
+        int readElements = 0;
+        if(value.size() > 0)
+        {
+            readElements = sscanf(value.c_str(), "%d,%d", &tmp.num, &tmp.den);
+        }
+        if(readElements)
+        {
+            return tmp;
+        }
+        res = AMF_INVALID_ARG;
+        return tmp;
+    }
+    static AMF_INLINE AMFColor AMF_STD_CALL AMFConvertStringToColor(const AMFVariant::String& value, AMF_RESULT& res)
+    {
+        res = AMF_OK;
+        int readElements = 0;
+        amf_uint32 r = 0;
+        amf_uint32 g = 0;
+        amf_uint32 b = 0;
+        amf_uint32 a = 0;
+        if(value.size() > 0)
+        { 
+            readElements = sscanf(value.c_str(), "%u,%u,%u,%u", &r, &g, &b, &a);
+        }
+        if(readElements)
+        {
+            return AMFConstructColor((amf_uint8)r, (amf_uint8)g, (amf_uint8)b, (amf_uint8)a);
+        }
+        res = AMF_INVALID_ARG;
+        return AMFConstructColor(0, 0, 0, 255);
+    }
+///////////////////////
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRectToWString(const AMFRect& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertRectToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertSizeToWString(const AMFSize& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertSizeToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertPointToWString(const AMFPoint& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertPointToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertFloatSizeToWString(const AMFFloatSize& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertFloatSizeToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertFloatPoint2DToWString(const AMFFloatPoint2D& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertFloatPoint2DToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertFloatPoint3DToWString(const AMFFloatPoint3D& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertFloatPoint3DToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertFloatVector4DToWString(const AMFFloatVector4D& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertFloatVector4DToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRateToWString(const AMFRate& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertRateToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRatioToWString(const AMFRatio& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertRatioToString(value, res), res);
+    }
+    static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertColorToWString(const AMFColor& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToWString(AMFConvertColorToString(value, res), res);
+    }
+
+    static AMF_INLINE AMFRect  AMF_STD_CALL AMFConvertWStringToRect(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToRect(AMFConvertWStringToString(value, res), res);
+    }
+
+    static AMF_INLINE AMFSize  AMF_STD_CALL AMFConvertWStringToSize(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToSize(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE AMFPoint AMF_STD_CALL AMFConvertWStringToPoint(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToPoint(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE AMFFloatSize AMF_STD_CALL AMFConvertWStringToFloatSize(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToFloatSize(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE AMFFloatPoint2D AMF_STD_CALL AMFConvertWStringToFloatPoint2D(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToFloatPoint2D(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE AMFFloatPoint3D AMF_STD_CALL AMFConvertWStringToFloatPoint3D(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToFloatPoint3D(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE AMFFloatVector4D AMF_STD_CALL AMFConvertWStringToFloatVector4D(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToFloatVector4D(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE AMFRate  AMF_STD_CALL AMFConvertWStringToRate(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToRate(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE AMFRatio AMF_STD_CALL AMFConvertWStringToRatio(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToRatio(AMFConvertWStringToString(value, res), res);
+    }
+    static AMF_INLINE AMFColor AMF_STD_CALL AMFConvertWStringToColor(const AMFVariant::WString& value, AMF_RESULT& res)
+    {
+        return AMFConvertStringToColor(AMFConvertWStringToString(value, res), res);
+    }
+
+    //-------------------------------------------------------------------------------------------------
+    #define AMFConvertTool(srcType, dstType)\
+        if(AMFVariantGetType(pSrc) == AMFVariantType##srcType && newType == AMFVariantType##dstType)\
+        {\
+            AMF_RESULT res = AMF_OK;\
+            AMFVariantAssign##dstType(pDest, AMFConvert##srcType##To##dstType(AMFVariant##srcType(pSrc), res));\
+            return res;\
+        }\
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantChangeType(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc, AMF_VARIANT_TYPE newType)
+    {
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        if(pSrc == 0)
+        {
+            pSrc = pDest;
+        }
+
+        if(AMFVariantGetType(pSrc) == newType)
+        {
+            if(pDest == pSrc)
+            {
+                return AMF_OK;
+            }
+            return AMFVariantCopy(pDest, pSrc);
+        }
+        AMFVariantClear(pDest);
+
+        AMFConvertTool(Empty, Bool);
+        AMFConvertTool(Empty, Int64);
+        AMFConvertTool(Empty, Double);
+        AMFConvertTool(Empty, Float);
+        AMFConvertTool(Empty, String);
+        AMFConvertTool(Empty, WString);
+
+        AMFConvertTool(Bool, Int64);
+        AMFConvertTool(Bool, Double);
+        AMFConvertTool(Bool, Float);
+        AMFConvertTool(Bool, String);
+        AMFConvertTool(Bool, WString);
+
+        AMFConvertTool(Int64, Bool);
+        AMFConvertTool(Int64, Double);
+        AMFConvertTool(Int64, Float);
+        AMFConvertTool(Int64, String);
+        AMFConvertTool(Int64, WString);
+
+        AMFConvertTool(Double, Bool);
+        AMFConvertTool(Double, Int64);
+        AMFConvertTool(Double, String);
+        AMFConvertTool(Double, String);
+
+        AMFConvertTool(Float, Bool);
+        AMFConvertTool(Float, Int64);
+        AMFConvertTool(Float, String);
+        AMFConvertTool(Float, String);
+
+        AMFConvertTool(String, Bool);
+        AMFConvertTool(String, Int64);
+        AMFConvertTool(String, Double);
+        AMFConvertTool(String, Float);
+        AMFConvertTool(String, WString);
+
+        AMFConvertTool(WString, Bool);
+        AMFConvertTool(WString, Int64);
+        AMFConvertTool(WString, Double);
+        AMFConvertTool(WString, Float);
+        AMFConvertTool(WString, String);
+
+        AMFConvertTool(String, Rect);
+        AMFConvertTool(String, Size);
+        AMFConvertTool(String, Point);
+        AMFConvertTool(String, Rate);
+        AMFConvertTool(String, Ratio);
+        AMFConvertTool(String, Color);
+
+        AMFConvertTool(Rect , String);
+        AMFConvertTool(Size , String);
+        AMFConvertTool(Point, String);
+        AMFConvertTool(Rate , String);
+        AMFConvertTool(Ratio, String);
+        AMFConvertTool(Color, String);
+
+        AMFConvertTool(WString, Rect);
+        AMFConvertTool(WString, Size);
+        AMFConvertTool(WString, Point);
+        AMFConvertTool(WString, Rate);
+        AMFConvertTool(WString, Ratio);
+        AMFConvertTool(WString, Color);
+
+        AMFConvertTool(Rect , WString);
+        AMFConvertTool(Size , WString);
+        AMFConvertTool(Point, WString);
+        AMFConvertTool(Rate , WString);
+        AMFConvertTool(Ratio, WString);
+        AMFConvertTool(Color, WString);
+
+        return AMF_INVALID_ARG;
+    }
+#endif // #if defined(__cplusplus)
+
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignBool(AMFVariantStruct* pDest, amf_bool value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_BOOL;
+            AMFVariantBool(pDest) = value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignInt64(AMFVariantStruct* pDest, amf_int64 value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_INT64;
+            AMFVariantInt64(pDest) = value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignDouble(AMFVariantStruct* pDest, amf_double value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_DOUBLE;
+            AMFVariantDouble(pDest) = value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloat(AMFVariantStruct* pDest, amf_float value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if (errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_FLOAT;
+            AMFVariantFloat(pDest) = value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignString(AMFVariantStruct* pDest, const char* pValue)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pValue);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            const size_t size = (strlen(pValue) + 1);
+            pDest->type = AMF_VARIANT_STRING;
+            AMFVariantString(pDest) = (char*)amf_variant_alloc(size * sizeof(char));
+            if(AMFVariantString(pDest))
+            {
+                memcpy(AMFVariantString(pDest), pValue, size * sizeof(char));
+            }
+            else
+            {
+                errRet = AMF_OUT_OF_MEMORY;
+            }
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignWString(AMFVariantStruct* pDest, const wchar_t* pValue)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pValue);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            const size_t size = (wcslen(pValue) + 1);
+            pDest->type = AMF_VARIANT_WSTRING;
+            AMFVariantWString(pDest) = (wchar_t*)amf_variant_alloc(size * sizeof(wchar_t));
+            if(AMFVariantWString(pDest))
+            {
+                memcpy(AMFVariantWString(pDest), pValue, size * sizeof(wchar_t));
+            }
+            else
+            {
+                errRet = AMF_OUT_OF_MEMORY;
+            }
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignInterface(AMFVariantStruct* pDest, AMFInterface* pValue)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+        //AMF_VARIANT_RETURN_IF_INVALID_POINTER(pValue);//can be NULL
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_INTERFACE;
+            AMFVariantInterface(pDest) = pValue;
+            if(AMFVariantInterface(pDest))
+            {
+#if defined(__cplusplus)
+                AMFVariantInterface(pDest)->Acquire();
+#else
+                AMFVariantInterface(pDest)->pVtbl->Acquire(AMFVariantInterface(pDest));
+#endif
+            }
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRect(AMFVariantStruct* pDest, const AMFRect& value)
+    {
+        return AMFVariantAssignRect(pDest, &value);
+    }
+#endif
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRect (AMFVariantStruct* pDest, const AMFRect* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_RECT;
+            AMFVariantRect(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignSize (AMFVariantStruct* pDest, const AMFSize& value)
+    {
+        return AMFVariantAssignSize (pDest, &value);
+    }
+#endif
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignSize (AMFVariantStruct* pDest, const AMFSize* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_SIZE;
+            AMFVariantSize(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint& value)
+    {
+        return AMFVariantAssignPoint(pDest, &value);
+    }
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloatSize(AMFVariantStruct* pDest, const AMFFloatSize& value)
+    {
+        return AMFVariantAssignFloatSize(pDest, &value);
+    }
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloatPoint2D(AMFVariantStruct* pDest, const AMFFloatPoint2D& value)
+    {
+        return AMFVariantAssignFloatPoint2D(pDest, &value);
+    }
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloatPoint3D(AMFVariantStruct* pDest, const AMFFloatPoint3D& value)
+    {
+        return AMFVariantAssignFloatPoint3D(pDest, &value);
+    }
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloatVector4D(AMFVariantStruct* pDest, const AMFFloatVector4D& value)
+    {
+        return AMFVariantAssignFloatVector4D(pDest, &value);
+    }
+#endif
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_POINT;
+            AMFVariantPoint(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloatSize(AMFVariantStruct* pDest, const AMFFloatSize* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if (errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_FLOAT_SIZE;
+            AMFVariantFloatSize(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloatPoint2D(AMFVariantStruct* pDest, const AMFFloatPoint2D* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if (errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_FLOAT_POINT2D;
+            AMFVariantFloatPoint2D(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloatPoint3D(AMFVariantStruct* pDest, const AMFFloatPoint3D* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if (errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_FLOAT_POINT3D;
+            AMFVariantFloatPoint3D(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignFloatVector4D(AMFVariantStruct* pDest, const AMFFloatVector4D* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if (errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_FLOAT_VECTOR4D;
+            AMFVariantFloatVector4D(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRate (AMFVariantStruct* pDest, const AMFRate& value)
+    {
+        return AMFVariantAssignRate (pDest, &value);
+    }
+#endif
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRate (AMFVariantStruct* pDest, const AMFRate* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_RATE;
+            AMFVariantRate(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio& value)
+    {
+        return AMFVariantAssignRatio(pDest, &value);
+    }
+#endif
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_RATIO;
+            AMFVariantRatio(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor& value)
+    {
+        return AMFVariantAssignColor(pDest, &value);
+    }
+#endif
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor* value)
+    {
+        AMF_RESULT errRet = AMF_OK;
+        AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
+
+        errRet = AMFVariantClear(pDest);
+        if(errRet == AMF_OK)
+        {
+            pDest->type = AMF_VARIANT_COLOR;
+            AMFVariantColor(pDest) = *value;
+        }
+        return errRet;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE char* AMF_CDECL_CALL AMFVariantDuplicateString(const char* from)
+    {
+        char* ret = 0;
+        if(from)
+        {
+            ret = (char*)amf_variant_alloc(sizeof(char)*(strlen(from) + 1));
+            if(ret)
+            {
+                strcpy(ret, from);
+            }
+        }
+        return ret;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE void AMF_CDECL_CALL AMFVariantFreeString(char* from)
+    {
+        amf_variant_free(from);
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE wchar_t* AMF_CDECL_CALL AMFVariantDuplicateWString(const wchar_t* from)
+    {
+        wchar_t* ret = 0;
+        if(from)
+        {
+            ret = (wchar_t*)amf_variant_alloc(sizeof(wchar_t)*(wcslen(from) + 1));
+            if(ret)
+            {
+                wcscpy(ret, from);
+            }
+        }
+        return ret;
+    }
+    //-------------------------------------------------------------------------------------------------
+    static AMF_INLINE void AMF_CDECL_CALL AMFVariantFreeWString(wchar_t* from)
+    {
+        amf_variant_free(from);
+    }
+    //----------------------------------------------------------------------------------------------
+    // AMF_INLINE implementation of AMFVariant class
+    //----------------------------------------------------------------------------------------------
+#if defined(__cplusplus)
+    AMF_INLINE AMFVariant::AMFVariant(const AMFVariantStruct* pOther)
+    {
+        AMFVariantInit(this);
+        if(pOther != NULL)
+        {
+            AMFVariantCopy(this, const_cast<AMFVariantStruct*>(pOther));
+        }
+    }
+    //-------------------------------------------------------------------------------------------------
+    template<typename T>
+    AMFVariant::AMFVariant(const AMFInterfacePtr_T<T>& pValue)
+    {
+        AMFVariantInit(this);
+        AMFVariantAssignInterface(this, pValue);
+    }
+    //-------------------------------------------------------------------------------------------------
+    template<class ReturnType, AMF_VARIANT_TYPE variantType, typename Getter>
+    ReturnType AMFVariant::GetValue(Getter getter) const
+    {
+        ReturnType str = ReturnType();
+        if(AMFVariantGetType(this) == variantType)
+        {
+            str = static_cast<ReturnType>(getter(this));
+        }
+        else
+        {
+            AMFVariant varDest;
+            varDest.ChangeType(variantType, this);
+            if(varDest.type != AMF_VARIANT_EMPTY)
+            {
+                str = static_cast<ReturnType>(getter(&varDest));
+            }
+        }
+        return str;
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariantStruct& other)
+    {
+        AMFVariantCopy(this, const_cast<AMFVariantStruct*>(&other));
+        return *this;
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariantStruct* pOther)
+    {
+        if(pOther != NULL)
+        {
+            AMFVariantCopy(this, const_cast<AMFVariantStruct*>(pOther));
+        }
+        return *this;
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariant& other)
+    {
+        AMFVariantCopy(this,
+                const_cast<AMFVariantStruct*>(static_cast<const AMFVariantStruct*>(&other)));
+        return *this;
+    }
+    //-------------------------------------------------------------------------------------------------
+    template<typename T>
+    AMFVariant& AMFVariant::operator=(const AMFInterfacePtr_T<T>& value)
+    {
+        AMFVariantAssignInterface(this, value);
+        return *this;
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE bool AMFVariant::operator==(const AMFVariantStruct& other) const
+    {
+        return *this == &other;
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE bool AMFVariant::operator==(const AMFVariantStruct* pOther) const
+    {
+        //TODO: double check
+        amf_bool ret = false;
+        if(pOther == NULL)
+        {
+            ret = false;
+        }
+        else
+        {
+            AMFVariantCompare(this, pOther, &ret);
+        }
+        return ret;
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE bool AMFVariant::operator!=(const AMFVariantStruct& other) const
+    {
+        return !(*this == &other);
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE bool AMFVariant::operator!=(const AMFVariantStruct* pOther) const
+    {
+        return !(*this == pOther);
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE void AMFVariant::Attach(AMFVariantStruct& variant)
+    {
+        Clear();
+        memcpy(this, &variant, sizeof(variant));
+        AMFVariantGetType(&variant) = AMF_VARIANT_EMPTY;
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE AMFVariantStruct AMFVariant::Detach()
+    {
+        AMFVariantStruct varResult = *this;
+        AMFVariantGetType(this) = AMF_VARIANT_EMPTY;
+        return varResult;
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE AMFVariantStruct& AMFVariant::GetVariant()
+    {
+        return *static_cast<AMFVariantStruct*>(this);
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE void AMFVariant::ChangeType(AMF_VARIANT_TYPE newType, const AMFVariant* pSrc)
+    {
+        AMFVariantChangeType(this, pSrc, newType);
+    }
+    //-------------------------------------------------------------------------------------------------
+    AMF_INLINE bool AMFVariant::Empty() const
+    {
+        return type == AMF_VARIANT_EMPTY;
+    }
+    //-------------------------------------------------------------------------------------------------
+#endif // #if defined(__cplusplus)
+
+#if defined(__cplusplus)
+} //namespace amf
+#endif
+
+#endif //#ifndef AMF_Variant_h

+ 59 - 0
plugins/obs-ffmpeg/external/AMF/include/core/Version.h

@@ -0,0 +1,59 @@
+// 
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+// 
+// MIT license 
+// 
+// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+/**
+***************************************************************************************************
+* @file  Version.h
+* @brief Version declaration
+***************************************************************************************************
+*/
+#ifndef AMF_Version_h
+#define AMF_Version_h
+#pragma once
+
+#include "Platform.h"
+
+#define AMF_MAKE_FULL_VERSION(VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE, VERSION_BUILD_NUM)    ( ((amf_uint64)(VERSION_MAJOR) << 48ull) | ((amf_uint64)(VERSION_MINOR) << 32ull) | ((amf_uint64)(VERSION_RELEASE) << 16ull)  | (amf_uint64)(VERSION_BUILD_NUM))
+
+#define AMF_GET_MAJOR_VERSION(x)      ((x >> 48ull) & 0xFFFF)
+#define AMF_GET_MINOR_VERSION(x)      ((x >> 32ull) & 0xFFFF)
+#define AMF_GET_SUBMINOR_VERSION(x)   ((x >> 16ull) & 0xFFFF)
+#define AMF_GET_BUILD_VERSION(x)      ((x >>  0ull) & 0xFFFF)
+
+#define AMF_VERSION_MAJOR       1
+#define AMF_VERSION_MINOR       4
+#define AMF_VERSION_RELEASE     24
+#define AMF_VERSION_BUILD_NUM   0
+
+#define AMF_FULL_VERSION AMF_MAKE_FULL_VERSION(AMF_VERSION_MAJOR, AMF_VERSION_MINOR, AMF_VERSION_RELEASE, AMF_VERSION_BUILD_NUM)
+
+#endif //#ifndef AMF_Version_h

+ 108 - 0
plugins/obs-ffmpeg/external/AMF/include/core/VulkanAMF.h

@@ -0,0 +1,108 @@
+//
+// Notice Regarding Standards.  AMD does not provide a license or sublicense to
+// any Intellectual Property Rights relating to any standards, including but not
+// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4;
+// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3
+// (collectively, the "Media Technologies"). For clarity, you will pay any
+// royalties due for such third party technologies, which may include the Media
+// Technologies that are owed as a result of AMD providing the Software to you.
+//
+// MIT license
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#ifndef __VulkanAMF_h__
+#define __VulkanAMF_h__
+#pragma once
+#include "Platform.h"
+
+#include "vulkan/vulkan.h"
+
+#if defined(__cplusplus)
+namespace amf
+{
+#endif
+    typedef struct AMFVulkanDevice
+    {
+        amf_size            cbSizeof;           // sizeof(AMFVulkanDevice)
+        void*               pNext;              // reserved for extensions
+        VkInstance          hInstance;
+        VkPhysicalDevice    hPhysicalDevice;
+        VkDevice            hDevice;
+    } AMFVulkanDevice;
+
+    typedef struct AMFVulkanSync
+    {
+        amf_size            cbSizeof;           // sizeof(AMFVulkanSemaphore)
+        void*               pNext;              // reserved for extensions
+        VkSemaphore         hSemaphore;
+        bool                bSubmitted;         // if true - wait for hSemaphore. re-submit hSemaphore if not synced by other ways and set to true
+        VkFence             hFence;             // To sync on CPU; can be nullptr. Submitted in vkQueueSubmit. If waited for hFence, null it, do not delete or reset.
+    } AMFVulkanSync;
+
+    typedef struct AMFVulkanBuffer
+    {
+        amf_size            cbSizeof;           // sizeof(AMFVulkanBuffer)
+        void*               pNext;              // reserved for extensions
+        VkBuffer            hBuffer;
+        VkDeviceMemory      hMemory;
+        amf_int64           iSize;
+        amf_int64           iAllocatedSize;     // for reuse
+        amf_uint32          eAccessFlags;       // VkAccessFlagBits
+        amf_uint32          eUsage;             // AMF_BUFFER_USAGE
+        amf_uint32          eAccess;            // AMF_MEMORY_CPU_ACCESS
+        AMFVulkanSync       Sync;
+    } AMFVulkanBuffer;
+
+    typedef struct AMFVulkanSurface
+    {
+        amf_size            cbSizeof;           // sizeof(AMFVulkanSurface)
+        void*               pNext;              // reserved for extensions
+        // surface properties
+        VkImage             hImage;
+        VkDeviceMemory      hMemory;
+        amf_int64           iSize;              // memory size
+        amf_uint32          eFormat;            // VkFormat
+        amf_int32           iWidth;
+        amf_int32           iHeight;
+        amf_uint32          eCurrentLayout;     // VkImageLayout
+        amf_uint32          eUsage;             // AMF_SURFACE_USAGE
+        amf_uint32          eAccess;            // AMF_MEMORY_CPU_ACCESS
+        AMFVulkanSync       Sync;               // To sync on GPU
+    } AMFVulkanSurface;
+
+    typedef struct AMFVulkanView
+    {
+        amf_size            cbSizeof;           // sizeof(AMFVulkanSurface)
+        void*               pNext;              // reserved for extensions
+        // surface properties
+        AMFVulkanSurface    *pSurface;
+        VkImageView         hView;
+        amf_int32           iPlaneWidth;
+        amf_int32           iPlaneHeight;
+        amf_int32           iPlaneWidthPitch;
+        amf_int32           iPlaneHeightPitch;
+    } AMFVulkanView;
+#if defined(__cplusplus)
+} // namespace amf
+#endif
+#endif // __VulkanAMF_h__

+ 11 - 0
plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt

@@ -0,0 +1,11 @@
+project(obs-amf-test)
+
+include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/libobs)
+
+add_executable(obs-amf-test)
+target_sources(obs-amf-test PRIVATE obs-amf-test.cpp)
+target_link_libraries(obs-amf-test d3d11 dxgi dxguid)
+
+set_target_properties(obs-amf-test PROPERTIES FOLDER "plugins/obs-ffmpeg")
+
+setup_binary_target(obs-amf-test)

+ 131 - 0
plugins/obs-ffmpeg/obs-amf-test/obs-amf-test.cpp

@@ -0,0 +1,131 @@
+#include "../external/AMF/include/core/Factory.h"
+#include "../external/AMF/include/core/Trace.h"
+#include "../external/AMF/include/components/VideoEncoderVCE.h"
+#include "../external/AMF/include/components/VideoEncoderHEVC.h"
+
+#include <util/windows/ComPtr.hpp>
+
+#include <dxgi.h>
+#include <d3d11.h>
+#include <d3d11_1.h>
+
+#include <string>
+#include <map>
+
+using namespace amf;
+
+#ifdef _MSC_VER
+extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
+#endif
+
+#define AMD_VENDOR_ID 0x1002
+
+struct adapter_caps {
+	bool is_amd = false;
+	bool supports_avc = false;
+	bool supports_hevc = false;
+};
+
+static AMFFactory *amf_factory = nullptr;
+static std::map<uint32_t, adapter_caps> adapter_info;
+
+static bool has_encoder(AMFContextPtr &amf_context, const wchar_t *encoder_name)
+{
+	AMFComponentPtr encoder;
+	AMF_RESULT res = amf_factory->CreateComponent(amf_context, encoder_name,
+						      &encoder);
+	return res == AMF_OK;
+}
+
+static bool get_adapter_caps(IDXGIFactory *factory, uint32_t adapter_idx)
+{
+	AMF_RESULT res;
+	HRESULT hr;
+
+	ComPtr<IDXGIAdapter> adapter;
+	hr = factory->EnumAdapters(adapter_idx, &adapter);
+	if (FAILED(hr))
+		return false;
+
+	adapter_caps &caps = adapter_info[adapter_idx];
+
+	DXGI_ADAPTER_DESC desc;
+	adapter->GetDesc(&desc);
+
+	if (desc.VendorId != AMD_VENDOR_ID)
+		return true;
+
+	caps.is_amd = true;
+
+	ComPtr<IDXGIOutput> output;
+	hr = adapter->EnumOutputs(0, &output);
+	if (FAILED(hr))
+		return true;
+
+	ComPtr<ID3D11Device> device;
+	ComPtr<ID3D11DeviceContext> context;
+	hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0,
+			       nullptr, 0, D3D11_SDK_VERSION, &device, nullptr,
+			       &context);
+	if (FAILED(hr))
+		return true;
+
+	AMFContextPtr amf_context;
+	res = amf_factory->CreateContext(&amf_context);
+	if (res != AMF_OK)
+		return true;
+
+	res = amf_context->InitDX11(device);
+	if (res != AMF_OK)
+		return true;
+
+	caps.supports_avc = has_encoder(amf_context, AMFVideoEncoderVCE_AVC);
+	caps.supports_hevc = has_encoder(amf_context, AMFVideoEncoder_HEVC);
+
+	return true;
+}
+
+int main(void)
+try {
+	ComPtr<IDXGIFactory> factory;
+	AMF_RESULT res;
+	HRESULT hr;
+
+	/* --------------------------------------------------------- */
+	/* try initializing amf, I guess                             */
+
+	HMODULE amf_module = LoadLibraryW(AMF_DLL_NAME);
+	if (!amf_module)
+		throw "Failed to load AMF lib";
+
+	auto init =
+		(AMFInit_Fn)GetProcAddress(amf_module, AMF_INIT_FUNCTION_NAME);
+	if (!init)
+		throw "Failed to get init func";
+
+	res = init(AMF_FULL_VERSION, &amf_factory);
+	if (res != AMF_OK)
+		throw "AMFInit failed";
+
+	hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), (void **)&factory);
+	if (FAILED(hr))
+		throw "CreateDXGIFactory1 failed";
+
+	uint32_t idx = 0;
+	while (get_adapter_caps(factory, idx++))
+		;
+
+	for (auto &[idx, caps] : adapter_info) {
+		printf("[%d]\n", idx);
+		printf("is_amd=%s\n", caps.is_amd ? "true" : "false");
+		printf("supports_avc=%s\n",
+		       caps.supports_avc ? "true" : "false");
+		printf("supports_hevc=%s\n",
+		       caps.supports_hevc ? "true" : "false");
+	}
+
+	return 0;
+} catch (const char *text) {
+	printf("[error]\nstring=%s\n", text);
+	return 0;
+}

+ 8 - 0
plugins/obs-ffmpeg/obs-ffmpeg.c

@@ -294,6 +294,8 @@ static bool vaapi_supported(void)
 #ifdef _WIN32
 extern void jim_nvenc_load(bool h264, bool hevc);
 extern void jim_nvenc_unload(void);
+extern void amf_load(void);
+extern void amf_unload(void);
 #endif
 
 #if ENABLE_FFMPEG_LOGGING
@@ -353,6 +355,11 @@ bool obs_module_load(void)
 			obs_register_encoder(&hevc_nvenc_encoder_info);
 #endif
 	}
+
+#ifdef _WIN32
+	amf_load();
+#endif
+
 #if !defined(_WIN32) && defined(LIBAVUTIL_VAAPI_AVAILABLE)
 	if (vaapi_supported()) {
 		blog(LOG_INFO, "FFMPEG VAAPI supported");
@@ -374,6 +381,7 @@ void obs_module_unload(void)
 #endif
 
 #ifdef _WIN32
+	amf_unload();
 	jim_nvenc_unload();
 #endif
 }

+ 272 - 0
plugins/obs-ffmpeg/texture-amf-opts.hpp

@@ -0,0 +1,272 @@
+static bool str_to_bool(const char *str)
+{
+	if (!str)
+		return false;
+	if (*str == '1')
+		return true;
+	if (*str == '0')
+		return false;
+	if (astrcmpi(str, "true") == 0)
+		return true;
+	if (astrcmpi(str, "false") == 0)
+		return false;
+	return false;
+}
+
+static void amf_apply_opt(amf_base *enc, obs_option *opt)
+{
+	bool avc = enc->codec == amf_codec_type::AVC;
+	bool hevc = enc->codec == amf_codec_type::HEVC;
+
+	if (strcmp(opt->name, "g") == 0 || strcmp(opt->name, "keyint") == 0) {
+
+		int val = atoi(opt->value);
+		if (enc->codec == amf_codec_type::AVC)
+			set_avc_opt(IDR_PERIOD, val);
+		else
+			set_hevc_opt(NUM_GOPS_PER_IDR, val);
+
+	} else if (strcmp(opt->name, "usage") == 0) {
+
+		if (strcmp(opt->value, "transcoding") == 0) {
+			set_enum_opt(USAGE, TRANSCONDING);
+		} else if (strcmp(opt->value, "ultralowlatency") == 0) {
+			set_enum_opt(USAGE, ULTRA_LOW_LATENCY);
+		} else if (strcmp(opt->value, "lowlatency") == 0) {
+			set_enum_opt(USAGE, LOW_LATENCY);
+		} else if (strcmp(opt->value, "webcam") == 0) {
+			set_enum_opt(USAGE, WEBCAM);
+		} else {
+			warn("Invalid value for %s: %s", opt->name, opt->value);
+		}
+
+	} else if (strcmp(opt->name, "profile") == 0) {
+
+		if (strcmp(opt->value, "main") == 0) {
+			set_enum_opt(PROFILE, MAIN);
+		} else if (enc->codec != amf_codec_type::AVC) {
+			warn("Invalid value for %s: %s", opt->name, opt->value);
+			return;
+		}
+
+		if (strcmp(opt->value, "high") == 0) {
+			set_opt(PROFILE, AMF_VIDEO_ENCODER_PROFILE_HIGH);
+		} else if (strcmp(opt->value, "constrained_baseline") == 0) {
+			set_opt(PROFILE,
+				AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE);
+		} else if (strcmp(opt->value, "constrained_high") == 0) {
+			set_opt(PROFILE,
+				AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH);
+		} else {
+			warn("Invalid value for %s: %s", opt->name, opt->value);
+		}
+
+	} else if (strcmp(opt->name, "level") == 0) {
+
+		std::string val = opt->value;
+		size_t pos = val.find('.');
+		if (pos != std::string::npos)
+			val.erase(pos, 1);
+
+		int level = std::stoi(val);
+		set_opt(PROFILE_LEVEL, level);
+
+	} else if (strcmp(opt->name, "quality") == 0) {
+
+		if (strcmp(opt->value, "speed") == 0) {
+			set_enum_opt(QUALITY_PRESET, SPEED);
+		} else if (strcmp(opt->value, "balanced") == 0) {
+			set_enum_opt(QUALITY_PRESET, BALANCED);
+		} else if (strcmp(opt->value, "quality") == 0) {
+			set_enum_opt(QUALITY_PRESET, QUALITY);
+		} else {
+			warn("Invalid value for %s: %s", opt->name, opt->value);
+		}
+
+	} else if (strcmp(opt->name, "rc") == 0) {
+
+		if (strcmp(opt->value, "cqp") == 0) {
+			set_enum_opt(RATE_CONTROL_METHOD, CONSTANT_QP);
+		} else if (strcmp(opt->value, "cbr") == 0) {
+			set_enum_opt(RATE_CONTROL_METHOD, CBR);
+		} else if (strcmp(opt->value, "vbr_peak") == 0) {
+			set_enum_opt(RATE_CONTROL_METHOD, PEAK_CONSTRAINED_VBR);
+		} else if (strcmp(opt->value, "vbr_latency") == 0) {
+			set_enum_opt(RATE_CONTROL_METHOD,
+				     LATENCY_CONSTRAINED_VBR);
+		} else {
+			warn("Invalid value for %s: %s", opt->name, opt->value);
+		}
+
+	} else if (strcmp(opt->name, "enforce_hrd") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_opt(ENFORCE_HRD, val);
+
+	} else if (strcmp(opt->name, "filler_data") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_opt(FILLER_DATA_ENABLE, val);
+
+	} else if (strcmp(opt->name, "vbaq") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_opt(ENABLE_VBAQ, val);
+
+	} else if (strcmp(opt->name, "qp_i") == 0) {
+
+		int val = atoi(opt->value);
+		set_opt(QP_I, val);
+
+	} else if (strcmp(opt->name, "qp_p") == 0) {
+
+		int val = atoi(opt->value);
+		set_opt(QP_P, val);
+
+	} else if (strcmp(opt->name, "me_half_pel") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_opt(MOTION_HALF_PIXEL, val);
+
+	} else if (strcmp(opt->name, "me_quarter_pel") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_opt(MOTION_QUARTERPIXEL, val);
+
+	} else if (strcmp(opt->name, "aud") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_opt(INSERT_AUD, val);
+
+	} else if (strcmp(opt->name, "max_au_size") == 0) {
+
+		int val = atoi(opt->value);
+		set_opt(MAX_AU_SIZE, val);
+
+	} else if (avc && strcmp(opt->name, "preanalysis") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_avc_property(enc, PREENCODE_ENABLE, val);
+
+	} else if (avc && strcmp(opt->name, "qp_b") == 0) {
+
+		int val = atoi(opt->value);
+		set_avc_property(enc, QP_B, val);
+
+	} else if (avc && strcmp(opt->name, "frame_skipping") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_avc_property(enc, RATE_CONTROL_SKIP_FRAME_ENABLE, val);
+
+	} else if (avc && strcmp(opt->name, "header_spacing") == 0) {
+
+		int val = atoi(opt->value);
+		set_avc_property(enc, HEADER_INSERTION_SPACING, val);
+
+	} else if (avc && strcmp(opt->name, "bf_delta_qp") == 0) {
+
+		int val = atoi(opt->value);
+		set_avc_property(enc, B_PIC_DELTA_QP, val);
+
+	} else if (avc && strcmp(opt->name, "bf_ref") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_avc_property(enc, B_REFERENCE_ENABLE, val);
+
+	} else if (avc && strcmp(opt->name, "bf_ref_delta_qp") == 0) {
+
+		int val = atoi(opt->value);
+		set_avc_property(enc, REF_B_PIC_DELTA_QP, val);
+
+	} else if (avc && strcmp(opt->name, "intra_refresh_mb") == 0) {
+
+		int val = atoi(opt->value);
+		set_avc_property(enc, INTRA_REFRESH_NUM_MBS_PER_SLOT, val);
+
+	} else if (avc && strcmp(opt->name, "coder") == 0) {
+
+		if (strcmp(opt->value, "auto") == 0) {
+			set_avc_opt(CABAC_ENABLE, AMF_VIDEO_ENCODER_UNDEFINED);
+		} else if (strcmp(opt->value, "cavlc") == 0) {
+			set_avc_opt(CABAC_ENABLE, AMF_VIDEO_ENCODER_CALV);
+		} else if (strcmp(opt->value, "cabac") == 0) {
+			set_avc_opt(CABAC_ENABLE, AMF_VIDEO_ENCODER_CABAC);
+		} else {
+			warn("Invalid value for %s: %s", opt->name, opt->value);
+		}
+
+	} else if (hevc && strcmp(opt->name, "profile_tier") == 0) {
+
+		if (strcmp(opt->value, "main") == 0) {
+			set_hevc_enum(TIER, MAIN);
+		} else if (strcmp(opt->value, "high") == 0) {
+			set_hevc_enum(TIER, HIGH);
+		} else {
+			warn("Invalid value for %s: %s", opt->name, opt->value);
+		}
+
+	} else if (hevc && strcmp(opt->name, "header_insertion_mode") == 0) {
+
+		if (strcmp(opt->value, "none") == 0) {
+			set_hevc_enum(HEADER_INSERTION_MODE, NONE);
+		} else if (strcmp(opt->value, "gop") == 0) {
+			set_hevc_enum(HEADER_INSERTION_MODE, GOP_ALIGNED);
+		} else if (strcmp(opt->value, "idr") == 0) {
+			set_hevc_enum(HEADER_INSERTION_MODE, IDR_ALIGNED);
+		} else {
+			warn("Invalid value for %s: %s", opt->name, opt->value);
+		}
+
+	} else if (hevc && strcmp(opt->name, "skip_frame") == 0) {
+
+		bool val = str_to_bool(opt->value);
+		set_hevc_property(enc, RATE_CONTROL_SKIP_FRAME_ENABLE, val);
+
+	} else if (hevc && strcmp(opt->name, "gops_per_idr") == 0) {
+
+		int val = atoi(opt->value);
+		set_hevc_property(enc, NUM_GOPS_PER_IDR, val);
+
+	} else if (hevc && strcmp(opt->name, "min_qp_i") == 0) {
+
+		int val = atoi(opt->value);
+		set_hevc_property(enc, MIN_QP_I, val);
+
+	} else if (hevc && strcmp(opt->name, "max_qp_i") == 0) {
+
+		int val = atoi(opt->value);
+		set_hevc_property(enc, MAX_QP_I, val);
+
+	} else if (hevc && strcmp(opt->name, "min_qp_i") == 0) {
+
+		int val = atoi(opt->value);
+		set_hevc_property(enc, MIN_QP_P, val);
+
+	} else if (hevc && strcmp(opt->name, "max_qp_i") == 0) {
+
+		int val = atoi(opt->value);
+		set_hevc_property(enc, MAX_QP_P, val);
+	} else {
+		wchar_t wname[256];
+		int val;
+		bool is_bool = false;
+
+		if (astrcmpi(opt->value, "true") == 0) {
+			is_bool = true;
+			val = 1;
+		} else if (astrcmpi(opt->value, "false") == 0) {
+			is_bool = true;
+			val = 0;
+		} else {
+			val = atoi(opt->value);
+		}
+
+		os_utf8_to_wcs(opt->name, 0, wname, _countof(wname));
+		if (is_bool) {
+			bool bool_val = (bool)val;
+			set_amf_property(enc, wname, bool_val);
+		} else {
+			set_amf_property(enc, wname, val);
+		}
+	}
+}

+ 1732 - 0
plugins/obs-ffmpeg/texture-amf.cpp

@@ -0,0 +1,1732 @@
+#include <util/threading.h>
+#include <opts-parser.h>
+#include <obs-module.h>
+#include <obs-avc.h>
+
+#include "obs-ffmpeg-config.h"
+
+#include <unordered_map>
+#include <cstdlib>
+#include <memory>
+#include <string>
+#include <vector>
+#include <mutex>
+#include <deque>
+#include <map>
+
+#include "external/AMF/include/components/VideoEncoderHEVC.h"
+#include "external/AMF/include/components/VideoEncoderVCE.h"
+#include "external/AMF/include/core/Factory.h"
+#include "external/AMF/include/core/Trace.h"
+
+#include <dxgi.h>
+#include <d3d11.h>
+#include <d3d11_1.h>
+
+#include <util/windows/HRError.hpp>
+#include <util/windows/ComPtr.hpp>
+#include <util/platform.h>
+#include <util/util.hpp>
+#include <util/pipe.h>
+#include <util/dstr.h>
+
+using namespace amf;
+
+/* ========================================================================= */
+/* Junk                                                                      */
+
+#define do_log(level, format, ...)                          \
+	blog(level, "[%s: '%s'] " format, enc->encoder_str, \
+	     obs_encoder_get_name(enc->encoder), ##__VA_ARGS__)
+
+#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__)
+#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
+#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
+#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
+
+struct amf_error {
+	const char *str;
+	AMF_RESULT res;
+
+	inline amf_error(const char *str, AMF_RESULT res) : str(str), res(res)
+	{
+	}
+};
+
+struct handle_tex {
+	uint32_t handle;
+	ComPtr<ID3D11Texture2D> tex;
+	ComPtr<IDXGIKeyedMutex> km;
+};
+
+struct adapter_caps {
+	bool is_amd = false;
+	bool supports_avc = false;
+	bool supports_hevc = false;
+};
+
+/* ------------------------------------------------------------------------- */
+
+static std::map<uint32_t, adapter_caps> caps;
+static bool h264_supported = false;
+static AMFFactory *amf_factory = nullptr;
+static AMFTrace *amf_trace = nullptr;
+static HMODULE amf_module = nullptr;
+static uint64_t amf_version = 0;
+
+/* ========================================================================= */
+/* Main Implementation                                                       */
+
+enum class amf_codec_type {
+	AVC,
+	HEVC,
+};
+
+struct amf_base {
+	obs_encoder_t *encoder;
+	const char *encoder_str;
+	amf_codec_type codec;
+	bool fallback;
+
+	AMFContextPtr amf_context;
+	AMFComponentPtr amf_encoder;
+	AMFBufferPtr packet_data;
+	AMFRate amf_frame_rate;
+	AMFBufferPtr header;
+
+	std::deque<AMFDataPtr> queued_packets;
+	int last_query_timeout_ms = 0;
+
+	AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM amf_color_profile;
+	AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM amf_characteristic;
+	AMF_COLOR_PRIMARIES_ENUM amf_primaries;
+	AMF_SURFACE_FORMAT amf_format;
+
+	amf_int64 max_throughput = 0;
+	amf_int64 throughput = 0;
+	uint32_t cx;
+	uint32_t cy;
+	uint32_t linesize = 0;
+	int fps_num;
+	int fps_den;
+	bool full_range;
+	bool bframes_supported = false;
+	bool using_bframes = false;
+	bool first_update = true;
+
+	inline amf_base(bool fallback) : fallback(fallback) {}
+	virtual ~amf_base() = default;
+	virtual void init() = 0;
+};
+
+using d3dtex_t = ComPtr<ID3D11Texture2D>;
+using buf_t = std::vector<uint8_t>;
+
+struct amf_texencode : amf_base, public AMFSurfaceObserver {
+	volatile bool destroying = false;
+
+	std::vector<handle_tex> input_textures;
+
+	std::mutex textures_mutex;
+	std::vector<d3dtex_t> available_textures;
+	std::unordered_map<AMFSurface *, d3dtex_t> active_textures;
+
+	ComPtr<ID3D11Device> device;
+	ComPtr<ID3D11DeviceContext> context;
+
+	inline amf_texencode() : amf_base(false) {}
+	~amf_texencode() { os_atomic_set_bool(&destroying, true); }
+
+	void AMF_STD_CALL OnSurfaceDataRelease(amf::AMFSurface *surf) override
+	{
+		if (os_atomic_load_bool(&destroying))
+			return;
+
+		std::scoped_lock lock(textures_mutex);
+
+		auto it = active_textures.find(surf);
+		if (it != active_textures.end()) {
+			available_textures.push_back(it->second);
+			active_textures.erase(it);
+		}
+	}
+
+	void init() override
+	{
+		AMF_RESULT res = amf_context->InitDX11(device, AMF_DX11_1);
+		if (res != AMF_OK)
+			throw amf_error("InitDX11 failed", res);
+	}
+};
+
+struct amf_fallback : amf_base, public AMFSurfaceObserver {
+	volatile bool destroying = false;
+
+	std::mutex buffers_mutex;
+	std::vector<buf_t> available_buffers;
+	std::unordered_map<AMFSurface *, buf_t> active_buffers;
+
+	inline amf_fallback() : amf_base(true) {}
+	~amf_fallback() { os_atomic_set_bool(&destroying, true); }
+
+	void AMF_STD_CALL OnSurfaceDataRelease(amf::AMFSurface *surf) override
+	{
+		if (os_atomic_load_bool(&destroying))
+			return;
+
+		std::scoped_lock lock(buffers_mutex);
+
+		auto it = active_buffers.find(surf);
+		if (it != active_buffers.end()) {
+			available_buffers.push_back(std::move(it->second));
+			active_buffers.erase(it);
+		}
+	}
+
+	void init() override
+	{
+		AMF_RESULT res = amf_context->InitDX11(nullptr, AMF_DX11_1);
+		if (res != AMF_OK)
+			throw amf_error("InitDX11 failed", res);
+	}
+};
+
+/* ------------------------------------------------------------------------- */
+/* More garbage                                                              */
+
+template<typename T>
+static bool get_amf_property(amf_base *enc, const wchar_t *name, T *value)
+{
+	AMF_RESULT res = enc->amf_encoder->GetProperty(name, value);
+	return res == AMF_OK;
+}
+
+template<typename T>
+static void set_amf_property(amf_base *enc, const wchar_t *name, const T &value)
+{
+	AMF_RESULT res = enc->amf_encoder->SetProperty(name, value);
+	if (res != AMF_OK)
+		error("Failed to set property '%ls': %ls", name,
+		      amf_trace->GetResultText(res));
+}
+
+#define set_avc_property(enc, name, value) \
+	set_amf_property(enc, AMF_VIDEO_ENCODER_##name, value)
+#define set_hevc_property(enc, name, value) \
+	set_amf_property(enc, AMF_VIDEO_ENCODER_HEVC_##name, value)
+
+#define get_avc_property(enc, name, value) \
+	get_amf_property(enc, AMF_VIDEO_ENCODER_##name, value)
+#define get_hevc_property(enc, name, value) \
+	get_amf_property(enc, AMF_VIDEO_ENCODER_HEVC_##name, value)
+
+#define get_opt_name(name)                                              \
+	((enc->codec == amf_codec_type::AVC) ? AMF_VIDEO_ENCODER_##name \
+					     : AMF_VIDEO_ENCODER_HEVC_##name)
+#define set_opt(name, value) set_amf_property(enc, get_opt_name(name), value)
+#define get_opt(name, value) get_amf_property(enc, get_opt_name(name), value)
+#define set_avc_opt(name, value) set_avc_property(enc, name, value)
+#define set_hevc_opt(name, value) set_hevc_property(enc, name, value)
+#define set_enum_opt(name, value) \
+	set_amf_property(enc, get_opt_name(name), get_opt_name(name##_##value))
+#define set_avc_enum(name, value) \
+	set_avc_property(enc, name, AMF_VIDEO_ENCODER_##name##_##value)
+#define set_hevc_enum(name, value) \
+	set_hevc_property(enc, name, AMF_VIDEO_ENCODER_HEVC_##name##_##value)
+
+/* ------------------------------------------------------------------------- */
+/* Implementation                                                            */
+
+static HMODULE get_lib(const char *lib)
+{
+	HMODULE mod = GetModuleHandleA(lib);
+	if (mod)
+		return mod;
+
+	return LoadLibraryA(lib);
+}
+
+#define AMD_VENDOR_ID 0x1002
+
+typedef HRESULT(WINAPI *CREATEDXGIFACTORY1PROC)(REFIID, void **);
+
+static bool amf_init_d3d11(amf_texencode *enc)
+try {
+	HMODULE dxgi = get_lib("DXGI.dll");
+	HMODULE d3d11 = get_lib("D3D11.dll");
+	CREATEDXGIFACTORY1PROC create_dxgi;
+	PFN_D3D11_CREATE_DEVICE create_device;
+	ComPtr<IDXGIFactory> factory;
+	ComPtr<ID3D11Device> device;
+	ComPtr<ID3D11DeviceContext> context;
+	ComPtr<IDXGIAdapter> adapter;
+	DXGI_ADAPTER_DESC desc;
+	HRESULT hr;
+
+	if (!dxgi || !d3d11)
+		throw "Couldn't get D3D11/DXGI libraries? "
+		      "That definitely shouldn't be possible.";
+
+	create_dxgi = (CREATEDXGIFACTORY1PROC)GetProcAddress(
+		dxgi, "CreateDXGIFactory1");
+	create_device = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(
+		d3d11, "D3D11CreateDevice");
+
+	if (!create_dxgi || !create_device)
+		throw "Failed to load D3D11/DXGI procedures";
+
+	hr = create_dxgi(__uuidof(IDXGIFactory2), (void **)&factory);
+	if (FAILED(hr))
+		throw HRError("CreateDXGIFactory1 failed", hr);
+
+	obs_video_info ovi;
+	obs_get_video_info(&ovi);
+
+	hr = factory->EnumAdapters(ovi.adapter, &adapter);
+	if (FAILED(hr))
+		throw HRError("EnumAdapters failed", hr);
+
+	adapter->GetDesc(&desc);
+	if (desc.VendorId != AMD_VENDOR_ID)
+		throw "Seems somehow AMF is trying to initialize "
+		      "on a non-AMD adapter";
+
+	hr = create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0,
+			   nullptr, 0, D3D11_SDK_VERSION, &device, nullptr,
+			   &context);
+	if (FAILED(hr))
+		throw HRError("D3D11CreateDevice failed", hr);
+
+	enc->device = device;
+	enc->context = context;
+	return true;
+
+} catch (const HRError &err) {
+	error("%s: %s: 0x%lX", __FUNCTION__, err.str, err.hr);
+	return false;
+
+} catch (const char *err) {
+	error("%s: %s", __FUNCTION__, err);
+	return false;
+}
+
+static void add_output_tex(amf_texencode *enc,
+			   ComPtr<ID3D11Texture2D> &output_tex,
+			   ID3D11Texture2D *from)
+{
+	ID3D11Device *device = enc->device;
+	HRESULT hr;
+
+	D3D11_TEXTURE2D_DESC desc;
+	from->GetDesc(&desc);
+	desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+	desc.MiscFlags = 0;
+
+	hr = device->CreateTexture2D(&desc, nullptr, &output_tex);
+	if (FAILED(hr))
+		throw HRError("Failed to create texture", hr);
+}
+
+static inline bool get_available_tex(amf_texencode *enc,
+				     ComPtr<ID3D11Texture2D> &output_tex)
+{
+	std::scoped_lock lock(enc->textures_mutex);
+	if (enc->available_textures.size()) {
+		output_tex = enc->available_textures.back();
+		enc->available_textures.pop_back();
+		return true;
+	}
+
+	return false;
+}
+
+static inline void get_output_tex(amf_texencode *enc,
+				  ComPtr<ID3D11Texture2D> &output_tex,
+				  ID3D11Texture2D *from)
+{
+	if (!get_available_tex(enc, output_tex))
+		add_output_tex(enc, output_tex, from);
+}
+
+static void get_tex_from_handle(amf_texencode *enc, uint32_t handle,
+				IDXGIKeyedMutex **km_out,
+				ID3D11Texture2D **tex_out)
+{
+	ID3D11Device *device = enc->device;
+	ComPtr<ID3D11Texture2D> tex;
+	HRESULT hr;
+
+	for (size_t i = 0; i < enc->input_textures.size(); i++) {
+		struct handle_tex &ht = enc->input_textures[i];
+		if (ht.handle == handle) {
+			ht.km.CopyTo(km_out);
+			ht.tex.CopyTo(tex_out);
+			return;
+		}
+	}
+
+	hr = device->OpenSharedResource((HANDLE)(uintptr_t)handle,
+					__uuidof(ID3D11Resource),
+					(void **)&tex);
+	if (FAILED(hr))
+		throw HRError("OpenSharedResource failed", hr);
+
+	ComQIPtr<IDXGIKeyedMutex> km(tex);
+	if (!km)
+		throw "QueryInterface(IDXGIKeyedMutex) failed";
+
+	tex->SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM);
+
+	struct handle_tex new_ht = {handle, tex, km};
+	enc->input_textures.push_back(std::move(new_ht));
+
+	*km_out = km.Detach();
+	*tex_out = tex.Detach();
+}
+
+static constexpr amf_int64 macroblock_size = 16;
+
+static inline void calc_throughput(amf_base *enc)
+{
+	amf_int64 mb_cx =
+		((amf_int64)enc->cx + (macroblock_size - 1)) / macroblock_size;
+	amf_int64 mb_cy =
+		((amf_int64)enc->cy + (macroblock_size - 1)) / macroblock_size;
+	amf_int64 mb_frame = mb_cx * mb_cy;
+
+	enc->throughput =
+		mb_frame * (amf_int64)enc->fps_num / (amf_int64)enc->fps_den;
+}
+
+static inline void check_preset_compatibility(amf_base *enc,
+					      const char *&preset)
+{
+	/* 1.8 * current base throughput == quality,
+	 * 1.1 * current base throughput == balanced */
+	static constexpr amf_int64 throughput_quality_mul = 18;
+	static constexpr amf_int64 throughput_balanced_mul = 11;
+
+	/* if the throughput * 1.8 is lower than the max throughput, switch to
+	 * a lower preset */
+	if (astrcmpi(preset, "quality") == 0) {
+		if (!enc->max_throughput) {
+			preset = "balanced";
+		} else {
+			amf_int64 req_throughput =
+				enc->throughput * throughput_quality_mul / 10;
+			if (enc->max_throughput < req_throughput)
+				preset = "balanced";
+		}
+	}
+
+	if (astrcmpi(preset, "balanced") == 0) {
+		amf_int64 req_throughput =
+			enc->throughput * throughput_balanced_mul / 10;
+		if (enc->max_throughput < req_throughput)
+			preset = "speed";
+	}
+}
+
+static inline int64_t convert_to_amf_ts(amf_base *enc, int64_t ts)
+{
+	constexpr int64_t amf_timebase = AMF_SECOND;
+	return ts * amf_timebase / (int64_t)enc->fps_den;
+}
+
+static inline int64_t convert_to_obs_ts(amf_base *enc, int64_t ts)
+{
+	constexpr int64_t amf_timebase = AMF_SECOND;
+	return ts * (int64_t)enc->fps_den / amf_timebase;
+}
+
+static void convert_to_encoder_packet(amf_base *enc, AMFDataPtr &data,
+				      encoder_packet *packet)
+{
+	if (!data)
+		return;
+
+	enc->packet_data = AMFBufferPtr(data);
+	data->GetProperty(L"PTS", &packet->pts);
+
+	bool hevc = enc->codec == amf_codec_type::HEVC;
+	const wchar_t *get_output_type =
+		hevc ? AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE
+		     : AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE;
+
+	uint64_t type;
+	data->GetProperty(get_output_type, &type);
+
+	switch (type) {
+	case AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR:
+		packet->priority = OBS_NAL_PRIORITY_HIGHEST;
+		break;
+	case AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_I:
+		packet->priority = OBS_NAL_PRIORITY_HIGH;
+		break;
+	case AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_P:
+		packet->priority = OBS_NAL_PRIORITY_LOW;
+		break;
+	case AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_B:
+		packet->priority = OBS_NAL_PRIORITY_DISPOSABLE;
+		break;
+	}
+
+	packet->data = (uint8_t *)enc->packet_data->GetNative();
+	packet->size = enc->packet_data->GetSize();
+	packet->type = OBS_ENCODER_VIDEO;
+	packet->dts = convert_to_obs_ts(enc, data->GetPts());
+	packet->keyframe = type == AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR;
+
+	if (enc->using_bframes)
+		packet->dts -= 2;
+}
+
+static void amf_encode_base(amf_base *enc, AMFSurface *amf_surf,
+			    encoder_packet *packet, bool *received_packet)
+{
+	auto &queued_packets = enc->queued_packets;
+	uint64_t ts_start = os_gettime_ns();
+	AMF_RESULT res;
+
+	*received_packet = false;
+
+	bool waiting = true;
+	while (waiting) {
+		/* ----------------------------------- */
+		/* submit frame                        */
+
+		res = enc->amf_encoder->SubmitInput(amf_surf);
+		int timeout = 0;
+
+		if (res == AMF_OK || res == AMF_NEED_MORE_INPUT) {
+			waiting = false;
+
+		} else if (res == AMF_INPUT_FULL) {
+			timeout = 1;
+
+		} else {
+			throw amf_error("SubmitInput failed", res);
+		}
+
+		if (enc->last_query_timeout_ms != timeout) {
+			set_opt(QUERY_TIMEOUT, timeout);
+			enc->last_query_timeout_ms = timeout;
+		}
+
+		/* ----------------------------------- */
+		/* query as many packets as possible   */
+
+		AMFDataPtr new_packet;
+		do {
+			res = enc->amf_encoder->QueryOutput(&new_packet);
+			if (new_packet)
+				queued_packets.push_back(new_packet);
+
+			if (res != AMF_REPEAT && res != AMF_OK) {
+				throw amf_error("QueryOutput failed", res);
+			}
+		} while (!!new_packet);
+	}
+
+	/* ----------------------------------- */
+	/* return a packet if available        */
+
+	if (queued_packets.size()) {
+		AMFDataPtr amf_out;
+
+		amf_out = queued_packets.front();
+		queued_packets.pop_front();
+
+		*received_packet = true;
+		convert_to_encoder_packet(enc, amf_out, packet);
+	}
+}
+
+static bool amf_encode_tex(void *data, uint32_t handle, int64_t pts,
+			   uint64_t lock_key, uint64_t *next_key,
+			   encoder_packet *packet, bool *received_packet)
+try {
+	amf_texencode *enc = (amf_texencode *)data;
+	ID3D11DeviceContext *context = enc->context;
+	ComPtr<ID3D11Texture2D> output_tex;
+	ComPtr<ID3D11Texture2D> input_tex;
+	ComPtr<IDXGIKeyedMutex> km;
+	AMFSurfacePtr amf_surf;
+	AMF_RESULT res;
+
+	if (handle == GS_INVALID_HANDLE) {
+		*next_key = lock_key;
+		throw "Encode failed: bad texture handle";
+	}
+
+	/* ------------------------------------ */
+	/* get the input tex                    */
+
+	get_tex_from_handle(enc, handle, &km, &input_tex);
+
+	/* ------------------------------------ */
+	/* get an output tex                    */
+
+	get_output_tex(enc, output_tex, input_tex);
+
+	/* ------------------------------------ */
+	/* copy to output tex                   */
+
+	km->AcquireSync(lock_key, INFINITE);
+	context->CopyResource((ID3D11Resource *)output_tex.Get(),
+			      (ID3D11Resource *)input_tex.Get());
+	context->Flush();
+	km->ReleaseSync(*next_key);
+
+	/* ------------------------------------ */
+	/* map output tex to amf surface        */
+
+	res = enc->amf_context->CreateSurfaceFromDX11Native(output_tex,
+							    &amf_surf, enc);
+	if (res != AMF_OK)
+		throw amf_error("CreateSurfaceFromDX11Native failed", res);
+
+	int64_t last_ts = convert_to_amf_ts(enc, pts - 1);
+	int64_t cur_ts = convert_to_amf_ts(enc, pts);
+
+	amf_surf->SetPts(cur_ts);
+	amf_surf->SetProperty(L"PTS", pts);
+
+	{
+		std::scoped_lock lock(enc->textures_mutex);
+		enc->active_textures[amf_surf.GetPtr()] = output_tex;
+	}
+
+	/* ------------------------------------ */
+	/* do actual encode                     */
+
+	amf_encode_base(enc, amf_surf, packet, received_packet);
+	return true;
+
+} catch (const char *err) {
+	amf_texencode *enc = (amf_texencode *)data;
+	error("%s: %s", __FUNCTION__, err);
+	return false;
+
+} catch (const amf_error &err) {
+	amf_texencode *enc = (amf_texencode *)data;
+	error("%s: %s: %ls", __FUNCTION__, err.str,
+	      amf_trace->GetResultText(err.res));
+	*received_packet = false;
+	return false;
+
+} catch (const HRError &err) {
+	amf_texencode *enc = (amf_texencode *)data;
+	error("%s: %s: 0x%lX", __FUNCTION__, err.str, err.hr);
+	*received_packet = false;
+	return false;
+}
+
+static buf_t alloc_buf(amf_fallback *enc)
+{
+	buf_t buf;
+	size_t size;
+
+	if (enc->amf_format == AMF_SURFACE_NV12) {
+		size = enc->linesize * enc->cy * 2;
+	} else if (enc->amf_format == AMF_SURFACE_RGBA) {
+		size = enc->linesize * enc->cy * 4;
+	} else if (enc->amf_format == AMF_SURFACE_P010) {
+		size = enc->linesize * enc->cy * 2 * 2;
+	}
+
+	buf.resize(size);
+	return buf;
+}
+
+static buf_t get_buf(amf_fallback *enc)
+{
+	std::scoped_lock lock(enc->buffers_mutex);
+	buf_t buf;
+
+	if (enc->available_buffers.size()) {
+		buf = std::move(enc->available_buffers.back());
+		enc->available_buffers.pop_back();
+	} else {
+		buf = alloc_buf(enc);
+	}
+
+	return buf;
+}
+
+static inline void copy_frame_data(amf_fallback *enc, buf_t &buf,
+				   struct encoder_frame *frame)
+{
+	uint8_t *dst = &buf[0];
+
+	if (enc->amf_format == AMF_SURFACE_NV12 ||
+	    enc->amf_format == AMF_SURFACE_P010) {
+		size_t size = enc->linesize * enc->cy;
+		memcpy(&buf[0], frame->data[0], size);
+		memcpy(&buf[size], frame->data[1], size / 2);
+
+	} else if (enc->amf_format == AMF_SURFACE_RGBA) {
+		memcpy(dst, frame->data[0], enc->linesize * enc->cy);
+	}
+}
+
+static bool amf_encode_fallback(void *data, struct encoder_frame *frame,
+				struct encoder_packet *packet,
+				bool *received_packet)
+try {
+	amf_fallback *enc = (amf_fallback *)data;
+	AMFSurfacePtr amf_surf;
+	AMF_RESULT res;
+	buf_t buf;
+
+	if (!enc->linesize)
+		enc->linesize = frame->linesize[0];
+
+	if (enc->available_buffers.size()) {
+		buf = std::move(enc->available_buffers.back());
+		enc->available_buffers.pop_back();
+	} else {
+		buf = alloc_buf(enc);
+	}
+
+	copy_frame_data(enc, buf, frame);
+
+	res = enc->amf_context->CreateSurfaceFromHostNative(
+		enc->amf_format, enc->cx, enc->cy, enc->linesize, 0, &buf[0],
+		&amf_surf, enc);
+	if (res != AMF_OK)
+		throw amf_error("CreateSurfaceFromHostNative failed", res);
+
+	int64_t last_ts = convert_to_amf_ts(enc, frame->pts - 1);
+	int64_t cur_ts = convert_to_amf_ts(enc, frame->pts);
+
+	amf_surf->SetPts(cur_ts);
+	amf_surf->SetProperty(L"PTS", frame->pts);
+
+	{
+		std::scoped_lock lock(enc->buffers_mutex);
+		enc->active_buffers[amf_surf.GetPtr()] = std::move(buf);
+	}
+
+	/* ------------------------------------ */
+	/* do actual encode                     */
+
+	amf_encode_base(enc, amf_surf, packet, received_packet);
+	return true;
+
+} catch (const amf_error &err) {
+	amf_fallback *enc = (amf_fallback *)data;
+	error("%s: %s: %ls", __FUNCTION__, err.str,
+	      amf_trace->GetResultText(err.res));
+	*received_packet = false;
+	return false;
+}
+
+static bool amf_extra_data(void *data, uint8_t **header, size_t *size)
+{
+	amf_base *enc = (amf_base *)data;
+	if (!enc->header)
+		return false;
+
+	*header = (uint8_t *)enc->header->GetNative();
+	*size = enc->header->GetSize();
+	return true;
+}
+
+static void h264_video_info_fallback(void *, struct video_scale_info *info)
+{
+	switch (info->format) {
+	case VIDEO_FORMAT_RGBA:
+	case VIDEO_FORMAT_BGRA:
+	case VIDEO_FORMAT_BGRX:
+		info->format = VIDEO_FORMAT_RGBA;
+		break;
+	default:
+		info->format = VIDEO_FORMAT_NV12;
+		break;
+	}
+}
+
+static void h265_video_info_fallback(void *, struct video_scale_info *info)
+{
+	switch (info->format) {
+	case VIDEO_FORMAT_RGBA:
+	case VIDEO_FORMAT_BGRA:
+	case VIDEO_FORMAT_BGRX:
+		info->format = VIDEO_FORMAT_RGBA;
+		break;
+	case VIDEO_FORMAT_I010:
+	case VIDEO_FORMAT_P010:
+		info->format = VIDEO_FORMAT_P010;
+		break;
+	default:
+		info->format = VIDEO_FORMAT_NV12;
+	}
+}
+
+static bool amf_create_encoder(amf_base *enc)
+try {
+	AMF_RESULT res;
+
+	/* ------------------------------------ */
+	/* get video info                       */
+
+	struct obs_video_info ovi;
+	obs_get_video_info(&ovi);
+
+	struct video_scale_info info;
+	info.format = ovi.output_format;
+	info.colorspace = ovi.colorspace;
+	info.range = ovi.range;
+
+	if (enc->fallback) {
+		if (enc->codec == amf_codec_type::AVC)
+			h264_video_info_fallback(NULL, &info);
+		else
+			h265_video_info_fallback(NULL, &info);
+	}
+
+	enc->cx = obs_encoder_get_width(enc->encoder);
+	enc->cy = obs_encoder_get_height(enc->encoder);
+	enc->amf_frame_rate = AMFConstructRate(ovi.fps_num, ovi.fps_den);
+	enc->fps_num = (int)ovi.fps_num;
+	enc->fps_den = (int)ovi.fps_den;
+	enc->full_range = info.range == VIDEO_RANGE_FULL;
+
+	switch (info.colorspace) {
+	case VIDEO_CS_601:
+		enc->amf_color_profile =
+			enc->full_range
+				? AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601
+				: AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
+		enc->amf_primaries = AMF_COLOR_PRIMARIES_SMPTE170M;
+		enc->amf_characteristic =
+			AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE170M;
+		break;
+	case VIDEO_CS_DEFAULT:
+	case VIDEO_CS_709:
+		enc->amf_color_profile =
+			enc->full_range
+				? AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709
+				: AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+		enc->amf_primaries = AMF_COLOR_PRIMARIES_BT709;
+		enc->amf_characteristic =
+			AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709;
+		break;
+	case VIDEO_CS_SRGB:
+		enc->amf_color_profile =
+			enc->full_range
+				? AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709
+				: AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+		enc->amf_primaries = AMF_COLOR_PRIMARIES_BT709;
+		enc->amf_characteristic =
+			AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_1;
+		break;
+	case VIDEO_CS_2100_HLG:
+		enc->amf_color_profile =
+			enc->full_range
+				? AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020
+				: AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+		enc->amf_primaries = AMF_COLOR_PRIMARIES_BT2020;
+		enc->amf_characteristic =
+			AMF_COLOR_TRANSFER_CHARACTERISTIC_ARIB_STD_B67;
+		break;
+	case VIDEO_CS_2100_PQ:
+		enc->amf_color_profile =
+			enc->full_range
+				? AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020
+				: AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+		enc->amf_primaries = AMF_COLOR_PRIMARIES_BT2020;
+		enc->amf_characteristic =
+			AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084;
+		break;
+	}
+
+	switch (info.format) {
+	case VIDEO_FORMAT_NV12:
+		enc->amf_format = AMF_SURFACE_NV12;
+		break;
+	case VIDEO_FORMAT_P010:
+		enc->amf_format = AMF_SURFACE_P010;
+		break;
+	case VIDEO_FORMAT_RGBA:
+		enc->amf_format = AMF_SURFACE_RGBA;
+		break;
+	}
+
+	/* ------------------------------------ */
+	/* create encoder                       */
+
+	res = amf_factory->CreateContext(&enc->amf_context);
+	if (res != AMF_OK)
+		throw amf_error("CreateContext failed", res);
+
+	enc->init();
+
+	res = amf_factory->CreateComponent(enc->amf_context,
+					   enc->codec == amf_codec_type::HEVC
+						   ? AMFVideoEncoder_HEVC
+						   : AMFVideoEncoderVCE_AVC,
+					   &enc->amf_encoder);
+	if (res != AMF_OK)
+		throw amf_error("CreateComponent failed", res);
+
+	calc_throughput(enc);
+	return true;
+
+} catch (const amf_error &err) {
+	error("%s: %s: %ls", __FUNCTION__, err.str,
+	      amf_trace->GetResultText(err.res));
+	return false;
+}
+
+static void amf_destroy(void *data)
+{
+	amf_base *enc = (amf_base *)data;
+	delete enc;
+}
+
+static void check_texture_encode_capability(obs_encoder_t *encoder, bool hevc)
+{
+	obs_video_info ovi;
+	obs_get_video_info(&ovi);
+
+	if (obs_encoder_scaling_enabled(encoder))
+		throw "Encoder scaling is active";
+	if (hevc) {
+		if (!obs_nv12_tex_active() && !obs_p010_tex_active())
+			throw "NV12/P010 textures aren't active";
+	} else if (!obs_nv12_tex_active()) {
+		throw "NV12 textures aren't active";
+	}
+
+	if ((hevc && !caps[ovi.adapter].supports_hevc) ||
+	    (!hevc && !caps[ovi.adapter].supports_avc))
+		throw "Wrong adapter";
+}
+
+#include "texture-amf-opts.hpp"
+
+static void amf_defaults(obs_data_t *settings)
+{
+	obs_data_set_default_int(settings, "bitrate", 2500);
+	obs_data_set_default_int(settings, "cqp", 20);
+	obs_data_set_default_string(settings, "rate_control", "CBR");
+	obs_data_set_default_string(settings, "preset", "quality");
+	obs_data_set_default_string(settings, "profile", "high");
+}
+
+static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
+				  obs_data_t *settings)
+{
+	const char *rc = obs_data_get_string(settings, "rate_control");
+	bool cqp = astrcmpi(rc, "CQP") == 0;
+
+	p = obs_properties_get(ppts, "bitrate");
+	obs_property_set_visible(p, !cqp);
+	p = obs_properties_get(ppts, "cqp");
+	obs_property_set_visible(p, cqp);
+	return true;
+}
+
+static obs_properties_t *amf_properties_internal(bool hevc)
+{
+	obs_properties_t *props = obs_properties_create();
+	obs_property_t *p;
+
+	p = obs_properties_add_list(props, "rate_control",
+				    obs_module_text("RateControl"),
+				    OBS_COMBO_TYPE_LIST,
+				    OBS_COMBO_FORMAT_STRING);
+	obs_property_list_add_string(p, "CBR", "CBR");
+	obs_property_list_add_string(p, "CQP", "CQP");
+	obs_property_list_add_string(p, "VBR", "VBR");
+
+	obs_property_set_modified_callback(p, rate_control_modified);
+
+	p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"),
+				   50, 300000, 50);
+	obs_property_int_set_suffix(p, " Kbps");
+
+	obs_properties_add_int(props, "cqp", obs_module_text("NVENC.CQLevel"),
+			       1, 30, 1);
+
+	obs_properties_add_int(props, "keyint_sec",
+			       obs_module_text("KeyframeIntervalSec"), 0, 10,
+			       1);
+
+	p = obs_properties_add_list(props, "preset", obs_module_text("Preset"),
+				    OBS_COMBO_TYPE_LIST,
+				    OBS_COMBO_FORMAT_STRING);
+
+#define add_preset(val) \
+	obs_property_list_add_string(p, obs_module_text("AMF.Preset." val), val)
+	add_preset("quality");
+	add_preset("balanced");
+	add_preset("speed");
+#undef add_preset
+
+	if (!hevc) {
+		p = obs_properties_add_list(props, "profile",
+					    obs_module_text("Profile"),
+					    OBS_COMBO_TYPE_LIST,
+					    OBS_COMBO_FORMAT_STRING);
+
+#define add_profile(val) obs_property_list_add_string(p, val, val)
+		add_profile("high");
+		add_profile("main");
+		add_profile("baseline");
+#undef add_profile
+	}
+
+	p = obs_properties_add_text(props, "ffmpeg_opts",
+				    obs_module_text("AMFOpts"),
+				    OBS_TEXT_DEFAULT);
+	obs_property_set_long_description(p,
+					  obs_module_text("AMFOpts.ToolTip"));
+
+	return props;
+}
+
+static obs_properties_t *amf_avc_properties(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+	return amf_properties_internal(false);
+}
+
+static obs_properties_t *amf_hevc_properties(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+	return amf_properties_internal(true);
+}
+
+/* ========================================================================= */
+/* AVC Implementation                                                        */
+
+static const char *amf_avc_get_name(void *)
+{
+	return "AMD HW H.264";
+}
+
+static inline int get_avc_preset(amf_base *enc, obs_data_t *settings)
+{
+	const char *preset = obs_data_get_string(settings, "preset");
+
+	check_preset_compatibility(enc, preset);
+
+	if (astrcmpi(preset, "quality") == 0)
+		return AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY;
+	else if (astrcmpi(preset, "speed") == 0)
+		return AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED;
+
+	return AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED;
+}
+
+static inline int get_avc_rate_control(const char *rc_str)
+{
+	if (astrcmpi(rc_str, "cqp") == 0)
+		return AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP;
+	else if (astrcmpi(rc_str, "vbr") == 0)
+		return AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
+
+	return AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR;
+}
+
+static inline int get_avc_profile(obs_data_t *settings)
+{
+	const char *profile = obs_data_get_string(settings, "profile");
+
+	if (astrcmpi(profile, "baseline") == 0)
+		return AMF_VIDEO_ENCODER_PROFILE_BASELINE;
+	else if (astrcmpi(profile, "main") == 0)
+		return AMF_VIDEO_ENCODER_PROFILE_MAIN;
+	else if (astrcmpi(profile, "constrained_baseline") == 0)
+		return AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE;
+	else if (astrcmpi(profile, "constrained_high") == 0)
+		return AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH;
+
+	return AMF_VIDEO_ENCODER_PROFILE_HIGH;
+}
+
+static void amf_avc_update_data(amf_base *enc, int rc, int64_t bitrate,
+				int64_t qp)
+{
+	if (rc != AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
+		set_avc_property(enc, TARGET_BITRATE, bitrate);
+		set_avc_property(enc, PEAK_BITRATE, bitrate);
+		set_avc_property(enc, VBV_BUFFER_SIZE, bitrate);
+
+		if (rc == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR) {
+			set_avc_property(enc, FILLER_DATA_ENABLE, true);
+		}
+	} else {
+		set_avc_property(enc, QP_I, qp);
+		set_avc_property(enc, QP_P, qp);
+		set_avc_property(enc, QP_B, qp);
+	}
+}
+
+static bool amf_avc_update(void *data, obs_data_t *settings)
+try {
+	amf_base *enc = (amf_base *)data;
+
+	if (enc->first_update) {
+		enc->first_update = false;
+		return true;
+	}
+
+	int64_t bitrate = obs_data_get_int(settings, "bitrate") * 1000;
+	int64_t qp = obs_data_get_int(settings, "cqp");
+	const char *rc_str = obs_data_get_string(settings, "rate_control");
+	int rc = get_avc_rate_control(rc_str);
+	AMF_RESULT res;
+
+	amf_avc_update_data(enc, rc, bitrate, qp);
+
+	res = enc->amf_encoder->ReInit(enc->cx, enc->cy);
+	if (res != AMF_OK)
+		throw amf_error("AMFComponent::Init failed", res);
+
+	return true;
+
+} catch (const amf_error &err) {
+	amf_base *enc = (amf_base *)data;
+	error("%s: %s: %ls", __FUNCTION__, err.str,
+	      amf_trace->GetResultText(err.res));
+	return false;
+}
+
+static bool amf_avc_init(void *data, obs_data_t *settings)
+{
+	amf_base *enc = (amf_base *)data;
+
+	int64_t bitrate = obs_data_get_int(settings, "bitrate") * 1000;
+	int64_t qp = obs_data_get_int(settings, "cqp");
+	const char *preset = obs_data_get_string(settings, "preset");
+	const char *profile = obs_data_get_string(settings, "profile");
+	const char *rc_str = obs_data_get_string(settings, "rate_control");
+
+	check_preset_compatibility(enc, preset);
+
+	int rc = get_avc_rate_control(rc_str);
+
+	set_avc_property(enc, RATE_CONTROL_METHOD, rc);
+	set_avc_property(enc, ENABLE_VBAQ, true);
+
+	amf_avc_update_data(enc, rc, bitrate, qp);
+
+	set_avc_property(enc, ENFORCE_HRD, true);
+	set_avc_property(enc, HIGH_MOTION_QUALITY_BOOST_ENABLE, false);
+
+	int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
+	int gop_size = (keyint_sec) ? keyint_sec * enc->fps_num / enc->fps_den
+				    : 250;
+
+	set_avc_property(enc, IDR_PERIOD, gop_size);
+	set_avc_property(enc, DE_BLOCKING_FILTER, true);
+
+	const char *ffmpeg_opts = obs_data_get_string(settings, "ffmpeg_opts");
+	if (ffmpeg_opts && *ffmpeg_opts) {
+		struct obs_options opts = obs_parse_options(ffmpeg_opts);
+		for (size_t i = 0; i < opts.count; i++) {
+			amf_apply_opt(enc, &opts.options[i]);
+		}
+		obs_free_options(opts);
+	}
+
+	if (!ffmpeg_opts || !*ffmpeg_opts)
+		ffmpeg_opts = "(none)";
+
+	info("settings:\n"
+	     "\trate_control: %s\n"
+	     "\tbitrate:      %d\n"
+	     "\tcqp:          %d\n"
+	     "\tkeyint:       %d\n"
+	     "\tpreset:       %s\n"
+	     "\tprofile:      %s\n"
+	     "\twidth:        %d\n"
+	     "\theight:       %d\n"
+	     "\tparams:       %s",
+	     rc_str, bitrate, qp, gop_size, preset, profile, enc->cx, enc->cy,
+	     ffmpeg_opts);
+
+	return true;
+}
+
+static void amf_avc_create_internal(amf_base *enc, obs_data_t *settings)
+{
+	AMF_RESULT res;
+	AMFVariant p;
+
+	enc->codec = amf_codec_type::AVC;
+
+	if (!amf_create_encoder(enc))
+		throw "Failed to create encoder";
+
+	AMFCapsPtr caps;
+	res = enc->amf_encoder->GetCaps(&caps);
+	if (res == AMF_OK) {
+		caps->GetProperty(AMF_VIDEO_ENCODER_CAP_BFRAMES,
+				  &enc->bframes_supported);
+		caps->GetProperty(AMF_VIDEO_ENCODER_CAP_MAX_THROUGHPUT,
+				  &enc->max_throughput);
+	}
+
+	set_avc_property(enc, FRAMESIZE, AMFConstructSize(enc->cx, enc->cy));
+	set_avc_property(enc, USAGE, AMF_VIDEO_ENCODER_USAGE_TRANSCONDING);
+	set_avc_property(enc, QUALITY_PRESET, get_avc_preset(enc, settings));
+	set_avc_property(enc, PROFILE, get_avc_profile(settings));
+	set_avc_property(enc, LOWLATENCY_MODE, false);
+	set_avc_property(enc, CABAC_ENABLE, AMF_VIDEO_ENCODER_UNDEFINED);
+	set_avc_property(enc, PREENCODE_ENABLE, true);
+	set_avc_property(enc, OUTPUT_COLOR_PROFILE, enc->amf_color_profile);
+	set_avc_property(enc, OUTPUT_TRANSFER_CHARACTERISTIC,
+			 enc->amf_characteristic);
+	set_avc_property(enc, OUTPUT_COLOR_PRIMARIES, enc->amf_primaries);
+	set_avc_property(enc, FULL_RANGE_COLOR, enc->full_range);
+
+	amf_avc_init(enc, settings);
+
+	res = enc->amf_encoder->Init(enc->amf_format, enc->cx, enc->cy);
+	if (res != AMF_OK)
+		throw amf_error("AMFComponent::Init failed", res);
+
+	set_avc_property(enc, FRAMERATE, enc->amf_frame_rate);
+
+	res = enc->amf_encoder->GetProperty(AMF_VIDEO_ENCODER_EXTRADATA, &p);
+	if (res == AMF_OK && p.type == AMF_VARIANT_INTERFACE)
+		enc->header = AMFBufferPtr(p.pInterface);
+
+	if (enc->bframes_supported) {
+		amf_int64 b_frames = 0;
+		amf_int64 b_max = 0;
+
+		if (get_avc_property(enc, B_PIC_PATTERN, &b_frames) &&
+		    get_avc_property(enc, MAX_CONSECUTIVE_BPICTURES, &b_max))
+			enc->using_bframes = b_frames && b_max;
+		else
+			enc->using_bframes = false;
+	}
+}
+
+static void *amf_avc_create_texencode(obs_data_t *settings,
+				      obs_encoder_t *encoder)
+try {
+	check_texture_encode_capability(encoder, false);
+
+	amf_texencode *enc = new amf_texencode;
+	enc->encoder = encoder;
+	enc->encoder_str = "texture-amf-h264";
+
+	if (!amf_init_d3d11(enc))
+		throw "Failed to create D3D11";
+
+	amf_avc_create_internal(enc, settings);
+	return enc;
+
+} catch (const amf_error &err) {
+	blog(LOG_ERROR, "[texture-amf-h264] %s: %s: %ls", __FUNCTION__, err.str,
+	     amf_trace->GetResultText(err.res));
+	return obs_encoder_create_rerouted(encoder, "h264_fallback_amf");
+
+} catch (const char *err) {
+	blog(LOG_ERROR, "[texture-amf-h264] %s: %s", __FUNCTION__, err);
+	return obs_encoder_create_rerouted(encoder, "h264_fallback_amf");
+}
+
+static void *amf_avc_create_fallback(obs_data_t *settings,
+				     obs_encoder_t *encoder)
+try {
+	amf_fallback *enc = new amf_fallback;
+	enc->encoder = encoder;
+	enc->encoder_str = "fallback-amf-h264";
+
+	amf_avc_create_internal(enc, settings);
+	return enc;
+
+} catch (const amf_error &err) {
+	blog(LOG_ERROR, "[texture-amf-h264] %s: %s: %ls", __FUNCTION__, err.str,
+	     amf_trace->GetResultText(err.res));
+	return nullptr;
+
+} catch (const char *err) {
+	blog(LOG_ERROR, "[texture-amf-h264] %s: %s", __FUNCTION__, err);
+	return nullptr;
+}
+
+static void register_avc()
+{
+	struct obs_encoder_info amf_encoder_info = {};
+	amf_encoder_info.id = "h264_texture_amf";
+	amf_encoder_info.type = OBS_ENCODER_VIDEO;
+	amf_encoder_info.codec = "h264";
+	amf_encoder_info.get_name = amf_avc_get_name;
+	amf_encoder_info.create = amf_avc_create_texencode;
+	amf_encoder_info.destroy = amf_destroy;
+	amf_encoder_info.update = amf_avc_update;
+	amf_encoder_info.encode_texture = amf_encode_tex;
+	amf_encoder_info.get_defaults = amf_defaults;
+	amf_encoder_info.get_properties = amf_avc_properties;
+	amf_encoder_info.get_extra_data = amf_extra_data;
+	amf_encoder_info.caps = OBS_ENCODER_CAP_PASS_TEXTURE |
+				OBS_ENCODER_CAP_DYN_BITRATE;
+
+	obs_register_encoder(&amf_encoder_info);
+
+	amf_encoder_info.id = "h264_fallback_amf";
+	amf_encoder_info.caps = OBS_ENCODER_CAP_INTERNAL |
+				OBS_ENCODER_CAP_DYN_BITRATE;
+	amf_encoder_info.encode_texture = nullptr;
+	amf_encoder_info.create = amf_avc_create_fallback;
+	amf_encoder_info.encode = amf_encode_fallback;
+	amf_encoder_info.get_video_info = h264_video_info_fallback;
+
+	obs_register_encoder(&amf_encoder_info);
+}
+
+/* ========================================================================= */
+/* HEVC Implementation                                                       */
+
+#if ENABLE_HEVC
+
+static const char *amf_hevc_get_name(void *)
+{
+	return "AMD HW H.265 (HEVC)";
+}
+
+static inline int get_hevc_preset(amf_base *enc, obs_data_t *settings)
+{
+	const char *preset = obs_data_get_string(settings, "preset");
+
+	check_preset_compatibility(enc, preset);
+
+	if (astrcmpi(preset, "balanced") == 0)
+		return AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED;
+	else if (astrcmpi(preset, "speed") == 0)
+		return AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED;
+
+	return AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY;
+}
+
+static inline int get_hevc_rate_control(const char *rc_str)
+{
+	if (astrcmpi(rc_str, "cqp") == 0)
+		return AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP;
+	else if (astrcmpi(rc_str, "vbr") == 0)
+		return AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
+
+	return AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR;
+}
+
+static void amf_hevc_update_data(amf_base *enc, int rc, int64_t bitrate,
+				 int64_t qp)
+{
+	if (rc != AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
+		set_hevc_property(enc, TARGET_BITRATE, bitrate);
+		set_hevc_property(enc, PEAK_BITRATE, bitrate);
+		set_hevc_property(enc, VBV_BUFFER_SIZE, bitrate);
+
+		if (rc == AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR) {
+			set_hevc_property(enc, FILLER_DATA_ENABLE, true);
+		}
+	} else {
+		set_hevc_property(enc, QP_I, qp);
+		set_hevc_property(enc, QP_P, qp);
+	}
+}
+
+static bool amf_hevc_update(void *data, obs_data_t *settings)
+try {
+	amf_base *enc = (amf_base *)data;
+
+	if (enc->first_update) {
+		enc->first_update = false;
+		return true;
+	}
+
+	int64_t bitrate = obs_data_get_int(settings, "bitrate") * 1000;
+	int64_t qp = obs_data_get_int(settings, "cqp");
+	const char *rc_str = obs_data_get_string(settings, "rate_control");
+	int rc = get_hevc_rate_control(rc_str);
+	AMF_RESULT res;
+
+	amf_hevc_update_data(enc, rc, bitrate, qp);
+
+	res = enc->amf_encoder->ReInit(enc->cx, enc->cy);
+	if (res != AMF_OK)
+		throw amf_error("AMFComponent::Init failed", res);
+
+	return true;
+
+} catch (const amf_error &err) {
+	amf_base *enc = (amf_base *)data;
+	error("%s: %s: %ls", __FUNCTION__, err.str,
+	      amf_trace->GetResultText(err.res));
+	return false;
+}
+
+static bool amf_hevc_init(void *data, obs_data_t *settings)
+{
+	amf_base *enc = (amf_base *)data;
+
+	int64_t bitrate = obs_data_get_int(settings, "bitrate") * 1000;
+	int64_t qp = obs_data_get_int(settings, "cqp");
+	const char *preset = obs_data_get_string(settings, "preset");
+	const char *profile = obs_data_get_string(settings, "profile");
+	const char *rc_str = obs_data_get_string(settings, "rate_control");
+	int rc = get_hevc_rate_control(rc_str);
+
+	set_hevc_property(enc, RATE_CONTROL_METHOD, rc);
+	set_hevc_property(enc, ENABLE_VBAQ, true);
+
+	amf_hevc_update_data(enc, rc, bitrate, qp);
+
+	set_hevc_property(enc, ENFORCE_HRD, true);
+	set_hevc_property(enc, HIGH_MOTION_QUALITY_BOOST_ENABLE, false);
+
+	int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
+	int gop_size = (keyint_sec) ? keyint_sec * enc->fps_num / enc->fps_den
+				    : 250;
+
+	set_hevc_property(enc, GOP_SIZE, gop_size);
+
+	const char *ffmpeg_opts = obs_data_get_string(settings, "ffmpeg_opts");
+	if (ffmpeg_opts && *ffmpeg_opts) {
+		struct obs_options opts = obs_parse_options(ffmpeg_opts);
+		for (size_t i = 0; i < opts.count; i++) {
+			amf_apply_opt(enc, &opts.options[i]);
+		}
+		obs_free_options(opts);
+	}
+
+	if (!ffmpeg_opts || !*ffmpeg_opts)
+		ffmpeg_opts = "(none)";
+
+	info("settings:\n"
+	     "\trate_control: %s\n"
+	     "\tbitrate:      %d\n"
+	     "\tcqp:          %d\n"
+	     "\tkeyint:       %d\n"
+	     "\tpreset:       %s\n"
+	     "\tprofile:      %s\n"
+	     "\twidth:        %d\n"
+	     "\theight:       %d\n"
+	     "\tparams:       %s",
+	     rc_str, bitrate, qp, gop_size, preset, profile, enc->cx, enc->cy,
+	     ffmpeg_opts);
+
+	return true;
+}
+
+static inline bool is_hlg(amf_base *enc)
+{
+	return enc->amf_characteristic ==
+	       AMF_COLOR_TRANSFER_CHARACTERISTIC_ARIB_STD_B67;
+}
+
+static inline bool is_pq(amf_base *enc)
+{
+	return enc->amf_characteristic ==
+	       AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084;
+}
+
+constexpr amf_uint16 amf_hdr_primary(uint32_t num, uint32_t den)
+{
+	return (amf_uint16)(num * 50000 / den);
+}
+
+constexpr amf_uint32 lum_mul = 10000;
+constexpr float lum_mul_f = (float)lum_mul;
+
+constexpr amf_uint32 amf_make_lum(amf_uint32 val)
+{
+	return val * lum_mul;
+}
+
+static inline amf_uint32 amf_nominal_level()
+{
+	return (amf_uint32)(obs_get_video_hdr_nominal_peak_level() * lum_mul_f);
+}
+
+static void amf_hevc_create_internal(amf_base *enc, obs_data_t *settings)
+{
+	AMF_RESULT res;
+	AMFVariant p;
+
+	enc->codec = amf_codec_type::HEVC;
+
+	if (!amf_create_encoder(enc))
+		throw "Failed to create encoder";
+
+	AMFCapsPtr caps;
+	res = enc->amf_encoder->GetCaps(&caps);
+	if (res == AMF_OK) {
+		caps->GetProperty(AMF_VIDEO_ENCODER_HEVC_CAP_MAX_THROUGHPUT,
+				  &enc->max_throughput);
+	}
+
+	const bool is10bit = enc->amf_format == AMF_SURFACE_P010;
+	const bool pq = is_pq(enc);
+	const bool hlg = is_hlg(enc);
+	const bool is_hdr = pq || hlg;
+
+	set_hevc_property(enc, FRAMESIZE, AMFConstructSize(enc->cx, enc->cy));
+	set_hevc_property(enc, USAGE, AMF_VIDEO_ENCODER_USAGE_TRANSCONDING);
+	set_hevc_property(enc, QUALITY_PRESET, get_hevc_preset(enc, settings));
+	set_hevc_property(enc, COLOR_BIT_DEPTH,
+			  is10bit ? AMF_COLOR_BIT_DEPTH_10
+				  : AMF_COLOR_BIT_DEPTH_8);
+	set_hevc_property(enc, PROFILE,
+			  is10bit ? AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10
+				  : AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN);
+	set_hevc_property(enc, LOWLATENCY_MODE, false);
+	set_hevc_property(enc, OUTPUT_COLOR_PROFILE, enc->amf_color_profile);
+	set_hevc_property(enc, OUTPUT_TRANSFER_CHARACTERISTIC,
+			  enc->amf_characteristic);
+	set_hevc_property(enc, OUTPUT_COLOR_PRIMARIES, enc->amf_primaries);
+	set_hevc_property(enc, NOMINAL_RANGE, enc->full_range);
+
+	if (is_hdr) {
+		AMFBufferPtr buf;
+		enc->amf_context->AllocBuffer(AMF_MEMORY_HOST,
+					      sizeof(AMFHDRMetadata), &buf);
+		AMFHDRMetadata *md = (AMFHDRMetadata *)buf->GetNative();
+		md->redPrimary[0] = amf_hdr_primary(17, 25);
+		md->redPrimary[1] = amf_hdr_primary(8, 25);
+		md->greenPrimary[0] = amf_hdr_primary(53, 200);
+		md->greenPrimary[1] = amf_hdr_primary(69, 100);
+		md->bluePrimary[0] = amf_hdr_primary(3, 20);
+		md->bluePrimary[1] = amf_hdr_primary(3, 50);
+		md->whitePoint[0] = amf_hdr_primary(3127, 10000);
+		md->whitePoint[1] = amf_hdr_primary(329, 1000);
+		md->minMasteringLuminance = 0;
+		md->maxMasteringLuminance = pq ? amf_nominal_level()
+					       : (hlg ? amf_make_lum(1000) : 0);
+		md->maxContentLightLevel = 0;
+		md->maxFrameAverageLightLevel = 0;
+		set_hevc_property(enc, INPUT_HDR_METADATA, buf);
+	}
+
+	amf_hevc_init(enc, settings);
+
+	res = enc->amf_encoder->Init(enc->amf_format, enc->cx, enc->cy);
+	if (res != AMF_OK)
+		throw amf_error("AMFComponent::Init failed", res);
+
+	set_hevc_property(enc, FRAMERATE, enc->amf_frame_rate);
+
+	res = enc->amf_encoder->GetProperty(AMF_VIDEO_ENCODER_HEVC_EXTRADATA,
+					    &p);
+	if (res == AMF_OK && p.type == AMF_VARIANT_INTERFACE)
+		enc->header = AMFBufferPtr(p.pInterface);
+}
+
+static void *amf_hevc_create_texencode(obs_data_t *settings,
+				       obs_encoder_t *encoder)
+try {
+	check_texture_encode_capability(encoder, true);
+
+	amf_texencode *enc = new amf_texencode;
+	enc->encoder = encoder;
+	enc->encoder_str = "texture-amf-h265";
+
+	if (!amf_init_d3d11(enc))
+		throw "Failed to create D3D11";
+
+	amf_hevc_create_internal(enc, settings);
+	return enc;
+
+} catch (const amf_error &err) {
+	blog(LOG_ERROR, "[texture-amf-h265] %s: %s: %ls", __FUNCTION__, err.str,
+	     amf_trace->GetResultText(err.res));
+	return obs_encoder_create_rerouted(encoder, "h265_fallback_amf");
+
+} catch (const char *err) {
+	blog(LOG_ERROR, "[texture-amf-h265] %s: %s", __FUNCTION__, err);
+	return obs_encoder_create_rerouted(encoder, "h265_fallback_amf");
+}
+
+static void *amf_hevc_create_fallback(obs_data_t *settings,
+				      obs_encoder_t *encoder)
+try {
+	amf_fallback *enc = new amf_fallback;
+	enc->encoder = encoder;
+	enc->encoder_str = "fallback-amf-h265";
+
+	amf_hevc_create_internal(enc, settings);
+	return enc;
+
+} catch (const amf_error &err) {
+	blog(LOG_ERROR, "[texture-amf-h265] %s: %s: %ls", __FUNCTION__, err.str,
+	     amf_trace->GetResultText(err.res));
+	return nullptr;
+
+} catch (const char *err) {
+	blog(LOG_ERROR, "[texture-amf-h265] %s: %s", __FUNCTION__, err);
+	return nullptr;
+}
+
+static void register_hevc()
+{
+	struct obs_encoder_info amf_encoder_info = {};
+	amf_encoder_info.id = "h265_texture_amf";
+	amf_encoder_info.type = OBS_ENCODER_VIDEO;
+	amf_encoder_info.codec = "hevc";
+	amf_encoder_info.get_name = amf_hevc_get_name;
+	amf_encoder_info.create = amf_hevc_create_texencode;
+	amf_encoder_info.destroy = amf_destroy;
+	amf_encoder_info.update = amf_hevc_update;
+	amf_encoder_info.encode_texture = amf_encode_tex;
+	amf_encoder_info.get_defaults = amf_defaults;
+	amf_encoder_info.get_properties = amf_hevc_properties;
+	amf_encoder_info.get_extra_data = amf_extra_data;
+	amf_encoder_info.caps = OBS_ENCODER_CAP_PASS_TEXTURE |
+				OBS_ENCODER_CAP_DYN_BITRATE;
+
+	obs_register_encoder(&amf_encoder_info);
+
+	amf_encoder_info.id = "h265_fallback_amf";
+	amf_encoder_info.caps = OBS_ENCODER_CAP_INTERNAL |
+				OBS_ENCODER_CAP_DYN_BITRATE;
+	amf_encoder_info.encode_texture = nullptr;
+	amf_encoder_info.create = amf_hevc_create_fallback;
+	amf_encoder_info.encode = amf_encode_fallback;
+	amf_encoder_info.get_video_info = h265_video_info_fallback;
+
+	obs_register_encoder(&amf_encoder_info);
+}
+
+#endif //ENABLE_HEVC
+
+/* ========================================================================= */
+/* Global Stuff                                                              */
+
+extern "C" void amf_load(void)
+try {
+	AMF_RESULT res;
+
+	amf_module = LoadLibraryW(AMF_DLL_NAME);
+	if (!amf_module)
+		throw "No AMF library";
+
+	/* ----------------------------------- */
+	/* Check for AVC/HEVC support          */
+
+	BPtr<char> test_exe = os_get_executable_path_ptr("obs-amf-test.exe");
+	std::string caps_str;
+
+	os_process_pipe_t *pp = os_process_pipe_create(test_exe, "r");
+	if (!pp)
+		throw "Failed to launch the AMF test process I guess";
+
+	for (;;) {
+		char data[2048];
+		size_t len =
+			os_process_pipe_read(pp, (uint8_t *)data, sizeof(data));
+		if (!len)
+			break;
+
+		caps_str.append(data, len);
+	}
+
+	os_process_pipe_destroy(pp);
+
+	if (caps_str.empty())
+		throw "Seems the AMF test subprocess crashed. "
+		      "Better there than here I guess. "
+		      "Let's just skip loading AMF then I suppose.";
+
+	ConfigFile config;
+	if (config.OpenString(caps_str.c_str()) != 0)
+		throw "Failed to open config string";
+
+	const char *error = config_get_string(config, "error", "string");
+	if (error)
+		throw std::string(error);
+
+	uint32_t adapter_count = (uint32_t)config_num_sections(config);
+	bool avc_supported = false;
+	bool hevc_supported = false;
+
+	for (uint32_t i = 0; i < adapter_count; i++) {
+		std::string section = std::to_string(i);
+		adapter_caps &info = caps[i];
+
+		info.is_amd =
+			config_get_bool(config, section.c_str(), "is_amd");
+		info.supports_avc = config_get_bool(config, section.c_str(),
+						    "supports_avc");
+		info.supports_hevc = config_get_bool(config, section.c_str(),
+						     "supports_hevc");
+
+		avc_supported |= info.supports_avc;
+		hevc_supported |= info.supports_hevc;
+	}
+
+	if (!avc_supported || !hevc_supported)
+		throw "Neither AVC nor HEVC are supported by any devices";
+
+	/* ----------------------------------- */
+	/* Init AMF                            */
+
+	AMFInit_Fn init =
+		(AMFInit_Fn)GetProcAddress(amf_module, AMF_INIT_FUNCTION_NAME);
+	if (!init)
+		throw "Failed to get AMFInit address";
+
+	res = init(AMF_FULL_VERSION, &amf_factory);
+	if (res != AMF_OK)
+		throw amf_error("AMFInit failed", res);
+
+	res = amf_factory->GetTrace(&amf_trace);
+	if (res != AMF_OK)
+		throw amf_error("GetTrace failed", res);
+
+	AMFQueryVersion_Fn get_ver = (AMFQueryVersion_Fn)GetProcAddress(
+		amf_module, AMF_QUERY_VERSION_FUNCTION_NAME);
+	if (!get_ver)
+		throw "Failed to get AMFQueryVersion address";
+
+	res = get_ver(&amf_version);
+	if (res != AMF_OK)
+		throw amf_error("AMFQueryVersion failed", res);
+
+#ifndef DEBUG_AMF_STUFF
+	amf_trace->EnableWriter(AMF_TRACE_WRITER_DEBUG_OUTPUT, false);
+	amf_trace->EnableWriter(AMF_TRACE_WRITER_CONSOLE, false);
+#endif
+
+	/* ----------------------------------- */
+	/* Register encoders                   */
+
+	if (avc_supported)
+		register_avc();
+#if ENABLE_HEVC
+	if (hevc_supported)
+		register_hevc();
+#endif
+
+} catch (const std::string &str) {
+	/* doing debug here because string exceptions indicate the user is
+	 * probably not using AMD */
+	blog(LOG_DEBUG, "%s: %s", __FUNCTION__, str.c_str());
+
+} catch (const char *str) {
+	/* doing debug here because string exceptions indicate the user is
+	 * probably not using AMD */
+	blog(LOG_DEBUG, "%s: %s", __FUNCTION__, str);
+
+} catch (const amf_error &err) {
+	/* doing an error here because it means at least the library has loaded
+	 * successfully, so they probably have AMD at this point */
+	blog(LOG_ERROR, "%s: %s: 0x%lX", __FUNCTION__, err.str,
+	     (uint32_t)err.res);
+}
+
+extern "C" void amf_unload(void)
+{
+	if (amf_module && amf_trace) {
+		amf_trace->TraceFlush();
+		amf_trace->UnregisterWriter(L"obs_amf_trace_writer");
+	}
+}