From bb89b1fdb5c419a39c26315bfec4da64e1417170 Mon Sep 17 00:00:00 2001 From: OvchinnikovDmitrii Date: Fri, 22 Apr 2022 17:39:59 -0700 Subject: [PATCH] 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 --- plugins/obs-ffmpeg/CMakeLists.txt | 7 +- plugins/obs-ffmpeg/data/locale/en-US.ini | 10 + .../include/components/Ambisonic2SRenderer.h | 79 + .../AMF/include/components/AudioCapture.h | 86 + .../external/AMF/include/components/Capture.h | 198 ++ .../AMF/include/components/ChromaKey.h | 76 + .../AMF/include/components/ColorSpace.h | 138 ++ .../AMF/include/components/Component.h | 443 ++++ .../AMF/include/components/ComponentCaps.h | 172 ++ .../AMF/include/components/CursorCapture.h | 53 + .../AMF/include/components/DisplayCapture.h | 81 + .../include/components/FFMPEGAudioConverter.h | 62 + .../include/components/FFMPEGAudioDecoder.h | 68 + .../include/components/FFMPEGAudioEncoder.h | 66 + .../AMF/include/components/FFMPEGComponents.h | 54 + .../include/components/FFMPEGFileDemuxer.h | 66 + .../AMF/include/components/FFMPEGFileMuxer.h | 53 + .../include/components/FFMPEGVideoDecoder.h | 53 + .../AMF/include/components/HQScaler.h | 64 + .../AMF/include/components/MediaSource.h | 79 + .../AMF/include/components/PreAnalysis.h | 110 + .../AMF/include/components/PreProcessing.h | 59 + .../AMF/include/components/VideoCapture.h | 52 + .../AMF/include/components/VideoConverter.h | 121 + .../AMF/include/components/VideoDecoderUVD.h | 122 + .../AMF/include/components/VideoEncoderHEVC.h | 296 +++ .../AMF/include/components/VideoEncoderVCE.h | 326 +++ .../AMF/include/components/VideoStitch.h | 124 + .../AMF/include/components/ZCamLiveStream.h | 83 + .../external/AMF/include/core/AudioBuffer.h | 234 ++ .../external/AMF/include/core/Buffer.h | 187 ++ .../external/AMF/include/core/Compute.h | 302 +++ .../AMF/include/core/ComputeFactory.h | 147 ++ .../external/AMF/include/core/Context.h | 786 +++++++ .../external/AMF/include/core/CurrentTime.h | 52 + .../external/AMF/include/core/D3D12AMF.h | 44 + .../external/AMF/include/core/Data.h | 177 ++ .../external/AMF/include/core/Debug.h | 78 + .../external/AMF/include/core/Dump.h | 112 + .../external/AMF/include/core/Factory.h | 133 ++ .../external/AMF/include/core/Interface.h | 258 ++ .../external/AMF/include/core/Plane.h | 112 + .../external/AMF/include/core/Platform.h | 547 +++++ .../AMF/include/core/PropertyStorage.h | 275 +++ .../AMF/include/core/PropertyStorageEx.h | 207 ++ .../external/AMF/include/core/Result.h | 127 + .../external/AMF/include/core/Surface.h | 279 +++ .../external/AMF/include/core/Trace.h | 183 ++ .../external/AMF/include/core/Variant.h | 2075 +++++++++++++++++ .../external/AMF/include/core/Version.h | 59 + .../external/AMF/include/core/VulkanAMF.h | 108 + .../obs-ffmpeg/obs-amf-test/CMakeLists.txt | 11 + .../obs-ffmpeg/obs-amf-test/obs-amf-test.cpp | 131 ++ plugins/obs-ffmpeg/obs-ffmpeg.c | 8 + plugins/obs-ffmpeg/texture-amf-opts.hpp | 272 +++ plugins/obs-ffmpeg/texture-amf.cpp | 1732 ++++++++++++++ 56 files changed, 11835 insertions(+), 2 deletions(-) create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/Ambisonic2SRenderer.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/AudioCapture.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/Capture.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/ChromaKey.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/ColorSpace.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/Component.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/ComponentCaps.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/CursorCapture.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/DisplayCapture.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioConverter.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioDecoder.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioEncoder.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGComponents.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileDemuxer.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileMuxer.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGVideoDecoder.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/HQScaler.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/MediaSource.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/PreAnalysis.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/PreProcessing.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/VideoCapture.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/VideoConverter.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/VideoDecoderUVD.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderHEVC.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderVCE.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/VideoStitch.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/components/ZCamLiveStream.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/AudioBuffer.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Buffer.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Compute.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/ComputeFactory.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Context.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/CurrentTime.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/D3D12AMF.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Data.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Debug.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Dump.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Factory.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Interface.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Plane.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Platform.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorage.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorageEx.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Result.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Surface.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Trace.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Variant.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/Version.h create mode 100644 plugins/obs-ffmpeg/external/AMF/include/core/VulkanAMF.h create mode 100644 plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt create mode 100644 plugins/obs-ffmpeg/obs-amf-test/obs-amf-test.cpp create mode 100644 plugins/obs-ffmpeg/texture-amf-opts.hpp create mode 100644 plugins/obs-ffmpeg/texture-amf.cpp diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt index 239ecf31a92365..f3b091b59620cb 100644 --- a/plugins/obs-ffmpeg/CMakeLists.txt +++ b/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) diff --git a/plugins/obs-ffmpeg/data/locale/en-US.ini b/plugins/obs-ffmpeg/data/locale/en-US.ini index 0c5ccb2e011cfc..9790c47d7b76dc 100644 --- a/plugins/obs-ffmpeg/data/locale/en-US.ini +++ b/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." diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/Ambisonic2SRenderer.h b/plugins/obs-ffmpeg/external/AMF/include/components/Ambisonic2SRenderer.h new file mode 100644 index 00000000000000..63ac79770626cf --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/AudioCapture.h b/plugins/obs-ffmpeg/external/AMF/include/components/AudioCapture.h new file mode 100644 index 00000000000000..af5b4287689dd8 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/Capture.h b/plugins/obs-ffmpeg/external/AMF/include/components/Capture.h new file mode 100644 index 00000000000000..78fb12fcf8ba4c --- /dev/null +++ b/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 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 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__ \ No newline at end of file diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/ChromaKey.h b/plugins/obs-ffmpeg/external/AMF/include/components/ChromaKey.h new file mode 100644 index 00000000000000..82b3516f38b272 --- /dev/null +++ b/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__ diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/ColorSpace.h b/plugins/obs-ffmpeg/external/AMF/include/components/ColorSpace.h new file mode 100644 index 00000000000000..fa6c752d4093e7 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/Component.h b/plugins/obs-ffmpeg/external/AMF/include/components/Component.h new file mode 100644 index 00000000000000..2cd9fa5e460e09 --- /dev/null +++ b/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 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 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 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 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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/ComponentCaps.h b/plugins/obs-ffmpeg/external/AMF/include/components/ComponentCaps.h new file mode 100644 index 00000000000000..48197670dac9d4 --- /dev/null +++ b/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 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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/CursorCapture.h b/plugins/obs-ffmpeg/external/AMF/include/components/CursorCapture.h new file mode 100644 index 00000000000000..8b071c99acc6de --- /dev/null +++ b/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 AMFCursorCapturePtr; +} + +#endif // #ifndef AMF_CursorCapture_h diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/DisplayCapture.h b/plugins/obs-ffmpeg/external/AMF/include/components/DisplayCapture.h new file mode 100644 index 00000000000000..30820d6aab5d8c --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioConverter.h b/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioConverter.h new file mode 100644 index 00000000000000..5ce79cab608fbc --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioDecoder.h b/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioDecoder.h new file mode 100644 index 00000000000000..e0c324c6b9c9d9 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioEncoder.h b/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGAudioEncoder.h new file mode 100644 index 00000000000000..872080b1931958 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGComponents.h b/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGComponents.h new file mode 100644 index 00000000000000..a3fbaff2b01d4d --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileDemuxer.h b/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileDemuxer.h new file mode 100644 index 00000000000000..60fd2934a91bba --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileMuxer.h b/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGFileMuxer.h new file mode 100644 index 00000000000000..e8adf2bbc1cbfb --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGVideoDecoder.h b/plugins/obs-ffmpeg/external/AMF/include/components/FFMPEGVideoDecoder.h new file mode 100644 index 00000000000000..c844145d814c42 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/HQScaler.h b/plugins/obs-ffmpeg/external/AMF/include/components/HQScaler.h new file mode 100644 index 00000000000000..592dfb56aad630 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/MediaSource.h b/plugins/obs-ffmpeg/external/AMF/include/components/MediaSource.h new file mode 100644 index 00000000000000..1afdb6745ef69b --- /dev/null +++ b/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 AMFMediaSourcePtr; +} //namespace amf + +#endif //#ifndef AMF_MediaSource_h diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/PreAnalysis.h b/plugins/obs-ffmpeg/external/AMF/include/components/PreAnalysis.h new file mode 100644 index 00000000000000..2ab817f78920de --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/PreProcessing.h b/plugins/obs-ffmpeg/external/AMF/include/components/PreProcessing.h new file mode 100644 index 00000000000000..ab59d826b7155e --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/VideoCapture.h b/plugins/obs-ffmpeg/external/AMF/include/components/VideoCapture.h new file mode 100644 index 00000000000000..db0f6c0b23fc0f --- /dev/null +++ b/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 \ No newline at end of file diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/VideoConverter.h b/plugins/obs-ffmpeg/external/AMF/include/components/VideoConverter.h new file mode 100644 index 00000000000000..ed8559a206aed4 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/VideoDecoderUVD.h b/plugins/obs-ffmpeg/external/AMF/include/components/VideoDecoderUVD.h new file mode 100644 index 00000000000000..14ca91db1846c7 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderHEVC.h b/plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderHEVC.h new file mode 100644 index 00000000000000..c1ead898505caa --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderVCE.h b/plugins/obs-ffmpeg/external/AMF/include/components/VideoEncoderVCE.h new file mode 100644 index 00000000000000..6a9a9cc9a165db --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/VideoStitch.h b/plugins/obs-ffmpeg/external/AMF/include/components/VideoStitch.h new file mode 100644 index 00000000000000..0ae2af5275e761 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/components/ZCamLiveStream.h b/plugins/obs-ffmpeg/external/AMF/include/components/ZCamLiveStream.h new file mode 100644 index 00000000000000..7f4a6bbee8a2ed --- /dev/null +++ b/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 \ No newline at end of file diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/AudioBuffer.h b/plugins/obs-ffmpeg/external/AMF/include/core/AudioBuffer.h new file mode 100644 index 00000000000000..5f07dc4723fe35 --- /dev/null +++ b/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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Buffer.h b/plugins/obs-ffmpeg/external/AMF/include/core/Buffer.h new file mode 100644 index 00000000000000..15c2907813befe --- /dev/null +++ b/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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Compute.h b/plugins/obs-ffmpeg/external/AMF/include/core/Compute.h new file mode 100644 index 00000000000000..bc34749f9ffc1e --- /dev/null +++ b/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 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 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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/ComputeFactory.h b/plugins/obs-ffmpeg/external/AMF/include/core/ComputeFactory.h new file mode 100644 index 00000000000000..e335ee31c0dec4 --- /dev/null +++ b/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 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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Context.h b/plugins/obs-ffmpeg/external/AMF/include/core/Context.h new file mode 100644 index 00000000000000..3555f0803cc202 --- /dev/null +++ b/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 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 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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/CurrentTime.h b/plugins/obs-ffmpeg/external/AMF/include/core/CurrentTime.h new file mode 100644 index 00000000000000..dcbc35466a1ad6 --- /dev/null +++ b/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 AMFCurrentTimePtr; + //----------------------------------------------------------------------------------------------} +} +#endif // AMF_CurrentTime_h diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/D3D12AMF.h b/plugins/obs-ffmpeg/external/AMF/include/core/D3D12AMF.h new file mode 100644 index 00000000000000..19fa8ba880a2ef --- /dev/null +++ b/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__ \ No newline at end of file diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Data.h b/plugins/obs-ffmpeg/external/AMF/include/core/Data.h new file mode 100644 index 00000000000000..f32055a5105885 --- /dev/null +++ b/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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Debug.h b/plugins/obs-ffmpeg/external/AMF/include/core/Debug.h new file mode 100644 index 00000000000000..40610b01ce3a27 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Dump.h b/plugins/obs-ffmpeg/external/AMF/include/core/Dump.h new file mode 100644 index 00000000000000..b8c27446a2a5f8 --- /dev/null +++ b/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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Factory.h b/plugins/obs-ffmpeg/external/AMF/include/core/Factory.h new file mode 100644 index 00000000000000..ece7defaead442 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Interface.h b/plugins/obs-ffmpeg/external/AMF/include/core/Interface.h new file mode 100644 index 00000000000000..9ac7e41165f9c1 --- /dev/null +++ b/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 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 + 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 + 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 AMFInterfacePtr; + //---------------------------------------------------------------------------------------------- +#endif + +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef AMF_Interface_h diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Plane.h b/plugins/obs-ffmpeg/external/AMF/include/core/Plane.h new file mode 100644 index 00000000000000..6d3e9f946e9c40 --- /dev/null +++ b/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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Platform.h b/plugins/obs-ffmpeg/external/AMF/include/core/Platform.h new file mode 100644 index 00000000000000..7fa61cc932b051 --- /dev/null +++ b/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 +#include +#include + +#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 + + #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 + #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 + +#define media_status_t int +#define ANativeWindow void +#define JNIEnv void +#define jobject int +#define JavaVM void + +#endif + +#endif //#ifndef AMF_Platform_h diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorage.h b/plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorage.h new file mode 100644 index 00000000000000..9fb87bec0273de --- /dev/null +++ b/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 + AMF_RESULT AMF_STD_CALL SetProperty(const wchar_t* name, const _T& value); + template + AMF_RESULT AMF_STD_CALL GetProperty(const wchar_t* name, _T* pValue) const; + template + AMF_RESULT AMF_STD_CALL GetPropertyString(const wchar_t* name, _T* pValue) const; + template + AMF_RESULT AMF_STD_CALL GetPropertyWString(const wchar_t* name, _T* pValue) const; + + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T 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 inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::SetProperty(const wchar_t* name, const _T& value) + { + AMF_RESULT err = SetProperty(name, static_cast(AMFVariant(value))); + return err; + } + //---------------------------------------------------------------------------------------------- + template inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetProperty(const wchar_t* name, _T* pValue) const + { + AMFVariant var; + AMF_RESULT err = GetProperty(name, static_cast(&var)); + if(err == AMF_OK) + { + *pValue = static_cast<_T>(var); + } + return err; + } + //---------------------------------------------------------------------------------------------- + template inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetPropertyString(const wchar_t* name, _T* pValue) const + { + AMFVariant var; + AMF_RESULT err = GetProperty(name, static_cast(&var)); + if(err == AMF_OK) + { + *pValue = var.ToString().c_str(); + } + return err; + } + //---------------------------------------------------------------------------------------------- + template inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetPropertyWString(const wchar_t* name, _T* pValue) const + { + AMFVariant var; + AMF_RESULT err = GetProperty(name, static_cast(&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(&var)); + if(err == AMF_OK) + { + *ppValue = static_cast(var); + } + if(*ppValue) + { + (*ppValue)->Acquire(); + } + return err; + } +#endif // #if defined(__cplusplus) + +#if defined(__cplusplus) +} //namespace amf +#endif + +#endif // #ifndef AMF_PropertyStorage_h diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorageEx.h b/plugins/obs-ffmpeg/external/AMF/include/core/PropertyStorageEx.h new file mode 100644 index 00000000000000..94ccd1ea9b4d92 --- /dev/null +++ b/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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Result.h b/plugins/obs-ffmpeg/external/AMF/include/core/Result.h new file mode 100644 index 00000000000000..cf84bed730d4e9 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Surface.h b/plugins/obs-ffmpeg/external/AMF/include/core/Surface.h new file mode 100644 index 00000000000000..20b9a50c44c9b9 --- /dev/null +++ b/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 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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Trace.h b/plugins/obs-ffmpeg/external/AMF/include/core/Trace.h new file mode 100644 index 00000000000000..69b80739487b03 --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Variant.h b/plugins/obs-ffmpeg/external/AMF/include/core/Variant.h new file mode 100644 index 00000000000000..69e8874ab94581 --- /dev/null +++ b/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 +#include +#include + +#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(&other)); } + + explicit AMFVariant(const AMFVariantStruct* pOther); + template + explicit AMFVariant(const AMFInterfacePtr_T& pValue); + + AMFVariant(const AMFVariant& other) { AMFVariantInit(this); AMFVariantCopy(this, const_cast(static_cast(&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 AMFVariant& operator=(const AMFInterfacePtr_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(AMFVariantGetBool); } + AMF_INLINE amf_int64 ToInt64() const { return Empty() ? 0 : GetValue(AMFVariantGetInt64); } + AMF_INLINE amf_uint64 ToUInt64() const { return Empty() ? 0 : GetValue(AMFVariantGetInt64); } + AMF_INLINE amf_int32 ToInt32() const { return Empty() ? 0 : GetValue(AMFVariantGetInt64); } + AMF_INLINE amf_uint32 ToUInt32() const { return Empty() ? 0 : GetValue(AMFVariantGetInt64); } + AMF_INLINE amf_double ToDouble() const { return Empty() ? 0 : GetValue(AMFVariantGetDouble); } + AMF_INLINE amf_float ToFloat() const { return Empty() ? 0 : GetValue(AMFVariantGetFloat); } + AMF_INLINE AMFRect ToRect () const { return Empty() ? AMFRect() : GetValue(AMFVariantGetRect); } + AMF_INLINE AMFSize ToSize () const { return Empty() ? AMFSize() : GetValue(AMFVariantGetSize); } + AMF_INLINE AMFPoint ToPoint() const { return Empty() ? AMFPoint() : GetValue(AMFVariantGetPoint); } + AMF_INLINE AMFFloatSize ToFloatSize() const { return Empty() ? AMFFloatSize() : GetValue(AMFVariantGetFloatSize); } + AMF_INLINE AMFFloatPoint2D ToFloatPoint2D() const { return Empty() ? AMFFloatPoint2D() : GetValue(AMFVariantGetFloatPoint2D); } + AMF_INLINE AMFFloatPoint3D ToFloatPoint3D() const { return Empty() ? AMFFloatPoint3D() : GetValue(AMFVariantGetFloatPoint3D); } + AMF_INLINE AMFFloatVector4D ToFloatVector4D() const { return Empty() ? AMFFloatVector4D() : GetValue(AMFVariantGetFloatVector4D); } + AMF_INLINE AMFRate ToRate () const { return Empty() ? AMFRate() : GetValue(AMFVariantGetRate); } + AMF_INLINE AMFRatio ToRatio() const { return Empty() ? AMFRatio() : GetValue(AMFVariantGetRatio); } + AMF_INLINE AMFColor ToColor() const { return Empty() ? AMFColor() : GetValue(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 + 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(AMFVariantGetString); + return String(temp.c_str()); + } + //------------------------------------------------------------------------------------------------- + AMFVariant::WString AMFVariant::ToWString() const + { + WString temp = GetValue(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(pOther)); + } + } + //------------------------------------------------------------------------------------------------- + template + AMFVariant::AMFVariant(const AMFInterfacePtr_T& pValue) + { + AMFVariantInit(this); + AMFVariantAssignInterface(this, pValue); + } + //------------------------------------------------------------------------------------------------- + template + ReturnType AMFVariant::GetValue(Getter getter) const + { + ReturnType str = ReturnType(); + if(AMFVariantGetType(this) == variantType) + { + str = static_cast(getter(this)); + } + else + { + AMFVariant varDest; + varDest.ChangeType(variantType, this); + if(varDest.type != AMF_VARIANT_EMPTY) + { + str = static_cast(getter(&varDest)); + } + } + return str; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariantStruct& other) + { + AMFVariantCopy(this, const_cast(&other)); + return *this; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariantStruct* pOther) + { + if(pOther != NULL) + { + AMFVariantCopy(this, const_cast(pOther)); + } + return *this; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariant& other) + { + AMFVariantCopy(this, + const_cast(static_cast(&other))); + return *this; + } + //------------------------------------------------------------------------------------------------- + template + AMFVariant& AMFVariant::operator=(const AMFInterfacePtr_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(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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/Version.h b/plugins/obs-ffmpeg/external/AMF/include/core/Version.h new file mode 100644 index 00000000000000..10fba299d5c39b --- /dev/null +++ b/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 diff --git a/plugins/obs-ffmpeg/external/AMF/include/core/VulkanAMF.h b/plugins/obs-ffmpeg/external/AMF/include/core/VulkanAMF.h new file mode 100644 index 00000000000000..459d5538ca9612 --- /dev/null +++ b/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__ diff --git a/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt b/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt new file mode 100644 index 00000000000000..85347e73dfeaf0 --- /dev/null +++ b/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) diff --git a/plugins/obs-ffmpeg/obs-amf-test/obs-amf-test.cpp b/plugins/obs-ffmpeg/obs-amf-test/obs-amf-test.cpp new file mode 100644 index 00000000000000..4064193d33c48f --- /dev/null +++ b/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 + +#include +#include +#include + +#include +#include + +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 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 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 output; + hr = adapter->EnumOutputs(0, &output); + if (FAILED(hr)) + return true; + + ComPtr device; + ComPtr 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 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; +} diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c index da9ef85cd5fee9..e081d721a58640 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg.c +++ b/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 } diff --git a/plugins/obs-ffmpeg/texture-amf-opts.hpp b/plugins/obs-ffmpeg/texture-amf-opts.hpp new file mode 100644 index 00000000000000..f07b553a0cd347 --- /dev/null +++ b/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); + } + } +} diff --git a/plugins/obs-ffmpeg/texture-amf.cpp b/plugins/obs-ffmpeg/texture-amf.cpp new file mode 100644 index 00000000000000..306da3cda2a9ce --- /dev/null +++ b/plugins/obs-ffmpeg/texture-amf.cpp @@ -0,0 +1,1732 @@ +#include +#include +#include +#include + +#include "obs-ffmpeg-config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include + +#include +#include +#include +#include +#include +#include + +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 tex; + ComPtr km; +}; + +struct adapter_caps { + bool is_amd = false; + bool supports_avc = false; + bool supports_hevc = false; +}; + +/* ------------------------------------------------------------------------- */ + +static std::map 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 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; +using buf_t = std::vector; + +struct amf_texencode : amf_base, public AMFSurfaceObserver { + volatile bool destroying = false; + + std::vector input_textures; + + std::mutex textures_mutex; + std::vector available_textures; + std::unordered_map active_textures; + + ComPtr device; + ComPtr 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 available_buffers; + std::unordered_map 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 +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 +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 factory; + ComPtr device; + ComPtr context; + ComPtr 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 &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 &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 &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 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 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 output_tex; + ComPtr input_tex; + ComPtr 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, NUM_GOPS_PER_IDR, 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 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"); + } +}