This commit is contained in:
mofeng-git
2025-12-28 18:19:16 +08:00
commit d143d158e4
771 changed files with 220548 additions and 0 deletions

View File

@@ -0,0 +1,262 @@
//
// 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.
//
#include "AMFFactory.h"
#include "Thread.h"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#endif
AMFFactoryHelper g_AMFFactory;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef AMF_CORE_STATIC
extern "C"
{
extern AMF_CORE_LINK AMF_RESULT AMF_CDECL_CALL AMFInit(amf_uint64 version, amf::AMFFactory **ppFactory);
}
#endif
//-------------------------------------------------------------------------------------------------
AMFFactoryHelper::AMFFactoryHelper() :
m_hDLLHandle(NULL),
m_pFactory(NULL),
m_pDebug(NULL),
m_pTrace(NULL),
m_AMFRuntimeVersion(0),
m_iRefCount(0)
{
}
//-------------------------------------------------------------------------------------------------
AMFFactoryHelper::~AMFFactoryHelper()
{
Terminate();
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMFFactoryHelper::Init(const wchar_t* dllName)
{
dllName;
#ifndef AMF_CORE_STATIC
if (m_hDLLHandle != NULL)
{
amf_atomic_inc(&m_iRefCount);
return AMF_OK;
}
const wchar_t* dllName_ = dllName == NULL ? AMF_DLL_NAME : dllName;
#if defined (_WIN32) || defined (__APPLE__)
m_hDLLHandle = amf_load_library(dllName_);
#else
m_hDLLHandle = amf_load_library1(dllName_, false); //load with local flags
#endif
if(m_hDLLHandle == NULL)
{
return AMF_FAIL;
}
AMFInit_Fn initFun = (AMFInit_Fn)::amf_get_proc_address(m_hDLLHandle, AMF_INIT_FUNCTION_NAME);
if(initFun == NULL)
{
return AMF_FAIL;
}
AMF_RESULT res = initFun(AMF_FULL_VERSION, &m_pFactory);
if(res != AMF_OK)
{
return res;
}
AMFQueryVersion_Fn versionFun = (AMFQueryVersion_Fn)::amf_get_proc_address(m_hDLLHandle, AMF_QUERY_VERSION_FUNCTION_NAME);
if(versionFun == NULL)
{
return AMF_FAIL;
}
res = versionFun(&m_AMFRuntimeVersion);
if(res != AMF_OK)
{
return res;
}
#else
AMF_RESULT res = AMFInit(AMF_FULL_VERSION, &m_pFactory);
if (res != AMF_OK)
{
return res;
}
m_AMFRuntimeVersion = AMF_FULL_VERSION;
#endif
m_pFactory->GetTrace(&m_pTrace);
m_pFactory->GetDebug(&m_pDebug);
amf_atomic_inc(&m_iRefCount);
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMFFactoryHelper::Terminate()
{
if(m_hDLLHandle != NULL)
{
amf_atomic_dec(&m_iRefCount);
if(m_iRefCount == 0)
{
amf_free_library(m_hDLLHandle);
m_hDLLHandle = NULL;
m_pFactory= NULL;
m_pDebug = NULL;
m_pTrace = NULL;
}
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
amf::AMFFactory* AMFFactoryHelper::GetFactory()
{
return m_pFactory;
}
//-------------------------------------------------------------------------------------------------
amf::AMFDebug* AMFFactoryHelper::GetDebug()
{
return m_pDebug;
}
//-------------------------------------------------------------------------------------------------
amf::AMFTrace* AMFFactoryHelper::GetTrace()
{
return m_pTrace;
}
//-------------------------------------------------------------------------------------------------
amf_uint64 AMFFactoryHelper::AMFQueryVersion()
{
return m_AMFRuntimeVersion;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMFFactoryHelper::LoadExternalComponent(amf::AMFContext* pContext, const wchar_t* dll, const char* function, void* reserved, amf::AMFComponent** ppComponent)
{
// check passed in parameters
if (!pContext || !dll || !function)
{
return AMF_INVALID_ARG;
}
// check if DLL has already been loaded
amf_handle hDll = NULL;
for (std::vector<ComponentHolder>::iterator it = m_extComponents.begin(); it != m_extComponents.end(); ++it)
{
#if defined(_WIN32)
if (wcsicmp(it->m_DLL.c_str(), dll) == 0) // ignore case on Windows
#elif defined(__linux) // Linux
if (wcscmp(it->m_DLL.c_str(), dll) == 0) // case sensitive on Linux
#endif
{
if (it->m_hDLLHandle != NULL)
{
hDll = it->m_hDLLHandle;
amf_atomic_inc(&it->m_iRefCount);
break;
}
return AMF_UNEXPECTED;
}
}
// DLL wasn't loaded before so load it now and
// add it to the internal list
if (hDll == NULL)
{
ComponentHolder component;
component.m_iRefCount = 0;
component.m_hDLLHandle = NULL;
component.m_DLL = dll;
#if defined(_WIN32) || defined(__APPLE__)
hDll = amf_load_library(dll);
#else
hDll = amf_load_library1(dll, false); //global flag set to true
#endif
if (hDll == NULL)
return AMF_FAIL;
// since LoadLibrary succeeded add the information
// into the internal list so we can properly free
// the DLL later on, even if we fail to get the
// required information from it...
component.m_hDLLHandle = hDll;
amf_atomic_inc(&component.m_iRefCount);
m_extComponents.push_back(component);
}
// look for function we want in the dll we just loaded
typedef AMF_RESULT(AMF_CDECL_CALL *AMFCreateComponentFunc)(amf::AMFContext*, void* reserved, amf::AMFComponent**);
AMFCreateComponentFunc initFn = (AMFCreateComponentFunc)::amf_get_proc_address(hDll, function);
if (initFn == NULL)
return AMF_FAIL;
return initFn(pContext, reserved, ppComponent);
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMFFactoryHelper::UnLoadExternalComponent(const wchar_t* dll)
{
if (!dll)
{
return AMF_INVALID_ARG;
}
for (std::vector<ComponentHolder>::iterator it = m_extComponents.begin(); it != m_extComponents.end(); ++it)
{
#if defined(_WIN32)
if (wcsicmp(it->m_DLL.c_str(), dll) == 0) // ignore case on Windows
#elif defined(__linux) // Linux
if (wcscmp(it->m_DLL.c_str(), dll) == 0) // case sensitive on Linux
#endif
{
if (it->m_hDLLHandle == NULL)
{
return AMF_UNEXPECTED;
}
amf_atomic_dec(&it->m_iRefCount);
if (it->m_iRefCount == 0)
{
amf_free_library(it->m_hDLLHandle);
m_extComponents.erase(it);
}
break;
}
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,89 @@
//
// 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_AMFFactory_h
#define AMF_AMFFactory_h
#pragma once
#include "../include/core/Factory.h"
#include <string>
#include <vector>
class AMFFactoryHelper
{
public:
AMFFactoryHelper();
virtual ~AMFFactoryHelper();
AMF_RESULT Init(const wchar_t* dllName = NULL);
AMF_RESULT Terminate();
AMF_RESULT LoadExternalComponent(amf::AMFContext* pContext, const wchar_t* dll, const char* function, void* reserved, amf::AMFComponent** ppComponent);
AMF_RESULT UnLoadExternalComponent(const wchar_t* dll);
amf::AMFFactory* GetFactory();
amf::AMFDebug* GetDebug();
amf::AMFTrace* GetTrace();
amf_uint64 AMFQueryVersion();
amf_handle GetAMFDLLHandle() { return m_hDLLHandle; }
protected:
struct ComponentHolder
{
amf_handle m_hDLLHandle;
amf_long m_iRefCount;
std::wstring m_DLL;
ComponentHolder()
{
m_hDLLHandle = NULL;
m_iRefCount = 0;
}
};
amf_handle m_hDLLHandle;
amf::AMFFactory* m_pFactory;
amf::AMFDebug* m_pDebug;
amf::AMFTrace* m_pTrace;
amf_uint64 m_AMFRuntimeVersion;
amf_long m_iRefCount;
std::vector<ComponentHolder> m_extComponents;
};
extern ::AMFFactoryHelper g_AMFFactory;
#endif // AMF_AMFFactory_h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,362 @@
//
// 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_AMFSTL_h
#define AMF_AMFSTL_h
#pragma once
#if defined(__GNUC__)
//disable gcc warinings on STL code
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#include <memory> //default stl allocator
#else
#include <xmemory> //default stl allocator
#endif
#include <algorithm>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include "../include/core/Interface.h"
#if defined(__cplusplus)
extern "C"
{
#endif
// allocator
void* AMF_STD_CALL amf_alloc(amf_size count);
void AMF_STD_CALL amf_free(void* ptr);
void* AMF_STD_CALL amf_aligned_alloc(size_t count, size_t alignment);
void AMF_STD_CALL amf_aligned_free(void* ptr);
#if defined(__cplusplus)
}
#endif
namespace amf
{
#pragma warning(push)
#pragma warning(disable: 4996) // was declared deprecated
//-------------------------------------------------------------------------------------------------
// STL allocator redefined - will allocate all memory in "C" runtime of Common.DLL
//-------------------------------------------------------------------------------------------------
template<class _Ty>
class amf_allocator : public std::allocator<_Ty>
{
public:
amf_allocator() : std::allocator<_Ty>()
{}
amf_allocator(const amf_allocator<_Ty>& rhs) : std::allocator<_Ty>(rhs)
{}
template<class _Other> amf_allocator(const amf_allocator<_Other>& rhs) : std::allocator<_Ty>(rhs)
{}
template<class _Other> struct rebind // convert an allocator<_Ty> to an allocator <_Other>
{
typedef amf_allocator<_Other> other;
};
void deallocate(_Ty* const _Ptr, const size_t _Count)
{
_Count;
amf_free((void*)_Ptr);
}
_Ty* allocate(const size_t _Count, const void* = static_cast<const void*>(0))
{ // allocate array of _Count el ements
return static_cast<_Ty*>(amf_alloc(_Count * sizeof(_Ty)));
}
};
//-------------------------------------------------------------------------------------------------
// STL container templates with changed memory allocation
//-------------------------------------------------------------------------------------------------
template<class _Ty>
class amf_vector
: public std::vector<_Ty, amf_allocator<_Ty> >
{
public:
typedef std::vector<_Ty, amf_allocator<_Ty> > _base;
amf_vector() : _base() {}
explicit amf_vector(size_t _Count) : _base(_Count) {} //MM GCC has strange compile error. to get around replaced size_type with size_t
amf_vector(size_t _Count, const _Ty& _Val) : _base(_Count,_Val) {}
};
template<class _Ty>
class amf_list
: public std::list<_Ty, amf_allocator<_Ty> >
{};
template<class _Ty>
class amf_deque
: public std::deque<_Ty, amf_allocator<_Ty> >
{};
template<class _Ty>
class amf_queue
: public std::queue<_Ty, amf_deque<_Ty> >
{};
template<class _Kty, class _Ty, class _Pr = std::less<_Kty> >
class amf_map
: public std::map<_Kty, _Ty, _Pr, amf_allocator<std::pair<const _Kty, _Ty>> >
{};
template<class _Kty, class _Pr = std::less<_Kty> >
class amf_set
: public std::set<_Kty, _Pr, amf_allocator<_Kty> >
{};
template<class _Ty>
class amf_limited_deque
: public amf_deque<_Ty> // circular queue of pointers to blocks
{
public:
typedef amf_deque<_Ty> _base;
amf_limited_deque(size_t size_limit) : _base(), _size_limit(size_limit)
{ // construct empty deque
}
size_t size_limit()
{
return _size_limit;
}
void set_size_limit(size_t size_limit)
{
_size_limit = size_limit;
while(_base::size() > _size_limit)
{
_base::pop_front();
}
}
_Ty push_front(const _Ty& _Val)
{ // insert element at beginning
_Ty ret;
if(_size_limit > 0)
{
_base::push_front(_Val);
if(_base::size() > _size_limit)
{
ret = _base::back();
_base::pop_back();
}
}
return ret;
}
void push_front_ex(const _Ty& _Val)
{ // insert element at beginning
_base::push_front(_Val);
}
_Ty push_back(const _Ty& _Val)
{ // insert element at beginning
_Ty ret;
if(_size_limit > 0)
{
_base::push_back(_Val);
if(_base::size() > _size_limit)
{
ret = _base::front();
_base::pop_front();
}
}
return ret;
}
protected:
size_t _size_limit;
};
#pragma warning(pop)
//---------------------------------------------------------------
#if defined(__GNUC__)
//disable gcc warinings on STL code
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#endif
template<class _Interf>
class AMFInterfacePtr_TAdapted : public AMFInterfacePtr_T<_Interf>
{
public:
AMFInterfacePtr_TAdapted* operator&()
{
return this;
}
AMFInterfacePtr_TAdapted()
: AMFInterfacePtr_T<_Interf>()
{}
AMFInterfacePtr_TAdapted(_Interf* pOther)
: AMFInterfacePtr_T<_Interf>(pOther)
{}
AMFInterfacePtr_TAdapted(const AMFInterfacePtr_T<_Interf>& other)
: AMFInterfacePtr_T<_Interf>(other)
{}
};
template<class _Interf>
class amf_vector<AMFInterfacePtr_T<_Interf> >
: public std::vector<AMFInterfacePtr_TAdapted<_Interf>, amf_allocator<AMFInterfacePtr_TAdapted<_Interf> > >
{
public:
typedef AMFInterfacePtr_T<_Interf>& reference;
typedef std::vector<AMFInterfacePtr_TAdapted<_Interf>, amf_allocator<AMFInterfacePtr_TAdapted<_Interf> > > baseclass;
reference operator[](size_t n)
{
return baseclass::operator[](n);
}
};
template<class _Interf>
class amf_deque<AMFInterfacePtr_T<_Interf> >
: public std::deque<AMFInterfacePtr_TAdapted<_Interf>, amf_allocator<AMFInterfacePtr_TAdapted<_Interf> > >
{};
template<class _Interf>
class amf_list<AMFInterfacePtr_T<_Interf> >
: public std::list<AMFInterfacePtr_TAdapted<_Interf>, amf_allocator<AMFInterfacePtr_TAdapted<_Interf> > >
{};
#if defined(__GNUC__)
// restore gcc warnings
#pragma GCC diagnostic pop
#endif
}
//-------------------------------------------------------------------------------------------------
// string classes
//-------------------------------------------------------------------------------------------------
typedef std::basic_string<char, std::char_traits<char>, amf::amf_allocator<char> > amf_string;
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, amf::amf_allocator<wchar_t> > amf_wstring;
template <class TAmfString>
std::size_t amf_string_hash(TAmfString const& s) noexcept
{
#if defined(_WIN64) || defined(__x86_64__)
constexpr size_t fnvOffsetBasis = 14695981039346656037ULL;
constexpr size_t fnvPrime = 1099511628211ULL;
#else // defined(_WIN64) || defined(__x86_64__)
constexpr size_t fnvOffsetBasis = 2166136261U;
constexpr size_t fnvPrime = 16777619U;
#endif // defined(_WIN64) || defined(__x86_64__)
const unsigned char* const pStr = reinterpret_cast<const unsigned char*>(s.c_str());
const size_t count = s.size() * sizeof(typename TAmfString::value_type);
size_t value = fnvOffsetBasis;
for (size_t i = 0; i < count; ++i)
{
value ^= static_cast<size_t>(pStr[i]);
value *= fnvPrime;
}
return value;
}
template<>
struct std::hash<amf_wstring>
{
std::size_t operator()(amf_wstring const& s) const noexcept
{
return amf_string_hash<amf_wstring>(s);
}
};
template<>
struct std::hash<amf_string>
{
std::size_t operator()(amf_string const& s) const noexcept
{
return amf_string_hash<amf_string>(s);
}
};
namespace amf
{
//-------------------------------------------------------------------------------------------------
// string conversion
//-------------------------------------------------------------------------------------------------
amf_string AMF_STD_CALL amf_from_unicode_to_utf8(const amf_wstring& str);
amf_wstring AMF_STD_CALL amf_from_utf8_to_unicode(const amf_string& str);
amf_string AMF_STD_CALL amf_from_unicode_to_multibyte(const amf_wstring& str);
amf_wstring AMF_STD_CALL amf_from_multibyte_to_unicode(const amf_string& str);
amf_string AMF_STD_CALL amf_from_string_to_hex_string(const amf_string& str);
amf_string AMF_STD_CALL amf_from_hex_string_to_string(const amf_string& str);
amf_string AMF_STD_CALL amf_string_to_lower(const amf_string& str);
amf_wstring AMF_STD_CALL amf_string_to_lower(const amf_wstring& str);
amf_string AMF_STD_CALL amf_string_to_upper(const amf_string& str);
amf_wstring AMF_STD_CALL amf_string_to_upper(const amf_wstring& str);
amf_string AMF_STD_CALL amf_from_unicode_to_url_utf8(const amf_wstring& data, bool bQuery = false); // converts to UTF8 and replace fobidden symbols
amf_wstring AMF_STD_CALL amf_from_url_utf8_to_unicode(const amf_string& data);
amf_wstring AMF_STD_CALL amf_convert_path_to_os_accepted_path(const amf_wstring& path);
amf_wstring AMF_STD_CALL amf_convert_path_to_url_accepted_path(const amf_wstring& path);
//-------------------------------------------------------------------------------------------------
// string helpers
//-------------------------------------------------------------------------------------------------
amf_wstring AMF_STD_CALL amf_string_format(const wchar_t* format, ...);
amf_string AMF_STD_CALL amf_string_format(const char* format, ...);
amf_wstring AMF_STD_CALL amf_string_formatVA(const wchar_t* format, va_list args);
amf_string AMF_STD_CALL amf_string_formatVA(const char* format, va_list args);
amf_int AMF_STD_CALL amf_string_ci_compare(const amf_wstring& left, const amf_wstring& right);
amf_int AMF_STD_CALL amf_string_ci_compare(const amf_string& left, const amf_string& right);
amf_size AMF_STD_CALL amf_string_ci_find(const amf_wstring& left, const amf_wstring& right, amf_size off = 0);
amf_size AMF_STD_CALL amf_string_ci_rfind(const amf_wstring& left, const amf_wstring& right, amf_size off = amf_wstring::npos);
//-------------------------------------------------------------------------------------------------
} // namespace amf
#if defined(__GNUC__)
// restore gcc warnings
#pragma GCC diagnostic pop
#endif
#endif // AMF_AMFSTL_h

View File

@@ -0,0 +1,136 @@
//
// 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_ByteArray_h
#define AMF_ByteArray_h
#pragma once
#include "../include/core/Platform.h"
#define INIT_ARRAY_SIZE 1024
#define ARRAY_MAX_SIZE (1LL << 60LL) // extremely large maximum size
//------------------------------------------------------------------------
class AMFByteArray
{
protected:
amf_uint8 *m_pData;
amf_size m_iSize;
amf_size m_iMaxSize;
public:
AMFByteArray() : m_pData(0), m_iSize(0), m_iMaxSize(0)
{
}
AMFByteArray(const AMFByteArray &other) : m_pData(0), m_iSize(0), m_iMaxSize(0)
{
*this = other;
}
AMFByteArray(amf_size num) : m_pData(0), m_iSize(0), m_iMaxSize(0)
{
SetSize(num);
}
virtual ~AMFByteArray()
{
if (m_pData != 0)
{
delete[] m_pData;
}
}
void SetSize(amf_size num)
{
if (num == m_iSize)
{
return;
}
if (num < m_iSize)
{
memset(m_pData + num, 0, m_iMaxSize - num);
}
else if (num > m_iMaxSize)
{
// This is done to prevent the following error from surfacing
// for the pNewData allocation on some compilers:
// -Werror=alloc-size-larger-than=
amf_size newSize = (num / INIT_ARRAY_SIZE) * INIT_ARRAY_SIZE + INIT_ARRAY_SIZE;
if (newSize > ARRAY_MAX_SIZE)
{
return;
}
m_iMaxSize = newSize;
amf_uint8 *pNewData = new amf_uint8[m_iMaxSize];
memset(pNewData, 0, m_iMaxSize);
if (m_pData != NULL)
{
memcpy(pNewData, m_pData, m_iSize);
delete[] m_pData;
}
m_pData = pNewData;
}
m_iSize = num;
}
void Copy(const AMFByteArray &old)
{
if (m_iMaxSize < old.m_iSize)
{
m_iMaxSize = old.m_iMaxSize;
if (m_pData != NULL)
{
delete[] m_pData;
}
m_pData = new amf_uint8[m_iMaxSize];
memset(m_pData, 0, m_iMaxSize);
}
memcpy(m_pData, old.m_pData, old.m_iSize);
m_iSize = old.m_iSize;
}
amf_uint8 operator[] (amf_size iPos) const
{
return m_pData[iPos];
}
amf_uint8& operator[] (amf_size iPos)
{
return m_pData[iPos];
}
AMFByteArray& operator=(const AMFByteArray &other)
{
SetSize(other.GetSize());
if (GetSize() > 0)
{
memcpy(GetData(), other.GetData(), GetSize());
}
return *this;
}
amf_uint8 *GetData() const { return m_pData; }
amf_size GetSize() const { return m_iSize; }
};
#endif // AMF_ByteArray_h

View File

@@ -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) 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.
//
#include <iostream>
#include <vector>
#include <bitset>
#include <array>
#include <string>
#include <cstring>
#if defined(_WIN32)
#include <intrin.h>
#else
#include <stdint.h>
#endif
class InstructionSet
{
// forward declarations
class InstructionSet_Internal;
public:
// getters
static std::string Vendor(void) { return CPU_Rep.vendor_; }
static std::string Brand(void) { return CPU_Rep.brand_; }
static bool SSE3(void) { return CPU_Rep.f_1_ECX_[0]; }
static bool PCLMULQDQ(void) { return CPU_Rep.f_1_ECX_[1]; }
static bool MONITOR(void) { return CPU_Rep.f_1_ECX_[3]; }
static bool SSSE3(void) { return CPU_Rep.f_1_ECX_[9]; }
static bool FMA(void) { return CPU_Rep.f_1_ECX_[12]; }
static bool CMPXCHG16B(void) { return CPU_Rep.f_1_ECX_[13]; }
static bool SSE41(void) { return CPU_Rep.f_1_ECX_[19]; }
static bool SSE42(void) { return CPU_Rep.f_1_ECX_[20]; }
static bool MOVBE(void) { return CPU_Rep.f_1_ECX_[22]; }
static bool POPCNT(void) { return CPU_Rep.f_1_ECX_[23]; }
static bool AES(void) { return CPU_Rep.f_1_ECX_[25]; }
static bool XSAVE(void) { return CPU_Rep.f_1_ECX_[26]; }
static bool OSXSAVE(void) { return CPU_Rep.f_1_ECX_[27]; }
static bool AVX(void) { return CPU_Rep.f_1_ECX_[28]; }
static bool F16C(void) { return CPU_Rep.f_1_ECX_[29]; }
static bool RDRAND(void) { return CPU_Rep.f_1_ECX_[30]; }
static bool MSR(void) { return CPU_Rep.f_1_EDX_[5]; }
static bool CX8(void) { return CPU_Rep.f_1_EDX_[8]; }
static bool SEP(void) { return CPU_Rep.f_1_EDX_[11]; }
static bool CMOV(void) { return CPU_Rep.f_1_EDX_[15]; }
static bool CLFSH(void) { return CPU_Rep.f_1_EDX_[19]; }
static bool MMX(void) { return CPU_Rep.f_1_EDX_[23]; }
static bool FXSR(void) { return CPU_Rep.f_1_EDX_[24]; }
static bool SSE(void) { return CPU_Rep.f_1_EDX_[25]; }
static bool SSE2(void) { return CPU_Rep.f_1_EDX_[26]; }
static bool FSGSBASE(void) { return CPU_Rep.f_7_EBX_[0]; }
static bool BMI1(void) { return CPU_Rep.f_7_EBX_[3]; }
static bool HLE(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_7_EBX_[4]; }
static bool AVX2(void) { return CPU_Rep.f_7_EBX_[5]; }
static bool BMI2(void) { return CPU_Rep.f_7_EBX_[8]; }
static bool ERMS(void) { return CPU_Rep.f_7_EBX_[9]; }
static bool INVPCID(void) { return CPU_Rep.f_7_EBX_[10]; }
static bool RTM(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_7_EBX_[11]; }
static bool AVX512F(void) { return CPU_Rep.f_7_EBX_[16]; }
static bool RDSEED(void) { return CPU_Rep.f_7_EBX_[18]; }
static bool ADX(void) { return CPU_Rep.f_7_EBX_[19]; }
static bool AVX512PF(void) { return CPU_Rep.f_7_EBX_[26]; }
static bool AVX512ER(void) { return CPU_Rep.f_7_EBX_[27]; }
static bool AVX512CD(void) { return CPU_Rep.f_7_EBX_[28]; }
static bool SHA(void) { return CPU_Rep.f_7_EBX_[29]; }
static bool AVX512BW(void) { return CPU_Rep.f_7_EBX_[30]; }
static bool AVX512VL(void) { return CPU_Rep.f_7_EBX_[31]; }
static bool PREFETCHWT1(void) { return CPU_Rep.f_7_ECX_[0]; }
static bool LAHF(void) { return CPU_Rep.f_81_ECX_[0]; }
static bool LZCNT(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_ECX_[5]; }
static bool ABM(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[5]; }
static bool SSE4a(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[6]; }
static bool XOP(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[11]; }
static bool TBM(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_ECX_[21]; }
static bool SYSCALL(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_EDX_[11]; }
static bool MMXEXT(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[22]; }
static bool RDTSCP(void) { return CPU_Rep.isIntel_ && CPU_Rep.f_81_EDX_[27]; }
static bool _3DNOWEXT(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[30]; }
static bool _3DNOW(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[31]; }
private:
static const InstructionSet_Internal CPU_Rep;
class InstructionSet_Internal
{
protected:
void GetCpuID
(
int32_t registers[4], //out
int32_t functionID,
int32_t subfunctionID = 0
)
{
#ifdef _WIN32
if(!subfunctionID)
{
__cpuid((int *)registers, (int)functionID);
}
else
{
__cpuidex((int *)registers, (int)functionID, subfunctionID);
}
#else
asm volatile
(
"cpuid":
"=a" (registers[0]),
"=b" (registers[1]),
"=c" (registers[2]),
"=d" (registers[3]):
"a" (functionID),
"c" (subfunctionID)
);
#endif
}
public:
InstructionSet_Internal()
: nIds_( 0 ),
nExIds_( 0 ),
isIntel_( false ),
isAMD_( false ),
f_1_ECX_( 0 ),
f_1_EDX_( 0 ),
f_7_EBX_( 0 ),
f_7_ECX_( 0 ),
f_81_ECX_( 0 ),
f_81_EDX_( 0 )
{
//int cpuInfo[4] = {-1};
std::array<int, 4> cpui;
// Calling __cpuid with 0x0 as the function_id argument
// gets the number of the highest valid function ID.
//todo: verify
//__cpuid(cpui.data(), 0);
GetCpuID(cpui.data(), 0);
nIds_ = cpui[0];
for (int i = 0; i <= nIds_; ++i)
{
//todo: verify
//__cpuidex(cpui.data(), i, 0);
GetCpuID(cpui.data(), i, 0);
data_.push_back(cpui);
}
// Capture vendor string
char vendor[0x20];
std::memset(vendor, 0, sizeof(vendor));
*reinterpret_cast<int*>(vendor) = data_[0][1];
*reinterpret_cast<int*>(vendor + 4) = data_[0][3];
*reinterpret_cast<int*>(vendor + 8) = data_[0][2];
vendor_ = vendor;
if (vendor_ == "GenuineIntel")
{
isIntel_ = true;
}
else if (vendor_ == "AuthenticAMD")
{
isAMD_ = true;
}
// load bitset with flags for function 0x00000001
if (nIds_ >= 1)
{
f_1_ECX_ = data_[1][2];
f_1_EDX_ = data_[1][3];
}
// load bitset with flags for function 0x00000007
if (nIds_ >= 7)
{
f_7_EBX_ = data_[7][1];
f_7_ECX_ = data_[7][2];
}
// Calling __cpuid with 0x80000000 as the function_id argument
// gets the number of the highest valid extended ID.
//todo: verify
//__cpuid(cpui.data(), 0x80000000);
GetCpuID(cpui.data(), 0x80000000);
nExIds_ = cpui[0];
char brand[0x40];
memset(brand, 0, sizeof(brand));
for (int i = 0x80000000; i <= nExIds_; ++i)
{
//todo: verify
//__cpuidex(cpui.data(), i, 0);
GetCpuID(cpui.data(), i, 0);
extdata_.push_back(cpui);
}
// load bitset with flags for function 0x80000001
if (nExIds_ >= 0x80000001)
{
f_81_ECX_ = extdata_[1][2];
f_81_EDX_ = extdata_[1][3];
}
// Interpret CPU brand string if reported
if (nExIds_ >= 0x80000004)
{
memcpy(brand, extdata_[2].data(), sizeof(cpui));
memcpy(brand + 16, extdata_[3].data(), sizeof(cpui));
memcpy(brand + 32, extdata_[4].data(), sizeof(cpui));
brand_ = brand;
}
};
virtual ~InstructionSet_Internal()
{
int i = 0;
++i;
}
int nIds_;
int nExIds_;
std::string vendor_;
std::string brand_;
bool isIntel_;
bool isAMD_;
std::bitset<32> f_1_ECX_;
std::bitset<32> f_1_EDX_;
std::bitset<32> f_7_EBX_;
std::bitset<32> f_7_ECX_;
std::bitset<32> f_81_ECX_;
std::bitset<32> f_81_EDX_;
std::vector<std::array<int, 4>> data_;
std::vector<std::array<int, 4>> extdata_;
};
};

View File

@@ -0,0 +1,71 @@
//
// 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.
//
#include "CurrentTimeImpl.h"
namespace amf
{
//-------------------------------------------------------------------------------------------------
AMFCurrentTimeImpl::AMFCurrentTimeImpl()
: m_timeOfFirstCall(-1)
{
}
//-------------------------------------------------------------------------------------------------
AMFCurrentTimeImpl::~AMFCurrentTimeImpl()
{
m_timeOfFirstCall = -1;
}
//-------------------------------------------------------------------------------------------------
amf_pts AMF_STD_CALL AMFCurrentTimeImpl::Get()
{
amf::AMFLock lock(&m_sync);
// We want pts time to start at 0 and subsequent
// times to be relative to that
if (m_timeOfFirstCall < 0)
{
m_timeOfFirstCall = amf_high_precision_clock();
return 0;
}
return (amf_high_precision_clock() - m_timeOfFirstCall); // In nanoseconds
}
//-------------------------------------------------------------------------------------------------
void AMF_STD_CALL AMFCurrentTimeImpl::Reset()
{
m_timeOfFirstCall = -1;
}
}

View File

@@ -0,0 +1,69 @@
//
// 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_CurrentTimeImpl_h
#define AMF_CurrentTimeImpl_h
#include "../include/core/CurrentTime.h"
#include "InterfaceImpl.h"
#include "Thread.h"
namespace amf
{
class AMFCurrentTimeImpl : public AMFInterfaceImpl<AMFCurrentTime>
{
public:
AMFCurrentTimeImpl();
~AMFCurrentTimeImpl();
AMF_BEGIN_INTERFACE_MAP
AMF_INTERFACE_ENTRY(AMFCurrentTime)
AMF_END_INTERFACE_MAP
virtual amf_pts AMF_STD_CALL Get();
virtual void AMF_STD_CALL Reset();
private:
amf_pts m_timeOfFirstCall;
mutable AMFCriticalSection m_sync;
};
//----------------------------------------------------------------------------------------------
// smart pointer
//----------------------------------------------------------------------------------------------
typedef AMFInterfacePtr_T<AMFCurrentTime> AMFCurrentTimePtr;
//----------------------------------------------------------------------------------------------}
}
#endif // AMF_CurrentTimeImpl_h

View File

@@ -0,0 +1,109 @@
//
// 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 DataStream.h
* @brief AMFDataStream declaration
***************************************************************************************************
*/
#ifndef AMF_DataStream_h
#define AMF_DataStream_h
#pragma once
#include "../include/core/Interface.h"
namespace amf
{
// currently supports only
// file://
// memory://
// eventually can be extended with:
// rtsp://
// rtmp://
// http://
// etc
//----------------------------------------------------------------------------------------------
enum AMF_STREAM_OPEN
{
AMFSO_READ = 0,
AMFSO_WRITE = 1,
AMFSO_READ_WRITE = 2,
AMFSO_APPEND = 3,
};
//----------------------------------------------------------------------------------------------
enum AMF_FILE_SHARE
{
AMFFS_EXCLUSIVE = 0,
AMFFS_SHARE_READ = 1,
AMFFS_SHARE_WRITE = 2,
AMFFS_SHARE_READ_WRITE = 3,
};
//----------------------------------------------------------------------------------------------
enum AMF_SEEK_ORIGIN
{
AMF_SEEK_BEGIN = 0,
AMF_SEEK_CURRENT = 1,
AMF_SEEK_END = 2,
};
//----------------------------------------------------------------------------------------------
// AMFDataStream interface
//----------------------------------------------------------------------------------------------
class AMF_NO_VTABLE AMFDataStream : public AMFInterface
{
public:
AMF_DECLARE_IID(0xdb08fe70, 0xb743, 0x4c26, 0xb2, 0x77, 0xa5, 0xc8, 0xe8, 0x14, 0xda, 0x4)
// interface
virtual AMF_RESULT AMF_STD_CALL Open(const wchar_t* pFileUrl, AMF_STREAM_OPEN eOpenType, AMF_FILE_SHARE eShareType) = 0;
virtual AMF_RESULT AMF_STD_CALL Close() = 0;
virtual AMF_RESULT AMF_STD_CALL Read(void* pData, amf_size iSize, amf_size* pRead) = 0;
virtual AMF_RESULT AMF_STD_CALL Write(const void* pData, amf_size iSize, amf_size* pWritten) = 0;
virtual AMF_RESULT AMF_STD_CALL Seek(AMF_SEEK_ORIGIN eOrigin, amf_int64 iPosition, amf_int64* pNewPosition) = 0;
virtual AMF_RESULT AMF_STD_CALL GetPosition(amf_int64* pPosition) = 0;
virtual AMF_RESULT AMF_STD_CALL GetSize(amf_int64* pSize) = 0;
virtual bool AMF_STD_CALL IsSeekable() = 0;
static AMF_RESULT AMF_STD_CALL OpenDataStream(const wchar_t* pFileUrl, AMF_STREAM_OPEN eOpenType, AMF_FILE_SHARE eShareType, AMFDataStream** str);
};
//----------------------------------------------------------------------------------------------
// smart pointer
//----------------------------------------------------------------------------------------------
typedef AMFInterfacePtr_T<AMFDataStream> AMFDataStreamPtr;
//----------------------------------------------------------------------------------------------
} //namespace amf
#endif // AMF_DataStream_h

View File

@@ -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) 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.
//
#include "DataStream.h"
#include "DataStreamMemory.h"
#include "DataStreamFile.h"
#include "TraceAdapter.h"
#include <string>
using namespace amf;
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL amf::AMFDataStream::OpenDataStream(const wchar_t* pFileUrl, AMF_STREAM_OPEN eOpenType, AMF_FILE_SHARE eShareType, AMFDataStream** str)
{
AMF_RETURN_IF_FALSE(pFileUrl != NULL, AMF_INVALID_ARG);
AMF_RESULT res = AMF_NOT_SUPPORTED;
std::wstring url(pFileUrl);
std::wstring protocol;
std::wstring path;
std::wstring::size_type found_pos = url.find(L"://", 0);
if(found_pos != std::wstring::npos)
{
protocol = url.substr(0, found_pos);
path = url.substr(found_pos + 3);
}
else
{
protocol = L"file";
path = url;
}
AMFDataStreamPtr ptr = NULL;
if(protocol == L"file")
{
ptr = new AMFDataStreamFileImpl;
res = AMF_OK;
}
if(protocol == L"memory")
{
ptr = new AMFDataStreamMemoryImpl();
res = AMF_OK;
}
if( res == AMF_OK )
{
res = ptr->Open(path.c_str(), eOpenType, eShareType);
if( res != AMF_OK )
{
return res;
}
*str = ptr.Detach();
return AMF_OK;
}
return res;
}
//-------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,271 @@
//
// 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.
//
#include "TraceAdapter.h"
#include "DataStreamFile.h"
#pragma warning(disable: 4996)
#if defined(_WIN32)
#include <io.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(_WIN32)
#define amf_close _close
#define amf_read _read
#define amf_write _write
#define amf_seek64 _lseeki64
#elif defined(__linux)// Linux
#include <unistd.h>
#define amf_close close
#define amf_read read
#define amf_write write
#define amf_seek64 lseek64
#elif defined(__APPLE__)
#include <unistd.h>
#define amf_close close
#define amf_read read
#define amf_write write
#define amf_seek64 lseek
#endif
using namespace amf;
#define AMF_FACILITY L"AMFDataStreamFileImpl"
#define AMF_FILE_PROTOCOL L"file"
//-------------------------------------------------------------------------------------------------
AMFDataStreamFileImpl::AMFDataStreamFileImpl()
: m_iFileDescriptor(-1), m_Path()
{}
//-------------------------------------------------------------------------------------------------
AMFDataStreamFileImpl::~AMFDataStreamFileImpl()
{
Close();
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Close()
{
AMF_RESULT err = AMF_OK;
if(m_iFileDescriptor != -1)
{
const int status = amf_close(m_iFileDescriptor);
if(status != 0)
{
err = AMF_FAIL;
}
m_iFileDescriptor = -1;
}
return err;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Read(void* pData, amf_size iSize, amf_size* pRead)
{
AMF_RETURN_IF_FALSE(m_iFileDescriptor != -1, AMF_FILE_NOT_OPEN, L"Read() - File not open");
AMF_RESULT err = AMF_OK;
int ready = amf_read(m_iFileDescriptor, pData, (amf_uint)iSize);
if(pRead != NULL)
{
*pRead = ready;
}
if(ready == 0) // eof
{
err = AMF_EOF;
}
else if(ready == -1)
{
err = AMF_FAIL;
}
return err;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Write(const void* pData, amf_size iSize, amf_size* pWritten)
{
AMF_RETURN_IF_FALSE(m_iFileDescriptor != -1, AMF_FILE_NOT_OPEN, L"Write() - File not Open");
AMF_RESULT err = AMF_OK;
amf_uint32 written = amf_write(m_iFileDescriptor, pData, (amf_uint)iSize);
if(pWritten != NULL)
{
*pWritten = written;
}
if(written != iSize) // check errors
{
err = AMF_FAIL;
}
return err;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Seek(AMF_SEEK_ORIGIN eOrigin, amf_int64 iPosition, amf_int64* pNewPosition)
{
AMF_RETURN_IF_FALSE(m_iFileDescriptor != -1, AMF_FILE_NOT_OPEN, L"Seek() - File not Open");
int org = 0;
switch(eOrigin)
{
case AMF_SEEK_BEGIN:
org = SEEK_SET;
break;
case AMF_SEEK_CURRENT:
org = SEEK_CUR;
break;
case AMF_SEEK_END:
org = SEEK_END;
break;
}
amf_int64 new_pos = 0;
new_pos = amf_seek64(m_iFileDescriptor, iPosition, org);
if(new_pos == -1L) // check errors
{
return AMF_FAIL;
}
if(pNewPosition != NULL)
{
*pNewPosition = new_pos;
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::GetPosition(amf_int64* pPosition)
{
AMF_RETURN_IF_FALSE(pPosition != NULL, AMF_INVALID_POINTER);
AMF_RETURN_IF_FALSE(m_iFileDescriptor != -1, AMF_FILE_NOT_OPEN, L"GetPosition() - File not Open");
*pPosition = amf_seek64(m_iFileDescriptor, 0, SEEK_CUR);
if(*pPosition == -1L)
{
return AMF_FAIL;
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::GetSize(amf_int64* pSize)
{
AMF_RETURN_IF_FALSE(pSize != NULL, AMF_INVALID_POINTER);
AMF_RETURN_IF_FALSE(m_iFileDescriptor != -1, AMF_FILE_NOT_OPEN, L"GetSize() - File not open");
amf_int64 cur_pos = amf_seek64(m_iFileDescriptor, 0, SEEK_CUR);
*pSize = amf_seek64(m_iFileDescriptor, 0, SEEK_END);
amf_seek64(m_iFileDescriptor, cur_pos, SEEK_SET);
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
bool AMF_STD_CALL AMFDataStreamFileImpl::IsSeekable()
{
return true;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamFileImpl::Open(const wchar_t* pFilePath, AMF_STREAM_OPEN eOpenType, AMF_FILE_SHARE eShareType)
{
if(m_iFileDescriptor != -1)
{
Close();
}
AMF_RETURN_IF_FALSE(pFilePath != NULL, AMF_INVALID_ARG);
m_Path = pFilePath;
#if defined(_WIN32)
int access = _O_BINARY;
#else
int access = 0;
#endif
switch(eOpenType)
{
case AMFSO_READ:
access |= O_RDONLY;
break;
case AMFSO_WRITE:
access |= O_CREAT | O_TRUNC | O_WRONLY;
break;
case AMFSO_READ_WRITE:
access |= O_CREAT | O_TRUNC | O_RDWR;
break;
case AMFSO_APPEND:
access |= O_CREAT | O_APPEND | O_RDWR;
break;
}
#ifdef _WIN32
int shflag = 0;
switch(eShareType)
{
case AMFFS_EXCLUSIVE:
shflag = _SH_DENYRW;
break;
case AMFFS_SHARE_READ:
shflag = _SH_DENYWR;
break;
case AMFFS_SHARE_WRITE:
shflag = _SH_DENYRD;
break;
case AMFFS_SHARE_READ_WRITE:
shflag = _SH_DENYNO;
break;
}
#endif
#ifdef O_BINARY
access |= O_BINARY;
#endif
#ifdef _WIN32
m_iFileDescriptor = _wsopen(m_Path.c_str(), access, shflag, 0666);
#else
amf_string str = amf_from_unicode_to_utf8(m_Path);
m_iFileDescriptor = open(str.c_str(), access, 0666);
#endif
if(m_iFileDescriptor == -1)
{
return AMF_FAIL;
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,67 @@
//
// 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_DataStreamFile_h
#define AMF_DataStreamFile_h
#pragma once
#include "DataStream.h"
#include "InterfaceImpl.h"
#include "AMFSTL.h"
#include <string>
namespace amf
{
class AMFDataStreamFileImpl : public AMFInterfaceImpl<AMFDataStream>
{
public:
AMFDataStreamFileImpl();
virtual ~AMFDataStreamFileImpl();
// interface
virtual AMF_RESULT AMF_STD_CALL Close();
virtual AMF_RESULT AMF_STD_CALL Read(void* pData, amf_size iSize, amf_size* pRead);
virtual AMF_RESULT AMF_STD_CALL Write(const void* pData, amf_size iSize, amf_size* pWritten);
virtual AMF_RESULT AMF_STD_CALL Seek(AMF_SEEK_ORIGIN eOrigin, amf_int64 iPosition, amf_int64* pNewPosition);
virtual AMF_RESULT AMF_STD_CALL GetPosition(amf_int64* pPosition);
virtual AMF_RESULT AMF_STD_CALL GetSize(amf_int64* pSize);
virtual bool AMF_STD_CALL IsSeekable();
// local
// aways pass full URL just in case
virtual AMF_RESULT AMF_STD_CALL Open(const wchar_t* pFilePath, AMF_STREAM_OPEN eOpenType, AMF_FILE_SHARE eShareType);
protected:
int m_iFileDescriptor;
amf_wstring m_Path;
};
} //namespace amf
#endif // AMF_DataStreamFile_h

View File

@@ -0,0 +1,175 @@
//
// 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.
//
#include "Thread.h"
#include "TraceAdapter.h"
#include "DataStreamMemory.h"
using namespace amf;
#define AMF_FACILITY L"AMFDataStreamMemoryImpl"
//-------------------------------------------------------------------------------------------------
AMFDataStreamMemoryImpl::AMFDataStreamMemoryImpl()
: m_pMemory(NULL),
m_uiMemorySize(0),
m_uiAllocatedSize(0),
m_pos(0)
{}
//-------------------------------------------------------------------------------------------------
AMFDataStreamMemoryImpl::~AMFDataStreamMemoryImpl()
{
Close();
}
//-------------------------------------------------------------------------------------------------
// interface
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::Close()
{
if(m_pMemory != NULL)
{
amf_virtual_free(m_pMemory);
}
m_pMemory = NULL,
m_uiMemorySize = 0,
m_uiAllocatedSize = 0,
m_pos = 0;
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMFDataStreamMemoryImpl::Realloc(amf_size iSize)
{
if(iSize > m_uiMemorySize)
{
amf_uint8* pNewMemory = (amf_uint8*)amf_virtual_alloc(iSize);
if(pNewMemory == NULL)
{
return AMF_OUT_OF_MEMORY;
}
m_uiAllocatedSize = iSize;
if(m_pMemory != NULL)
{
memcpy(pNewMemory, m_pMemory, m_uiMemorySize);
amf_virtual_free(m_pMemory);
}
m_pMemory = pNewMemory;
}
m_uiMemorySize = iSize;
if(m_pos > m_uiMemorySize)
{
m_pos = m_uiMemorySize;
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::Read(void* pData, amf_size iSize, amf_size* pRead)
{
AMF_RETURN_IF_FALSE(pData != NULL, AMF_INVALID_POINTER, L"Read() - pData==NULL");
AMF_RETURN_IF_FALSE(m_pMemory != NULL, AMF_NOT_INITIALIZED, L"Read() - Stream is not allocated");
amf_size toRead = AMF_MIN(iSize, m_uiMemorySize - m_pos);
memcpy(pData, m_pMemory + m_pos, toRead);
m_pos += toRead;
if(pRead != NULL)
{
*pRead = toRead;
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::Write(const void* pData, amf_size iSize, amf_size* pWritten)
{
AMF_RETURN_IF_FALSE(pData != NULL, AMF_INVALID_POINTER, L"Write() - pData==NULL");
AMF_RETURN_IF_FAILED(Realloc(m_pos + iSize), L"Write() - Stream is not allocated");
amf_size toWrite = AMF_MIN(iSize, m_uiMemorySize - m_pos);
memcpy(m_pMemory + m_pos, pData, toWrite);
m_pos += toWrite;
if(pWritten != NULL)
{
*pWritten = toWrite;
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::Seek(AMF_SEEK_ORIGIN eOrigin, amf_int64 iPosition, amf_int64* pNewPosition)
{
switch(eOrigin)
{
case AMF_SEEK_BEGIN:
m_pos = (amf_size)iPosition;
break;
case AMF_SEEK_CURRENT:
m_pos += (amf_size)iPosition;
break;
case AMF_SEEK_END:
m_pos = m_uiMemorySize - (amf_size)iPosition;
break;
}
if(m_pos > m_uiMemorySize)
{
m_pos = m_uiMemorySize;
}
if(pNewPosition != NULL)
{
*pNewPosition = m_pos;
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::GetPosition(amf_int64* pPosition)
{
AMF_RETURN_IF_FALSE(pPosition != NULL, AMF_INVALID_POINTER, L"GetPosition() - pPosition==NULL");
*pPosition = m_pos;
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT AMF_STD_CALL AMFDataStreamMemoryImpl::GetSize(amf_int64* pSize)
{
AMF_RETURN_IF_FALSE(pSize != NULL, AMF_INVALID_POINTER, L"GetPosition() - pSize==NULL");
*pSize = m_uiMemorySize;
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
bool AMF_STD_CALL AMFDataStreamMemoryImpl::IsSeekable()
{
return true;
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,77 @@
//
// 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_DataStreamMemory_h
#define AMF_DataStreamMemory_h
#pragma once
#include "DataStream.h"
#include "InterfaceImpl.h"
namespace amf
{
class AMFDataStreamMemoryImpl : public AMFInterfaceImpl<AMFDataStream>
{
public:
AMFDataStreamMemoryImpl();
virtual ~AMFDataStreamMemoryImpl();
// interface
virtual AMF_RESULT AMF_STD_CALL Open(const wchar_t* /*pFileUrl*/, AMF_STREAM_OPEN /*eOpenType*/, AMF_FILE_SHARE /*eShareType*/)
{
//pFileUrl;
//eOpenType;
//eShareType;
return AMF_OK;
}
virtual AMF_RESULT AMF_STD_CALL Close();
virtual AMF_RESULT AMF_STD_CALL Read(void* pData, amf_size iSize, amf_size* pRead);
virtual AMF_RESULT AMF_STD_CALL Write(const void* pData, amf_size iSize, amf_size* pWritten);
virtual AMF_RESULT AMF_STD_CALL Seek(AMF_SEEK_ORIGIN eOrigin, amf_int64 iPosition, amf_int64* pNewPosition);
virtual AMF_RESULT AMF_STD_CALL GetPosition(amf_int64* pPosition);
virtual AMF_RESULT AMF_STD_CALL GetSize(amf_int64* pSize);
virtual bool AMF_STD_CALL IsSeekable();
protected:
AMF_RESULT Realloc(amf_size iSize);
amf_uint8* m_pMemory;
amf_size m_uiMemorySize;
amf_size m_uiAllocatedSize;
amf_size m_pos;
private:
AMFDataStreamMemoryImpl(const AMFDataStreamMemoryImpl&);
AMFDataStreamMemoryImpl& operator=(const AMFDataStreamMemoryImpl&);
};
} //namespace amf
#endif // AMF_DataStreamMemory_h

View File

@@ -0,0 +1,250 @@
//
// 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.
//
#include "IOCapsImpl.h"
namespace amf
{
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AMFIOCapsImpl::SurfaceFormat::SurfaceFormat() :
m_Format(AMF_SURFACE_UNKNOWN),
m_Native(false)
{
}
AMFIOCapsImpl::SurfaceFormat::SurfaceFormat(AMF_SURFACE_FORMAT format, amf_bool native) :
m_Format(format),
m_Native(native)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AMFIOCapsImpl::MemoryType::MemoryType() :
m_Type(AMF_MEMORY_UNKNOWN),
m_Native(false)
{
}
AMFIOCapsImpl::MemoryType::MemoryType(AMF_MEMORY_TYPE type, amf_bool native) :
m_Type(type),
m_Native(native)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AMFIOCapsImpl::AMFIOCapsImpl() :
m_MinWidth(-1),
m_MaxWidth(-1),
m_MinHeight(-1),
m_MaxHeight(-1),
m_VertAlign(-1),
m_InterlacedSupported(false)
{
}
AMFIOCapsImpl::AMFIOCapsImpl(amf_int32 minWidth, amf_int32 maxWidth,
amf_int32 minHeight, amf_int32 maxHeight,
amf_int32 vertAlign, amf_bool interlacedSupport,
amf_int32 numOfNativeFormats, const AMF_SURFACE_FORMAT* nativeFormats,
amf_int32 numOfNonNativeFormats, const AMF_SURFACE_FORMAT* nonNativeFormats,
amf_int32 numOfNativeMemTypes, const AMF_MEMORY_TYPE* nativeMemTypes,
amf_int32 numOfNonNativeMemTypes, const AMF_MEMORY_TYPE* nonNativeMemTypes)
{
m_MinWidth = minWidth;
m_MaxWidth = maxWidth;
m_MinHeight = minHeight;
m_MaxHeight = maxHeight;
m_VertAlign = vertAlign;
m_InterlacedSupported = interlacedSupport;
PopulateSurfaceFormats(numOfNativeFormats, nativeFormats, true);
PopulateSurfaceFormats(numOfNonNativeFormats, nonNativeFormats, false);
PopulateMemoryTypes(numOfNativeMemTypes, nativeMemTypes, true);
PopulateMemoryTypes(numOfNonNativeMemTypes, nonNativeMemTypes, false);
}
void AMFIOCapsImpl::PopulateSurfaceFormats(amf_int32 numOfFormats, const AMF_SURFACE_FORMAT* formats, amf_bool native)
{
if (formats != NULL)
{
for (amf_int32 i = 0; i < numOfFormats; i++)
{
bool found = false;
for(amf_size exists_idx = 0; exists_idx < m_SurfaceFormats.size(); exists_idx++)
{
if(m_SurfaceFormats[exists_idx].GetFormat() == formats[i])
{
found = true;
}
}
if(!found)
{
m_SurfaceFormats.push_back(SurfaceFormat(formats[i], native));
}
}
}
}
void AMFIOCapsImpl::PopulateMemoryTypes(amf_int32 numOfTypes, const AMF_MEMORY_TYPE* memTypes, amf_bool native)
{
if (memTypes != NULL)
{
for (amf_int32 i = 0; i < numOfTypes; i++)
{
bool found = false;
for(amf_size exists_idx = 0; exists_idx < m_MemoryTypes.size(); exists_idx++)
{
if(m_MemoryTypes[exists_idx].GetType() == memTypes[i])
{
found = true;
}
}
if(!found)
{
m_MemoryTypes.push_back(MemoryType(memTypes[i], native));
}
}
}
}
// Get supported resolution ranges in pixels/lines:
void AMF_STD_CALL AMFIOCapsImpl::GetWidthRange(amf_int32* minWidth, amf_int32* maxWidth) const
{
if (minWidth != NULL)
{
*minWidth = m_MinWidth;
}
if (maxWidth != NULL)
{
*maxWidth = m_MaxWidth;
}
}
void AMF_STD_CALL AMFIOCapsImpl::GetHeightRange(amf_int32* minHeight, amf_int32* maxHeight) const
{
if (minHeight != NULL)
{
*minHeight = m_MinHeight;
}
if (maxHeight != NULL)
{
*maxHeight = m_MaxHeight;
}
}
// Get memory alignment in lines:
// Vertical aligmnent should be multiples of this number
amf_int32 AMF_STD_CALL AMFIOCapsImpl::GetVertAlign() const
{
return m_VertAlign;
}
// Enumerate supported surface pixel formats:
amf_int32 AMF_STD_CALL AMFIOCapsImpl::GetNumOfFormats() const
{
return (amf_int32)m_SurfaceFormats.size();
}
AMF_RESULT AMF_STD_CALL AMFIOCapsImpl::GetFormatAt(amf_int32 index, AMF_SURFACE_FORMAT* format, bool* native) const
{
if (index >= 0 && index < static_cast<amf_int32>(m_SurfaceFormats.size()))
{
SurfaceFormat curFormat(m_SurfaceFormats.at(index));
if (format != NULL)
{
*format = curFormat.GetFormat();
}
if (native != NULL)
{
*native = curFormat.IsNative();
}
return AMF_OK;
}
else
{
return AMF_INVALID_ARG;
}
}
// Enumerate supported surface formats:
amf_int32 AMF_STD_CALL AMFIOCapsImpl::GetNumOfMemoryTypes() const
{
return (amf_int32)m_MemoryTypes.size();
}
AMF_RESULT AMF_STD_CALL AMFIOCapsImpl::GetMemoryTypeAt(amf_int32 index, AMF_MEMORY_TYPE* memType, bool* native) const
{
if (index >= 0 && index < static_cast<amf_int32>(m_MemoryTypes.size()))
{
MemoryType curType(m_MemoryTypes.at(index));
if (memType != NULL)
{
*memType = curType.GetType();
}
if (native != NULL)
{
*native = curType.IsNative();
}
return AMF_OK;
}
else
{
return AMF_INVALID_ARG;
}
}
// interlaced support:
amf_bool AMF_STD_CALL AMFIOCapsImpl::IsInterlacedSupported() const
{
return m_InterlacedSupported;
}
void AMFIOCapsImpl::SetResolution(amf_int32 minWidth, amf_int32 maxWidth, amf_int32 minHeight, amf_int32 maxHeight)
{
m_MinWidth = minWidth;
m_MaxWidth = maxWidth;
m_MinHeight = minHeight;
m_MaxHeight = maxHeight;
}
void AMFIOCapsImpl::SetVertAlign(amf_int32 vertAlign)
{
m_VertAlign = vertAlign;
}
void AMFIOCapsImpl::SetInterlacedSupport(amf_bool interlaced)
{
m_InterlacedSupported = interlaced;
}
}

View File

@@ -0,0 +1,132 @@
//
// 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_IOCapsImpl_h
#define AMF_IOCapsImpl_h
#pragma once
#include "InterfaceImpl.h"
#include "../include/components/ComponentCaps.h"
#include <vector>
namespace amf
{
class AMFIOCapsImpl : public AMFInterfaceImpl<AMFIOCaps>
{
protected:
class SurfaceFormat
{
public:
typedef std::vector<SurfaceFormat> Collection;
public:
SurfaceFormat();
SurfaceFormat(AMF_SURFACE_FORMAT format, amf_bool native);
inline AMF_SURFACE_FORMAT GetFormat() const throw() { return m_Format; }
inline amf_bool IsNative() const throw() { return m_Native; }
private:
AMF_SURFACE_FORMAT m_Format;
amf_bool m_Native;
};
class MemoryType
{
public:
typedef std::vector<MemoryType> Collection;
public:
MemoryType();
MemoryType(AMF_MEMORY_TYPE type, amf_bool native);
inline AMF_MEMORY_TYPE GetType() const throw() { return m_Type; }
inline amf_bool IsNative() const throw() { return m_Native; }
private:
AMF_MEMORY_TYPE m_Type;
amf_bool m_Native;
};
struct Resolution
{
amf_int32 m_Width;
amf_int32 m_Height;
};
protected:
AMFIOCapsImpl();
AMFIOCapsImpl(amf_int32 minWidth, amf_int32 maxWidth,
amf_int32 minHeight, amf_int32 maxHeight,
amf_int32 vertAlign, amf_bool interlacedSupport,
amf_int32 numOfNativeFormats, const AMF_SURFACE_FORMAT* nativeFormats,
amf_int32 numOfNonNativeFormats, const AMF_SURFACE_FORMAT* nonNativeFormats,
amf_int32 numOfNativeMemTypes, const AMF_MEMORY_TYPE* nativeMemTypes,
amf_int32 numOfNonNativeMemTypes, const AMF_MEMORY_TYPE* nonNativeMemTypes);
public:
// Get supported resolution ranges in pixels/lines:
virtual void AMF_STD_CALL GetWidthRange(amf_int32* minWidth, amf_int32* maxWidth) const;
virtual void AMF_STD_CALL GetHeightRange(amf_int32* minHeight, amf_int32* maxHeight) const;
// Get memory alignment in lines:
// Vertical aligmnent should be multiples of this number
virtual amf_int32 AMF_STD_CALL GetVertAlign() const;
// Enumerate supported surface pixel formats:
virtual amf_int32 AMF_STD_CALL GetNumOfFormats() const;
virtual AMF_RESULT AMF_STD_CALL GetFormatAt(amf_int32 index, AMF_SURFACE_FORMAT* format, amf_bool* native) const;
// Enumerate supported surface formats:
virtual amf_int32 AMF_STD_CALL GetNumOfMemoryTypes() const;
virtual AMF_RESULT AMF_STD_CALL GetMemoryTypeAt(amf_int32 index, AMF_MEMORY_TYPE* memType, amf_bool* native) const;
// interlaced support:
virtual amf_bool AMF_STD_CALL IsInterlacedSupported() const;
protected:
void SetResolution(amf_int32 minWidth, amf_int32 maxWidth, amf_int32 minHeight, amf_int32 maxHeight);
void SetVertAlign(amf_int32 alignment);
void SetInterlacedSupport(amf_bool interlaced);
void PopulateSurfaceFormats(amf_int32 numOfFormats, const AMF_SURFACE_FORMAT* formats, amf_bool native);
void PopulateMemoryTypes(amf_int32 numOfTypes, const AMF_MEMORY_TYPE* memTypes, amf_bool native);
protected:
amf_int32 m_MinWidth;
amf_int32 m_MaxWidth;
amf_int32 m_MinHeight;
amf_int32 m_MaxHeight;
amf_int32 m_VertAlign;
amf_bool m_InterlacedSupported;
SurfaceFormat::Collection m_SurfaceFormats;
MemoryType::Collection m_MemoryTypes;
};
}
#endif // AMF_IOCapsImpl_h

View File

@@ -0,0 +1,214 @@
//
// 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_InterfaceImpl_h
#define AMF_InterfaceImpl_h
#pragma once
#include "../include/core/Interface.h"
#include "Thread.h"
#pragma warning(disable : 4511)
namespace amf
{
#define AMF_BEGIN_INTERFACE_MAP \
virtual AMF_RESULT AMF_STD_CALL QueryInterface(const amf::AMFGuid & interfaceID, void** ppInterface) \
{ \
AMF_RESULT err = AMF_NO_INTERFACE; \
#define AMF_INTERFACE_ENTRY(T) \
if(AMFCompareGUIDs(interfaceID, T::IID())) \
{ \
*ppInterface = (void*)static_cast<T*>(this); \
this->Acquire(); \
err = AMF_OK; \
} \
else \
#define AMF_INTERFACE_ENTRY_THIS(T, _TI) \
if(AMFCompareGUIDs(interfaceID, T::IID())) \
{ \
*ppInterface = (void*)static_cast<T*>(static_cast<_TI*>(this)); \
this->Acquire(); \
err = AMF_OK; \
} \
else \
#define AMF_INTERFACE_MULTI_ENTRY(T) \
if(AMFCompareGUIDs(interfaceID, T::IID())) \
{ \
*ppInterface = (void*)static_cast<T*>(this); \
AcquireInternal(); \
err = AMF_OK; \
} \
else \
#define AMF_INTERFACE_CHAIN_ENTRY(T) \
if(static_cast<T&>(*this).T::QueryInterface(interfaceID, ppInterface) == AMF_OK) \
{err = AMF_OK;} \
else \
//good as an example but we should not use aggregate pattern without big reason - very hard to debug
#define AMF_INTERFACE_AGREGATED_ENTRY(T, _Ptr) \
if(AMFCompareGUIDs(interfaceID, T::IID())) \
{ \
T* ptr = static_cast<T*>(_Ptr); \
*ppInterface = (void*)ptr; \
ptr->Acquire(); \
err = AMF_OK; \
} \
else \
#define AMF_INTERFACE_CHAIN_AGREGATED_ENTRY(T, _Ptr) \
if(err = static_cast<T*>(_Ptr)->QueryInterface(interfaceID, ppInterface)) { \
} \
else \
#define AMF_END_INTERFACE_MAP \
{} \
return err; \
} \
//---------------------------------------------------------------
class AMFInterfaceBase
{
protected:
amf_long m_refCount;
virtual ~AMFInterfaceBase()
#if __GNUC__ == 11 //WORKAROUND for gcc-11 bug
__attribute__ ((noinline))
#endif
{}
public:
AMFInterfaceBase() : m_refCount(0)
{}
virtual amf_long AMF_STD_CALL AcquireInternal()
{
amf_long newVal = amf_atomic_inc(&m_refCount);
return newVal;
}
virtual amf_long AMF_STD_CALL ReleaseInternal()
{
amf_long newVal = amf_atomic_dec(&m_refCount);
if(newVal == 0)
{
delete this;
}
return newVal;
}
virtual amf_long AMF_STD_CALL RefCountInternal()
{
return m_refCount;
}
};
//---------------------------------------------------------------
template<class _Base , typename _Param1 = int, typename _Param2 = int, typename _Param3 = int>
class AMFInterfaceImpl : public _Base, public AMFInterfaceBase
{
protected:
virtual ~AMFInterfaceImpl()
{}
public:
AMFInterfaceImpl(_Param1 param1, _Param2 param2, _Param3 param3) : _Base(param1, param2, param3)
{}
AMFInterfaceImpl(_Param1 param1, _Param2 param2) : _Base(param1, param2)
{}
AMFInterfaceImpl(_Param1 param1) : _Base(param1)
{}
AMFInterfaceImpl()
{}
virtual amf_long AMF_STD_CALL Acquire()
{
return AMFInterfaceBase::AcquireInternal();
}
virtual amf_long AMF_STD_CALL Release()
{
return AMFInterfaceBase::ReleaseInternal();
}
virtual amf_long AMF_STD_CALL RefCount()
{
return AMFInterfaceBase::RefCountInternal();
}
AMF_BEGIN_INTERFACE_MAP
AMF_INTERFACE_ENTRY(AMFInterface)
AMF_INTERFACE_ENTRY(_Base)
AMF_END_INTERFACE_MAP
};
//---------------------------------------------------------------
template<class _Base, class _BaseInterface, typename _Param1 = int, typename _Param2 = int, typename _Param3 = int, typename _Param4 = int, typename _Param5 = int, typename _Param6 = int>
class AMFInterfaceMultiImpl : public _Base
{
protected:
virtual ~AMFInterfaceMultiImpl()
{}
public:
AMFInterfaceMultiImpl(_Param1 param1, _Param2 param2, _Param3 param3, _Param4 param4, _Param5 param5, _Param6 param6) : _Base(param1, param2, param3, param4, param5, param6)
{}
AMFInterfaceMultiImpl(_Param1 param1, _Param2 param2, _Param3 param3, _Param4 param4, _Param5 param5) : _Base(param1, param2, param3, param4, param5)
{}
AMFInterfaceMultiImpl(_Param1 param1, _Param2 param2, _Param3 param3, _Param4 param4) : _Base(param1, param2, param3, param4)
{}
AMFInterfaceMultiImpl(_Param1 param1, _Param2 param2, _Param3 param3) : _Base(param1, param2, param3)
{}
AMFInterfaceMultiImpl(_Param1 param1, _Param2 param2) : _Base(param1, param2)
{}
AMFInterfaceMultiImpl(_Param1 param1) : _Base(param1)
{}
AMFInterfaceMultiImpl()
{}
virtual amf_long AMF_STD_CALL Acquire()
{
return AMFInterfaceBase::AcquireInternal();
}
virtual amf_long AMF_STD_CALL Release()
{
return AMFInterfaceBase::ReleaseInternal();
}
virtual amf_long AMF_STD_CALL RefCount()
{
return AMFInterfaceBase::RefCountInternal();
}
AMF_BEGIN_INTERFACE_MAP
AMF_INTERFACE_ENTRY_THIS(AMFInterface, _BaseInterface)
AMF_INTERFACE_CHAIN_ENTRY(_Base)
AMF_END_INTERFACE_MAP
};
} // namespace amf
#endif // AMF_InterfaceImpl_h

View File

@@ -0,0 +1,318 @@
//
// 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.
//
#pragma once
#include "public/include/core/Interface.h"
#include "public/include/core/Variant.h"
#include <string>
#include <stdint.h>
namespace amf
{
class JSONParser : public amf::AMFInterface
{
public:
//-----------------------------------------------------------------------------------------
enum Result
{
OK,
MISSING_QUOTE,
MISSING_BRACE,
MISSING_BRACKET,
MISSING_DELIMITER,
MISSING_VALUE,
UNEXPECTED_END,
DUPLICATE_NAME,
INVALID_ARG,
INVALID_VALUE
};
//-----------------------------------------------------------------------------------------
typedef amf::AMFInterfacePtr_T<JSONParser> Ptr;
AMF_DECLARE_IID(0x14aefb78, 0x80af, 0x4ee1, 0x82, 0x9f, 0xa2, 0xfc, 0xc7, 0xae, 0xab, 0x33)
//-----------------------------------------------------------------------------------------
class Error
{
public:
Error(JSONParser::Result error) :
m_Ofs(0),
m_Error(error)
{
}
Error(size_t ofs, JSONParser::Result error) :
m_Ofs(ofs),
m_Error(error)
{
}
inline size_t GetOffset() const { return m_Ofs; }
inline JSONParser::Result GetResult() const { return m_Error; }
private:
size_t m_Ofs;
JSONParser::Result m_Error;
};
//-----------------------------------------------------------------------------------------
struct OutputFormatDesc
{
bool bHumanReadable;
bool bNewLineBeforeBrace;
char cOffsetWith;
uint8_t nOffsetSize;
};
//-----------------------------------------------------------------------------------------
class Element : public amf::AMFInterface
{
public:
typedef amf::AMFInterfacePtr_T<Element> Ptr;
AMF_DECLARE_IID(0xd2d71993, 0xbbcb, 0x420f, 0xbc, 0xdd, 0xd8, 0xd6, 0xb6, 0x2e, 0x46, 0x5e)
virtual Error Parse(const std::string& str, size_t start, size_t end) = 0;
virtual std::string Stringify() const = 0;
virtual std::string StringifyFormatted(const OutputFormatDesc& format, int indent) const = 0;
};
//-----------------------------------------------------------------------------------------
class Value : public Element
{
public:
typedef amf::AMFInterfacePtr_T<Value> Ptr;
AMF_DECLARE_IID(0xba0e44d4, 0xa487, 0x4d64, 0xa4, 0x94, 0x93, 0x9b, 0xfd, 0x76, 0x72, 0x32)
virtual void SetValue(const std::string& val) = 0;
virtual void SetValueAsInt32(int32_t val) = 0;
virtual void SetValueAsUInt32(uint32_t val) = 0;
virtual void SetValueAsInt64(int64_t val) = 0;
virtual void SetValueAsUInt64(uint64_t val) = 0;
virtual void SetValueAsDouble(double val) = 0;
virtual void SetValueAsFloat(float val) = 0;
virtual void SetValueAsBool(bool val) = 0;
virtual void SetValueAsTime(time_t date, bool utc) = 0;
virtual void SetToNull() = 0;
virtual const std::string& GetValue() const = 0;
virtual int32_t GetValueAsInt32() const = 0;
virtual uint32_t GetValueAsUInt32() const = 0;
virtual int64_t GetValueAsInt64() const = 0;
virtual uint64_t GetValueAsUInt64() const = 0;
virtual double GetValueAsDouble() const = 0;
virtual float GetValueAsFloat() const = 0;
virtual bool GetValueAsBool() const = 0;
virtual time_t GetValueAsTime() const = 0;
virtual bool IsNull() const = 0;
};
//-----------------------------------------------------------------------------------------
class Node : public Element
{
public:
typedef amf::AMFInterfacePtr_T<Node> Ptr;
AMF_DECLARE_IID(0x6623d6b8, 0x533d, 0x4824, 0x9d, 0x3b, 0x45, 0x1a, 0xa8, 0xc3, 0x7b, 0x5d)
virtual size_t GetElementCount() const = 0;
virtual JSONParser::Element* GetElementByName(const std::string& name) const = 0;
virtual JSONParser::Result AddElement(const std::string& name, Element* element) = 0;
virtual JSONParser::Element* GetElementAt(size_t idx, std::string& name) const = 0;
};
//-----------------------------------------------------------------------------------------
class Array : public Element
{
public:
typedef amf::AMFInterfacePtr_T<Array> Ptr;
AMF_DECLARE_IID(0x8c066a6d, 0xb377, 0x44e8, 0x8c, 0xf5, 0xf8, 0xbf, 0x88, 0x85, 0xbb, 0xe9)
virtual size_t GetElementCount() const = 0;
virtual JSONParser::Element* GetElementAt(size_t idx) const = 0;
virtual void AddElement(Element* element) = 0;
};
//-----------------------------------------------------------------------------------------
virtual Result Parse(const std::string& str, Node** root) = 0; // Parse a JSON string into a tree of DOM elements
virtual std::string Stringify(const Node* root) const = 0; // Convert a DOM to a JSON string
virtual std::string StringifyFormatted(const Node* root, const OutputFormatDesc& format, int indent = 0) const = 0;
virtual Result CreateNode(Node** node) const = 0;
virtual Result CreateValue(Value** value) const = 0;
virtual Result CreateArray(Array** array) const = 0;
virtual size_t GetLastErrorOffset() const = 0; // Returns the offset of the last syntax error (same as what is passed in the exception if thrown)
};
extern "C"
{
// Helpers
#define TAG_JSON_VALUE "Val"
void SetBoolValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, bool val);
void CreateBoolValue(amf::JSONParser* parser, amf::JSONParser::Value** node, bool val);
bool GetBoolValue(const amf::JSONParser::Node* root, const char* name, bool& val);
bool GetBoolFromJSON(const amf::JSONParser::Value* element, bool& val);
void SetDoubleValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, double val);
void CreateDoubleValue(amf::JSONParser* parser, amf::JSONParser::Value** node, double val);
bool GetDoubleValue(const amf::JSONParser::Node* root, const char* name, double& val);
bool GetDoubleFromJSON(const amf::JSONParser::Value* element, double& val);
void SetFloatValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, float val);
void CreateFloatValue(amf::JSONParser* parser, amf::JSONParser::Value** node, float val);
bool GetFloatValue(const amf::JSONParser::Node* root, const char* name, float& val);
bool GetFloatFromJSON(const amf::JSONParser::Value* element, float& val);
void SetInt64Value(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, int64_t val);
void CreateInt64Value(amf::JSONParser* parser, amf::JSONParser::Value** node, const int64_t val);
bool GetInt64Value(const amf::JSONParser::Node* root, const char* name, int64_t& val);
bool GetInt64FromJSON(const amf::JSONParser::Value* element, int64_t& val);
void SetUInt64Value(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, uint64_t val);
bool GetUInt64Value(const amf::JSONParser::Node* root, const char* name, uint64_t& val);
bool GetUInt64FromJSON(const amf::JSONParser::Value* element, uint64_t& val);
void SetInt32Value(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, int32_t val);
bool GetInt32Value(const amf::JSONParser::Node* root, const char* name, int32_t& val);
bool GetInt32FromJSON(const amf::JSONParser::Value* element, int32_t& val);
void SetUInt32Value(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, uint32_t val);
bool GetUInt32Value(const amf::JSONParser::Node* root, const char* name, uint32_t& val);
bool GetUInt32FromJSON(const amf::JSONParser::Value* element, uint32_t& val);
void SetUInt32Array(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const uint32_t* val, size_t size);
void CreateUInt32Array(amf::JSONParser* parser, amf::JSONParser::Array** array, const uint32_t* val, size_t size);
bool GetUInt32Array(const amf::JSONParser::Node* root, const char* name, uint32_t* val, size_t& size);
bool GetUInt32ArrayFromJSON(const amf::JSONParser::Array* element, uint32_t* val, size_t& size);
void SetInt32Array(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const int32_t* val, size_t size);
void CreateInt32Array(amf::JSONParser* parser, amf::JSONParser::Array** array, const int32_t* val, size_t size);
bool GetInt32Array(const amf::JSONParser::Node* root, const char* name, int32_t* val, size_t& size);
bool GetInt32ArrayFromJSON(const amf::JSONParser::Array* element, int32_t* val, size_t& size);
void SetInt64Array(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const int64_t* val, size_t size);
bool GetInt64Array(const amf::JSONParser::Node* root, const char* name, int64_t* val, size_t& size);
bool GetInt64ArrayFromJSON(const amf::JSONParser::Array* element, int64_t* val, size_t& size);
void SetFloatArray(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const float* val, size_t size);
void CreateFloatArray(amf::JSONParser* parser, amf::JSONParser::Array** array, const float* val, size_t size);
bool GetFloatArray(const amf::JSONParser::Node* root, const char* name, float* val, size_t& size);
bool GetFloatArrayFromJSON(const amf::JSONParser::Array* element, float* val, size_t& size);
void SetDoubleArray(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const double* val, size_t size);
bool GetDoubleArray(const amf::JSONParser::Node* root, const char* name, double* val, size_t& size);
bool GetDoubleArrayFromJSON(const amf::JSONParser::Array* element, double* val, size_t& size);
void SetSizeValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFSize& val);
void CreateSizeValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFSize& val);
bool GetSizeValue(const amf::JSONParser::Node* root, const char* name, AMFSize& val);
bool GetSizeFromJSON(const amf::JSONParser::Element* element, AMFSize& val);
void SetRectValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFRect& val);
void CreateRectValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFRect& val);
bool GetRectValue(const amf::JSONParser::Node* root, const char* name, AMFRect& val);
bool GetRectFromJSON(const amf::JSONParser::Element* element, AMFRect& val);
void SetPointValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFPoint& val);
void CreatePointValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFPoint& val);
bool GetPointValue(const amf::JSONParser::Node* root, const char* name, AMFPoint& val);
bool GetPointFromJSON(const amf::JSONParser::Element* element, AMFPoint& val);
void SetRateValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFRate& val);
void CreateRateValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFRate& val);
bool GetRateValue(const amf::JSONParser::Node* root, const char* name, AMFRate& val);
bool GetRateFromJSON(const amf::JSONParser::Element* element, AMFRate& val);
void SetRatioValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFRatio& val);
void CreateRatioValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFRatio& val);
bool GetRatioValue(const amf::JSONParser::Node* root, const char* name, AMFRatio& val);
bool GetRatioFromJSON(const amf::JSONParser::Element* element, AMFRatio& val);
void SetColorValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFColor& val);
void CreateColorValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFColor& val);
bool GetColorValue(const amf::JSONParser::Node* root, const char* name, AMFColor& val);
bool GetColorFromJSON(const amf::JSONParser::Element* element, AMFColor& val);
void SetFloatSizeValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFFloatSize& val);
void CreateFloatSizeValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFFloatSize& val);
bool GetFloatSizeValue(const amf::JSONParser::Node* root, const char* name, AMFFloatSize& val);
bool GetFloatSizeFromJSON(const amf::JSONParser::Element* element, AMFFloatSize& val);
void SetFloatPoint2DValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFFloatPoint2D& val);
void CreateFloatPoint2DValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFFloatPoint2D& val);
bool GetFloatPoint2DValue(const amf::JSONParser::Node* root, const char* name, AMFFloatPoint2D& val);
bool GetFloatPoint2DFromJSON(const amf::JSONParser::Element* element, AMFFloatPoint2D& val);
void SetFloatPoint3DValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFFloatPoint3D& val);
void CreateFloatPoint3DValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFFloatPoint3D& val);
bool GetFloatPoint3DValue(const amf::JSONParser::Node* root, const char* name, AMFFloatPoint3D& val);
bool GetFloatPoint3DFromJSON(const amf::JSONParser::Element* element, AMFFloatPoint3D& val);
void SetFloatVector4DValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const AMFFloatVector4D& val);
void CreateFloatVector4DValue(amf::JSONParser* parser, amf::JSONParser::Array** array, const AMFFloatVector4D& val);
bool GetFloatVector4DValue(const amf::JSONParser::Node* root, const char* name, AMFFloatVector4D& val);
bool GetFloatVector4DFromJSON(const amf::JSONParser::Element* element, AMFFloatVector4D& val);
void SetStringValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const std::string& val);
void CreateStringValue(amf::JSONParser* parser, amf::JSONParser::Value** node, const std::string& val);
bool GetStringValue(const amf::JSONParser::Node* root, const char* name, std::string& val);
bool GetStringFromJSON(const amf::JSONParser::Value* element, std::string& val);
void SetInterfaceValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, /*const*/ AMFInterface* pVal);
void CreateInterfaceValue(amf::JSONParser* parser, amf::JSONParser::Node** node, /*const*/ AMFInterface* pval);
bool GetInterfaceValue(const amf::JSONParser::Node* root, const char* name, AMFInterface* ppVal);
bool GetInterfaceFromJSON(const amf::JSONParser::Element* element, AMFInterface* ppVal);
void SetVariantValue(amf::JSONParser* parser, amf::JSONParser::Node* root, const char* name, const amf::AMFVariant& value);
void SetVariantToJSON(amf::JSONParser* parser, amf::JSONParser::Node** node, const amf::AMFVariant& value);
bool GetVariantValue(const amf::JSONParser::Node* root, const char* name, amf::AMFVariant& val);
bool GetVariantFromJSON(const amf::JSONParser::Node* element, amf::AMFVariant& val);
// variant value only; variant type assumed to be pre-set
void CreateVariantValue(amf::JSONParser* parser, amf::JSONParser::Element** el, const amf::AMFVariant& value);
bool GetVariantValueFromJSON(const amf::JSONParser::Element* element, amf::AMFVariant& val);
}
class AMFInterfaceJSONSerializable : public amf::AMFInterface
{
public:
// {EC40A26C-1345-4281-9B6C-362DDD6E05B5}
AMF_DECLARE_IID(0xec40a26c, 0x1345, 0x4281, 0x9b, 0x6c, 0x36, 0x2d, 0xdd, 0x6e, 0x5, 0xb5)
//
virtual AMF_RESULT AMF_STD_CALL ToJson(amf::JSONParser* parser, amf::JSONParser::Node* node) const = 0;
//
virtual AMF_RESULT AMF_STD_CALL FromJson(const amf::JSONParser::Node* node) = 0;
};
typedef AMFInterfacePtr_T<AMFInterfaceJSONSerializable> AMFInterfaceJSONSerializablePtr;
}
extern "C"
{
AMF_RESULT AMF_CDECL_CALL CreateJSONParser(amf::JSONParser** parser);
#define AMF_JSON_PARSER_FACTORY "CreateJSONParser"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,185 @@
//
// 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.
//
#pragma once
#pragma once
#include "Json.h"
#include "InterfaceImpl.h"
#include <map>
#include <ctime>
namespace amf
{
//-----------------------------------------------------------------------------------------
class JSONParserImpl :
public AMFInterfaceImpl<JSONParser>
{
public:
//-----------------------------------------------------------------------------------------
class ElementHelper
{
protected:
ElementHelper();
Error CreateElement(const std::string& str, size_t start, size_t& valueStart, size_t& valueEnd, JSONParser::Element** val);
size_t FindClosure(const std::string& str, char opener, char closer, size_t start);
void InsertTabs(std::string& target, int count, const OutputFormatDesc& format) const;
protected:
};
//-----------------------------------------------------------------------------------------
class ValueImpl :
public AMFInterfaceImpl<JSONParser::Value>,
public ElementHelper
{
public:
ValueImpl();
AMF_BEGIN_INTERFACE_MAP
AMF_INTERFACE_ENTRY(JSONParser::Element)
AMF_INTERFACE_ENTRY(JSONParser::Value)
AMF_END_INTERFACE_MAP
virtual JSONParser::Error Parse(const std::string& str, size_t start, size_t end);
virtual std::string Stringify() const;
virtual std::string StringifyFormatted(const OutputFormatDesc& format, int indent) const;
virtual void SetValue(const std::string& val);
virtual void SetValueAsInt32(int32_t val);
virtual void SetValueAsUInt32(uint32_t val);
virtual void SetValueAsInt64(int64_t val);
virtual void SetValueAsUInt64(uint64_t val);
virtual void SetValueAsDouble(double val);
virtual void SetValueAsFloat(float val);
virtual void SetValueAsBool(bool val);
virtual void SetValueAsTime(time_t date, bool utc);
virtual void SetToNull();
virtual const std::string& GetValue() const;
virtual int32_t GetValueAsInt32() const;
virtual uint32_t GetValueAsUInt32() const;
virtual int64_t GetValueAsInt64() const;
virtual uint64_t GetValueAsUInt64() const;
virtual double GetValueAsDouble() const;
virtual float GetValueAsFloat() const;
virtual bool GetValueAsBool() const;
virtual time_t GetValueAsTime() const;
virtual bool IsNull() const;
private:
enum VALUE_TYPE
{
VT_Unknown = 0,
VT_Null = 1,
VT_Bool = 2,
VT_String = 3,
VT_Numeric = 4,
};
VALUE_TYPE m_eType;
std::string m_Value;
};
//-----------------------------------------------------------------------------------------
class NodeImpl :
public AMFInterfaceImpl<JSONParser::Node>,
public ElementHelper
{
public:
typedef std::map<std::string, Element::Ptr> ElementMap;
AMF_BEGIN_INTERFACE_MAP
AMF_INTERFACE_ENTRY(JSONParser::Element)
AMF_INTERFACE_ENTRY(JSONParser::Node)
AMF_END_INTERFACE_MAP
NodeImpl();
virtual JSONParser::Error Parse(const std::string& str, size_t start, size_t end);
virtual std::string Stringify() const;
virtual std::string StringifyFormatted(const OutputFormatDesc& format, int indent) const;
virtual size_t GetElementCount() const;
virtual JSONParser::Element* GetElementByName(const std::string& name) const;
virtual JSONParser::Result AddElement(const std::string& name, JSONParser::Element* element);
virtual JSONParser::Element* GetElementAt(size_t idx, std::string& name) const;
const ElementMap& GetElements() const { return m_Elements; }
private:
ElementMap m_Elements;
};
//-----------------------------------------------------------------------------------------
class ArrayImpl :
public AMFInterfaceImpl<JSONParser::Array>,
public ElementHelper
{
public:
typedef std::vector<Element::Ptr> ElementVector;
AMF_BEGIN_INTERFACE_MAP
AMF_INTERFACE_ENTRY(JSONParser::Element)
AMF_INTERFACE_ENTRY(JSONParser::Array)
AMF_END_INTERFACE_MAP
ArrayImpl();
virtual JSONParser::Error Parse(const std::string& str, size_t start, size_t end);
virtual std::string Stringify() const;
virtual std::string StringifyFormatted(const OutputFormatDesc& format, int indent) const;
virtual size_t GetElementCount() const;
virtual JSONParser::Element* GetElementAt(size_t idx) const;
virtual void AddElement(Element* element);
private:
ElementVector m_Elements;
};
//-----------------------------------------------------------------------------------------
JSONParserImpl();
virtual JSONParser::Result Parse(const std::string& str, Node** root);
virtual std::string Stringify(const Node* root) const;
virtual std::string StringifyFormatted(const Node* root, const OutputFormatDesc& format, int indent) const;
virtual size_t GetLastErrorOffset() const;
virtual Result CreateNode(Node** node) const;
virtual Result CreateValue(Value** value) const;
virtual Result CreateArray(Array** array) const;
private:
size_t m_LastErrorOfs;
};
}

View File

@@ -0,0 +1,90 @@
//
// 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 PulseAudioImprotTable.cpp
/// @brief pulseaudio import table
///-------------------------------------------------------------------------
#include "CairoImportTable.h"
#include "public/common/TraceAdapter.h"
#include "../Thread.h"
using namespace amf;
#define GET_SO_ENTRYPOINT(m, h, f) m = reinterpret_cast<decltype(&f)>(amf_get_proc_address(h, #f)); \
AMF_RETURN_IF_FALSE(nullptr != m, AMF_FAIL, L"Failed to acquire entrypoint %S", #f);
//-------------------------------------------------------------------------------------------------
CairoImportTable::CairoImportTable()
{}
//-------------------------------------------------------------------------------------------------
CairoImportTable::~CairoImportTable()
{
UnloadFunctionsTable();
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT CairoImportTable::LoadFunctionsTable()
{
if (nullptr == m_hLibCairoSO)
{
m_hLibCairoSO = amf_load_library(L"libcairo.so.2");
AMF_RETURN_IF_FALSE(nullptr != m_hLibCairoSO, AMF_FAIL, L"Failed to load libcairo.so.2");
}
GET_SO_ENTRYPOINT(m_cairo_image_surface_create_from_png_stream, m_hLibCairoSO, cairo_image_surface_create_from_png_stream);
GET_SO_ENTRYPOINT(m_cairo_surface_destroy, m_hLibCairoSO, cairo_surface_destroy);
GET_SO_ENTRYPOINT(m_cairo_image_surface_get_width, m_hLibCairoSO, cairo_image_surface_get_width);
GET_SO_ENTRYPOINT(m_cairo_image_surface_get_height, m_hLibCairoSO, cairo_image_surface_get_height);
GET_SO_ENTRYPOINT(m_cairo_image_surface_get_stride, m_hLibCairoSO, cairo_image_surface_get_stride);
GET_SO_ENTRYPOINT(m_cairo_image_surface_get_format, m_hLibCairoSO, cairo_image_surface_get_format);
GET_SO_ENTRYPOINT(m_cairo_image_surface_get_data, m_hLibCairoSO, cairo_image_surface_get_data);
return AMF_OK;
}
void CairoImportTable::UnloadFunctionsTable()
{
if (nullptr != m_hLibCairoSO)
{
amf_free_library(m_hLibCairoSO);
m_hLibCairoSO = nullptr;
}
m_cairo_image_surface_create_from_png_stream = nullptr;
m_cairo_surface_destroy = nullptr;
m_cairo_image_surface_get_width = nullptr;
m_cairo_image_surface_get_height = nullptr;
m_cairo_image_surface_get_stride = nullptr;
m_cairo_image_surface_get_format = nullptr;
m_cairo_image_surface_get_data = nullptr;
}

View File

@@ -0,0 +1,63 @@
//
// 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 CairoImportTable.h
/// @brief Cairo import table
///-------------------------------------------------------------------------
#pragma once
#include "../../include/core/Result.h"
#include <memory>
#include <cairo.h>
struct CairoImportTable{
CairoImportTable();
~CairoImportTable();
AMF_RESULT LoadFunctionsTable();
void UnloadFunctionsTable();
decltype(&cairo_image_surface_create_from_png_stream) m_cairo_image_surface_create_from_png_stream = nullptr;
decltype(&cairo_surface_destroy) m_cairo_surface_destroy = nullptr;
decltype(&cairo_image_surface_get_width) m_cairo_image_surface_get_width = nullptr;
decltype(&cairo_image_surface_get_height) m_cairo_image_surface_get_height = nullptr;
decltype(&cairo_image_surface_get_stride) m_cairo_image_surface_get_stride = nullptr;
decltype(&cairo_image_surface_get_format) m_cairo_image_surface_get_format = nullptr;
decltype(&cairo_image_surface_get_data) m_cairo_image_surface_get_data = nullptr;
amf_handle m_hLibCairoSO = nullptr;
};
typedef std::shared_ptr<CairoImportTable> CairoImportTablePtr;

View File

@@ -0,0 +1,309 @@
//
// 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; AV1; 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) 2023 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.
//
#include "DRMDevice.h"
#include <drm.h>
#include <drm_fourcc.h>
#include <drm_mode.h>
#include <amdgpu_drm.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#define AMF_FACILITY L"DRMDevice"
struct FormatMapEntry
{
amf::AMF_SURFACE_FORMAT formatAMF;
uint32_t formatDRM;
};
static const FormatMapEntry formatMap [] =
{
#ifdef DRM_FORMAT_R8
{ amf::AMF_SURFACE_GRAY8, DRM_FORMAT_R8 },
#endif
#ifdef DRM_FORMAT_R16
// { , DRM_FORMAT_R16 },
// { , DRM_FORMAT_R16 | DRM_FORMAT_BIG_ENDIAN },
#endif
// { , DRM_FORMAT_BGR233 },
// { , DRM_FORMAT_XRGB1555 },
// { , DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN },
// { , DRM_FORMAT_XBGR1555 },
// { , DRM_FORMAT_XBGR1555 | DRM_FORMAT_BIG_ENDIAN },
// { , DRM_FORMAT_RGB565 },
// { , DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN },
// { , DRM_FORMAT_BGR565 },
// { , DRM_FORMAT_BGR565 | DRM_FORMAT_BIG_ENDIAN },
// { , DRM_FORMAT_RGB888 },
// { , DRM_FORMAT_BGR888 },
{ amf::AMF_SURFACE_BGRA, DRM_FORMAT_BGRX8888 },
{ amf::AMF_SURFACE_RGBA, DRM_FORMAT_RGBX8888 },
{ amf::AMF_SURFACE_BGRA, DRM_FORMAT_XBGR8888 },
{ amf::AMF_SURFACE_BGRA /*AMF_SURFACE_ARGB*/, DRM_FORMAT_XRGB8888 },
{ amf::AMF_SURFACE_RGBA, DRM_FORMAT_BGRA8888 },
{ amf::AMF_SURFACE_ARGB, DRM_FORMAT_ARGB8888 },
{ amf::AMF_SURFACE_YUY2, DRM_FORMAT_YUYV },
// { , DRM_FORMAT_YVYU },
{ amf::AMF_SURFACE_UYVY, DRM_FORMAT_UYVY },
};
amf::AMF_SURFACE_FORMAT AMF_STD_CALL FromDRMtoAMF(uint32_t formatDRM)
{
for(int i = 0; i < amf_countof(formatMap); i++)
{
if(formatMap[i].formatDRM == formatDRM)
{
return formatMap[i].formatAMF;
}
}
return amf::AMF_SURFACE_UNKNOWN;
}
drmModeFB2Ptr AMF_STD_CALL AMFdrmModeGetFB2(int fd, uint32_t fb_id)
{
struct drm_mode_fb_cmd2 get = {
.fb_id = fb_id,
};
drmModeFB2Ptr ret;
int err;
err = drmIoctl(fd, DRM_IOCTL_MODE_GETFB2, &get);
if (err != 0)
return NULL;
ret = (drmModeFB2Ptr)drmMalloc(sizeof(drmModeFB2));
if (!ret)
return NULL;
ret->fb_id = fb_id;
ret->width = get.width;
ret->height = get.height;
ret->pixel_format = get.pixel_format;
ret->flags = get.flags;
ret->modifier = get.modifier[0];
memcpy(ret->handles, get.handles, sizeof(uint32_t) * 4);
memcpy(ret->pitches, get.pitches, sizeof(uint32_t) * 4);
memcpy(ret->offsets, get.offsets, sizeof(uint32_t) * 4);
return ret;
}
void AMF_STD_CALL AMFdrmModeFreeFB2(drmModeFB2Ptr ptr)
{
drmFree(ptr);
}
DRMDevice::DRMDevice() {}
DRMDevice::~DRMDevice()
{
Terminate();
}
AMF_RESULT AMF_STD_CALL DRMDevice::InitFromVulkan(int pciDomain, int pciBus, int pciDevice, int pciFunction)
{
int dirfd = open("/dev/dri/by-path", O_RDONLY);
AMF_RETURN_IF_FALSE(dirfd != -1, AMF_FAIL, L"Couldn't open /dev/dri/by-path")
DIR *pDir = fdopendir(dirfd);
if (pDir == nullptr)
{
close(dirfd);
return AMF_FAIL;
}
struct dirent *entry;
while ((entry = readdir(pDir)) != NULL)
{
int entryDomain = -1, entryBus = -1, entryDevice = -1, entryFunction = -1, length = -1;
int res = sscanf(entry->d_name, "pci-%x:%x:%x.%x-card%n",
&entryDomain, &entryBus, &entryDevice, &entryFunction, &length);
//check if matches pattern
if (res != 4 || length != strlen(entry->d_name))
{
continue;
}
if (entryDomain == pciDomain && entryBus == pciBus && entryDevice == pciDevice && entryFunction == pciFunction)
{
m_fd = openat(dirfd, entry->d_name, O_RDWR | O_CLOEXEC);
m_pathToCard = entry->d_name;
break;
}
}
closedir(pDir); //implicitly closes dirfd
if (m_fd < 0)
{
return AMF_FAIL;
}
return SetupDevice();
}
AMF_RESULT AMF_STD_CALL DRMDevice::InitFromPath(const char* pathToCard)
{
m_fd = open(pathToCard, O_RDWR | O_CLOEXEC);
m_pathToCard = pathToCard;
if (m_fd < 0)
{
return AMF_FAIL;
}
return SetupDevice();
}
AMF_RESULT DRMDevice::SetupDevice()
{
drmVersionPtr version = drmGetVersion(m_fd);
AMF_RETURN_IF_FALSE(version != nullptr, AMF_FAIL, L"drmGetVersion() failed from %S", m_pathToCard.c_str());
AMFTraceDebug(AMF_FACILITY, L"Opened DRM device %S: driver name %S version %d.%d.%d", m_pathToCard.c_str(), version->name,
version->version_major, version->version_minor, version->version_patchlevel);
drmFreeVersion(version);
uint64_t valueExport = 0;
int err = drmGetCap(m_fd, DRM_PRIME_CAP_EXPORT, &valueExport);
err = drmSetClientCap(m_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
if (err < 0)
{
AMFTraceWarning(AMF_FACILITY, L"drmSetClientCap(DRM_CLIENT_CAP_UNIVERSAL_PLANES) Failed with %d", err);
}
drmSetClientCap(m_fd, DRM_CLIENT_CAP_ATOMIC, 1);
return AMF_OK;
}
AMF_RESULT AMF_STD_CALL DRMDevice::Terminate()
{
if (m_fd >= 0)
{
close(m_fd);
m_fd = -1;
}
m_pathToCard = "";
return AMF_OK;
}
int AMF_STD_CALL DRMDevice::GetFD() const
{
return m_fd;
}
std::string AMF_STD_CALL DRMDevice::GetPathToCard() const
{
return m_pathToCard;
}
AMF_RESULT AMF_STD_CALL DRMDevice::GetCRTCs(std::vector<DRMCRTC>& crtcs) const
{
AMF_RETURN_IF_FALSE(m_fd >= 0, AMF_FAIL, L"Not Initialized");
AMFdrmModeResPtr resources = drmModeGetResources(m_fd);
AMF_RETURN_IF_FALSE(resources.p != nullptr, AMF_FAIL, L"drmModeGetResources() return nullptr");
crtcs.clear();
for(int i = 0; i < resources.p->count_crtcs; i ++)
{
AMFdrmModeCrtcPtr crtc = drmModeGetCrtc(m_fd, resources.p->crtcs[i]);
AMFRect crop = {};
amf::AMF_SURFACE_FORMAT formatAMF = amf::AMF_SURFACE_UNKNOWN;
int formatDRM = 0;
int handle = 0;
if(GetCrtcInfo(crtc, crop, formatDRM, formatAMF, handle) != AMF_OK)
{
continue;
}
AMFTraceDebug(AMF_FACILITY, L" CRTC id=%d fb=%d crop(%d,%d,%d,%d)", crtc.p->crtc_id, crtc.p->buffer_id, crop.left, crop.top, crop.right, crop.bottom);
DRMCRTC drmCrtc = {};
drmCrtc.crtcID = crtc.p->crtc_id;
drmCrtc.fbID = crtc.p->buffer_id;
drmCrtc.crop = crop;
drmCrtc.formatDRM = formatDRM;
drmCrtc.formatAMF = formatAMF;
drmCrtc.handle = handle;
crtcs.push_back(drmCrtc);
}
return AMF_OK;
}
AMF_RESULT AMF_STD_CALL DRMDevice::GetCrtcInfo(const AMFdrmModeCrtcPtr& crtc, AMFRect &crop, int& formatDRM, amf::AMF_SURFACE_FORMAT& formatAMF, int& handle) const
{
if(crtc.p == nullptr)
{
return AMF_FAIL;
}
if(crtc.p->buffer_id == 0)
{
return AMF_FAIL;
}
// check if active
AMFdrmModeObjectPropertiesPtr properties = drmModeObjectGetProperties (m_fd, crtc.p->crtc_id, DRM_MODE_OBJECT_CRTC);
if(properties.p == nullptr)
{
return AMF_FAIL;
}
for(int k = 0; k < properties.p->count_props; k++)
{
AMFdrmModePropertyPtr prop = drmModeGetProperty(m_fd, properties.p->props[k]);
if(std::string(prop.p->name) == "ACTIVE" && properties.p->prop_values[k] == 0)
{
return AMF_FAIL;
}
}
// check FB
AMFdrmModeFB2Ptr fb2 = AMFdrmModeGetFB2(m_fd, crtc.p->buffer_id);
if(fb2.p == nullptr)
{
return AMF_FAIL;
}
crop.left = crtc.p->x;
crop.top = crtc.p->y;
crop.right = crtc.p->x + crtc.p->width;
crop.bottom = crtc.p->y + crtc.p->height;
formatDRM = fb2.p->pixel_format;
formatAMF= FromDRMtoAMF(fb2.p->pixel_format);
handle = fb2.p->handles[0];
return AMF_OK;
}

View File

@@ -0,0 +1,123 @@
//
// 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; AV1; 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) 2023 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.
//
#pragma once
#include <string>
#include <vector>
#include "public/common/TraceAdapter.h"
#include "public/include/core/Surface.h"
#include <drm.h>
#include <drm_fourcc.h>
#include <drm_mode.h>
#include <amdgpu_drm.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
// These classed provide a nice interface to a DRM card using libdrm
amf::AMF_SURFACE_FORMAT AMF_STD_CALL FromDRMtoAMF(uint32_t formatDRM);
drmModeFB2Ptr AMF_STD_CALL AMFdrmModeGetFB2(int fd, uint32_t fb_id);
void AMF_STD_CALL AMFdrmModeFreeFB2(drmModeFB2Ptr ptr);
template <class type, void function(type)>
class AMFAutoDRMPtr
{
public:
AMFAutoDRMPtr() : p(nullptr){}
AMFAutoDRMPtr(type ptr) : p(ptr){}
~AMFAutoDRMPtr()
{
Clear();
}
AMFAutoDRMPtr<type, function>& operator=(type ptr)
{
if(p != ptr)
{
Clear();
p = ptr;
}
return *this;
}
void Clear()
{
if(p != nullptr)
{
function(p);
p = nullptr;
}
}
type p;
private:
AMFAutoDRMPtr<type, function>& operator=(const AMFAutoDRMPtr<type, function>& other);
};
typedef AMFAutoDRMPtr<drmModePlanePtr, drmModeFreePlane> AMFdrmModePlanePtr;
typedef AMFAutoDRMPtr<drmModeFBPtr, drmModeFreeFB> AMFdrmModeFBPtr;
typedef AMFAutoDRMPtr<drmModeFB2Ptr, AMFdrmModeFreeFB2> AMFdrmModeFB2Ptr;
typedef AMFAutoDRMPtr<drmModePlaneResPtr, drmModeFreePlaneResources> AMFdrmModePlaneResPtr;
typedef AMFAutoDRMPtr<drmModeObjectPropertiesPtr, drmModeFreeObjectProperties> AMFdrmModeObjectPropertiesPtr;
typedef AMFAutoDRMPtr<drmModePropertyPtr, drmModeFreeProperty> AMFdrmModePropertyPtr;
typedef AMFAutoDRMPtr<drmModeCrtcPtr, drmModeFreeCrtc> AMFdrmModeCrtcPtr;
typedef AMFAutoDRMPtr<drmModeResPtr, drmModeFreeResources> AMFdrmModeResPtr;
struct DRMCRTC {
int crtcID;
int fbID;
AMFRect crop;
int formatDRM;
amf::AMF_SURFACE_FORMAT formatAMF;
int handle;
};
class DRMDevice {
public:
DRMDevice();
~DRMDevice();
AMF_RESULT AMF_STD_CALL InitFromVulkan(int pciDomain, int pciBus, int pciDevice, int pciFunction);
AMF_RESULT AMF_STD_CALL InitFromPath(const char* pathToCard);
AMF_RESULT AMF_STD_CALL Terminate();
int AMF_STD_CALL GetFD() const;
std::string AMF_STD_CALL GetPathToCard() const;
AMF_RESULT AMF_STD_CALL GetCRTCs(std::vector<DRMCRTC>& crtcs) const;
AMF_RESULT AMF_STD_CALL GetCrtcInfo(const AMFdrmModeCrtcPtr& crtc, AMFRect &crop, int& formatDRM, amf::AMF_SURFACE_FORMAT& formatAMF, int& handle) const;
private:
AMF_RESULT SetupDevice();
int m_fd = -1;
std::string m_pathToCard;
};

View File

@@ -0,0 +1,155 @@
//
// 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 PulseAudioImprotTable.cpp
/// @brief pulseaudio import table
///-------------------------------------------------------------------------
#include "PulseAudioImportTable.h"
#include "public/common/TraceAdapter.h"
#include "../Thread.h"
using namespace amf;
#define GET_SO_ENTRYPOINT(m, h, f) m = reinterpret_cast<decltype(&f)>(amf_get_proc_address(h, #f)); \
AMF_RETURN_IF_FALSE(nullptr != m, AMF_FAIL, L"Failed to acquire entrypoint %S", #f);
//-------------------------------------------------------------------------------------------------
PulseAudioImportTable::PulseAudioImportTable()
{}
//-------------------------------------------------------------------------------------------------
PulseAudioImportTable::~PulseAudioImportTable()
{
UnloadFunctionsTable();
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT PulseAudioImportTable::LoadFunctionsTable()
{
// Load pulseaudio simple api shared library and pulseaudio shared library.
if (nullptr == m_hLibPulseSimpleSO)
{
m_hLibPulseSimpleSO = amf_load_library(L"libpulse-simple.so.0");
AMF_RETURN_IF_FALSE(nullptr != m_hLibPulseSimpleSO, AMF_FAIL, L"Failed to load libpulse-simple.so.0");
}
if (nullptr == m_hLibPulseSO)
{
m_hLibPulseSO = amf_load_library(L"libpulse.so.0");
AMF_RETURN_IF_FALSE(nullptr != m_hLibPulseSO, AMF_FAIL, L"Failed to load libpulse.so.0");
}
// Load pulseaudio mainloop functions.
GET_SO_ENTRYPOINT(m_pPA_Mainloop_Free, m_hLibPulseSO, pa_mainloop_free);
GET_SO_ENTRYPOINT(m_pPA_Mainloop_New, m_hLibPulseSO, pa_mainloop_new);
GET_SO_ENTRYPOINT(m_pPA_Mainloop_Quit, m_hLibPulseSO, pa_mainloop_quit);
GET_SO_ENTRYPOINT(m_pPA_Mainloop_Get_API, m_hLibPulseSO, pa_mainloop_get_api);
GET_SO_ENTRYPOINT(m_pPA_Mainloop_Run, m_hLibPulseSO, pa_mainloop_run);
// Load pulseaudio context functions.
GET_SO_ENTRYPOINT(m_pPA_Context_Unref, m_hLibPulseSO, pa_context_unref);
GET_SO_ENTRYPOINT(m_pPA_Context_Load_Module, m_hLibPulseSO, pa_context_load_module);
GET_SO_ENTRYPOINT(m_pPA_Context_Unload_Module, m_hLibPulseSO, pa_context_unload_module);
GET_SO_ENTRYPOINT(m_pPA_Context_New, m_hLibPulseSO, pa_context_new);
GET_SO_ENTRYPOINT(m_pPA_Context_Get_State, m_hLibPulseSO, pa_context_get_state);
GET_SO_ENTRYPOINT(m_pPA_Context_Set_State_Callback, m_hLibPulseSO, pa_context_set_state_callback);
GET_SO_ENTRYPOINT(m_pPA_Context_Get_Server_Info, m_hLibPulseSO, pa_context_get_server_info);
GET_SO_ENTRYPOINT(m_pPA_Context_Connect, m_hLibPulseSO, pa_context_connect);
GET_SO_ENTRYPOINT(m_pPA_Context_Disconnect, m_hLibPulseSO, pa_context_disconnect);
GET_SO_ENTRYPOINT(m_pPA_Context_Get_Sink_Info_By_Name, m_hLibPulseSO, pa_context_get_sink_info_by_name);
GET_SO_ENTRYPOINT(m_pPA_Context_Get_Sink_Info_List, m_hLibPulseSO, pa_context_get_sink_info_list);
GET_SO_ENTRYPOINT(m_pPA_Context_Get_Source_Info_List, m_hLibPulseSO, pa_context_get_source_info_list);
// Load other pulse audio functions.
GET_SO_ENTRYPOINT(m_pPA_Operation_Unref, m_hLibPulseSO, pa_operation_unref);
GET_SO_ENTRYPOINT(m_pPA_Strerror, m_hLibPulseSO, pa_strerror);
// Load pulse audio simple api functions.
GET_SO_ENTRYPOINT(m_pPA_Simple_New, m_hLibPulseSimpleSO, pa_simple_new);
GET_SO_ENTRYPOINT(m_pPA_Simple_Free, m_hLibPulseSimpleSO, pa_simple_free);
GET_SO_ENTRYPOINT(m_pPA_Simple_Write, m_hLibPulseSimpleSO, pa_simple_write);
GET_SO_ENTRYPOINT(m_pPA_Simple_Read, m_hLibPulseSimpleSO, pa_simple_read);
GET_SO_ENTRYPOINT(m_pPA_Simple_Flush, m_hLibPulseSimpleSO, pa_simple_flush);
GET_SO_ENTRYPOINT(m_pPA_Simple_Get_Latency, m_hLibPulseSimpleSO, pa_simple_get_latency);
return AMF_OK;
}
void PulseAudioImportTable::UnloadFunctionsTable()
{
if (nullptr != m_hLibPulseSimpleSO)
{
amf_free_library(m_hLibPulseSimpleSO);
m_hLibPulseSO = nullptr;
}
if (nullptr != m_hLibPulseSO)
{
amf_free_library(m_hLibPulseSO);
m_hLibPulseSO = nullptr;
}
m_pPA_Mainloop_Free = nullptr;
m_pPA_Mainloop_Quit = nullptr;
m_pPA_Mainloop_New = nullptr;
m_pPA_Mainloop_Get_API = nullptr;
m_pPA_Mainloop_Run = nullptr;
// Context functions.
m_pPA_Context_Unref = nullptr;
m_pPA_Context_Load_Module = nullptr;
m_pPA_Context_Unload_Module = nullptr;
m_pPA_Context_New = nullptr;
m_pPA_Context_Get_State = nullptr;
m_pPA_Context_Set_State_Callback = nullptr;
m_pPA_Context_Get_Server_Info = nullptr;
m_pPA_Context_Connect = nullptr;
m_pPA_Context_Disconnect = nullptr;
m_pPA_Context_Get_Sink_Info_By_Name = nullptr;
m_pPA_Context_Get_Sink_Info_List = nullptr;
m_pPA_Context_Get_Source_Info_List = nullptr;
// Others
m_pPA_Operation_Unref = nullptr;
m_pPA_Strerror = nullptr;
// PulseAudio Simple API functions.
m_pPA_Simple_New = nullptr;
m_pPA_Simple_Free = nullptr;
m_pPA_Simple_Write = nullptr;
m_pPA_Simple_Read = nullptr;
m_pPA_Simple_Flush = nullptr;
m_pPA_Simple_Get_Latency = nullptr;
}

View File

@@ -0,0 +1,91 @@
//
// 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 PulseAudioImportTable.h
/// @brief pulseaudio import table
///-------------------------------------------------------------------------
#pragma once
#include "../../include/core/Result.h"
#include <memory>
#include <pulse/simple.h>
#include <pulse/pulseaudio.h>
struct PulseAudioImportTable{
PulseAudioImportTable();
~PulseAudioImportTable();
AMF_RESULT LoadFunctionsTable();
void UnloadFunctionsTable();
// PulseAudio functions.
// Mainloop functions.
decltype(&pa_mainloop_free) m_pPA_Mainloop_Free = nullptr;
decltype(&pa_mainloop_quit) m_pPA_Mainloop_Quit = nullptr;
decltype(&pa_mainloop_new) m_pPA_Mainloop_New = nullptr;
decltype(&pa_mainloop_get_api) m_pPA_Mainloop_Get_API = nullptr;
decltype(&pa_mainloop_run) m_pPA_Mainloop_Run = nullptr;
// Context functions.
decltype(&pa_context_unref) m_pPA_Context_Unref = nullptr;
decltype(&pa_context_load_module) m_pPA_Context_Load_Module = nullptr;
decltype(&pa_context_unload_module) m_pPA_Context_Unload_Module = nullptr;
decltype(&pa_context_new) m_pPA_Context_New = nullptr;
decltype(&pa_context_get_state) m_pPA_Context_Get_State = nullptr;
decltype(&pa_context_set_state_callback) m_pPA_Context_Set_State_Callback = nullptr;
decltype(&pa_context_get_server_info) m_pPA_Context_Get_Server_Info = nullptr;
decltype(&pa_context_connect) m_pPA_Context_Connect = nullptr;
decltype(&pa_context_disconnect) m_pPA_Context_Disconnect = nullptr;
decltype(&pa_context_get_sink_info_by_name) m_pPA_Context_Get_Sink_Info_By_Name = nullptr;
decltype(&pa_context_get_sink_info_list) m_pPA_Context_Get_Sink_Info_List = nullptr;
decltype(&pa_context_get_source_info_list) m_pPA_Context_Get_Source_Info_List = nullptr;
// Others
decltype(&pa_operation_unref) m_pPA_Operation_Unref = nullptr;
decltype(&pa_strerror) m_pPA_Strerror = nullptr;
// PulseAudio Simple API functions.
decltype(&pa_simple_new) m_pPA_Simple_New = nullptr;
decltype(&pa_simple_free) m_pPA_Simple_Free = nullptr;
decltype(&pa_simple_write) m_pPA_Simple_Write = nullptr;
decltype(&pa_simple_read) m_pPA_Simple_Read = nullptr;
decltype(&pa_simple_flush) m_pPA_Simple_Flush = nullptr;
decltype(&pa_simple_get_latency) m_pPA_Simple_Get_Latency = nullptr;
amf_handle m_hLibPulseSO = nullptr;
amf_handle m_hLibPulseSimpleSO = nullptr;
};
typedef std::shared_ptr<PulseAudioImportTable> PulseAudioImportTablePtr;

View File

@@ -0,0 +1,757 @@
//
// 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.
//
#include "../Thread.h"
#if defined (__linux) || (__APPLE__)
#if defined(__GNUC__)
//disable gcc warinings on STL code
#pragma GCC diagnostic ignored "-Weffc++"
#endif
#define POSIX
#include <locale>
#include <algorithm>
#include <dirent.h>
#include <fnmatch.h>
#include <pwd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <sys/time.h>
#include <fstream>
#if !defined(__APPLE__)
#include <malloc.h>
#endif
#if defined(__ANDROID__)
#include <android/log.h>
#endif
#include <sys/types.h>
#include <semaphore.h>
#include <pthread.h>
#include "../AMFSTL.h"
using namespace amf;
extern "C" void AMF_STD_CALL amf_debug_trace(const wchar_t* text);
void perror(const char* errorModule)
{
char buf[128];
#if defined(__ANDROID__) || (__APPLE__)
strerror_r(errno, buf, sizeof(buf));
fprintf(stderr, "%s: %s", buf, errorModule);
#else
char* err = strerror_r(errno, buf, sizeof(buf));
fprintf(stderr, "%s: %s", err, errorModule);
#endif
exit(1);
}
#if defined(__APPLE__)
amf_uint64 AMF_STD_CALL get_current_thread_id()
{
return reinterpret_cast<amf_uint64>(pthread_self());
}
#else
amf_uint32 AMF_STD_CALL get_current_thread_id()
{
return static_cast<amf_uint32>(pthread_self());
}
#endif
// int clock_gettime(clockid_t clk_id, struct timespec *tp);
//----------------------------------------------------------------------------------------
// threading
//----------------------------------------------------------------------------------------
amf_long AMF_STD_CALL amf_atomic_inc(amf_long* X)
{
return __sync_add_and_fetch(X, 1);
}
//----------------------------------------------------------------------------------------
amf_long AMF_STD_CALL amf_atomic_dec(amf_long* X)
{
return __sync_sub_and_fetch(X, 1);
}
//----------------------------------------------------------------------------------------
amf_handle AMF_STD_CALL amf_create_critical_section()
{
pthread_mutex_t* mutex = new pthread_mutex_t;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(mutex, &attr);
return (amf_handle)mutex;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_delete_critical_section(amf_handle cs)
{
if(cs == NULL)
{
return false;
}
pthread_mutex_t* mutex = (pthread_mutex_t*)cs;
int err = pthread_mutex_destroy(mutex);
delete mutex;
return err == 0;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_enter_critical_section(amf_handle cs)
{
if(cs == NULL)
{
return false;
}
pthread_mutex_t* mutex = (pthread_mutex_t*)cs;
return pthread_mutex_lock(mutex) == 0;
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_wait_critical_section(amf_handle cs, amf_ulong ulTimeout)
{
if(cs == NULL)
{
return false;
}
return amf_wait_for_mutex(cs, ulTimeout);
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_leave_critical_section(amf_handle cs)
{
if(cs == NULL)
{
return false;
}
pthread_mutex_t* mutex = (pthread_mutex_t*)cs;
return pthread_mutex_unlock(mutex) == 0;
}
//----------------------------------------------------------------------------------------
struct MyEvent
{
bool m_manual_reset;
pthread_cond_t m_cond;
pthread_mutex_t m_mutex;
bool m_triggered;
};
//----------------------------------------------------------------------------------------
amf_handle AMF_STD_CALL amf_create_event(bool initially_owned, bool manual_reset, const wchar_t* name)
{
MyEvent* event = new MyEvent;
// Linux does not natively support Named Condition variables
// so raise an error.
// Implement this using boost (NamedCondition), Qt, or some other framework.
if(name != NULL)
{
perror("Named Events not supported under Linux yet");
exit(1);
}
event->m_manual_reset = manual_reset;
pthread_cond_t cond_tmp = PTHREAD_COND_INITIALIZER;
event->m_cond = cond_tmp;
pthread_mutex_t mutex_tmp = PTHREAD_MUTEX_INITIALIZER;
event->m_mutex = mutex_tmp;
event->m_triggered = false;
if(initially_owned)
{
amf_set_event((amf_handle)event);
}
return (amf_handle)event;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_delete_event(amf_handle hevent)
{
if(hevent == NULL)
{
return false;
}
MyEvent* event = (MyEvent*)hevent;
int err1 = pthread_mutex_destroy(&event->m_mutex);
int err2 = pthread_cond_destroy(&event->m_cond);
delete event;
return err1 == 0 && err2 == 0;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_set_event(amf_handle hevent)
{
if(hevent == NULL)
{
return false;
}
MyEvent* event = (MyEvent*)hevent;
pthread_mutex_lock(&event->m_mutex);
event->m_triggered = true;
int err1 = pthread_cond_broadcast(&event->m_cond);
pthread_mutex_unlock(&event->m_mutex);
return err1 == 0;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_reset_event(amf_handle hevent)
{
if(hevent == NULL)
{
return false;
}
MyEvent* event = (MyEvent*)hevent;
pthread_mutex_lock(&event->m_mutex);
event->m_triggered = false;
int err = pthread_mutex_unlock(&event->m_mutex);
return err == 0;
}
//----------------------------------------------------------------------------------------
static bool AMF_STD_CALL amf_wait_for_event_int(amf_handle hevent, unsigned long timeout, bool bTimeoutErr)
{
if(hevent == NULL)
{
return false;
}
bool ret = true;
int err = 0;
MyEvent* event = (MyEvent*)hevent;
pthread_mutex_lock(&event->m_mutex);
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
amf_uint64 start_time = ((amf_uint64)ts.tv_sec) * 1000 + ((amf_uint64)ts.tv_nsec) / 1000000; //to msec
if(event->m_manual_reset)
{
while(!event->m_triggered)
{
if(timeout == AMF_INFINITE)
{
err = pthread_cond_wait(&event->m_cond, &event->m_mutex); //MM todo - timeout is not supported
ret = err == 0;
}
else
{
clock_gettime(CLOCK_REALTIME, &ts);
amf_uint64 current_time = ((amf_uint64)ts.tv_sec) * 1000 + ((amf_uint64)ts.tv_nsec) / 1000000; //to msec
if(current_time - start_time > (amf_uint64)timeout)
{
ret = bTimeoutErr ? false : true;
break;
}
amf_uint64 to_wait = start_time + timeout;
timespec abstime;
abstime.tv_sec = (time_t)(to_wait / 1000); // timeout is in millisec
abstime.tv_nsec = (time_t)((to_wait - ((amf_uint64)abstime.tv_sec) * 1000) * 1000000); // the rest to nanosec
err = pthread_cond_timedwait(&event->m_cond, &event->m_mutex, &abstime);
ret = err == 0;
}
}
}
else
{
if(event->m_triggered)
{
ret = true;
}
else
{
if (timeout == AMF_INFINITE) {
err = pthread_cond_wait(&event->m_cond, &event->m_mutex);
} else {
start_time += timeout;
timespec abstime;
abstime.tv_sec = (time_t) (start_time / 1000); // timeout is in millisec
abstime.tv_nsec = (time_t) ((start_time - (amf_uint64) (abstime.tv_sec) * 1000) *
1000000); // the rest to nanosec
err = pthread_cond_timedwait(&event->m_cond, &event->m_mutex, &abstime);
}
if (bTimeoutErr) {
ret = (err == 0);
} else {
ret = (err == 0 || err == ETIMEDOUT);
}
}
if(ret == true)
{
event->m_triggered = false;
}
}
pthread_mutex_unlock(&event->m_mutex);
return ret;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_wait_for_event(amf_handle hevent, unsigned long timeout)
{
return amf_wait_for_event_int(hevent, timeout, true);
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_wait_for_event_timeout(amf_handle hevent, amf_ulong ulTimeout)
{
return amf_wait_for_event_int(hevent, ulTimeout, false);
}
//----------------------------------------------------------------------------------------
amf_handle AMF_STD_CALL amf_create_mutex(bool initially_owned, const wchar_t* name)
{
pthread_mutex_t* mutex = new pthread_mutex_t;
pthread_mutex_t mutex_tmp = PTHREAD_MUTEX_INITIALIZER;
*mutex = mutex_tmp;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(mutex, &attr);
if(initially_owned)
{
pthread_mutex_lock(mutex);
}
return (amf_handle)mutex;
}
//----------------------------------------------------------------------------------------
amf_handle AMF_STD_CALL amf_open_mutex(const wchar_t* pName)
{
assert(false);
return 0;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_delete_mutex(amf_handle hmutex)
{
if(hmutex == NULL)
{
return false;
}
pthread_mutex_t* mutex = (pthread_mutex_t*)hmutex;
int err = pthread_mutex_destroy(mutex);
delete mutex;
return err == 0;
}
//----------------------------------------------------------------------------------------
#if defined(__APPLE__)
int sem_timedwait1(sem_t* semaphore, const struct timespec* timeout)
{
struct timeval timenow;
struct timespec sleepytime;
int retcode;
/// This is just to avoid a completely busy wait
sleepytime.tv_sec = 0;
sleepytime.tv_nsec = 10000000; // 10ms
while((retcode = sem_trywait(semaphore)) != 0)
{
gettimeofday (&timenow, NULL);
if((timenow.tv_sec >= timeout->tv_sec) && ((timenow.tv_usec * 1000) >= timeout->tv_nsec))
{
return retcode;
}
nanosleep (&sleepytime, NULL);
}
return retcode;
}
#endif
#if defined(__ANDROID__) || defined(__APPLE__)
int pthread_mutex_timedlock1(pthread_mutex_t* mutex, const struct timespec* timeout)
{
struct timeval timenow;
struct timespec sleepytime;
int retcode;
/// This is just to avoid a completely busy wait
sleepytime.tv_sec = 0;
sleepytime.tv_nsec = 10000000; // 10ms
while((retcode = pthread_mutex_trylock (mutex)) == EBUSY)
{
gettimeofday (&timenow, NULL);
if((timenow.tv_sec >= timeout->tv_sec) && ((timenow.tv_usec * 1000) >= timeout->tv_nsec))
{
return ETIMEDOUT;
}
nanosleep (&sleepytime, NULL);
}
return retcode;
}
#endif
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_wait_for_mutex(amf_handle hmutex, unsigned long timeout)
{
if(hmutex == NULL)
{
return false;
}
pthread_mutex_t* mutex = (pthread_mutex_t*)hmutex;
if(timeout == AMF_INFINITE)
{
return pthread_mutex_lock(mutex) == 0;
}
// ulTimeout is in milliseconds
long timeout_sec = timeout / 1000; /* Seconds */;
long timeout_nsec = (timeout - (timeout / 1000) * 1000) * 1000000;
timespec wait_time; //absolute time
clock_gettime(CLOCK_REALTIME, &wait_time);
wait_time.tv_sec += timeout_sec;
wait_time.tv_nsec += timeout_nsec;
if (wait_time.tv_nsec >= 1000000000)
{
wait_time.tv_sec++;
wait_time.tv_nsec -= 1000000000;
}
#if defined(__ANDROID__) || defined (__APPLE__)
return pthread_mutex_timedlock1(mutex, &wait_time) == 0;
#else
return pthread_mutex_timedlock(mutex, &wait_time) == 0;
#endif
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_release_mutex(amf_handle hmutex)
{
if(hmutex == NULL)
{
return false;
}
pthread_mutex_t* mutex = (pthread_mutex_t*)hmutex;
return pthread_mutex_unlock(mutex) == 0;
}
//----------------------------------------------------------------------------------------
amf_handle AMF_STD_CALL amf_create_semaphore(amf_long iInitCount, amf_long iMaxCount, const wchar_t* /*pName*/)
{
if(iMaxCount == 0 || iInitCount > iMaxCount)
{
return NULL;
}
sem_t* semaphore = new sem_t;
if(sem_init(semaphore, 0, iInitCount) != 0)
{
delete semaphore;
return NULL;
}
return (amf_handle)semaphore;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_delete_semaphore(amf_handle hsemaphore)
{
if(hsemaphore == NULL)
{
return false;
}
bool ret = true;
sem_t* semaphore = (sem_t*)hsemaphore;
ret = (0==sem_destroy(semaphore)) ? 1:0;
delete semaphore;
return ret;
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_wait_for_semaphore(amf_handle hsemaphore, amf_ulong timeout)
{
if(hsemaphore == NULL)
{
return true;
}
// ulTimeout is in milliseconds
long timeout_sec = timeout / 1000; /* Seconds */;
long timeout_nsec = (timeout - (timeout / 1000) * 1000) * 1000000;
timespec wait_time; //absolute time
clock_gettime(CLOCK_REALTIME, &wait_time);
wait_time.tv_sec += timeout_sec;
wait_time.tv_nsec += timeout_nsec;
if (wait_time.tv_nsec >= 1000000000)
{
wait_time.tv_sec++;
wait_time.tv_nsec -= 1000000000;
}
sem_t* semaphore = (sem_t*)hsemaphore;
if(timeout != AMF_INFINITE)
{
#if defined(__APPLE__)
return sem_timedwait1 (semaphore, &wait_time) == 0; // errno=ETIMEDOU
#else
return sem_timedwait (semaphore, &wait_time) == 0; // errno=ETIMEDOUT
#endif
}
else
{
return sem_wait(semaphore) == 0;
}
}
//----------------------------------------------------------------------------------------
bool AMF_STD_CALL amf_release_semaphore(amf_handle hsemaphore, amf_long iCount, amf_long* iOldCount)
{
if(hsemaphore == NULL)
{
return false;
}
sem_t* semaphore = (sem_t*)hsemaphore;
if(iOldCount != NULL)
{
int iTmp = 0;
sem_getvalue(semaphore, &iTmp);
*iOldCount = iTmp;
}
for(int i = 0; i < iCount; i++)
{
sem_post(semaphore);
}
return true;
}
//------------------------------------------------------------------------------
/*
* Delay is specified in milliseconds.
* Function will return prematurely if msDelay value is invalid.
*
* */
void AMF_STD_CALL amf_sleep(amf_ulong msDelay)
{
#if defined(NANOSLEEP_DONTUSE)
struct timespec sts, sts_remaining;
int iErrorCode;
ts.tv_sec = msDelay / 1000;
ts.tv_nsec = (msDelay - sts.tv_sec * 1000) * 1000000; // nanosec
// put in code to measure sleep clock jitter
do
{
iErrorCode = nanosleep(&sts, &sts_remaining);
if(iErrorCode)
{
switch(errno)
{
case EINTR:
sts = sts_remaining;
break;
case EFAULT:
case EINVAL:
case default:
perror("amf_sleep");
return;
/* TODO: how to log errors? */
}
}
} while(iErrorCode);
#else
usleep(msDelay * 1000);
#endif
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
// memory
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
void AMF_STD_CALL amf_debug_trace(const wchar_t* text)
{
#if defined(__ANDROID__)
__android_log_write(ANDROID_LOG_DEBUG, "AMF_TRACE", amf_from_unicode_to_multibyte(text).c_str());
#else
fprintf(stderr, "%ls", text);
#endif
}
void* AMF_STD_CALL amf_virtual_alloc(size_t size)
{
void* mem = NULL;
#if defined(__ANDROID__)
mem = memalign(sysconf(_SC_PAGESIZE), size);
if(mem == NULL)
{
amf_debug_trace(L"Failed to alloc memory using memalign() function.");
}
#else
int exitCode = posix_memalign(&mem, sysconf(_SC_PAGESIZE), size);
if(exitCode != 0)
{
amf_debug_trace(L"Failed to alloc memory using posix_memaling() function.");
}
#endif
return mem;
}
//-------------------------------------------------------------------------------------------------------
void AMF_STD_CALL amf_virtual_free(void* ptr)
{
free(ptr); // according to linux help memory allocated by memalign() must be freed by free()
}
//----------------------------------------------------------------------------------------
amf_handle AMF_STD_CALL amf_load_library(const wchar_t* filename)
{
void *ret = dlopen(amf_from_unicode_to_multibyte(filename).c_str(), RTLD_NOW | RTLD_GLOBAL);
if(ret ==0 )
{
const char *err = dlerror();
int a=1;
}
return ret;
}
amf_handle AMF_STD_CALL amf_load_library1(const wchar_t* filename, bool bGlobal)
{
void *ret;
if (bGlobal) {
ret = dlopen(amf_from_unicode_to_multibyte(filename).c_str(), RTLD_NOW | RTLD_GLOBAL);
} else {
#if defined(__ANDROID__) || (__APPLE__)
ret = dlopen(amf_from_unicode_to_multibyte(filename).c_str(), RTLD_NOW | RTLD_LOCAL);
#else
ret = dlopen(amf_from_unicode_to_multibyte(filename).c_str(), RTLD_NOW | RTLD_LOCAL| RTLD_DEEPBIND);
#endif
}
if(ret == 0)
{
const char *err = dlerror();
int a=1;
}
return ret;
}
void* AMF_STD_CALL amf_get_proc_address(amf_handle module, const char* procName)
{
return dlsym(module, procName);
}
//-------------------------------------------------------------------------------------------------
int AMF_STD_CALL amf_free_library(amf_handle module)
{
return dlclose(module) == 0;
}
void AMF_STD_CALL amf_increase_timer_precision()
{
}
void AMF_STD_CALL amf_restore_timer_precision()
{
}
//----------------------------------------------------------------------------------------
double AMF_STD_CALL amf_clock()
{
//MM: clock() Win32 - returns time from beginning of the program
//MM: clock() works different in Linux - returns consumed processor time
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
double cur_time = ((double)ts.tv_sec) + ((double)ts.tv_nsec) / 1000000000.; //to sec
return cur_time;
}
//----------------------------------------------------------------------------------------
amf_int64 AMF_STD_CALL get_time_in_seconds_with_fraction()
{
struct timeval tv;
gettimeofday(&tv, NULL);
amf_int64 ntp_time = ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
return ntp_time;
}
//---------------------------------------------------------------------------------------
amf_pts AMF_STD_CALL amf_high_precision_clock()
{
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return ts.tv_sec * 10000000LL + ts.tv_nsec / 100.; //to nanosec
}
//---------------------------------------------------------------------------------------
// Returns number of physical cores
amf_int32 AMF_STD_CALL amf_get_cpu_cores()
{
// NOTE: get_nprocs is preffered way to get online cores on linux but it will
// return number of logical cores. Uncomment line bellow if that's the behaviour needed
//return get_nprocs();
const char CPUINFO_CORES_COUNT[] = "cpu cores";
std::ifstream cpuinfo("/proc/cpuinfo");
std::string line;
while (std::getline(cpuinfo, line))
{
if (line.compare(0, strlen(CPUINFO_CORES_COUNT), CPUINFO_CORES_COUNT) == 0)
{
size_t pos = line.rfind(':') + 2;
if (pos == std::string::npos)
{
continue;
}
std::string tmp = line.substr(pos);
const char* value = tmp.c_str();
int cores_online = std::atoi(value);
// Make sure we always return at least 1
return std::max(1, cores_online);
}
}
// Failure, return default
return 1;
}
//--------------------------------------------------------------------------------
// the end
//--------------------------------------------------------------------------------
#endif

View File

@@ -0,0 +1,75 @@
//
// 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; AV1; 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) 2023 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.
//
#pragma once
#include <memory>
#include <X11/X.h>
#include <X11/Xlib.h>
//this pattern makes it impossible to use the x11 Display* pointer without first calling XLockDisplay
class XDisplay {
public:
typedef std::shared_ptr<XDisplay> Ptr;
XDisplay()
: m_pDisplay(XOpenDisplay(nullptr))
, m_shouldClose(true)
{}
XDisplay(Display* dpy)
: m_pDisplay(dpy)
, m_shouldClose(false)
{}
~XDisplay() { if(IsValid() && m_shouldClose) XCloseDisplay(m_pDisplay); }
bool IsValid() { return m_pDisplay != nullptr; }
private:
Display* m_pDisplay;
bool m_shouldClose = false;
friend class XDisplayPtr;
};
class XDisplayPtr {
public:
XDisplayPtr() = delete;
XDisplayPtr(const XDisplayPtr&) = delete;
XDisplayPtr& operator=(const XDisplayPtr&) =delete;
explicit XDisplayPtr(std::shared_ptr<XDisplay> display) : m_pDisplay(display) { XLockDisplay(m_pDisplay->m_pDisplay); }
~XDisplayPtr() { XUnlockDisplay(m_pDisplay->m_pDisplay); }
//XDisplayPtr acts like a normal Display* pointer, but the only way to obtain it is by locking the Display
operator Display*() { return m_pDisplay->m_pDisplay; }
private:
XDisplay::Ptr m_pDisplay;
};

View File

@@ -0,0 +1,11 @@
///-------------------------------------------------------------------------
/// Copyright © 2020-2022 Advanced Micro Devices, Inc. All rights reserved.
///-------------------------------------------------------------------------
#pragma once
#include <memory>
#include <X11/extensions/Xrandr.h>
typedef std::shared_ptr<XRRScreenResources> XRRScreenResourcesPtr;
typedef std::shared_ptr<XRRCrtcInfo> XRRCrtcInfoPtr;

View File

@@ -0,0 +1,144 @@
//
// 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 ObservableImpl.h
* @brief AMFObservableImpl common template declaration
***************************************************************************************************
*/
#ifndef AMF_ObservableImpl_h
#define AMF_ObservableImpl_h
#pragma once
#include "Thread.h"
#include <list>
namespace amf
{
template<typename Observer>
class AMFObservableImpl
{
private:
typedef std::list<Observer*> ObserversList;
ObserversList m_observers;
public:
AMFObservableImpl() : m_observers()
{}
virtual ~AMFObservableImpl()
{
assert(m_observers.size() == 0);
}
virtual void AMF_STD_CALL AddObserver(Observer* pObserver)
{
if (pObserver == nullptr)
{
return;
}
amf_bool found = false;
AMFLock lock(&m_sc);
for (typename ObserversList::iterator it = m_observers.begin(); it != m_observers.end(); it++)
{
if (*it == pObserver)
{
found = true;
break;
}
}
if (found == false)
{
m_observers.push_back(pObserver);
}
}
virtual void AMF_STD_CALL RemoveObserver(Observer* pObserver)
{
AMFLock lock(&m_sc);
m_observers.remove(pObserver);
}
protected:
void AMF_STD_CALL ClearObservers()
{
AMFLock lock(&m_sc);
m_observers.clear();
}
void AMF_STD_CALL NotifyObservers(void (AMF_STD_CALL Observer::* pEvent)())
{
ObserversList tempList;
{
AMFLock lock(&m_sc);
tempList = m_observers;
}
for (typename ObserversList::iterator it = tempList.begin(); it != tempList.end(); ++it)
{
Observer* pObserver = *it;
(pObserver->*pEvent)();
}
}
template<typename TArg0>
void AMF_STD_CALL NotifyObservers(void (AMF_STD_CALL Observer::* pEvent)(TArg0), TArg0 arg0)
{
ObserversList tempList;
{
AMFLock lock(&m_sc);
tempList = m_observers;
}
for (typename ObserversList::iterator it = tempList.begin(); it != tempList.end(); ++it)
{
Observer* pObserver = *it;
(pObserver->*pEvent)(arg0);
}
}
template<typename TArg0, typename TArg1>
void AMF_STD_CALL NotifyObservers(void (AMF_STD_CALL Observer::* pEvent)(TArg0, TArg1), TArg0 arg0, TArg1 arg1)
{
ObserversList tempList;
{
AMFLock lock(&m_sc);
tempList = m_observers;
}
for (typename ObserversList::iterator it = tempList.begin(); it != tempList.end(); it++)
{
Observer* pObserver = *it;
(pObserver->*pEvent)(arg0, arg1);
}
}
private:
AMFCriticalSection m_sc;
};
}
#endif //AMF_ObservableImpl_h

View File

@@ -0,0 +1,563 @@
//
// 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 OpenGLImportTable.cpp
/// @brief OpenGL import table
///-------------------------------------------------------------------------
#include "OpenGLImportTable.h"
#include "public/common/TraceAdapter.h"
#include "public/common/Thread.h"
using namespace amf;
#define AMF_FACILITY L"OpenGLImportTable"
//-------------------------------------------------------------------------------------------------
#define TRY_GET_DLL_ENTRY_POINT_CORE(w) \
w = reinterpret_cast<w##_fn>(amf_get_proc_address(m_hOpenGLDll, #w));
#define GET_DLL_ENTRY_POINT_CORE(w)\
TRY_GET_DLL_ENTRY_POINT_CORE(w)\
AMF_RETURN_IF_FALSE(w != nullptr, AMF_NOT_FOUND, L"Failed to aquire entry point %S", #w);
// On windows, some functions are defined in the core opengl32.dll (especially the core old ones)
// and some are not and we have to use wglGetProcAddress. Its a problem because the ones defined in
// opengl32.dll are not included in the wglGetProcAddress and vice versa
#if defined(_WIN32)
#define TRY_GET_DLL_ENTRY_POINT(w) \
{\
void const * const p = (void*)wglGetProcAddress(#w);\
if (p == nullptr || p == (void*)0x1 || p == (void*)0x2 || p == (void*)0x3 || p == (void*)-1)\
{\
TRY_GET_DLL_ENTRY_POINT_CORE(w);\
}\
else\
{\
w = reinterpret_cast<w##_fn>(p);\
}\
}
#else
#define TRY_GET_DLL_ENTRY_POINT(w) TRY_GET_DLL_ENTRY_POINT_CORE(w)
#endif
#define GET_DLL_ENTRY_POINT(w)\
TRY_GET_DLL_ENTRY_POINT(w)\
AMF_RETURN_IF_FALSE(w != nullptr, AMF_NOT_FOUND, L"Failed to aquire entry point %S", #w);
OpenGLImportTable::OpenGLImportTable() :
m_hOpenGLDll(nullptr),
glGetError(nullptr),
glGetString(nullptr),
// glGetStringi(nullptr),
glEnable(nullptr),
glClear(nullptr),
glClearAccum(nullptr),
glClearColor(nullptr),
glClearDepth(nullptr),
glClearIndex(nullptr),
glClearStencil(nullptr),
glDrawArrays(nullptr),
glViewport(nullptr),
glFinish(nullptr),
#if defined(_WIN32)
wglCreateContext(nullptr),
wglDeleteContext(nullptr),
wglGetCurrentContext(nullptr),
wglGetCurrentDC(nullptr),
wglMakeCurrent(nullptr),
wglGetProcAddress(nullptr),
wglGetExtensionsStringARB(nullptr),
wglSwapIntervalEXT(nullptr),
wndClass{},
hDummyWnd(nullptr),
hDummyDC(nullptr),
hDummyOGLContext(nullptr),
#elif defined(__ANDROID__)
eglInitialize(nullptr),
eglGetDisplay(nullptr),
eglChooseConfig(nullptr),
eglCreateContext(nullptr),
eglDestroyImageKHR(nullptr),
eglCreateImageKHR(nullptr),
eglSwapInterval(nullptr),
glEGLImageTargetTexture2DOES(nullptr),
glReadPixels(nullptr),
#elif defined(__linux)
glXDestroyContext(nullptr),
glXDestroyWindow(nullptr),
glXSwapBuffers(nullptr),
glXQueryExtension(nullptr),
glXChooseFBConfig(nullptr),
glXCreateWindow(nullptr),
glXCreateNewContext(nullptr),
glXMakeCurrent(nullptr),
glXGetCurrentContext(nullptr),
glXGetCurrentDrawable(nullptr),
glXQueryExtensionsString(nullptr),
glXSwapIntervalEXT(nullptr),
#endif
glBindTexture(nullptr),
glDeleteTextures(nullptr),
glGenTextures(nullptr),
glGetTexImage(nullptr),
glGetTexLevelParameteriv(nullptr),
glTexParameteri(nullptr),
glTexImage2D(nullptr),
glActiveTexture(nullptr),
glBindFramebuffer(nullptr),
// glBindRenderbuffer(nullptr),
glBlitFramebuffer(nullptr),
glCheckFramebufferStatus(nullptr),
glDeleteFramebuffers(nullptr),
// glDeleteRenderbuffers(nullptr),
// glFramebufferRenderbuffer(nullptr),
// glFramebufferTexture1D(nullptr),
glFramebufferTexture2D(nullptr),
// glFramebufferTexture3D(nullptr),
glFramebufferTextureLayer(nullptr),
glGenFramebuffers(nullptr),
// glGenRenderbuffers(nullptr),
// glGenerateMipmap(nullptr),
// glGetFramebufferAttachmentParameteriv(nullptr),
// glGetRenderbufferParameteriv(nullptr),
// glIsFramebuffer(nullptr),
// glIsRenderbuffer(nullptr),
// glRenderbufferStorage(nullptr),
// glRenderbufferStorageMultisample(nullptr),
glGenBuffers(nullptr),
glBindBuffer(nullptr),
glBufferData(nullptr),
glBufferSubData(nullptr),
glDeleteBuffers(nullptr),
glVertexAttribPointer(nullptr),
// glVertexAttribLPointer(nullptr),
// glVertexAttribIPointer(nullptr),
glBindVertexBuffer(nullptr),
glDisableVertexAttribArray(nullptr),
glEnableVertexAttribArray(nullptr),
glBindVertexArray(nullptr),
glDeleteVertexArrays(nullptr),
glGenVertexArrays(nullptr),
glIsVertexArray(nullptr),
glCreateShader(nullptr),
glShaderSource(nullptr),
glCompileShader(nullptr),
glGetShaderInfoLog(nullptr),
glGetShaderSource(nullptr),
glGetShaderiv(nullptr),
glCreateProgram(nullptr),
glAttachShader(nullptr),
glLinkProgram(nullptr),
glGetProgramInfoLog(nullptr),
glGetProgramiv(nullptr),
glValidateProgram(nullptr),
glUseProgram(nullptr),
glDeleteShader(nullptr),
glDeleteProgram(nullptr),
glGetUniformLocation(nullptr),
// glUniform1f(nullptr),
// glUniform1fv(nullptr),
glUniform1i(nullptr),
// glUniform1iv(nullptr),
// glUniform2f(nullptr),
// glUniform2fv(nullptr),
// glUniform2i(nullptr),
// glUniform2iv(nullptr),
// glUniform3f(nullptr),
// glUniform3fv(nullptr),
// glUniform3i(nullptr),
// glUniform3iv(nullptr),
// glUniform4f(nullptr),
glUniform4fv(nullptr),
// glUniform4i(nullptr),
// glUniform4iv(nullptr),
// glUniformMatrix2fv(nullptr),
// glUniformMatrix3fv(nullptr),
// glUniformMatrix4fv(nullptr),
glBindBufferBase(nullptr),
glBindBufferRange(nullptr),
glGetUniformBlockIndex(nullptr),
glUniformBlockBinding(nullptr),
glBindSampler(nullptr),
glDeleteSamplers(nullptr),
glGenSamplers(nullptr),
// glGetSamplerParameterIiv(nullptr),
// glGetSamplerParameterIuiv(nullptr),
// glGetSamplerParameterfv(nullptr),
// glGetSamplerParameteriv(nullptr),
// glIsSampler(nullptr),
// glSamplerParameterIiv(nullptr),
// glSamplerParameterIuiv(nullptr),
glSamplerParameterf(nullptr),
glSamplerParameterfv(nullptr),
glSamplerParameteri(nullptr)
// glSamplerParameteriv(nullptr)
{
}
OpenGLImportTable::~OpenGLImportTable()
{
if (m_hOpenGLDll != nullptr)
{
amf_free_library(m_hOpenGLDll);
}
m_hOpenGLDll = nullptr;
#if defined(_WIN32)
DestroyDummy();
#endif
}
AMF_RESULT OpenGLImportTable::LoadFunctionsTable()
{
if (m_hOpenGLDll != nullptr)
{
return AMF_OK;
}
#if defined(_WIN32)
m_hOpenGLDll = amf_load_library(L"opengl32.dll");
#elif defined(__ANDROID__)
m_hOpenGLDll = amf_load_library1(L"libGLES.so", true);
#elif defined(__linux__)
m_hOpenGLDll = amf_load_library1(L"libGL.so.1", true);
#endif
if (m_hOpenGLDll == nullptr)
{
AMFTraceError(L"OpenGLImportTable", L"amf_load_library() failed to load opengl dll!");
return AMF_FAIL;
}
// Core
GET_DLL_ENTRY_POINT_CORE(glGetError);
GET_DLL_ENTRY_POINT_CORE(glGetString);
GET_DLL_ENTRY_POINT_CORE(glEnable);
GET_DLL_ENTRY_POINT_CORE(glClear);
GET_DLL_ENTRY_POINT_CORE(glClearAccum);
GET_DLL_ENTRY_POINT_CORE(glClearColor);
GET_DLL_ENTRY_POINT_CORE(glClearDepth);
GET_DLL_ENTRY_POINT_CORE(glClearIndex);
GET_DLL_ENTRY_POINT_CORE(glClearStencil);
GET_DLL_ENTRY_POINT_CORE(glDrawArrays);
GET_DLL_ENTRY_POINT_CORE(glViewport);
GET_DLL_ENTRY_POINT_CORE(glFinish);
// Core (platform-dependent)
#if defined(_WIN32)
GET_DLL_ENTRY_POINT_CORE(wglCreateContext);
GET_DLL_ENTRY_POINT_CORE(wglDeleteContext);
GET_DLL_ENTRY_POINT_CORE(wglGetCurrentContext);
GET_DLL_ENTRY_POINT_CORE(wglGetCurrentDC);
GET_DLL_ENTRY_POINT_CORE(wglMakeCurrent);
GET_DLL_ENTRY_POINT_CORE(wglGetProcAddress);
#elif defined(__ANDROID__)
GET_DLL_ENTRY_POINT_CORE(eglInitialize);
GET_DLL_ENTRY_POINT_CORE(eglGetDisplay);
GET_DLL_ENTRY_POINT_CORE(eglChooseConfig);
GET_DLL_ENTRY_POINT_CORE(eglCreateContext);
GET_DLL_ENTRY_POINT_CORE(eglDestroyImageKHR);
GET_DLL_ENTRY_POINT_CORE(eglCreateImageKHR);
GET_DLL_ENTRY_POINT_CORE(glEGLImageTargetTexture2DOES);
GET_DLL_ENTRY_POINT_CORE(glReadPixels);
#elif defined(__linux)
GET_DLL_ENTRY_POINT_CORE(glXDestroyContext);
GET_DLL_ENTRY_POINT_CORE(glXDestroyWindow);
GET_DLL_ENTRY_POINT_CORE(glXSwapBuffers);
GET_DLL_ENTRY_POINT_CORE(glXQueryExtension);
GET_DLL_ENTRY_POINT_CORE(glXChooseFBConfig);
GET_DLL_ENTRY_POINT_CORE(glXCreateWindow);
GET_DLL_ENTRY_POINT_CORE(glXCreateNewContext);
GET_DLL_ENTRY_POINT_CORE(glXMakeCurrent);
GET_DLL_ENTRY_POINT_CORE(glXGetCurrentContext);
GET_DLL_ENTRY_POINT_CORE(glXGetCurrentDrawable);
#endif
// Textures
GET_DLL_ENTRY_POINT_CORE(glBindTexture);
GET_DLL_ENTRY_POINT_CORE(glDeleteTextures);
GET_DLL_ENTRY_POINT_CORE(glGenTextures);
GET_DLL_ENTRY_POINT_CORE(glGetTexImage);
GET_DLL_ENTRY_POINT_CORE(glGetTexLevelParameteriv);
GET_DLL_ENTRY_POINT_CORE(glTexParameteri);
GET_DLL_ENTRY_POINT_CORE(glTexImage2D);
// For windows, we need to use wglGetProcAddress to get some
// addresses however that requires a context. We can just create
// a small dummy context/window and then delete it when we are done
#if defined(_WIN32)
{
AMF_RESULT res = CreateDummy();
if (res != AMF_OK)
{
DestroyDummy();
AMF_RETURN_IF_FAILED(res, L"CreateDummy() failed");
}
}
#endif
AMF_RESULT res = LoadContextFunctionsTable();
AMF_RETURN_IF_FAILED(res, L"LoadContextFunctionsTable() failed");
#if defined(_WIN32)
DestroyDummy();
#endif
return AMF_OK;
}
AMF_RESULT OpenGLImportTable::LoadContextFunctionsTable()
{
if (m_hOpenGLDll == nullptr)
{
AMF_RETURN_IF_FAILED(LoadFunctionsTable());
}
#if defined(_WIN32)
HGLRC context = wglGetCurrentContext();
AMF_RETURN_IF_FALSE(context != nullptr, AMF_NOT_INITIALIZED, L"LoadContextFunctionsTable() - context is not initialized");
#endif
// Core
// GET_DLL_ENTRY_POINT(glGetStringi);
#if defined(_WIN32)
TRY_GET_DLL_ENTRY_POINT(wglGetExtensionsStringARB);
TRY_GET_DLL_ENTRY_POINT(wglSwapIntervalEXT);
#elif defined(__ANDROID__)
TRY_GET_DLL_ENTRY_POINT(eglSwapInterval);
#elif defined(__linux)
TRY_GET_DLL_ENTRY_POINT(glXQueryExtensionsString);
TRY_GET_DLL_ENTRY_POINT(glXSwapIntervalEXT);
#endif
// Textures
GET_DLL_ENTRY_POINT(glActiveTexture);
// Frame buffer and render buffer objects
GET_DLL_ENTRY_POINT(glBindFramebuffer);
// GET_DLL_ENTRY_POINT(glBindRenderbuffer);
GET_DLL_ENTRY_POINT(glBlitFramebuffer);
GET_DLL_ENTRY_POINT(glCheckFramebufferStatus);
GET_DLL_ENTRY_POINT(glDeleteFramebuffers);
// GET_DLL_ENTRY_POINT(glDeleteRenderbuffers);
// GET_DLL_ENTRY_POINT(glFramebufferRenderbuffer);
// GET_DLL_ENTRY_POINT(glFramebufferTexture1D);
GET_DLL_ENTRY_POINT(glFramebufferTexture2D);
// GET_DLL_ENTRY_POINT(glFramebufferTexture3D);
GET_DLL_ENTRY_POINT(glFramebufferTextureLayer);
GET_DLL_ENTRY_POINT(glGenFramebuffers);
// GET_DLL_ENTRY_POINT(glGenRenderbuffers);
// GET_DLL_ENTRY_POINT(glGenerateMipmap);
// GET_DLL_ENTRY_POINT(glGetFramebufferAttachmentParameteriv);
// GET_DLL_ENTRY_POINT(glGetRenderbufferParameteriv);
// GET_DLL_ENTRY_POINT(glIsFramebuffer);
// GET_DLL_ENTRY_POINT(glIsRenderbuffer);
// GET_DLL_ENTRY_POINT(glRenderbufferStorage);
// GET_DLL_ENTRY_POINT(glRenderbufferStorageMultisample);
// Buffers
GET_DLL_ENTRY_POINT(glGenBuffers);
GET_DLL_ENTRY_POINT(glBindBuffer);
GET_DLL_ENTRY_POINT(glBufferData);
GET_DLL_ENTRY_POINT(glBufferSubData);
GET_DLL_ENTRY_POINT(glDeleteBuffers);
// Vertex buffer attributes
GET_DLL_ENTRY_POINT(glVertexAttribPointer);
// GET_DLL_ENTRY_POINT(glVertexAttribLPointer);
// GET_DLL_ENTRY_POINT(glVertexAttribIPointer);
GET_DLL_ENTRY_POINT(glBindVertexBuffer);
GET_DLL_ENTRY_POINT(glDisableVertexAttribArray);
GET_DLL_ENTRY_POINT(glEnableVertexAttribArray);
GET_DLL_ENTRY_POINT(glBindVertexArray);
GET_DLL_ENTRY_POINT(glDeleteVertexArrays);
GET_DLL_ENTRY_POINT(glGenVertexArrays);
GET_DLL_ENTRY_POINT(glIsVertexArray);
// Shaders
GET_DLL_ENTRY_POINT(glCreateShader);
GET_DLL_ENTRY_POINT(glShaderSource);
GET_DLL_ENTRY_POINT(glCompileShader);
GET_DLL_ENTRY_POINT(glGetShaderInfoLog);
GET_DLL_ENTRY_POINT(glGetShaderSource);
GET_DLL_ENTRY_POINT(glGetShaderiv);
GET_DLL_ENTRY_POINT(glCreateProgram);
GET_DLL_ENTRY_POINT(glAttachShader);
GET_DLL_ENTRY_POINT(glLinkProgram);
GET_DLL_ENTRY_POINT(glGetProgramInfoLog);
GET_DLL_ENTRY_POINT(glGetProgramiv);
GET_DLL_ENTRY_POINT(glValidateProgram);
GET_DLL_ENTRY_POINT(glUseProgram);
GET_DLL_ENTRY_POINT(glDeleteShader);
GET_DLL_ENTRY_POINT(glDeleteProgram);
// Uniforms
GET_DLL_ENTRY_POINT(glGetUniformLocation);
// GET_DLL_ENTRY_POINT(glUniform1f);
// GET_DLL_ENTRY_POINT(glUniform1fv);
GET_DLL_ENTRY_POINT(glUniform1i);
// GET_DLL_ENTRY_POINT(glUniform1iv);
// GET_DLL_ENTRY_POINT(glUniform2f);
// GET_DLL_ENTRY_POINT(glUniform2fv);
// GET_DLL_ENTRY_POINT(glUniform2i);
// GET_DLL_ENTRY_POINT(glUniform2iv);
// GET_DLL_ENTRY_POINT(glUniform3f);
// GET_DLL_ENTRY_POINT(glUniform3fv);
// GET_DLL_ENTRY_POINT(glUniform3i);
// GET_DLL_ENTRY_POINT(glUniform3iv);
// GET_DLL_ENTRY_POINT(glUniform4f);
GET_DLL_ENTRY_POINT(glUniform4fv);
// GET_DLL_ENTRY_POINT(glUniform4i);
// GET_DLL_ENTRY_POINT(glUniform4iv);
// GET_DLL_ENTRY_POINT(glUniformMatrix2fv);
// GET_DLL_ENTRY_POINT(glUniformMatrix3fv);
// GET_DLL_ENTRY_POINT(glUniformMatrix4fv);
// Uniform buffer objects
GET_DLL_ENTRY_POINT(glBindBufferBase);
GET_DLL_ENTRY_POINT(glBindBufferRange);
GET_DLL_ENTRY_POINT(glGetUniformBlockIndex);
GET_DLL_ENTRY_POINT(glUniformBlockBinding);
// Sampler objects
GET_DLL_ENTRY_POINT(glBindSampler);
GET_DLL_ENTRY_POINT(glDeleteSamplers);
GET_DLL_ENTRY_POINT(glGenSamplers);
// GET_DLL_ENTRY_POINT(glGetSamplerParameterIiv);
// GET_DLL_ENTRY_POINT(glGetSamplerParameterIuiv);
// GET_DLL_ENTRY_POINT(glGetSamplerParameterfv);
// GET_DLL_ENTRY_POINT(glGetSamplerParameteriv);
// GET_DLL_ENTRY_POINT(glIsSampler);
// GET_DLL_ENTRY_POINT(glSamplerParameterIiv);
// GET_DLL_ENTRY_POINT(glSamplerParameterIuiv);
GET_DLL_ENTRY_POINT(glSamplerParameterf);
GET_DLL_ENTRY_POINT(glSamplerParameterfv);
GET_DLL_ENTRY_POINT(glSamplerParameteri);
// GET_DLL_ENTRY_POINT(glSamplerParameteriv);
return AMF_OK;
}
#if defined(_WIN32)
AMF_RESULT OpenGLImportTable::CreateDummy()
{
DestroyDummy();
wndClass = { 0 };
wndClass.cbSize = sizeof(wndClass);
wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndClass.lpfnWndProc = DefWindowProcW;
wndClass.hInstance = GetModuleHandle(0);
wndClass.lpszClassName = L"OpenGL_Dummy_Class";
int ret = RegisterClassExW(&wndClass);
AMF_RETURN_IF_FALSE(ret != 0, AMF_FAIL, L"CreateDummy() - RegisterClassA() failed, error=%d", GetLastError());
hDummyWnd = CreateWindowExW(0, wndClass.lpszClassName, L"Dummy OpenGL Window", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, wndClass.hInstance, 0);
AMF_RETURN_IF_FALSE(hDummyWnd != nullptr, AMF_FAIL, L"CreateDummy() - CreateWindowExA() failed to create window");
hDummyDC = GetDC(hDummyWnd);
PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.cColorBits = 32;
pfd.cAlphaBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
int pixel_format = ChoosePixelFormat(hDummyDC, &pfd);
AMF_RETURN_IF_FALSE(pixel_format != 0, AMF_FAIL, L"CreateDummy() - ChoosePixelFormat() failed to find a suitable pixel format.");
ret = SetPixelFormat(hDummyDC, pixel_format, &pfd);
AMF_RETURN_IF_FALSE(ret != 0, AMF_FAIL, L"CreateDummy() - SetPixelFormat() failed");
hDummyOGLContext = wglCreateContext(hDummyDC);
AMF_RETURN_IF_FALSE(hDummyOGLContext != nullptr, AMF_FAIL, L"CreateDummy() - wglCreateContext() failed");
ret = !wglMakeCurrent(hDummyDC, hDummyOGLContext);
AMF_RETURN_IF_FALSE(hDummyOGLContext != nullptr, AMF_FAIL, L"CreateDummy() - wglMakeCurrent() failed");
return AMF_OK;
}
AMF_RESULT OpenGLImportTable::DestroyDummy()
{
if (hDummyOGLContext != nullptr)
{
wglDeleteContext(hDummyOGLContext);
hDummyOGLContext = nullptr;
}
if (hDummyWnd != nullptr || hDummyDC != nullptr)
{
if (wglMakeCurrent != nullptr)
{
wglMakeCurrent(hDummyDC, 0);
}
ReleaseDC(hDummyWnd, hDummyDC);
DestroyWindow(hDummyWnd);
hDummyWnd = nullptr;
hDummyDC = nullptr;
}
if (wndClass.lpszClassName != nullptr)
{
UnregisterClassW(wndClass.lpszClassName, wndClass.hInstance);
wndClass = {};
}
return AMF_OK;
}
#endif

View File

@@ -0,0 +1,540 @@
//
// 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 OpenGLImportTable.h
/// @brief OpenGL import table
///-------------------------------------------------------------------------
#pragma once
#include "public/include/core/Result.h"
#include "public/common/AMFSTL.h"
#if defined(_WIN32)
#include <Wingdi.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#elif defined(__ANDROID__)
////todo:AA #include <android/native_window.h> // requires ndk r5 or newer
#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h> // requires ndk r5 or newer
#include <EGL/eglext.h>
#include <GLES/gl.h> // requires ndk r5 or newer
#include <GLES/glext.h> // requires ndk r5 or newer
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
////todo:AA #include <ui/FramebufferNativeWindow.h>
// #include <gralloc_priv.h>
#include <time.h>
#if !defined(CLOCK_MONOTONIC_RAW)
#define CLOCK_MONOTONIC_RAW 4
#endif
////todo:AA #include <amdgralloc.h>
////todo:AA using namespace android;
#if !defined(GL_CLAMP)
#define GL_CLAMP GL_CLAMP_TO_EDGE
#endif
#elif defined(__linux)
#include <GL/glx.h>
#include <GL/glu.h>
#endif
#ifndef AMF_GLAPI
#if defined(_WIN32)
#define AMF_GLAPI WINGDIAPI
#elif defined(__ANDROID__)
#define AMF_GLAPI GL_API
#else // __linux
#define AMF_GLAPI
#endif
#endif
#ifndef AMF_GLAPIENTRY
#if defined(_WIN32)
#define AMF_GLAPIENTRY APIENTRY
#elif defined(__ANDROID__)
#define AMF_GLAPIENTRY GL_APIENTRY
#elif defined(__linux)
#define AMF_GLAPIENTRY GLAPIENTRY
#else
#define AMF_GLAPIENTRY
#endif
#endif
typedef char GLchar;
#if defined(__ANDROID__)
typedef double GLclampd;
#define GL_TEXTURE_BORDER_COLOR 0x1004
#else
typedef ptrdiff_t GLintptr;
#endif
#ifdef _WIN32
typedef size_t GLsizeiptr; // Defined in glx.h on linux
#endif
// Core
typedef AMF_GLAPI GLenum (AMF_GLAPIENTRY* glGetError_fn) (void);
typedef AMF_GLAPI const GLubyte* (AMF_GLAPIENTRY* glGetString_fn) (GLenum name);
typedef AMF_GLAPI const GLubyte* (AMF_GLAPIENTRY* glGetStringi_fn) (GLenum name, GLuint index);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glEnable_fn) (GLenum cap);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glClear_fn) (GLbitfield mask);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glClearAccum_fn) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glClearColor_fn) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glClearDepth_fn) (GLclampd depth);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glClearIndex_fn) (GLfloat c);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glClearStencil_fn) (GLint s);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDrawArrays_fn) (GLenum mode, GLint first, GLsizei count);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glViewport_fn) (GLint x, GLint y, GLsizei width, GLsizei height);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glFinish_fn) (void);
// Textures
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindTexture_fn) (GLenum target, GLuint texture);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDeleteTextures_fn) (GLsizei n, const GLuint* textures);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGenTextures_fn) (GLsizei n, GLuint* textures);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetTexImage_fn) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetTexLevelParameteriv_fn) (GLenum target, GLint level, GLenum pname, GLint* params);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glTexParameteri_fn) (GLenum target, GLenum pname, GLint param);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glTexImage2D_fn) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid* pixels);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glActiveTexture_fn) (GLenum texture);
// Framebuffer and Renderbuffer objects - EXT: GL_ARB_framebuffer_object
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindFramebuffer_fn) (GLenum target, GLuint framebuffer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindRenderbuffer_fn) (GLenum target, GLuint renderbuffer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBlitFramebuffer_fn) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
typedef AMF_GLAPI GLenum (AMF_GLAPIENTRY* glCheckFramebufferStatus_fn) (GLenum target);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDeleteFramebuffers_fn) (GLsizei n, const GLuint* framebuffers);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDeleteRenderbuffers_fn) (GLsizei n, const GLuint* renderbuffers);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glFramebufferRenderbuffer_fn) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glFramebufferTexture1D_fn) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glFramebufferTexture2D_fn) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glFramebufferTexture3D_fn) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glFramebufferTextureLayer_fn) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGenFramebuffers_fn) (GLsizei n, GLuint* framebuffers);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGenRenderbuffers_fn) (GLsizei n, GLuint* renderbuffers);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGenerateMipmap_fn) (GLenum target);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetFramebufferAttachmentParameteriv_fn) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetRenderbufferParameteriv_fn) (GLenum target, GLenum pname, GLint* params);
typedef AMF_GLAPI GLboolean (AMF_GLAPIENTRY* glIsFramebuffer_fn) (GLuint framebuffer);
typedef AMF_GLAPI GLboolean (AMF_GLAPIENTRY* glIsRenderbuffer_fn) (GLuint renderbuffer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glRenderbufferStorage_fn) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glRenderbufferStorageMultisample_fn) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
// Buffers
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGenBuffers_fn) (GLsizei n, GLuint* buffers);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindBuffer_fn) (GLenum target, GLuint buffer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBufferData_fn) (GLenum target, GLsizeiptr size, const void* data, GLenum usage);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBufferSubData_fn) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDeleteBuffers_fn) (GLsizei n, const GLuint* buffers);
// Vertex attributes
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glVertexAttribPointer_fn) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glVertexAttribLPointer_fn) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glVertexAttribIPointer_fn) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindVertexBuffer_fn) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDisableVertexAttribArray_fn) (GLuint index);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glEnableVertexAttribArray_fn) (GLuint index);
// Vertex array objects
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindVertexArray_fn) (GLuint array);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDeleteVertexArrays_fn) (GLsizei n, const GLuint* arrays);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGenVertexArrays_fn) (GLsizei n, GLuint* arrays);
typedef AMF_GLAPI GLboolean (AMF_GLAPIENTRY* glIsVertexArray_fn) (GLuint array);
// Shaders
typedef AMF_GLAPI GLuint (AMF_GLAPIENTRY* glCreateShader_fn) (GLenum type);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glShaderSource_fn) (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glCompileShader_fn) (GLuint shader);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetShaderInfoLog_fn) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetShaderSource_fn) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetShaderiv_fn) (GLuint shader, GLenum pname, GLint* param);
typedef AMF_GLAPI GLuint (AMF_GLAPIENTRY* glCreateProgram_fn) (void);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glAttachShader_fn) (GLuint program, GLuint shader);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glLinkProgram_fn) (GLuint program);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetProgramInfoLog_fn) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetProgramiv_fn) (GLuint program, GLenum pname, GLint* param);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glValidateProgram_fn) (GLuint program);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUseProgram_fn) (GLuint program);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDeleteShader_fn) (GLuint shader);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDeleteProgram_fn) (GLuint program);
// Uniforms
typedef AMF_GLAPI GLint (AMF_GLAPIENTRY* glGetUniformLocation_fn) (GLuint program, const GLchar* name);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform1f_fn) (GLint location, GLfloat v0);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform1fv_fn) (GLint location, GLsizei count, const GLfloat* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform1i_fn) (GLint location, GLint v0);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform1iv_fn) (GLint location, GLsizei count, const GLint* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform2f_fn) (GLint location, GLfloat v0, GLfloat v1);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform2fv_fn) (GLint location, GLsizei count, const GLfloat* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform2i_fn) (GLint location, GLint v0, GLint v1);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform2iv_fn) (GLint location, GLsizei count, const GLint* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform3f_fn) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform3fv_fn) (GLint location, GLsizei count, const GLfloat* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform3i_fn) (GLint location, GLint v0, GLint v1, GLint v2);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform3iv_fn) (GLint location, GLsizei count, const GLint* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform4f_fn) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform4fv_fn) (GLint location, GLsizei count, const GLfloat* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform4i_fn) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniform4iv_fn) (GLint location, GLsizei count, const GLint* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniformMatrix2fv_fn) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniformMatrix3fv_fn) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniformMatrix4fv_fn) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
// Uniform block objects - EXT: ARB_Uniform_Buffer_Object
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindBufferBase_fn) (GLenum target, GLuint index, GLuint buffer);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindBufferRange_fn) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
typedef AMF_GLAPI GLuint (AMF_GLAPIENTRY* glGetUniformBlockIndex_fn) (GLuint program, const GLchar* uniformBlockName);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glUniformBlockBinding_fn) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
// Sampler Objects - EXT: GL_ARB_sampler_objects
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glBindSampler_fn) (GLuint unit, GLuint sampler);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glDeleteSamplers_fn) (GLsizei count, const GLuint* samplers);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGenSamplers_fn) (GLsizei count, GLuint* samplers);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetSamplerParameterIiv_fn) (GLuint sampler, GLenum pname, GLint* params);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetSamplerParameterIuiv_fn) (GLuint sampler, GLenum pname, GLuint* params);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetSamplerParameterfv_fn) (GLuint sampler, GLenum pname, GLfloat* params);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glGetSamplerParameteriv_fn) (GLuint sampler, GLenum pname, GLint* params);
typedef AMF_GLAPI GLboolean (AMF_GLAPIENTRY* glIsSampler_fn) (GLuint sampler);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glSamplerParameterIiv_fn) (GLuint sampler, GLenum pname, const GLint* params);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glSamplerParameterIuiv_fn) (GLuint sampler, GLenum pname, const GLuint* params);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glSamplerParameterf_fn) (GLuint sampler, GLenum pname, GLfloat param);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glSamplerParameterfv_fn) (GLuint sampler, GLenum pname, const GLfloat* params);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glSamplerParameteri_fn) (GLuint sampler, GLenum pname, GLint param);
typedef AMF_GLAPI void (AMF_GLAPIENTRY* glSamplerParameteriv_fn) (GLuint sampler, GLenum pname, const GLint* params);
#if defined(_WIN32)
typedef WINGDIAPI HGLRC (WINAPI* wglCreateContext_fn) (HDC);
typedef WINGDIAPI BOOL (WINAPI* wglDeleteContext_fn) (HGLRC);
typedef WINGDIAPI HGLRC (WINAPI* wglGetCurrentContext_fn) (VOID);
typedef WINGDIAPI HDC (WINAPI* wglGetCurrentDC_fn) (VOID);
typedef WINGDIAPI BOOL (WINAPI* wglMakeCurrent_fn) (HDC, HGLRC);
typedef WINGDIAPI PROC (WINAPI* wglGetProcAddress_fn) (LPCSTR func);
typedef WINGDIAPI const char* (WINAPI* wglGetExtensionsStringARB_fn) (HDC hdc);
typedef WINGDIAPI BOOL (WINAPI* wglSwapIntervalEXT_fn) (int interval);
#elif defined(__ANDROID__)
typedef EGLAPI EGLBoolean (EGLAPIENTRY* eglInitialize_fn) (EGLDisplay dpy, EGLint* major, EGLint* minor);
typedef EGLAPI EGLDisplay (EGLAPIENTRY* eglGetDisplay_fn) (EGLNativeDisplayType display_id);
typedef EGLAPI EGLBoolean (EGLAPIENTRY* eglChooseConfig_fn) (EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config);
typedef EGLAPI EGLContext (EGLAPIENTRY* eglCreateContext_fn) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list);
typedef EGLAPI EGLBoolean (EGLAPIENTRY* eglDestroyImageKHR_fn) (EGLDisplay dpy, EGLImageKHR image);
typedef EGLAPI EGLImageKHR (EGLAPIENTRY* eglCreateImageKHR_fn) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint* attrib_list);
typedef EGLAPI EGLBoolean (EGLAPIENTRY* eglSwapInterval_fn) (EGLDisplay dpy, EGLint interval);
typedef GL_API void (GL_APIENTRY* glEGLImageTargetTexture2DOES_fn) (GLenum target, GLeglImageOES image);
typedef GL_API void (GL_APIENTRY* glReadPixels_fn) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
#elif defined(__linux)
typedef void (GLAPIENTRY* glXDestroyContext_fn) (Display* dpy, GLXContext ctx);
typedef void (GLAPIENTRY* glXDestroyWindow_fn) (Display* dpy, GLXWindow window);
typedef void (GLAPIENTRY* glXSwapBuffers_fn) (Display* dpy, GLXDrawable drawable);
typedef Bool (GLAPIENTRY* glXQueryExtension_fn) (Display* dpy, int* errorb, int* event);
typedef GLXFBConfig* (GLAPIENTRY* glXChooseFBConfig_fn) (Display* dpy, int screen, const int* attribList, int* nitems );
typedef GLXWindow (GLAPIENTRY* glXCreateWindow_fn) (Display* dpy, GLXFBConfig config, Window win, const int* attribList );
typedef GLXContext (GLAPIENTRY* glXCreateNewContext_fn) (Display* dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct );
typedef Bool (GLAPIENTRY* glXMakeCurrent_fn) (Display* dpy, GLXDrawable drawable, GLXContext ctx);
typedef GLXContext (GLAPIENTRY* glXGetCurrentContext_fn) (void);
typedef GLXDrawable (GLAPIENTRY* glXGetCurrentDrawable_fn) (void);
typedef const char* (GLAPIENTRY* glXQueryExtensionsString_fn) (Display* dpy, int screen);
typedef void (GLAPIENTRY* glXSwapIntervalEXT_fn) (Display* dpy, GLXDrawable drawable, int interval);
#endif
// Target
#define GL_DEPTH_BUFFER 0x8223
#define GL_STENCIL_BUFFER 0x8224
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_PIXEL_PACK_BUFFER 0x88EB
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
#define GL_UNIFORM_BUFFER 0x8A11
#define GL_TEXTURE_BUFFER 0x8C2A
#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
#define GL_READ_FRAMEBUFFER 0x8CA8
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#define GL_FRAMEBUFFER 0x8D40
#define GL_RENDERBUFFER 0x8D41
#define GL_COPY_READ_BUFFER 0x8F36
#define GL_COPY_WRITE_BUFFER 0x8F37
#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
#define GL_SHADER_STORAGE_BUFFER 0x90D2
#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
#define GL_QUERY_BUFFER 0x9192
#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
// Attachments
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_COLOR_ATTACHMENT_UNIT(x) (GL_COLOR_ATTACHMENT0 + x)
#define GL_DEPTH_ATTACHMENT 0x8D00
#define GL_STENCIL_ATTACHMENT 0x8D20
// Frame Buffer Status
#define GL_FRAMEBUFFER_UNDEFINED 0x8219
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
// Texture unit
#define GL_TEXTURE0 0x84C0
#define GL_TEXTURE_UNIT(x) (GL_TEXTURE0 + x)
// Usage
#define GL_STREAM_DRAW 0x88E0
#define GL_STREAM_READ 0x88E1
#define GL_STREAM_COPY 0x88E2
#define GL_STATIC_DRAW 0x88E4
#define GL_STATIC_READ 0x88E5
#define GL_STATIC_COPY 0x88E6
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_DYNAMIC_READ 0x88E9
#define GL_DYNAMIC_COPY 0x88EA
// Shader Type
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_GEOMETRY_SHADER 0x8DD9
#define GL_TESS_EVALUATION_SHADER 0x8E87
#define GL_TESS_CONTROL_SHADER 0x8E88
#define GL_COMPUTE_SHADER 0x91B9
// Shader Info
#define GL_DELETE_STATUS 0x8B80
#define GL_COMPILE_STATUS 0x8B81
#define GL_LINK_STATUS 0x8B82
#define GL_VALIDATE_STATUS 0x8B83
#define GL_INFO_LOG_LENGTH 0x8B84
// Sampler params
#define GL_TEXTURE_MIN_LOD 0x813A
#define GL_TEXTURE_MAX_LOD 0x813B
#define GL_TEXTURE_WRAP_R 0x8072
#define GL_TEXTURE_COMPARE_MODE 0x884C
#define GL_TEXTURE_COMPARE_FUNC 0x884D
struct OpenGLImportTable
{
OpenGLImportTable();
~OpenGLImportTable();
AMF_RESULT LoadFunctionsTable();
AMF_RESULT LoadContextFunctionsTable();
amf_handle m_hOpenGLDll;
// Core
glGetError_fn glGetError;
glGetString_fn glGetString;
// glGetStringi_fn glGetStringi;
glEnable_fn glEnable;
glClear_fn glClear;
glClearAccum_fn glClearAccum;
glClearColor_fn glClearColor;
glClearDepth_fn glClearDepth;
glClearIndex_fn glClearIndex;
glClearStencil_fn glClearStencil;
glDrawArrays_fn glDrawArrays;
glViewport_fn glViewport;
glFinish_fn glFinish;
// Core (platform-dependent)
#if defined(_WIN32)
wglCreateContext_fn wglCreateContext;
wglDeleteContext_fn wglDeleteContext;
wglGetCurrentContext_fn wglGetCurrentContext;
wglGetCurrentDC_fn wglGetCurrentDC;
wglMakeCurrent_fn wglMakeCurrent;
wglGetProcAddress_fn wglGetProcAddress;
wglGetExtensionsStringARB_fn wglGetExtensionsStringARB;
wglSwapIntervalEXT_fn wglSwapIntervalEXT;
#elif defined(__ANDROID__)
eglInitialize_fn eglInitialize;
eglGetDisplay_fn eglGetDisplay;
eglChooseConfig_fn eglChooseConfig;
eglCreateContext_fn eglCreateContext;
eglDestroyImageKHR_fn eglDestroyImageKHR;
eglCreateImageKHR_fn eglCreateImageKHR;
eglSwapInterval_fn eglSwapInterval;
glEGLImageTargetTexture2DOES_fn glEGLImageTargetTexture2DOES;
glReadPixels_fn glReadPixels;
#elif defined(__linux)
glXDestroyContext_fn glXDestroyContext;
glXDestroyWindow_fn glXDestroyWindow;
glXSwapBuffers_fn glXSwapBuffers;
glXQueryExtension_fn glXQueryExtension;
glXChooseFBConfig_fn glXChooseFBConfig;
glXCreateWindow_fn glXCreateWindow;
glXCreateNewContext_fn glXCreateNewContext;
glXMakeCurrent_fn glXMakeCurrent;
glXGetCurrentContext_fn glXGetCurrentContext;
glXGetCurrentDrawable_fn glXGetCurrentDrawable;
glXQueryExtensionsString_fn glXQueryExtensionsString;
glXSwapIntervalEXT_fn glXSwapIntervalEXT;
#endif
// Textures
glBindTexture_fn glBindTexture;
glDeleteTextures_fn glDeleteTextures;
glGenTextures_fn glGenTextures;
glGetTexImage_fn glGetTexImage;
glGetTexLevelParameteriv_fn glGetTexLevelParameteriv;
glTexParameteri_fn glTexParameteri;
glTexImage2D_fn glTexImage2D;
glActiveTexture_fn glActiveTexture;
// Frame buffer and render buffer objects
glBindFramebuffer_fn glBindFramebuffer;
// glBindRenderbuffer_fn glBindRenderbuffer;
glBlitFramebuffer_fn glBlitFramebuffer;
glCheckFramebufferStatus_fn glCheckFramebufferStatus;
glDeleteFramebuffers_fn glDeleteFramebuffers;
// glDeleteRenderbuffers_fn glDeleteRenderbuffers;
// glFramebufferRenderbuffer_fn glFramebufferRenderbuffer;
// glFramebufferTexture1D_fn glFramebufferTexture1D;
glFramebufferTexture2D_fn glFramebufferTexture2D;
// glFramebufferTexture3D_fn glFramebufferTexture3D;
glFramebufferTextureLayer_fn glFramebufferTextureLayer;
glGenFramebuffers_fn glGenFramebuffers;
// glGenRenderbuffers_fn glGenRenderbuffers;
// glGenerateMipmap_fn glGenerateMipmap;
// glGetFramebufferAttachmentParameteriv_fn glGetFramebufferAttachmentParameteriv;
// glGetRenderbufferParameteriv_fn glGetRenderbufferParameteriv;
// glIsFramebuffer_fn glIsFramebuffer;
// glIsRenderbuffer_fn glIsRenderbuffer;
// glRenderbufferStorage_fn glRenderbufferStorage;
// glRenderbufferStorageMultisample_fn glRenderbufferStorageMultisample;
// Buffers
glGenBuffers_fn glGenBuffers;
glBindBuffer_fn glBindBuffer;
glBufferData_fn glBufferData;
glBufferSubData_fn glBufferSubData;
glDeleteBuffers_fn glDeleteBuffers;
// Vertex attributes
glVertexAttribPointer_fn glVertexAttribPointer;
// glVertexAttribLPointer_fn glVertexAttribLPointer;
// glVertexAttribIPointer_fn glVertexAttribIPointer;
glBindVertexBuffer_fn glBindVertexBuffer;
glDisableVertexAttribArray_fn glDisableVertexAttribArray;
glEnableVertexAttribArray_fn glEnableVertexAttribArray;
// Vertex array objects
glBindVertexArray_fn glBindVertexArray;
glDeleteVertexArrays_fn glDeleteVertexArrays;
glGenVertexArrays_fn glGenVertexArrays;
glIsVertexArray_fn glIsVertexArray;
// Shaders
glCreateShader_fn glCreateShader;
glShaderSource_fn glShaderSource;
glCompileShader_fn glCompileShader;
glGetShaderInfoLog_fn glGetShaderInfoLog;
glGetShaderSource_fn glGetShaderSource;
glGetShaderiv_fn glGetShaderiv;
glCreateProgram_fn glCreateProgram;
glAttachShader_fn glAttachShader;
glLinkProgram_fn glLinkProgram;
glGetProgramInfoLog_fn glGetProgramInfoLog;
glGetProgramiv_fn glGetProgramiv;
glValidateProgram_fn glValidateProgram;
glUseProgram_fn glUseProgram;
glDeleteShader_fn glDeleteShader;
glDeleteProgram_fn glDeleteProgram;
// Uniforms
glGetUniformLocation_fn glGetUniformLocation;
// glUniform1f_fn glUniform1f;
// glUniform1fv_fn glUniform1fv;
glUniform1i_fn glUniform1i;
// glUniform1iv_fn glUniform1iv;
// glUniform2f_fn glUniform2f;
// glUniform2fv_fn glUniform2fv;
// glUniform2i_fn glUniform2i;
// glUniform2iv_fn glUniform2iv;
// glUniform3f_fn glUniform3f;
// glUniform3fv_fn glUniform3fv;
// glUniform3i_fn glUniform3i;
// glUniform3iv_fn glUniform3iv;
// glUniform4f_fn glUniform4f;
glUniform4fv_fn glUniform4fv;
// glUniform4i_fn glUniform4i;
// glUniform4iv_fn glUniform4iv;
// glUniformMatrix2fv_fn glUniformMatrix2fv;
// glUniformMatrix3fv_fn glUniformMatrix3fv;
// glUniformMatrix4fv_fn glUniformMatrix4fv;
// Uniform buffer objects
glBindBufferBase_fn glBindBufferBase;
glBindBufferRange_fn glBindBufferRange;
glGetUniformBlockIndex_fn glGetUniformBlockIndex;
glUniformBlockBinding_fn glUniformBlockBinding;
// Sampler objects
glBindSampler_fn glBindSampler;
glDeleteSamplers_fn glDeleteSamplers;
glGenSamplers_fn glGenSamplers;
// glGetSamplerParameterIiv_fn glGetSamplerParameterIiv;
// glGetSamplerParameterIuiv_fn glGetSamplerParameterIuiv;
// glGetSamplerParameterfv_fn glGetSamplerParameterfv;
// glGetSamplerParameteriv_fn glGetSamplerParameteriv;
// glIsSampler_fn glIsSampler;
// glSamplerParameterIiv_fn glSamplerParameterIiv;
// glSamplerParameterIuiv_fn glSamplerParameterIuiv;
glSamplerParameterf_fn glSamplerParameterf;
glSamplerParameterfv_fn glSamplerParameterfv;
glSamplerParameteri_fn glSamplerParameteri;
// glSamplerParameteriv_fn glSamplerParameteriv;
private:
#if defined(_WIN32)
WNDCLASSEX wndClass;
HWND hDummyWnd;
HDC hDummyDC;
HGLRC hDummyOGLContext;
AMF_RESULT CreateDummy();
AMF_RESULT DestroyDummy();
#endif
};

View File

@@ -0,0 +1,472 @@
//
// 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.
//
#include <climits>
#include "PropertyStorageExImpl.h"
#include "PropertyStorageImpl.h"
#include "TraceAdapter.h"
#pragma warning(disable: 4996)
using namespace amf;
#define AMF_FACILITY L"AMFPropertyStorageExImpl"
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#endif
amf::AMFCriticalSection amf::ms_csAMFPropertyStorageExImplMaps;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
//-------------------------------------------------------------------------------------------------
AMF_RESULT amf::CastVariantToAMFProperty(amf::AMFVariantStruct* pDest, const amf::AMFVariantStruct* pSrc, amf::AMF_VARIANT_TYPE eType,
amf::AMF_PROPERTY_CONTENT_TYPE /*contentType*/,
const amf::AMFEnumDescriptionEntry* pEnumDescription)
{
AMF_RETURN_IF_INVALID_POINTER(pDest);
AMF_RESULT err = AMF_OK;
switch (eType)
{
case AMF_VARIANT_INTERFACE:
if (pSrc->type == eType)
{
err = AMFVariantCopy(pDest, pSrc);
}
else
{
pDest->type = AMF_VARIANT_INTERFACE;
pDest->pInterface = nullptr;
}
break;
case AMF_VARIANT_INT64:
{
if(pEnumDescription)
{
const AMFEnumDescriptionEntry* pEnumDescriptionCache = pEnumDescription;
err = AMFVariantChangeType(pDest, pSrc, AMF_VARIANT_INT64);
bool found = false;
if(err == AMF_OK)
{
//mean numeric came. validating
while(pEnumDescriptionCache->name)
{
if(pEnumDescriptionCache->value == AMFVariantGetInt64(pDest))
{
AMFVariantAssignInt64(pDest, pEnumDescriptionCache->value);
found = true;
break;
}
pEnumDescriptionCache++;
}
err = found ? AMF_OK : AMF_INVALID_ARG;
}
if(!found)
{
pEnumDescriptionCache = pEnumDescription;
err = AMFVariantChangeType(pDest, pSrc, AMF_VARIANT_WSTRING);
if(err == AMF_OK)
{
//string came. validating and assigning numeric
found = false;
while(pEnumDescriptionCache->name)
{
if(amf_wstring(pEnumDescriptionCache->name) == AMFVariantGetWString(pDest))
{
AMFVariantAssignInt64(pDest, pEnumDescriptionCache->value);
found = true;
break;
}
pEnumDescriptionCache++;
}
err = found ? AMF_OK : AMF_INVALID_ARG;
}
}
}
else
{
err = AMFVariantChangeType(pDest, pSrc, AMF_VARIANT_INT64);
}
}
break;
default:
err = AMFVariantChangeType(pDest, pSrc, eType);
break;
}
return err;
}
//-------------------------------------------------------------------------------------------------
AMFPropertyInfoImpl::AMFPropertyInfoImpl(const wchar_t* name, const wchar_t* desc, AMF_VARIANT_TYPE type, AMF_PROPERTY_CONTENT_TYPE contentType,
AMFVariantStruct defaultValue, AMFVariantStruct minValue, AMFVariantStruct maxValue, bool allowChangeInRuntime,
const AMFEnumDescriptionEntry* pEnumDescription) : m_name(), m_desc()
{
AMF_PROPERTY_ACCESS_TYPE accessTypeTmp = allowChangeInRuntime ? AMF_PROPERTY_ACCESS_FULL : AMF_PROPERTY_ACCESS_READ_WRITE;
Init(name, desc, type, contentType, defaultValue, minValue, maxValue, accessTypeTmp, pEnumDescription);
}
//-------------------------------------------------------------------------------------------------
AMFPropertyInfoImpl::AMFPropertyInfoImpl(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) : m_name(), m_desc()
{
Init(name, desc, type, contentType, defaultValue, minValue, maxValue, accessType, pEnumDescription);
}
//-------------------------------------------------------------------------------------------------
AMFPropertyInfoImpl::AMFPropertyInfoImpl() : m_name(), m_desc()
{
AMFVariantInit(&this->defaultValue);
AMFVariantInit(&this->minValue);
AMFVariantInit(&this->maxValue);
name = L"";
desc = L"";
type = AMF_VARIANT_EMPTY;
contentType = AMF_PROPERTY_CONTENT_TYPE(-1);
accessType = AMF_PROPERTY_ACCESS_FULL;
}
//-------------------------------------------------------------------------------------------------
void AMFPropertyInfoImpl::Init(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_)
{
m_name = name_;
name = m_name.c_str();
m_desc = desc_;
desc = m_desc.c_str();
type = type_;
contentType = contentType_;
accessType = accessType_;
AMFVariantInit(&defaultValue);
AMFVariantInit(&minValue);
AMFVariantInit(&maxValue);
pEnumDescription = pEnumDescription_;
switch(type)
{
case AMF_VARIANT_BOOL:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignBool(&defaultValue, false);
}
}
break;
case AMF_VARIANT_RECT:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignRect(&defaultValue, AMFConstructRect(0, 0, 0, 0));
}
}
break;
case AMF_VARIANT_SIZE:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignSize(&defaultValue, AMFConstructSize(0, 0));
}
if (CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignSize(&minValue, AMFConstructSize(INT_MIN, INT_MIN));
}
if (CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignSize(&maxValue, AMFConstructSize(INT_MAX, INT_MAX));
}
}
break;
case AMF_VARIANT_POINT:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignPoint(&defaultValue, AMFConstructPoint(0, 0));
}
if (CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignPoint(&minValue, AMFConstructPoint(INT_MIN, INT_MIN));
}
if (CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignPoint(&maxValue, AMFConstructPoint(INT_MAX, INT_MAX));
}
}
break;
case AMF_VARIANT_RATE:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignRate(&defaultValue, AMFConstructRate(0, 0));
}
if (CastVariantToAMFProperty(&this->minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignRate(&this->minValue, AMFConstructRate(0, 1));
}
if (CastVariantToAMFProperty(&this->maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignRate(&this->maxValue, AMFConstructRate(INT_MAX, INT_MAX));
}
}
break;
case AMF_VARIANT_RATIO:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignRatio(&defaultValue, AMFConstructRatio(0, 0));
}
}
break;
case AMF_VARIANT_COLOR:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignColor(&defaultValue, AMFConstructColor(0, 0, 0, 255));
}
}
break;
case AMF_VARIANT_INT64:
{
if(pEnumDescription)
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignInt64(&defaultValue, pEnumDescription->value);
}
}
else //AMF_PROPERTY_CONTENT_DEFAULT
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignInt64(&defaultValue, 0);
}
if(CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignInt64(&minValue, INT_MIN);
}
if(CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignInt64(&maxValue, INT_MAX);
}
}
}
break;
case AMF_VARIANT_DOUBLE:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignDouble(&defaultValue, 0);
}
if(CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignDouble(&minValue, DBL_MIN);
}
if(CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignDouble(&maxValue, DBL_MAX);
}
}
break;
case AMF_VARIANT_STRING:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignString(&maxValue, "");
}
}
break;
case AMF_VARIANT_WSTRING:
{
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignWString(&maxValue, L"");
}
}
break;
case AMF_VARIANT_INTERFACE:
if(CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignWString(&maxValue, L"");
}
break;
case AMF_VARIANT_FLOAT:
{
if (CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloat(&defaultValue, 0);
}
if (CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloat(&minValue, FLT_MIN);
}
if (CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloat(&maxValue, FLT_MAX);
}
}
break;
case AMF_VARIANT_FLOAT_SIZE:
{
if (CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatSize(&defaultValue, AMFConstructFloatSize(0, 0));
}
if (CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatSize(&minValue, AMFConstructFloatSize(FLT_MIN, FLT_MIN));
}
if (CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatSize(&maxValue, AMFConstructFloatSize(FLT_MAX, FLT_MAX));
}
}
break;
case AMF_VARIANT_FLOAT_POINT2D:
{
if (CastVariantToAMFProperty(&defaultValue, &defaultValue, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatPoint2D(&defaultValue, AMFConstructFloatPoint2D(0, 0));
}
if (CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatPoint2D(&minValue, AMFConstructFloatPoint2D(FLT_MIN, FLT_MIN));
}
if (CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatPoint2D(&maxValue, AMFConstructFloatPoint2D(FLT_MAX, FLT_MAX));
}
}
break;
case AMF_VARIANT_FLOAT_POINT3D:
{
if (CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatPoint3D(&defaultValue, AMFConstructFloatPoint3D(0, 0, 0));
}
if (CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatPoint3D(&minValue, AMFConstructFloatPoint3D(FLT_MIN, FLT_MIN, FLT_MIN));
}
if (CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatPoint3D(&maxValue, AMFConstructFloatPoint3D(FLT_MAX, FLT_MAX, FLT_MAX));
}
}
break;
case AMF_VARIANT_FLOAT_VECTOR4D:
{
if (CastVariantToAMFProperty(&defaultValue, &defaultValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatVector4D(&defaultValue, AMFConstructFloatVector4D(0, 0, 0, 0));
}
if (CastVariantToAMFProperty(&minValue, &minValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatVector4D(&minValue, AMFConstructFloatVector4D(FLT_MIN, FLT_MIN, FLT_MIN, FLT_MIN));
}
if (CastVariantToAMFProperty(&maxValue, &maxValue_, type, contentType, pEnumDescription) != AMF_OK)
{
AMFVariantAssignFloatVector4D(&maxValue, AMFConstructFloatVector4D(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX));
}
}
break;
default:
break;
}
value = defaultValue;
}
AMFPropertyInfoImpl::AMFPropertyInfoImpl(const AMFPropertyInfoImpl& propertyInfo) : AMFPropertyInfo(), m_name(), m_desc()
{
Init(propertyInfo.name, propertyInfo.desc, propertyInfo.type, propertyInfo.contentType, propertyInfo.defaultValue, propertyInfo.minValue, propertyInfo.maxValue, propertyInfo.accessType, propertyInfo.pEnumDescription);
}
//-------------------------------------------------------------------------------------------------
AMFPropertyInfoImpl& AMFPropertyInfoImpl::operator=(const AMFPropertyInfoImpl& propertyInfo)
{
// store name and desc inside instance in m_sName and m_sDesc recpectively;
// m_pName and m_pDesc are pointed to our local copies
this->m_name = propertyInfo.name;
this->m_desc = propertyInfo.desc;
this->name = m_name.c_str();
this->desc = m_desc.c_str();
this->type = propertyInfo.type;
this->contentType = propertyInfo.contentType;
this->accessType = propertyInfo.accessType;
AMFVariantCopy(&this->defaultValue, &propertyInfo.defaultValue);
AMFVariantCopy(&this->minValue, &propertyInfo.minValue);
AMFVariantCopy(&this->maxValue, &propertyInfo.maxValue);
this->pEnumDescription = propertyInfo.pEnumDescription;
this->value = propertyInfo.value;
this->userModified = propertyInfo.userModified;
return *this;
}
//-------------------------------------------------------------------------------------------------
AMFPropertyInfoImpl::~AMFPropertyInfoImpl()
{
AMFVariantClear(&this->defaultValue);
AMFVariantClear(&this->minValue);
AMFVariantClear(&this->maxValue);
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,617 @@
//
// 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 PropertyStorageExImpl.h
/// @brief AMFPropertyStorageExImpl header
///-------------------------------------------------------------------------
#ifndef AMF_PropertyStorageExImpl_h
#define AMF_PropertyStorageExImpl_h
#pragma once
#include "../include/core/PropertyStorageEx.h"
#include "Thread.h"
#include "InterfaceImpl.h"
#include "ObservableImpl.h"
#include "TraceAdapter.h"
#include <limits.h>
#include <float.h>
#include <memory>
namespace amf
{
AMF_RESULT CastVariantToAMFProperty(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc, AMF_VARIANT_TYPE eType,
AMF_PROPERTY_CONTENT_TYPE contentType,
const AMFEnumDescriptionEntry* pEnumDescription = 0);
//---------------------------------------------------------------------------------------------
class AMFPropertyInfoImpl : public AMFPropertyInfo
{
private:
amf_wstring m_name;
amf_wstring m_desc;
void Init(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);
public:
AMFVariant value;
amf_bool userModified = false;
public:
AMFPropertyInfoImpl(const wchar_t* name, const wchar_t* desc, AMF_VARIANT_TYPE type, AMF_PROPERTY_CONTENT_TYPE contentType,
AMFVariantStruct defaultValue, AMFVariantStruct minValue, AMFVariantStruct maxValue, bool allowChangeInRuntime,
const AMFEnumDescriptionEntry* pEnumDescription);
AMFPropertyInfoImpl(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);
AMFPropertyInfoImpl();
AMFPropertyInfoImpl(const AMFPropertyInfoImpl& propertyInfo);
AMFPropertyInfoImpl& operator=(const AMFPropertyInfoImpl& propertyInfo);
virtual ~AMFPropertyInfoImpl();
virtual void OnPropertyChanged() { }
};
typedef amf_map<amf_wstring, std::shared_ptr<AMFPropertyInfoImpl> > PropertyInfoMap;
//---------------------------------------------------------------------------------------------
template<typename _TBase> class AMFPropertyStorageExImpl :
public _TBase,
public AMFObservableImpl<AMFPropertyStorageObserver>
{
protected:
PropertyInfoMap m_PropertiesInfo;
AMFCriticalSection m_Sync; //thread-safety lock.
public:
AMFPropertyStorageExImpl()
{
}
virtual ~AMFPropertyStorageExImpl()
{
}
// interface access
AMF_BEGIN_INTERFACE_MAP
AMF_INTERFACE_ENTRY(AMFPropertyStorage)
AMF_INTERFACE_ENTRY(AMFPropertyStorageEx)
AMF_END_INTERFACE_MAP
using _TBase::GetProperty;
using _TBase::SetProperty;
// interface
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL Clear()
{
ResetDefaultValues();
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL AddTo(AMFPropertyStorage* pDest, bool overwrite, bool /*deep*/) const
{
AMF_RETURN_IF_INVALID_POINTER(pDest);
if (pDest != this)
{
AMFLock lock(const_cast<AMFCriticalSection*>(&m_Sync));
for (PropertyInfoMap::const_iterator it = m_PropertiesInfo.begin(); it != m_PropertiesInfo.end(); it++)
{
if (!overwrite && pDest->HasProperty(it->first.c_str()))
{
continue;
}
AMF_RESULT err = pDest->SetProperty(it->first.c_str(), it->second->value);
if (err != AMF_INVALID_ARG) // not validated - skip it
{
AMF_RETURN_IF_FAILED(err, L"AddTo() - failed to copy property=%s", it->first.c_str());
}
}
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL CopyTo(AMFPropertyStorage* pDest, bool deep) const
{
AMF_RETURN_IF_INVALID_POINTER(pDest);
if (pDest != this)
{
pDest->Clear();
return AddTo(pDest, true, deep);
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL SetProperty(const wchar_t* name, AMFVariantStruct value)
{
AMF_RETURN_IF_INVALID_POINTER(name);
const AMFPropertyInfo* pParamInfo = NULL;
AMF_RESULT err = GetPropertyInfo(name, &pParamInfo);
if (err != AMF_OK)
{
return err;
}
if (pParamInfo && !pParamInfo->AllowedWrite())
{
return AMF_ACCESS_DENIED;
}
return SetPrivateProperty(name, value);
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL GetProperty(const wchar_t* name, AMFVariantStruct* pValue) const
{
AMF_RETURN_IF_INVALID_POINTER(name);
AMF_RETURN_IF_INVALID_POINTER(pValue);
const AMFPropertyInfo* pParamInfo = NULL;
AMF_RESULT err = GetPropertyInfo(name, &pParamInfo);
if (err != AMF_OK)
{
return err;
}
if (pParamInfo && !pParamInfo->AllowedRead())
{
return AMF_ACCESS_DENIED;
}
return GetPrivateProperty(name, pValue);
}
//-------------------------------------------------------------------------------------------------
virtual bool AMF_STD_CALL HasProperty(const wchar_t* name) const
{
const AMFPropertyInfo* pParamInfo = NULL;
AMF_RESULT err = GetPropertyInfo(name, &pParamInfo);
return (err != AMF_OK) ? false : true;
}
//-------------------------------------------------------------------------------------------------
virtual amf_size AMF_STD_CALL GetPropertyCount() const
{
return m_PropertiesInfo.size();
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL GetPropertyAt(amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue) const
{
AMF_RETURN_IF_INVALID_POINTER(name);
AMF_RETURN_IF_INVALID_POINTER(pValue);
AMF_RETURN_IF_FALSE(nameSize != 0, AMF_INVALID_ARG);
AMF_RETURN_IF_FALSE(index < m_PropertiesInfo.size(), AMF_INVALID_ARG);
PropertyInfoMap::const_iterator found = m_PropertiesInfo.begin();
for (amf_size i = 0; i < index; i++)
{
found++;
}
size_t copySize = AMF_MIN(nameSize-1, found->first.length());
memcpy(name, found->first.c_str(), copySize * sizeof(wchar_t));
name[copySize] = 0;
AMFLock lock(const_cast<AMFCriticalSection*>(&m_Sync));
AMFVariantCopy(pValue, &found->second->value);
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual amf_size AMF_STD_CALL GetPropertiesInfoCount() const
{
return m_PropertiesInfo.size();
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL GetPropertyInfo(amf_size szInd, const AMFPropertyInfo** ppParamInfo) const
{
AMF_RETURN_IF_INVALID_POINTER(ppParamInfo);
AMF_RETURN_IF_FALSE(szInd < m_PropertiesInfo.size(), AMF_INVALID_ARG);
PropertyInfoMap::const_iterator it = m_PropertiesInfo.begin();
for (; szInd > 0; --szInd)
{
it++;
}
*ppParamInfo = it->second.get();
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL GetPropertyInfo(const wchar_t* name, const AMFPropertyInfo** ppParamInfo) const
{
AMF_RETURN_IF_INVALID_POINTER(name);
AMF_RETURN_IF_INVALID_POINTER(ppParamInfo);
PropertyInfoMap::const_iterator it = m_PropertiesInfo.find(name);
if (it != m_PropertiesInfo.end())
{
*ppParamInfo = it->second.get();
return AMF_OK;
}
return AMF_NOT_FOUND;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL ValidateProperty(const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated) const
{
AMF_RETURN_IF_INVALID_POINTER(name);
AMF_RETURN_IF_INVALID_POINTER(pOutValidated);
AMF_RESULT err = AMF_OK;
const AMFPropertyInfo* pParamInfo = NULL;
AMF_RETURN_IF_FAILED(GetPropertyInfo(name, &pParamInfo), L"Property=%s", name);
AMF_RETURN_IF_FAILED(CastVariantToAMFProperty(pOutValidated, &value, pParamInfo->type, pParamInfo->contentType, pParamInfo->pEnumDescription), L"Property=%s", name);
switch(pParamInfo->type)
{
case AMF_VARIANT_INT64:
if((pParamInfo->minValue.type != AMF_VARIANT_EMPTY && AMFVariantGetInt64(pOutValidated) < AMFVariantGetInt64(&pParamInfo->minValue)) ||
(pParamInfo->maxValue.type != AMF_VARIANT_EMPTY && AMFVariantGetInt64(pOutValidated) > AMFVariantGetInt64(&pParamInfo->maxValue)) )
{
err = AMF_OUT_OF_RANGE;
}
break;
case AMF_VARIANT_DOUBLE:
if((AMFVariantGetDouble(pOutValidated) < AMFVariantGetDouble(&pParamInfo->minValue)) ||
(AMFVariantGetDouble(pOutValidated) > AMFVariantGetDouble(&pParamInfo->maxValue)) )
{
err = AMF_OUT_OF_RANGE;
}
break;
case AMF_VARIANT_FLOAT:
if ((AMFVariantGetFloat(pOutValidated) < AMFVariantGetFloat(&pParamInfo->minValue)) ||
(AMFVariantGetFloat(pOutValidated) > AMFVariantGetFloat(&pParamInfo->maxValue)))
{
err = AMF_OUT_OF_RANGE;
}
break;
case AMF_VARIANT_RATE:
{
// NOTE: denominator can't be 0
const AMFRate& validatedSize = AMFVariantGetRate(pOutValidated);
AMFRate minSize = AMFConstructRate(0, 1);
AMFRate maxSize = AMFConstructRate(INT_MAX, INT_MAX);
if (pParamInfo->minValue.type != AMF_VARIANT_EMPTY)
{
minSize = AMFVariantGetRate(&pParamInfo->minValue);
}
if (pParamInfo->maxValue.type != AMF_VARIANT_EMPTY)
{
maxSize = AMFVariantGetRate(&pParamInfo->maxValue);
}
if (validatedSize.num < minSize.num || validatedSize.num > maxSize.num ||
validatedSize.den < minSize.den || validatedSize.den > maxSize.den)
{
err = AMF_OUT_OF_RANGE;
}
}
break;
case AMF_VARIANT_SIZE:
{
AMFSize validatedSize = AMFVariantGetSize(pOutValidated);
AMFSize minSize = AMFConstructSize(0, 0);
AMFSize maxSize = AMFConstructSize(INT_MAX, INT_MAX);
if (pParamInfo->minValue.type != AMF_VARIANT_EMPTY)
{
minSize = AMFVariantGetSize(&pParamInfo->minValue);
}
if (pParamInfo->maxValue.type != AMF_VARIANT_EMPTY)
{
maxSize = AMFVariantGetSize(&pParamInfo->maxValue);
}
if (validatedSize.width < minSize.width || validatedSize.height < minSize.height ||
validatedSize.width > maxSize.width || validatedSize.height > maxSize.height)
{
err = AMF_OUT_OF_RANGE;
}
}
break;
case AMF_VARIANT_FLOAT_SIZE:
{
AMFFloatSize validatedSize = AMFVariantGetFloatSize(pOutValidated);
AMFFloatSize minSize = AMFConstructFloatSize(0, 0);
AMFFloatSize maxSize = AMFConstructFloatSize(FLT_MIN, FLT_MAX);
if (pParamInfo->minValue.type != AMF_VARIANT_EMPTY)
{
minSize = AMFVariantGetFloatSize(&pParamInfo->minValue);
}
if (pParamInfo->maxValue.type != AMF_VARIANT_EMPTY)
{
maxSize = AMFVariantGetFloatSize(&pParamInfo->maxValue);
}
if (validatedSize.width < minSize.width || validatedSize.height < minSize.height ||
validatedSize.width > maxSize.width || validatedSize.height > maxSize.height)
{
err = AMF_OUT_OF_RANGE;
}
}
break;
default: // GK: Clang issues a warning when not every value of an enum is handled in a switch-case
break;
}
return err;
}
//-------------------------------------------------------------------------------------------------
virtual void AMF_STD_CALL OnPropertyChanged(const wchar_t* /*name*/){ }
//-------------------------------------------------------------------------------------------------
virtual void AMF_STD_CALL AddObserver(AMFPropertyStorageObserver* pObserver)
{
AMFLock lock(&m_Sync);
AMFObservableImpl<AMFPropertyStorageObserver>::AddObserver(pObserver);
}
//-------------------------------------------------------------------------------------------------
virtual void AMF_STD_CALL RemoveObserver(AMFPropertyStorageObserver* pObserver)
{
AMFLock lock(&m_Sync);
AMFObservableImpl<AMFPropertyStorageObserver>::RemoveObserver(pObserver);
}
//-------------------------------------------------------------------------------------------------
protected:
//-------------------------------------------------------------------------------------------------
AMF_RESULT SetAccessType(const wchar_t* name, AMF_PROPERTY_ACCESS_TYPE accessType)
{
AMF_RETURN_IF_INVALID_POINTER(name);
PropertyInfoMap::iterator found = m_PropertiesInfo.find(name);
AMF_RETURN_IF_FALSE(found != m_PropertiesInfo.end(), AMF_NOT_FOUND);
if (found->second->accessType == accessType)
{
return AMF_OK;
}
found->second->accessType = accessType;
OnPropertyChanged(name);
NotifyObservers<const wchar_t*>(&AMFPropertyStorageObserver::OnPropertyChanged, name);
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT SetPrivateProperty(const wchar_t* name, AMFVariantStruct value)
{
AMF_RETURN_IF_INVALID_POINTER(name);
AMFVariant validatedValue;
AMF_RESULT validateResult = ValidateProperty(name, value, &validatedValue);
if (validateResult != AMF_OK)
{
return validateResult;
}
PropertyInfoMap::iterator found = m_PropertiesInfo.find(name);
if (found == m_PropertiesInfo.end())
{
return AMF_NOT_FOUND;
}
{
AMFLock lock(&m_Sync);
if (found->second->value == validatedValue)
{
return AMF_OK;
}
found->second->value = validatedValue;
}
found->second->OnPropertyChanged();
OnPropertyChanged(name);
NotifyObservers<const wchar_t*>(&AMFPropertyStorageObserver::OnPropertyChanged, name);
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT GetPrivateProperty(const wchar_t* name, AMFVariantStruct* pValue) const
{
AMF_RETURN_IF_INVALID_POINTER(name);
AMF_RETURN_IF_INVALID_POINTER(pValue);
PropertyInfoMap::const_iterator found = m_PropertiesInfo.find(name);
if (found != m_PropertiesInfo.end())
{
AMFLock lock(const_cast<AMFCriticalSection*>(&m_Sync));
AMFVariantCopy(pValue, &found->second->value);
return AMF_OK;
}
// NOTE: needed for internal components that don't automatically
// expose their properties in the main map...
const AMFPropertyInfo* pParamInfo;
if (GetPropertyInfo(name, &pParamInfo) == AMF_OK)
{
AMFLock lock(const_cast<AMFCriticalSection*>(&m_Sync));
AMFVariantCopy(pValue, &pParamInfo->defaultValue);
return AMF_OK;
}
return AMF_NOT_FOUND;
}
//-------------------------------------------------------------------------------------------------
template<typename _T>
AMF_RESULT AMF_STD_CALL SetPrivateProperty(const wchar_t* name, const _T& value)
{
AMF_RESULT err = SetPrivateProperty(name, static_cast<const AMFVariantStruct&>(AMFVariant(value)));
return err;
}
//-------------------------------------------------------------------------------------------------
template<typename _T>
AMF_RESULT AMF_STD_CALL GetPrivateProperty(const wchar_t* name, _T* pValue) const
{
AMFVariant var;
AMF_RESULT err = GetPrivateProperty(name, static_cast<AMFVariantStruct*>(&var));
if(err == AMF_OK)
{
*pValue = static_cast<_T>(var);
}
return err;
}
//-------------------------------------------------------------------------------------------------
bool HasPrivateProperty(const wchar_t* name) const
{
return m_PropertiesInfo.find(name) != m_PropertiesInfo.end();
}
//-------------------------------------------------------------------------------------------------
bool IsRuntimeChange(const wchar_t* name) const
{
PropertyInfoMap::const_iterator it = m_PropertiesInfo.find(name);
return (it != m_PropertiesInfo.end()) ? it->second->AllowedChangeInRuntime() : false;
}
//-------------------------------------------------------------------------------------------------
void ResetDefaultValues()
{
AMFLock lock(&m_Sync);
// copy defaults to property storage
for (PropertyInfoMap::iterator it = m_PropertiesInfo.begin(); it != m_PropertiesInfo.end(); ++it)
{
AMFPropertyInfoImpl* info = it->second.get();
info->value = info->defaultValue;
info->userModified = false;
}
}
//-------------------------------------------------------------------------------------------------
private:
AMFPropertyStorageExImpl(const AMFPropertyStorageExImpl&);
AMFPropertyStorageExImpl& operator=(const AMFPropertyStorageExImpl&);
};
extern AMFCriticalSection ms_csAMFPropertyStorageExImplMaps;
//---------------------------------------------------------------------------------------------
#define AMFPrimitivePropertyInfoMapBegin \
{ \
amf::AMFPropertyInfoImpl* s_PropertiesInfo[] = \
{
#define AMFPrimitivePropertyInfoMapEnd \
}; \
for (amf_size i = 0; i < sizeof(s_PropertiesInfo) / sizeof(s_PropertiesInfo[0]); ++i) \
{ \
amf::AMFPropertyInfoImpl* pPropInfo = s_PropertiesInfo[i]; \
m_PropertiesInfo[pPropInfo->name].reset(pPropInfo); \
} \
}
#define AMFPropertyInfoBool(_name, _desc, _defaultValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_BOOL, 0, amf::AMFVariant(_defaultValue), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoEnum(_name, _desc, _defaultValue, pEnumDescription, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_INT64, 0, amf::AMFVariant(amf_int64(_defaultValue)), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, pEnumDescription)
#define AMFPropertyInfoInt64(_name, _desc, _defaultValue, _minValue, _maxValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_INT64, 0, amf::AMFVariant(amf_int64(_defaultValue)), \
amf::AMFVariant(amf_int64(_minValue)), amf::AMFVariant(amf_int64(_maxValue)), _AccessType, 0)
#define AMFPropertyInfoDouble(_name, _desc, _defaultValue, _minValue, _maxValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_DOUBLE, 0, amf::AMFVariant(amf_double(_defaultValue)), \
amf::AMFVariant(amf_double(_minValue)), amf::AMFVariant(amf_double(_maxValue)), _AccessType, 0)
#define AMFPropertyInfoFloat(_name, _desc, _defaultValue, _minValue, _maxValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_FLOAT, 0, amf::AMFVariant(amf_float(_defaultValue)), \
amf::AMFVariant(amf_float(_minValue)), amf::AMFVariant(amf_float(_maxValue)), _AccessType, 0)
#define AMFPropertyInfoRect(_name, _desc, defaultLeft, defaultTop, defaultRight, defaultBottom, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_RECT, 0, amf::AMFVariant(AMFConstructRect(defaultLeft, defaultTop, defaultRight, defaultBottom)), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoPoint(_name, _desc, defaultX, defaultY, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_POINT, 0, amf::AMFVariant(AMFConstructPoint(defaultX, defaultY)), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoSize(_name, _desc, _defaultValue, _minValue, _maxValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_SIZE, 0, amf::AMFVariant(AMFSize(_defaultValue)), \
amf::AMFVariant(AMFSize(_minValue)), amf::AMFVariant(AMFSize(_maxValue)), _AccessType, 0)
#define AMFPropertyInfoFloatSize(_name, _desc, _defaultValue, _minValue, _maxValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_FLOAT_SIZE, 0, amf::AMFVariant(AMFFloatSize(_defaultValue)), \
amf::AMFVariant(AMFFloatSize(_minValue)), amf::AMFVariant(AMFFloatSize(_maxValue)), _AccessType, 0)
#define AMFPropertyInfoRate(_name, _desc, defaultNum, defaultDen, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_RATE, 0, amf::AMFVariant(AMFConstructRate(defaultNum, defaultDen)), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoRateEx(_name, _desc, _defaultValue, _minValue, _maxValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_RATE, 0, amf::AMFVariant(_defaultValue), \
amf::AMFVariant(_minValue), amf::AMFVariant(_maxValue), _AccessType, 0)
#define AMFPropertyInfoRatio(_name, _desc, defaultNum, defaultDen, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_RATIO, 0, amf::AMFVariant(AMFConstructRatio(defaultNum, defaultDen)), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoColor(_name, _desc, defaultR, defaultG, defaultB, defaultA, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_COLOR, 0, amf::AMFVariant(AMFConstructColor(defaultR, defaultG, defaultB, defaultA)), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoString(_name, _desc, _defaultValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_STRING, 0, amf::AMFVariant(_defaultValue), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoWString(_name, _desc, _defaultValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_WSTRING, 0, amf::AMFVariant(_defaultValue), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoInterface(_name, _desc, _defaultValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_INTERFACE, 0, amf::AMFVariant(amf::AMFInterfacePtr(_defaultValue)), \
amf::AMFVariant(amf::AMFInterfacePtr()), amf::AMFVariant(amf::AMFInterfacePtr()), _AccessType, 0)
#define AMFPropertyInfoXML(_name, _desc, _defaultValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_STRING, AMF_PROPERTY_CONTENT_XML, amf::AMFVariant(_defaultValue), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoPath(_name, _desc, _defaultValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_WSTRING, AMF_PROPERTY_CONTENT_FILE_OPEN_PATH, amf::AMFVariant(_defaultValue), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoSavePath(_name, _desc, _defaultValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_WSTRING, AMF_PROPERTY_CONTENT_FILE_SAVE_PATH, amf::AMFVariant(_defaultValue), \
amf::AMFVariant(), amf::AMFVariant(), _AccessType, 0)
#define AMFPropertyInfoFloatVector4D(_name, _desc, _defaultValue, _minValue, _maxValue, _AccessType) \
new amf::AMFPropertyInfoImpl(_name, _desc, amf::AMF_VARIANT_FLOAT_VECTOR4D, 0, amf::AMFVariant(_defaultValue), \
amf::AMFVariant(_minValue), amf::AMFVariant(_maxValue), _AccessType, 0)
} // namespace amf
#endif // #ifndef AMF_PropertyStorageExImpl_h

View File

@@ -0,0 +1,194 @@
//
// 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 PropertyStorageImpl.h
/// @brief AMFPropertyStorageImpl header
///-------------------------------------------------------------------------
#ifndef AMF_PropertyStorageImpl_h
#define AMF_PropertyStorageImpl_h
#pragma once
#include "../include/core/PropertyStorage.h"
#include "Thread.h"
#include "InterfaceImpl.h"
#include "ObservableImpl.h"
#include "TraceAdapter.h"
namespace amf
{
//---------------------------------------------------------------------------------------------
template<typename _TBase> class AMFPropertyStorageImpl :
public _TBase,
public AMFObservableImpl<AMFPropertyStorageObserver>
{
public:
//-------------------------------------------------------------------------------------------------
AMFPropertyStorageImpl() : m_PropertyValues()
{
}
//-------------------------------------------------------------------------------------------------
virtual ~AMFPropertyStorageImpl()
{
}
//-------------------------------------------------------------------------------------------------
// interface access
AMF_BEGIN_INTERFACE_MAP
AMF_INTERFACE_ENTRY(AMFPropertyStorage)
AMF_END_INTERFACE_MAP
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL SetProperty(const wchar_t* pName, AMFVariantStruct value)
{
AMF_RETURN_IF_INVALID_POINTER(pName);
m_PropertyValues[pName] = value;
OnPropertyChanged(pName);
NotifyObservers<const wchar_t*>(&AMFPropertyStorageObserver::OnPropertyChanged, pName);
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL GetProperty(const wchar_t* pName, AMFVariantStruct* pValue) const
{
AMF_RETURN_IF_INVALID_POINTER(pName);
AMF_RETURN_IF_INVALID_POINTER(pValue);
amf_wstring name(pName);
amf_map<amf_wstring, AMFVariant>::const_iterator found = m_PropertyValues.find(name);
if(found != m_PropertyValues.end())
{
AMFVariantCopy(pValue, &found->second);
return AMF_OK;
}
return AMF_NOT_FOUND;
}
//-------------------------------------------------------------------------------------------------
virtual bool AMF_STD_CALL HasProperty(const wchar_t* pName) const
{
AMF_ASSERT(pName != NULL);
return m_PropertyValues.find(pName) != m_PropertyValues.end();
}
//-------------------------------------------------------------------------------------------------
virtual amf_size AMF_STD_CALL GetPropertyCount() const
{
return m_PropertyValues.size();
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL GetPropertyAt(amf_size index, wchar_t* pName, amf_size nameSize, AMFVariantStruct* pValue) const
{
AMF_RETURN_IF_INVALID_POINTER(pName);
AMF_RETURN_IF_INVALID_POINTER(pValue);
AMF_RETURN_IF_FALSE(nameSize != 0, AMF_INVALID_ARG);
amf_map<amf_wstring, AMFVariant>::const_iterator found = m_PropertyValues.begin();
if(found == m_PropertyValues.end())
{
return AMF_INVALID_ARG;
}
for( amf_size i = 0; i < index; i++)
{
found++;
if(found == m_PropertyValues.end())
{
return AMF_INVALID_ARG;
}
}
size_t copySize = AMF_MIN(nameSize-1, found->first.length());
memcpy(pName, found->first.c_str(), copySize * sizeof(wchar_t));
pName[copySize] = 0;
AMFVariantCopy(pValue, &found->second);
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL Clear()
{
m_PropertyValues.clear();
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL AddTo(AMFPropertyStorage* pDest, bool overwrite, bool /*deep*/) const
{
AMF_RETURN_IF_INVALID_POINTER(pDest);
AMF_RESULT err = AMF_OK;
amf_map<amf_wstring, AMFVariant>::const_iterator it = m_PropertyValues.begin();
for(; it != m_PropertyValues.end(); it++)
{
if(!HasProperty(it->first.c_str())) // ignore properties which aren't accessible
{
continue;
}
if(!overwrite)
{
if(pDest->HasProperty(it->first.c_str()))
{
continue;
}
}
{
err = pDest->SetProperty(it->first.c_str(), it->second);
}
if(err == AMF_ACCESS_DENIED)
{
continue;
}
AMF_RETURN_IF_FAILED(err, L"AddTo() - failed to copy property=%s", it->first.c_str());
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
virtual AMF_RESULT AMF_STD_CALL CopyTo(AMFPropertyStorage* pDest, bool deep) const
{
AMF_RETURN_IF_INVALID_POINTER(pDest);
if(pDest != this)
{
pDest->Clear();
return AddTo(pDest, true, deep);
}
else
{
return AMF_OK;
}
}
//-------------------------------------------------------------------------------------------------
virtual void AMF_STD_CALL OnPropertyChanged(const wchar_t* /*name*/) { }
//-------------------------------------------------------------------------------------------------
virtual void AMF_STD_CALL AddObserver(AMFPropertyStorageObserver* pObserver) { AMFObservableImpl<AMFPropertyStorageObserver>::AddObserver(pObserver); }
//-------------------------------------------------------------------------------------------------
virtual void AMF_STD_CALL RemoveObserver(AMFPropertyStorageObserver* pObserver) { AMFObservableImpl<AMFPropertyStorageObserver>::RemoveObserver(pObserver); }
//-------------------------------------------------------------------------------------------------
protected:
//-------------------------------------------------------------------------------------------------
amf_map<amf_wstring, AMFVariant> m_PropertyValues;
};
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
}
#endif // AMF_PropertyStorageImpl_h

View File

@@ -0,0 +1,624 @@
//
// 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.
//
#if defined(_WIN32)
#include <process.h>
#else
#include <pthread.h>
#endif
#include "Thread.h"
#if defined(METRO_APP)
#include <ppl.h>
#include <ppltasks.h>
#endif
namespace amf
{
//----------------------------------------------------------------------------
AMFEvent::AMFEvent(bool bInitiallyOwned, bool bManualReset, const wchar_t* pName) : m_hSyncObject()
{
m_hSyncObject = amf_create_event(bInitiallyOwned, bManualReset, pName);
}
//----------------------------------------------------------------------------
AMFEvent::~AMFEvent()
{
amf_delete_event(m_hSyncObject);
}
//----------------------------------------------------------------------------
bool AMFEvent::Lock(amf_ulong ulTimeout)
{
return amf_wait_for_event(m_hSyncObject, ulTimeout);
}
//----------------------------------------------------------------------------
bool AMFEvent::LockTimeout(amf_ulong ulTimeout)
{
return amf_wait_for_event_timeout(m_hSyncObject, ulTimeout);
}
//----------------------------------------------------------------------------
bool AMFEvent::Unlock()
{
return true;
}
//----------------------------------------------------------------------------
bool AMFEvent::SetEvent()
{
return amf_set_event(m_hSyncObject);
}
//----------------------------------------------------------------------------
bool AMFEvent::ResetEvent()
{
return amf_reset_event(m_hSyncObject);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
AMFMutex::AMFMutex(bool bInitiallyOwned, const wchar_t* pName
#if defined(_WIN32)
, bool bOpenExistent
#endif
):m_hSyncObject()
{
#if defined(_WIN32)
if(bOpenExistent)
{
m_hSyncObject = amf_open_mutex(pName);
}
else
#else
//#pragma message AMF_TODO("Open mutex!!! missing functionality in Linux!!!")
#endif
{
m_hSyncObject = amf_create_mutex(bInitiallyOwned, pName);
}
}
//----------------------------------------------------------------------------
AMFMutex::~AMFMutex()
{
if(m_hSyncObject)
{
amf_delete_mutex(m_hSyncObject);
}
}
//----------------------------------------------------------------------------
bool AMFMutex::Lock(amf_ulong ulTimeout)
{
if(m_hSyncObject)
{
return amf_wait_for_mutex(m_hSyncObject, ulTimeout);
}
else
{
return false;
}
}
//----------------------------------------------------------------------------
bool AMFMutex::Unlock()
{
if(m_hSyncObject)
{
return amf_release_mutex(m_hSyncObject);
}
else
{
return false;
}
}
//----------------------------------------------------------------------------
bool AMFMutex::IsValid()
{
return m_hSyncObject != NULL;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
AMFCriticalSection::AMFCriticalSection() : m_Sect()
{
m_Sect = amf_create_critical_section();
}
//----------------------------------------------------------------------------
AMFCriticalSection::~AMFCriticalSection()
{
amf_delete_critical_section(m_Sect);
}
//----------------------------------------------------------------------------
bool AMFCriticalSection::Lock(amf_ulong ulTimeout)
{
return (ulTimeout != AMF_INFINITE) ? amf_wait_critical_section(m_Sect, ulTimeout)
: amf_enter_critical_section(m_Sect);
}
//----------------------------------------------------------------------------
bool AMFCriticalSection::Unlock()
{
return amf_leave_critical_section(m_Sect);
}
//----------------------------------------------------------------------------
AMFSemaphore::AMFSemaphore(amf_long iInitCount, amf_long iMaxCount, const wchar_t* pName)
: m_hSemaphore(NULL)
{
Create(iInitCount, iMaxCount, pName);
}
//----------------------------------------------------------------------------
AMFSemaphore::~AMFSemaphore()
{
amf_delete_semaphore(m_hSemaphore);
}
//----------------------------------------------------------------------------
bool AMFSemaphore::Create(amf_long iInitCount, amf_long iMaxCount, const wchar_t* pName)
{
if(m_hSemaphore != NULL) // delete old one
{
amf_delete_semaphore(m_hSemaphore);
m_hSemaphore = NULL;
}
if(iMaxCount > 0)
{
m_hSemaphore = amf_create_semaphore(iInitCount, iMaxCount, pName);
}
return true;
}
//----------------------------------------------------------------------------
bool AMFSemaphore::Lock(amf_ulong ulTimeout)
{
return amf_wait_for_semaphore(m_hSemaphore, ulTimeout);
}
//----------------------------------------------------------------------------
bool AMFSemaphore::Unlock()
{
amf_long iOldCount = 0;
return amf_release_semaphore(m_hSemaphore, 1, &iOldCount);
}
//----------------------------------------------------------------------------
AMFLock::AMFLock(AMFSyncBase* pBase, amf_ulong ulTimeout)
: m_pBase(pBase),
m_bLocked()
{
m_bLocked = Lock(ulTimeout);
}
//----------------------------------------------------------------------------
AMFLock::~AMFLock()
{
if (IsLocked() == true)
{
Unlock();
}
}
//----------------------------------------------------------------------------
bool AMFLock::Lock(amf_ulong ulTimeout)
{
if(m_pBase == NULL)
{
return false;
}
m_bLocked = m_pBase->Lock(ulTimeout);
return m_bLocked;
}
//----------------------------------------------------------------------------
bool AMFLock::Unlock()
{
if(m_pBase == NULL)
{
return false;
}
const bool unlockSucceeded = m_pBase->Unlock();
m_bLocked = m_bLocked && (unlockSucceeded == false);
return unlockSucceeded;
}
//----------------------------------------------------------------------------
bool AMFLock::IsLocked()
{
return m_bLocked;
}
//----------------------------------------------------------------------------
#if defined(METRO_APP)
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Navigation;
class AMFThreadObj
{
Windows::Foundation::IAsyncAction^ m_AsyncAction;
AMFEvent m_StopEvent;
AMFThread* m_pOwner;
public:
AMFThreadObj(AMFThread* owner);
virtual ~AMFThreadObj();
virtual bool Start();
virtual bool RequestStop();
virtual bool WaitForStop();
virtual bool StopRequested();
// this is executed in the thread and overloaded by implementor
virtual void Run() { m_pOwner->Run(); }
virtual bool Init(){ return m_pOwner->Init(); }
virtual bool Terminate(){ return m_pOwner->Terminate();}
};
AMFThreadObj::AMFThreadObj(AMFThread* owner)
: m_StopEvent(true, true), m_pOwner(owner)
{}
AMFThreadObj::~AMFThreadObj()
{}
bool AMFThreadObj::Start()
{
auto workItemDelegate = [this](IAsyncAction ^ workItem)
{
if( !this->Init() )
{
return;
}
this->Run();
this->Terminate();
this->m_AsyncAction = nullptr;
if( this->StopRequested() )
{
this->m_StopEvent.SetEvent();
}
};
Windows::System::Threading::WorkItemPriority WorkPriority;
WorkPriority = Windows::System::Threading::WorkItemPriority::Normal;
auto workItemHandler = ref new Windows::System::Threading::WorkItemHandler(workItemDelegate);
m_AsyncAction = Windows::System::Threading::ThreadPool::RunAsync(workItemHandler, WorkPriority);
return true;
}
bool AMFThreadObj::RequestStop()
{
if( m_AsyncAction == nullptr )
{
return true;
}
m_StopEvent.ResetEvent();
return true;
}
bool AMFThreadObj::WaitForStop()
{
if( m_AsyncAction == nullptr )
{
return true;
}
return m_StopEvent.Lock();
}
bool AMFThreadObj::StopRequested()
{
return !m_StopEvent.Lock(0);
}
bool AMFThreadObj::IsRunning()
{
return m_AsyncAction != nullptr;
}
void amf::ExitThread()
{}
//#endif//#if defined(METRO_APP)
//#if defined(_WIN32)
#elif defined(_WIN32) // _WIN32 and METRO_APP defines are not mutually exclusive
class AMFThreadObj
{
AMFThread* m_pOwner;
uintptr_t m_pThread;
AMFEvent m_StopEvent;
AMFCriticalSection m_Lock;
public:
// this is called by owner
AMFThreadObj(AMFThread* owner);
virtual ~AMFThreadObj();
virtual bool Start();
virtual bool RequestStop();
virtual bool WaitForStop();
virtual bool StopRequested();
virtual bool IsRunning();
protected:
static void AMF_CDECL_CALL AMFThreadProc(void* pThis);
// this is executed in the thread and overloaded by implementor
virtual void Run()
{
m_pOwner->Run();
}
virtual bool Init()
{
return m_pOwner->Init();
}
virtual bool Terminate()
{
return m_pOwner->Terminate();
}
};
//----------------------------------------------------------------------------
AMFThreadObj::AMFThreadObj(AMFThread* owner) :
m_pOwner(owner),
m_pThread(uintptr_t(-1)),
m_StopEvent(true, true)
{}
//----------------------------------------------------------------------------
AMFThreadObj::~AMFThreadObj()
{
// RequestStop();
// WaitForStop();
}
//----------------------------------------------------------------------------
void AMF_CDECL_CALL AMFThreadObj::AMFThreadProc(void* pThis)
{
AMFThreadObj* pT = (AMFThreadObj*)pThis;
if(!pT->Init())
{
return;
}
pT->Run();
pT->Terminate();
pT->m_pThread = uintptr_t(-1);
if(pT->StopRequested())
{
pT->m_StopEvent.SetEvent(); // signal to stop that we just finished
}
}
//----------------------------------------------------------------------------
bool AMFThreadObj::Start()
{
if(m_pThread != (uintptr_t)-1L)
{
return true;
}
AMFLock lock(&m_Lock);
m_pThread = _beginthread(AMFThreadProc, 0, (void* )this);
return m_pThread != (uintptr_t)-1L;
}
//----------------------------------------------------------------------------
bool AMFThreadObj::RequestStop()
{
if(m_pThread == (uintptr_t)-1L)
{
return true;
}
m_StopEvent.ResetEvent();
return true;
}
//----------------------------------------------------------------------------
bool AMFThreadObj::WaitForStop()
{
AMFLock lock(&m_Lock);
if(m_pThread == (uintptr_t)-1L)
{
return true;
}
bool stopped = m_StopEvent.Lock();
m_pThread = (uintptr_t)-1L;
return stopped;
}
//----------------------------------------------------------------------------
bool AMFThreadObj::StopRequested()
{
return !m_StopEvent.Lock(0);
}
bool AMFThreadObj::IsRunning()
{
return m_pThread != (uintptr_t)-1L;
}
//----------------------------------------------------------------------------
void ExitThread()
{
_endthread();
}
#endif //#if defined(_WIN32)
#if defined(__linux) || defined(__APPLE__)
class AMFThreadObj
{
public:
AMFThreadObj(AMFThread* owner);
virtual ~AMFThreadObj();
virtual bool Start();
virtual bool RequestStop();
virtual bool WaitForStop();
virtual bool StopRequested();
virtual bool IsRunning();
// this is executed in the thread and overloaded by implementor
virtual void Run() { m_pOwner->Run(); }
virtual bool Init(){ return m_pOwner->Init(); }
virtual bool Terminate(){ return m_pOwner->Terminate();}
private:
AMFThread* m_pOwner;
pthread_t m_hThread;
bool m_bStopRequested;
bool m_bRunning;
bool m_bInternalRunning; //used to detect thread auto-exit case and make join in Start
AMFCriticalSection m_Lock;
AMFThreadObj(const AMFThreadObj&);
AMFThreadObj& operator=(const AMFThreadObj&);
static void* AMF_CDECL_CALL AMFThreadProc(void* pThis);
};
AMFThreadObj::AMFThreadObj(AMFThread* owner)
: m_pOwner(owner),
m_bStopRequested(false),
m_bRunning(false),
m_bInternalRunning(false)
{
}
AMFThreadObj::~AMFThreadObj()
{
RequestStop();
WaitForStop();
}
void* AMF_CDECL_CALL AMFThreadObj::AMFThreadProc(void* pThis)
{
AMFThreadObj* pT = (AMFThreadObj*)pThis;
if(!pT->Init())
{
return 0;
}
pT->Run();
pT->Terminate();
pT->m_bStopRequested = false;
pT->m_bInternalRunning = false;
return 0;
}
bool AMFThreadObj::Start()
{
bool result = true;
if(m_bRunning == true && m_bInternalRunning == false)
{
pthread_join(m_hThread, 0);
m_bRunning = false;
m_bStopRequested = false;
}
if (IsRunning() == false)
{
WaitForStop();
AMFLock lock(&m_Lock);
if (pthread_create(&m_hThread, 0, AMFThreadProc, (void*)this) == 0)
{
m_bRunning = true;
m_bInternalRunning = true;
}
else
{
result = false;
}
}
return result;
}
bool AMFThreadObj::RequestStop()
{
AMFLock lock(&m_Lock);
if (IsRunning() == false)
{
return true;
}
m_bStopRequested = true;
return true;
}
bool AMFThreadObj::WaitForStop()
{
AMFLock lock(&m_Lock);
if (IsRunning() == true)
{
pthread_join(m_hThread, 0);
m_bRunning = false;
}
m_bStopRequested = false;
return true;
}
bool AMFThreadObj::StopRequested()
{
return m_bStopRequested;
}
bool AMFThreadObj::IsRunning()
{
return m_bRunning && m_bInternalRunning;
}
void ExitThread()
{
pthread_exit(0);
}
#endif //#if defined(__linux)
AMFThread::AMFThread() : m_thread()
{
m_thread = new AMFThreadObj(this);
}
AMFThread::~AMFThread()
{
delete m_thread;
}
bool AMFThread::Start()
{
return m_thread->Start();
}
bool AMFThread::RequestStop()
{
return m_thread->RequestStop();
}
bool AMFThread::WaitForStop()
{
return m_thread->WaitForStop();
}
bool AMFThread::StopRequested()
{
return m_thread->StopRequested();
}
bool AMFThread::IsRunning() const
{
return m_thread->IsRunning();
}
} //namespace

View File

@@ -0,0 +1,721 @@
//
// 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_Thread_h
#define AMF_Thread_h
#pragma once
#include <cassert>
#include <list>
#include <vector>
#include "../include/core/Platform.h"
#ifndef _WIN32
#include <pthread.h>
#endif
extern "C"
{
// threads
#define AMF_INFINITE (0xFFFFFFFF) // Infinite ulTimeout
// threads: atomic
amf_long AMF_CDECL_CALL amf_atomic_inc(amf_long* X);
amf_long AMF_CDECL_CALL amf_atomic_dec(amf_long* X);
// threads: critical section
amf_handle AMF_CDECL_CALL amf_create_critical_section();
bool AMF_CDECL_CALL amf_delete_critical_section(amf_handle cs);
bool AMF_CDECL_CALL amf_enter_critical_section(amf_handle cs);
bool AMF_CDECL_CALL amf_wait_critical_section(amf_handle cs, amf_ulong ulTimeout);
bool AMF_CDECL_CALL amf_leave_critical_section(amf_handle cs);
// threads: event
amf_handle AMF_CDECL_CALL amf_create_event(bool bInitiallyOwned, bool bManualReset, const wchar_t* pName);
bool AMF_CDECL_CALL amf_delete_event(amf_handle hevent);
bool AMF_CDECL_CALL amf_set_event(amf_handle hevent);
bool AMF_CDECL_CALL amf_reset_event(amf_handle hevent);
bool AMF_CDECL_CALL amf_wait_for_event(amf_handle hevent, amf_ulong ulTimeout);
bool AMF_CDECL_CALL amf_wait_for_event_timeout(amf_handle hevent, amf_ulong ulTimeout);
// threads: mutex
amf_handle AMF_CDECL_CALL amf_create_mutex(bool bInitiallyOwned, const wchar_t* pName);
#if defined(_WIN32)
amf_handle AMF_CDECL_CALL amf_open_mutex(const wchar_t* pName);
#endif
bool AMF_CDECL_CALL amf_delete_mutex(amf_handle hmutex);
bool AMF_CDECL_CALL amf_wait_for_mutex(amf_handle hmutex, amf_ulong ulTimeout);
bool AMF_CDECL_CALL amf_release_mutex(amf_handle hmutex);
// threads: semaphore
amf_handle AMF_CDECL_CALL amf_create_semaphore(amf_long iInitCount, amf_long iMaxCount, const wchar_t* pName);
bool AMF_CDECL_CALL amf_delete_semaphore(amf_handle hsemaphore);
bool AMF_CDECL_CALL amf_wait_for_semaphore(amf_handle hsemaphore, amf_ulong ulTimeout);
bool AMF_CDECL_CALL amf_release_semaphore(amf_handle hsemaphore, amf_long iCount, amf_long* iOldCount);
// threads: delay
void AMF_CDECL_CALL amf_sleep(amf_ulong delay);
amf_pts AMF_CDECL_CALL amf_high_precision_clock(); // in 100 of nanosec
void AMF_CDECL_CALL amf_increase_timer_precision();
void AMF_CDECL_CALL amf_restore_timer_precision();
amf_handle AMF_CDECL_CALL amf_load_library(const wchar_t* filename);
amf_handle AMF_CDECL_CALL amf_load_library1(const wchar_t* filename, bool bGlobal);
void* AMF_CDECL_CALL amf_get_proc_address(amf_handle module, const char* procName);
int AMF_CDECL_CALL amf_free_library(amf_handle module);
#if defined(__APPLE__)
amf_uint64 AMF_STD_CALL get_current_thread_id();
#else
amf_uint32 AMF_STD_CALL get_current_thread_id();
#endif
#if !defined(METRO_APP)
// virtual memory
void* AMF_CDECL_CALL amf_virtual_alloc(amf_size size);
void AMF_CDECL_CALL amf_virtual_free(void* ptr);
#else
#define amf_virtual_alloc amf_alloc
#define amf_virtual_free amf_free
#endif
// cpu
#if defined(_WIN32) || (__linux__)
amf_int32 AMF_STD_CALL amf_get_cpu_cores();
#endif
}
namespace amf
{
//----------------------------------------------------------------
class AMF_NO_VTABLE AMFSyncBase
{
public:
virtual bool Lock(amf_ulong ulTimeout = AMF_INFINITE) = 0;
virtual bool Unlock() = 0;
};
//----------------------------------------------------------------
class AMFEvent : public AMFSyncBase
{
private:
amf_handle m_hSyncObject;
AMFEvent(const AMFEvent&);
AMFEvent& operator=(const AMFEvent&);
public:
AMFEvent(bool bInitiallyOwned = false, bool bManualReset = false, const wchar_t* pName = NULL);
virtual ~AMFEvent();
virtual bool Lock(amf_ulong ulTimeout = AMF_INFINITE);
virtual bool LockTimeout(amf_ulong ulTimeout = AMF_INFINITE);
virtual bool Unlock();
bool SetEvent();
bool ResetEvent();
amf_handle GetNative() { return m_hSyncObject; }
};
//----------------------------------------------------------------
class AMFMutex : public AMFSyncBase
{
private:
amf_handle m_hSyncObject;
AMFMutex(const AMFMutex&);
AMFMutex& operator=(const AMFMutex&);
public:
AMFMutex(bool bInitiallyOwned = false, const wchar_t* pName = NULL
#if defined(_WIN32)
, bool bOpenExistent = false
#endif
);
virtual ~AMFMutex();
virtual bool Lock(amf_ulong ulTimeout = AMF_INFINITE);
virtual bool Unlock();
bool IsValid();
};
//----------------------------------------------------------------
class AMFCriticalSection : public AMFSyncBase
{
private:
amf_handle m_Sect;
AMFCriticalSection(const AMFCriticalSection&);
AMFCriticalSection& operator=(const AMFCriticalSection&);
public:
AMFCriticalSection();
virtual ~AMFCriticalSection();
virtual bool Lock(amf_ulong ulTimeout = AMF_INFINITE);
virtual bool Unlock();
};
//----------------------------------------------------------------
class AMFSemaphore : public AMFSyncBase
{
private:
amf_handle m_hSemaphore;
AMFSemaphore(const AMFSemaphore&);
AMFSemaphore& operator=(const AMFSemaphore&);
public:
AMFSemaphore(amf_long iInitCount, amf_long iMaxCount, const wchar_t* pName = NULL);
virtual ~AMFSemaphore();
virtual bool Create(amf_long iInitCount, amf_long iMaxCount, const wchar_t* pName = NULL);
virtual bool Lock(amf_ulong ulTimeout = AMF_INFINITE);
virtual bool Unlock();
};
//----------------------------------------------------------------
class AMFLock
{
private:
AMFSyncBase* m_pBase;
bool m_bLocked;
AMFLock(const AMFLock&);
AMFLock& operator=(const AMFLock&);
public:
AMFLock(AMFSyncBase* pBase, amf_ulong ulTimeout = AMF_INFINITE);
~AMFLock();
bool Lock(amf_ulong ulTimeout = AMF_INFINITE);
bool Unlock();
bool IsLocked();
};
//----------------------------------------------------------------
class AMFReadWriteSync
{
private:
struct ReadWriteResources
{
// max threads reading concurrently
const int m_maxReadThreads;
AMFSemaphore m_readSemaphore;
AMFCriticalSection m_writeCriticalSection;
ReadWriteResources() :
m_maxReadThreads(10),
m_readSemaphore(m_maxReadThreads, m_maxReadThreads),
m_writeCriticalSection()
{ }
};
class ReadSync : public AMFSyncBase
{
private:
ReadSync(const ReadSync&);
ReadSync& operator=(const ReadSync&);
ReadWriteResources& m_resources;
public:
ReadSync(ReadWriteResources& resources) : m_resources(resources)
{ }
virtual bool Lock(amf_ulong ulTimeout = AMF_INFINITE)
{
return m_resources.m_readSemaphore.Lock(ulTimeout);
}
virtual bool Unlock()
{
return m_resources.m_readSemaphore.Unlock();
}
};
class WriteSync : public AMFSyncBase
{
private:
WriteSync(const WriteSync&);
WriteSync& operator=(const WriteSync&);
ReadWriteResources& m_resources;
public:
WriteSync(ReadWriteResources& resources) : m_resources(resources)
{ }
/// waits passed timeout for other writers; wait readers for infinite
virtual bool Lock(amf_ulong ulTimeout = AMF_INFINITE)
{
if(!m_resources.m_writeCriticalSection.Lock(ulTimeout))
{
return false;
}
for(int i = 0; i < m_resources.m_maxReadThreads; i++)
{
m_resources.m_readSemaphore.Lock();
}
return true;
}
virtual bool Unlock()
{
// there is windows function to release N times by one call - could be optimize later
for(int i = 0; i < m_resources.m_maxReadThreads; i++)
{
m_resources.m_readSemaphore.Unlock();
}
return m_resources.m_writeCriticalSection.Unlock();
}
};
private:
ReadWriteResources m_resources;
ReadSync m_readSync;
WriteSync m_writeSync;
public:
AMFReadWriteSync() :
m_resources(),
m_readSync(m_resources),
m_writeSync(m_resources)
{ }
AMFSyncBase* GetReadSync()
{
return &m_readSync;
}
AMFSyncBase* GetWriteSync()
{
return &m_writeSync;
}
};
//----------------------------------------------------------------
class AMFThreadObj;
class AMFThread
{
friend class AMFThreadObj;
public:
AMFThread();
virtual ~AMFThread();
virtual bool Start();
virtual bool RequestStop();
virtual bool WaitForStop();
virtual bool StopRequested();
virtual bool IsRunning() const;
protected:
// this is executed in the thread and overloaded by implementor
virtual void Run() = 0;
virtual bool Init()
{
return true;
}
virtual bool Terminate()
{
return true;
}
private:
AMFThreadObj* m_thread;
AMFThread(const AMFThread&);
AMFThread& operator=(const AMFThread&);
};
void ExitThread();
//----------------------------------------------------------------
template<typename T>
class AMFQueue
{
protected:
class ItemData
{
public:
T data;
amf_ulong ulID;
amf_long ulPriority;
ItemData() : data(), ulID(), ulPriority(){}
};
typedef std::list< ItemData > QueueList;
QueueList m_Queue;
AMFCriticalSection m_cSect;
AMFEvent m_SomethingInQueueEvent;
AMFSemaphore m_QueueSizeSem;
amf_int32 m_iQueueSize;
bool InternalGet(amf_ulong& ulID, T& item)
{
AMFLock lock(&m_cSect);
if(!m_Queue.empty()) // something to get
{
ItemData& itemdata = m_Queue.front();
ulID = itemdata.ulID;
item = itemdata.data;
m_Queue.pop_front();
m_QueueSizeSem.Unlock();
if(m_Queue.empty())
{
m_SomethingInQueueEvent.ResetEvent();
}
return true;
}
return false;
}
public:
AMFQueue(amf_int32 iQueueSize = 0)
: m_Queue(),
m_cSect(),
m_SomethingInQueueEvent(false, false),
m_QueueSizeSem(iQueueSize, iQueueSize > 0 ? iQueueSize + 1 : 0),
m_iQueueSize(iQueueSize) {}
virtual ~AMFQueue(){}
virtual bool SetQueueSize(amf_int32 iQueueSize)
{
bool success = m_QueueSizeSem.Create(iQueueSize, iQueueSize > 0 ? iQueueSize + 1 : 0);
if(success)
{
m_iQueueSize = iQueueSize;
}
return success;
}
virtual amf_int32 GetQueueSize()
{
return m_iQueueSize;
}
virtual bool Add(amf_ulong ulID, const T& item, amf_long ulPriority = 0, amf_ulong ulTimeout = AMF_INFINITE)
{
if(m_QueueSizeSem.Lock(ulTimeout) == false)
{
return false;
}
{
AMFLock lock(&m_cSect);
ItemData itemdata;
itemdata.ulID = ulID;
itemdata.data = item;
itemdata.ulPriority = ulPriority;
typename QueueList::iterator iter = m_Queue.end();
for(; iter != m_Queue.begin(); )
{
iter--;
if(ulPriority <= (iter->ulPriority))
{
iter++;
break;
}
}
m_Queue.insert(iter, itemdata);
m_SomethingInQueueEvent.SetEvent(); // this will set all waiting threads - some of them get data, some of them not
}
return true;
}
virtual bool Get(amf_ulong& ulID, T& item, amf_ulong ulTimeout)
{
if(InternalGet(ulID, item)) // try right away
{
return true;
}
// wait for queue
if(m_SomethingInQueueEvent.Lock(ulTimeout))
{
return InternalGet(ulID, item);
}
return false;
}
virtual void Clear()
{
bool bValue = true;
while(bValue)
{
amf_ulong ulID;
T item;
bValue = InternalGet(ulID, item);
}
}
virtual amf_size GetSize()
{
AMFLock lock(&m_cSect);
return m_Queue.size();
}
};
//----------------------------------------------------------------
template<class inT, class outT>
class AMFQueueThread : public AMFThread
{
private:
AMFQueueThread(const AMFQueueThread&);
AMFQueueThread& operator=(const AMFQueueThread&);
protected:
AMFQueue<inT>* m_pInQueue;
AMFQueue<outT>* m_pOutQueue;
AMFMutex m_mutexInProcess; ///< This mutex shows other threads that the thread function allocates
///< some objects on stack and it is unsafe state. To manipulate objects owned by descendant classes
///< client must lock this mutex by calling BlockProcessing member function. When client finished its work
///< corresponding UnblockProcessing member function call must be done.
bool m_blockProcessingRequested;
AMFCriticalSection m_csBlockingRequest;
public:
AMFQueueThread(AMFQueue<inT>* pInQueue,
AMFQueue<outT>* pOutQueue) : m_pInQueue(pInQueue), m_pOutQueue(pOutQueue), m_mutexInProcess(),
m_blockProcessingRequested(false), m_csBlockingRequest()
{}
virtual bool Process(amf_ulong& ulID, inT& inData, outT& outData) = 0;
virtual void BlockProcessing()
{
AMFLock lock(&m_csBlockingRequest);
m_blockProcessingRequested = true;
m_mutexInProcess.Lock();
}
virtual void UnblockProcessing()
{
AMFLock lock(&m_csBlockingRequest);
m_mutexInProcess.Unlock();
m_blockProcessingRequested = false;
}
virtual bool IsPaused()
{
return false;
}
virtual void OnHaveOutput() {}
virtual void OnIdle() {}
virtual void Run()
{
bool bStop = false;
while(!bStop)
{
{
AMFLock lock(&m_mutexInProcess);
inT inData;
amf_ulong ulID = 0;
bool callProcess = true;
if(m_pInQueue != NULL)
{
amf_ulong waitTimeout = 5;
bool validInput = m_pInQueue->Get(ulID, inData, waitTimeout); // Pulse to check Stop from time to time
if(StopRequested())
{
bStop = true;
}
if(!validInput)
{
callProcess = false;
}
}
if(!bStop && callProcess)
{
outT outData;
bool validOutput = Process(ulID, inData, outData);
if(StopRequested())
{
bStop = true;
}
if(!bStop && (m_pOutQueue != NULL) && validOutput)
{
m_pOutQueue->Add(ulID, outData);
OnHaveOutput();
}
}
else
{
OnIdle();
}
}
if(StopRequested())
{
bStop = true;
}
#if defined(__linux) || defined(__APPLE__)
///< HACK
///< This amf_sleep(0) is required to emulate windows mutex behavior.
///< In Windows release mutext causes some other waiting thread is receiving ownership of mutex.
///< In Linux it is not true.
///< Without sleep AMFLock destructor releases mutex but immediately on next cycle AMFLock constructor tries to lock
///< the mutex and now system have two threads waiting for the mutex.
///< Using some random logic system decides who will be unlocked.
///< This thread may win during several seconds it looks like pipeline is hang.
///< amf_sleep call causes waiting thread is becoming unlocked.
if(m_blockProcessingRequested)
{
amf_sleep(0);
}
#endif
}
}
};
//----------------------------------------------------------------
template<class inT, class outT, class _Thread, class ThreadParam>
class AMFQueueThreadPipeline
{
private:
AMFQueueThreadPipeline(const AMFQueueThreadPipeline&);
AMFQueueThreadPipeline& operator=(const AMFQueueThreadPipeline&);
public:
AMFQueue<inT>* m_pInQueue;
AMFQueue<outT>* m_pOutQueue;
std::vector<_Thread*> m_ThreadPool;
AMFQueueThreadPipeline(AMFQueue<inT>* pInQueue, AMFQueue<outT>* pOutQueue)
: m_pInQueue(pInQueue),
m_pOutQueue(pOutQueue),
m_ThreadPool()
{}
virtual ~AMFQueueThreadPipeline()
{
Stop();
}
void Start(int iNumberOfThreads, ThreadParam param)
{
if((long)m_ThreadPool.size() >= iNumberOfThreads)
{
Stop(); //temporary to remove stopped threads. need callback from thread to clean pool
//return;
}
size_t initialSize = m_ThreadPool.size();
for(size_t i = initialSize; i < (size_t)iNumberOfThreads; i++)
{
_Thread* pThread = new _Thread(m_pInQueue, m_pOutQueue, param);
m_ThreadPool.push_back(pThread);
pThread->Start();
}
}
void RequestStop()
{
long num = (long)m_ThreadPool.size();
for(long i = 0; i < num; i++)
{
m_ThreadPool[i]->RequestStop();
}
}
void BlockProcessing()
{
long num = (long)m_ThreadPool.size();
for(long i = 0; i < num; i++)
{
m_ThreadPool[i]->BlockProcessing();
}
}
void UnblockProcessing()
{
long num = (long)m_ThreadPool.size();
for(long i = 0; i < num; i++)
{
m_ThreadPool[i]->UnblockProcessing();
}
}
void WaitForStop()
{
long num = (long)m_ThreadPool.size();
for(long i = 0; i < num; i++)
{
_Thread* pThread = m_ThreadPool[i];
pThread->WaitForStop();
delete pThread;
}
m_ThreadPool.clear();
}
void Stop()
{
RequestStop();
WaitForStop();
}
};
//----------------------------------------------------------------
class AMFPreciseWaiter
{
public:
AMFPreciseWaiter() : m_WaitEvent(), m_bCancel(false)
{}
virtual ~AMFPreciseWaiter()
{}
amf_pts Wait(amf_pts waittime)
{
if (waittime < 0)
{
return 0;
}
m_bCancel = false;
amf_pts start = amf_high_precision_clock();
amf_pts waited = 0;
int count = 0;
while(!m_bCancel)
{
count++;
if(!m_WaitEvent.LockTimeout(1))
{
break;
}
waited = amf_high_precision_clock() - start;
if(waited >= waittime)
{
break;
}
}
return waited;
}
amf_pts WaitEx(amf_pts waittime)
{
m_bCancel = false;
amf_pts start = amf_high_precision_clock();
amf_pts waited = 0;
int count = 0;
while (!m_bCancel && waited < waittime)
{
if (waittime - waited < 2 * AMF_SECOND / 1000)// last 2 ms burn CPU for precision
{
for (int i = 0; i < 1000; i++)
{
count++;
#ifdef _WIN32
YieldProcessor();
#endif
}
}
else if (!m_WaitEvent.LockTimeout(1))
{
break;
}
waited = amf_high_precision_clock() - start;
}
return waited;
}
void Cancel()
{
m_bCancel = true;
}
protected:
AMFEvent m_WaitEvent;
bool m_bCancel;
};
//----------------------------------------------------------------
} // namespace amf
#endif // AMF_Thread_h

View File

@@ -0,0 +1,252 @@
//
// 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.
//
#include "../include/core/Factory.h"
#include "Thread.h"
#include "TraceAdapter.h"
#pragma warning(disable: 4251)
#pragma warning(disable: 4996)
using namespace amf;
#if defined(AMF_CORE_STATIC) || defined(AMF_RUNTIME) || defined(AMF_LITE)
extern "C"
{
extern AMF_CORE_LINK AMF_RESULT AMF_CDECL_CALL AMFInit(amf_uint64 version, amf::AMFFactory **ppFactory);
}
#else
#include "AMFFactory.h"
#endif
//------------------------------------------------------------------------------------------------
static AMFTrace *s_pTrace = NULL;
//------------------------------------------------------------------------------------------------
static AMFTrace *GetTrace()
{
if (s_pTrace == NULL)
{
#if defined(AMF_CORE_STATIC) || defined(AMF_RUNTIME) || defined(AMF_LITE)
AMFFactory *pFactory = NULL;
AMFInit(AMF_FULL_VERSION, &pFactory);
pFactory->GetTrace(&s_pTrace);
#else
s_pTrace = g_AMFFactory.GetTrace();
if (s_pTrace == nullptr)
{
g_AMFFactory.Init(); // last resort, should not happen
s_pTrace = g_AMFFactory.GetTrace();
g_AMFFactory.Terminate();
}
#endif
}
return s_pTrace;
}
//------------------------------------------------------------------------------------------------
static AMFDebug *s_pDebug = NULL;
//------------------------------------------------------------------------------------------------
static AMFDebug *GetDebug()
{
if (s_pDebug == NULL)
{
#if defined(AMF_CORE_STATIC) || defined(AMF_RUNTIME) || defined(AMF_LITE)
AMFFactory *pFactory = NULL;
AMFInit(AMF_FULL_VERSION, &pFactory);
pFactory->GetDebug(&s_pDebug);
#else
s_pDebug = g_AMFFactory.GetDebug();
if (s_pDebug == nullptr)
{
g_AMFFactory.Init(); // last resort, should not happen
s_pDebug = g_AMFFactory.GetDebug();
g_AMFFactory.Terminate();
}
#endif
}
return s_pDebug;
}
//------------------------------------------------------------------------------------------------
AMF_RESULT AMF_CDECL_CALL amf::AMFSetCustomDebugger(AMFDebug *pDebugger)
{
s_pDebug = pDebugger;
return AMF_OK;
}
//------------------------------------------------------------------------------------------------
AMF_RESULT AMF_CDECL_CALL amf::AMFSetCustomTracer(AMFTrace *pTracer)
{
s_pTrace = pTracer;
return AMF_OK;
}
//------------------------------------------------------------------------------------------------
AMF_RESULT AMF_CDECL_CALL amf::AMFTraceEnableAsync(bool enable)
{
return GetTrace()->TraceEnableAsync(enable);
}
//------------------------------------------------------------------------------------------------
AMF_RESULT AMF_CDECL_CALL amf::AMFTraceFlush()
{
return GetTrace()->TraceFlush();
}
//------------------------------------------------------------------------------------------------
void AMF_CDECL_CALL amf::AMFTraceW(const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope,
amf_int32 countArgs, const wchar_t* format, ...) // if countArgs <= 0 -> no args, formatting could be optimized then
{
if(countArgs <= 0)
{
GetTrace()->Trace(src_path, line, level, scope, format, NULL);
}
else
{
va_list vl;
va_start(vl, format);
GetTrace()->Trace(src_path, line, level, scope, format, &vl);
va_end(vl);
}
}
//------------------------------------------------------------------------------------------------
AMF_RESULT AMF_CDECL_CALL amf::AMFTraceSetPath(const wchar_t* path)
{
return GetTrace()->SetPath(path);
}
//------------------------------------------------------------------------------------------------
AMF_RESULT AMF_CDECL_CALL amf::AMFTraceGetPath(wchar_t* path, amf_size* pSize)
{
return GetTrace()->GetPath(path, pSize);
}
//------------------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf::AMFTraceEnableWriter(const wchar_t* writerID, bool enable)
{
return GetTrace()->EnableWriter(writerID, enable);
}
//------------------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf::AMFTraceWriterEnabled(const wchar_t* writerID)
{
return GetTrace()->WriterEnabled(writerID);
}
//------------------------------------------------------------------------------------------------
amf_int32 AMF_CDECL_CALL amf::AMFTraceSetGlobalLevel(amf_int32 level)
{
return GetTrace()->SetGlobalLevel(level);
}
//------------------------------------------------------------------------------------------------
amf_int32 AMF_CDECL_CALL amf::AMFTraceGetGlobalLevel()
{
return GetTrace()->GetGlobalLevel();
}
//------------------------------------------------------------------------------------------------
amf_int32 AMF_CDECL_CALL amf::AMFTraceSetWriterLevel(const wchar_t* writerID, amf_int32 level)
{
return GetTrace()->SetWriterLevel(writerID, level);
}
//------------------------------------------------------------------------------------------------
amf_int32 AMF_CDECL_CALL amf::AMFTraceGetWriterLevel(const wchar_t* writerID)
{
return GetTrace()->GetWriterLevel(writerID);
}
//------------------------------------------------------------------------------------------------
amf_int32 AMF_CDECL_CALL amf::AMFTraceSetWriterLevelForScope(const wchar_t* writerID, const wchar_t* scope, amf_int32 level)
{
return GetTrace()->SetWriterLevelForScope(writerID, scope, level);
}
//------------------------------------------------------------------------------------------------
amf_int32 AMF_CDECL_CALL amf::AMFTraceGetWriterLevelForScope(const wchar_t* writerID, const wchar_t* scope)
{
return GetTrace()->GetWriterLevelForScope(writerID, scope);
}
//------------------------------------------------------------------------------------------------
void AMF_CDECL_CALL amf::AMFTraceRegisterWriter(const wchar_t* writerID, AMFTraceWriter* pWriter)
{
GetTrace()->RegisterWriter(writerID, pWriter, true);
}
void AMF_CDECL_CALL amf::AMFTraceUnregisterWriter(const wchar_t* writerID)
{
GetTrace()->UnregisterWriter(writerID);
}
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#endif
void AMF_CDECL_CALL amf::AMFTraceEnterScope()
{
GetTrace()->Indent(1);
}
amf_uint32 AMF_CDECL_CALL AMFTraceGetScopeDepth()
{
return GetTrace()->GetIndentation();
}
void AMF_CDECL_CALL amf::AMFTraceExitScope()
{
GetTrace()->Indent(-1);
}
void AMF_CDECL_CALL amf::AMFAssertsEnable(bool enable)
{
GetDebug()->AssertsEnable(enable);
}
bool AMF_CDECL_CALL amf::AMFAssertsEnabled()
{
return GetDebug()->AssertsEnabled();
}
amf_wstring AMF_CDECL_CALL amf::AMFFormatResult(AMF_RESULT result)
{
return amf::amf_string_format(L"AMF_ERROR %d : %s: ", result, GetTrace()->GetResultText(result));
}
const wchar_t* AMF_STD_CALL amf::AMFGetResultText(AMF_RESULT res)
{
return GetTrace()->GetResultText(res);
}
const wchar_t* AMF_STD_CALL amf::AMFSurfaceGetFormatName(const AMF_SURFACE_FORMAT eSurfaceFormat)
{
return GetTrace()->SurfaceGetFormatName(eSurfaceFormat);
}
AMF_SURFACE_FORMAT AMF_STD_CALL amf::AMFSurfaceGetFormatByName(const wchar_t* pwName)
{
return GetTrace()->SurfaceGetFormatByName(pwName);
}
const wchar_t* AMF_STD_CALL amf::AMFGetMemoryTypeName(const AMF_MEMORY_TYPE memoryType)
{
return GetTrace()->GetMemoryTypeName(memoryType);
}
AMF_MEMORY_TYPE AMF_STD_CALL amf::AMFGetMemoryTypeByName(const wchar_t* name)
{
return GetTrace()->GetMemoryTypeByName(name);
}

View File

@@ -0,0 +1,808 @@
//
// 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 TraceAdapter.h
/// @brief AMFTrace interface
///-------------------------------------------------------------------------
#ifndef AMF_TraceAdapter_h
#define AMF_TraceAdapter_h
#pragma once
#include "../include/core/Debug.h"
#include "../include/core/Trace.h"
#include "../include/core/Result.h"
#include "public/common/AMFFactory.h"
#include "AMFSTL.h"
#ifndef WIN32
#include <stdarg.h>
#endif
#include <assert.h>
//-----------------------------------
// Visual Studio memory leak report
#if defined(WIN32) && defined(_DEBUG) && defined(CRTDBG)
#include <crtdbg.h>
#if !defined(METRO_APP)
#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
#endif
#endif
//-----------------------------------
#if defined(_DEBUG) && defined(__linux)
#include <sys/ptrace.h>
#include <signal.h>
#endif
namespace amf
{
/**
*******************************************************************************
* AMFTraceEnableAsync
*
* @brief
* Enable or disable async mode
*
* There are 2 modes trace can work in:
* Synchronous - every Trace call immediately goes to writers: console, windows, file, ...
* Asynchronous - trace message go to thread local queues; separate thread passes them to writes
* Asynchronous mode offers no synchronization between working threads which are writing traces
* and high performance.
* Asynchronous mode is not enabled always as that dedicated thread (started in Media SDK module) cannot be
* terminated safely. See msdn ExitProcess description: it terminates all threads without notifications.
* ExitProcess is called after exit from main() -> before module static variables destroyed and before atexit
* notifiers are called -> no way to finish trace dedicated thread.
*
* Therefore here is direct enable of asynchronous mode.
* AMFTraceEnableAsync(true) increases internal asynchronous counter by 1; AMFTraceEnableAsync(false) decreases by 1
* when counter becomes > 0 mode - switches to async; when becomes 0 - switches to sync
*
* Tracer must be switched to sync mode before quit application, otherwise async writing thread will be force terminated by OS (at lease Windows)
* See MSDN ExitProcess article for details.
*******************************************************************************
*/
extern "C"
{
AMF_RESULT AMF_CDECL_CALL AMFTraceEnableAsync(bool enable);
/**
*******************************************************************************
* AMFDebugSetDebugger
*
* @brief
* it is used to set a local debugger, or set NULL to remove
*
*******************************************************************************
*/
AMF_RESULT AMF_CDECL_CALL AMFSetCustomDebugger(AMFDebug *pDebugger);
/**
*******************************************************************************
* AMFTraceSetTracer
*
* @brief
* it is used to set a local tracer, or set NULL to remove
*
*******************************************************************************
*/
AMF_RESULT AMF_CDECL_CALL AMFSetCustomTracer(AMFTrace *pTrace);
/**
*******************************************************************************
* AMFTraceFlush
*
* @brief
* Enforce trace writers flush
*
*******************************************************************************
*/
AMF_RESULT AMF_CDECL_CALL AMFTraceFlush();
/**
*******************************************************************************
* EXPAND
*
* @brief
* Auxilary Macro used to evaluate __VA_ARGS__ from 1 macro argument into list of them
*
* It is needed for COUNT_ARGS macro
*
*******************************************************************************
*/
#define EXPAND(x) x
/**
*******************************************************************************
* GET_TENTH_ARG
*
* @brief
* Auxilary Macro for COUNT_ARGS macro
*
*******************************************************************************
*/
#define GET_TENTH_ARG(a, b, c, d, e, f, g, h, i, j, name, ...) name
/**
*******************************************************************************
* COUNT_ARGS
*
* @brief
* Macro returns number of arguments actually passed into it
*
* COUNT_ARGS macro works ok for 1..10 arguments
* It is needed to distinguish macro call with optional parameters and without them
*******************************************************************************
*/
#define COUNT_ARGS(...) EXPAND(GET_TENTH_ARG(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
/**
*******************************************************************************
* AMFTraceW
*
* @brief
* General trace function with all possible parameters
*******************************************************************************
*/
void AMF_CDECL_CALL AMFTraceW(const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope,
amf_int32 countArgs, const wchar_t* format, ...);
/**
*******************************************************************************
* AMFTrace
*
* @brief
* Most general macro for trace, incapsulates passing source file and line
*******************************************************************************
*/
#define AMFTrace(level, scope, /*format, */...) amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, level, scope, COUNT_ARGS(__VA_ARGS__) - 1, __VA_ARGS__)
/**
*******************************************************************************
* AMFTraceError
*
* @brief
* Shortened macro to trace exactly error.
*
* Similar macroses are: AMFTraceWarning, AMFTraceInfo, AMFTraceDebug
*******************************************************************************
*/
#define AMFTraceError(scope, /*format, */...) amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, AMF_TRACE_ERROR, scope, COUNT_ARGS(__VA_ARGS__) - 1, __VA_ARGS__)
#define AMFTraceWarning(scope, /*format, */...) amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, AMF_TRACE_WARNING, scope, COUNT_ARGS(__VA_ARGS__) - 1, __VA_ARGS__)
#define AMFTraceInfo(scope, /*format, */...) amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, AMF_TRACE_INFO, scope, COUNT_ARGS(__VA_ARGS__) - 1, __VA_ARGS__)
#define AMFTraceDebug(scope, /*format, */...) amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, AMF_TRACE_DEBUG, scope, COUNT_ARGS(__VA_ARGS__) - 1, __VA_ARGS__)
/**
*******************************************************************************
* AMFDebugHitEvent
*
* @brief
* Designed to determine how many are specific events take place
*******************************************************************************
*/
void AMF_CDECL_CALL AMFDebugHitEvent(const wchar_t* scope, const wchar_t* eventName);
/**
*******************************************************************************
* AMFDebugGetEventsCount
*
* @brief
* Designed to acquire counter of events reported by call AMFDebugHitEvent
*******************************************************************************
*/
amf_int64 AMF_CDECL_CALL AMFDebugGetEventsCount(const wchar_t* scope, const wchar_t* eventName);
/**
*******************************************************************************
* AMFAssertsEnabled
*
* @brief
* Returns bool values indicating if asserts were enabled or not
*******************************************************************************
*/
bool AMF_CDECL_CALL AMFAssertsEnabled();
/**
*******************************************************************************
* AMFTraceEnterScope
*
* @brief
* Increase trace indentation value by 1
*
* Indentation value is thread specific
*******************************************************************************
*/
void AMF_CDECL_CALL AMFTraceEnterScope();
/**
*******************************************************************************
* AMFTraceExitScope
*
* @brief
* Decrease trace indentation value by 1
*
* Indentation value is thread specific
*******************************************************************************
*/
void AMF_CDECL_CALL AMFTraceExitScope();
/**
*******************************************************************************
* AMF_FACILITY
*
* @brief
* Default value for AMF_FACILITY, this NULL leads to generate facility from source file name
*
* This AMF_FACILITY could be overloaded locally with #define AMF_FACILITY L"LocalScope"
*******************************************************************************
*/
static const wchar_t* AMF_FACILITY = NULL;
} //extern "C"
/**
*******************************************************************************
* AMFDebugBreak
*
* @brief
* Macro for switching to debug of application
*******************************************************************************
*/
#if defined(_DEBUG)
#if defined(_WIN32)
#define AMFDebugBreak {if(amf::AMFAssertsEnabled()) {__debugbreak();} \
} //{ }
#elif defined(__linux)
// #define AMFDebugBreak ((void)0)
#define AMFDebugBreak {if(amf::AMFAssertsEnabled() && ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) {raise(SIGTRAP);} \
}//{ }
#elif defined(__APPLE__)
#define AMFDebugBreak {if(amf::AMFAssertsEnabled()) {assert(0);} \
}
#endif
#else
#define AMFDebugBreak
#endif
/**
*******************************************************************************
* __FormatMessage
*
* @brief
* Auxilary function to select from 2 messages and preformat message if any arguments are specified
*******************************************************************************
*/
inline amf_wstring __FormatMessage(int /*argsCount*/, const wchar_t* expression)
{
return amf_wstring(expression); // the only expression is provided - return this one
}
inline amf_wstring __FormatMessage(int argsCount, const wchar_t* /*expression*/, const wchar_t* message, ...)
{
// this version of __FormatMessage for case when descriptive message is provided with optional args
if(argsCount <= 0)
{
return amf_wstring(message);
}
else
{
va_list arglist;
va_start(arglist, message);
amf_wstring result = amf::amf_string_formatVA(message, arglist);
va_end(arglist);
return result;
}
}
/**
*******************************************************************************
* AMF_FIRST_VALUE
*
* @brief
* Auxilary macro: extracts first argument from the list
*******************************************************************************
*/
#define AMF_FIRST_VALUE(x, ...) x
/**
*******************************************************************************
* AMF_BASE_RETURN
*
* @brief
* Base generic macro: checks expression for success, if failed: trace error, debug break and return an error
*
* return_result is a parameter to return to upper level, could be hard-coded or
* specified exp_res what means pass inner level error
*******************************************************************************
*/
#define AMF_BASE_RETURN(exp, exp_type, check_func, format_prefix, level, scope, return_result/*(could be exp_res)*/, /* optional message args*/ ...) \
{ \
exp_type exp_res = (exp_type)(exp); \
if(!check_func(exp_res)) \
{ \
amf_wstring message = format_prefix(exp_res) + amf::__FormatMessage(COUNT_ARGS(__VA_ARGS__) - 2, __VA_ARGS__); \
EXPAND(amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, level, scope, 0, message.c_str()) ); \
AMFDebugBreak; \
return return_result; \
} \
}
/**
*******************************************************************************
* AMF_BASE_ASSERT
*
* @brief
* Base generic macro: checks expression for success, if failed: trace error, debug break
*******************************************************************************
*/
#define AMF_BASE_ASSERT(exp, exp_type, check_func, format_prefix, level, scope, return_result/*(could be exp_res)*/, /*optional message, optional message args*/ ...) \
{ \
exp_type exp_res = (exp_type)(exp); \
if(!check_func(exp_res)) \
{ \
amf_wstring message = format_prefix(exp_res) + amf::__FormatMessage(COUNT_ARGS(__VA_ARGS__) - 2, __VA_ARGS__); \
EXPAND(amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, level, scope, 0, message.c_str()) ); \
AMFDebugBreak; \
} \
}
/**
*******************************************************************************
* AMF_BASE_CALL
*
* @brief
* Macro supporting cascade call function returning AMF_RESULT from another
*
* return_result is a parameter to return to upper level, could be hard-coded or
* specified exp_res what means pass inner level error
*******************************************************************************
*/
#define AMF_BASE_CALL(exp, exp_type, check_func, format_prefix, level, scope, return_result/*(could be exp_res)*/, /*optional message, optional message args*/ ...) \
{ \
amf_wstring function_name = amf::__FormatMessage(COUNT_ARGS(__VA_ARGS__) - 2, __VA_ARGS__); \
amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, AMF_TRACE_DEBUG, scope, 0, function_name.c_str()); \
amf::AMFTraceEnterScope(); \
exp_type exp_res = (exp_type)(exp); \
amf::AMFTraceExitScope(); \
if(!check_func(exp_res)) \
{ \
amf_wstring message = format_prefix(exp_res) + function_name; \
EXPAND(amf::AMFTraceW(AMF_UNICODE(__FILE__), __LINE__, level, scope, 0, message.c_str()) ); \
AMFDebugBreak; \
return return_result; \
} \
}
/**
*******************************************************************************
* AMFCheckExpression
*
* @brief
* Checks if result succeeds
*******************************************************************************
*/
inline bool AMFCheckExpression(int result) { return result != 0; }
/**
*******************************************************************************
* AMFFormatAssert
*
* @brief
* Returns default assertion message
*******************************************************************************
*/
inline amf_wstring AMFFormatAssert(int result) { return result ? amf_wstring() : amf_wstring(L"Assertion failed:"); }
/**
*******************************************************************************
* AMFOpenCLSucceeded
*
* @brief
* Checks cl_status for success
*******************************************************************************
*/
inline bool AMFOpenCLSucceeded(int result) { return result == 0; }
/**
*******************************************************************************
* AMFFormatOpenCLError
*
* @brief
* Formats open CL error
*******************************************************************************
*/
inline amf_wstring AMFFormatOpenCLError(int result) { return amf::amf_string_format(L"OpenCL failed, error = %d:", result); }
/**
*******************************************************************************
* AMFResultIsOK
*
* @brief
* Checks if AMF_RESULT is OK
*******************************************************************************
*/
inline bool AMFResultIsOK(AMF_RESULT result) { return result == AMF_OK; }
/**
*******************************************************************************
* AMFSucceeded
*
* @brief
* Checks if AMF_RESULT is succeeded
*******************************************************************************
*/
inline bool AMFSucceeded(AMF_RESULT result) { return result == AMF_OK || result == AMF_REPEAT; }
/**
*******************************************************************************
* AMFFormatResult
*
* @brief
* Formats AMF_RESULT into descriptive string
*******************************************************************************
*/
amf_wstring AMF_CDECL_CALL AMFFormatResult(AMF_RESULT result);
/**
*******************************************************************************
* AMFHResultSucceded
*
* @brief
* Checks if HRESULT succeeded
*******************************************************************************
*/
inline bool AMFHResultSucceded(HRESULT result) { return SUCCEEDED(result); }
/**
*******************************************************************************
* AMFFormatHResult
*
* @brief
* Formats HRESULT into descriptive string
*******************************************************************************
*/
inline amf_wstring AMFFormatHResult(HRESULT result) { return amf::amf_string_format(L"COM failed, HR = 0x%0X:", result); }
/**
*******************************************************************************
* AMFVkResultSucceeded
*
* @brief
* Checks if VkResult succeeded
*******************************************************************************
*/
inline bool AMFVkResultSucceeded(int result) { return result == 0; }
/**
*******************************************************************************
* AMFFormatVkResult
*
* @brief
* Formats VkResult into descriptive string
*******************************************************************************
*/
inline amf_wstring AMFFormatVkResult(int result) { return amf::amf_string_format(L"Vulkan failed, VkResult = %d:", result); }
/**
*******************************************************************************
* AMF_CALL
*
* @brief
* Macro to call AMF_RESULT returning function from AMF_RESULT returning function
*
* It does:
* 1) Trace (level == debug) function name (or message if specified)
* 2) Indent trace
* 3) Call function
* 4) Unindent trace
* 5) Checks its result
* 6) If not OK trace error, switch to debugger (if asserts enabled) and return that error code to upper level
*
* Use cases:
* A) AMF_CALL(Init("Name")); // trace expression itself
* B) AMF_CALL(Init("Name"), L"Initialize resources"); // trace desciptive message
* C) AMF_CALL(Init(name), L"Initialize resources with %s", name); // trace descriptive message with aditional arguments from runtime
*******************************************************************************
*/
#define AMF_CALL(exp, ... /*optional format, args*/) AMF_BASE_CALL(exp, AMF_RESULT, amf::AMFResultIsOK, amf::AMFFormatResult, AMF_TRACE_ERROR, AMF_FACILITY, exp_res, L###exp, ##__VA_ARGS__)
/**
*******************************************************************************
* AMF_ASSERT_OK
*
* @brief
* Checks expression == AMF_OK, otherwise trace error and debug break
*
* Could be used: A) with just expression B) with optinal descriptive message C) message + args for printf
*******************************************************************************
*/
#define AMF_ASSERT_OK(exp, ... /*optional format, args*/) AMF_BASE_ASSERT(exp, AMF_RESULT, amf::AMFResultIsOK, amf::AMFFormatResult, AMF_TRACE_ERROR, AMF_FACILITY, AMF_FAIL, L###exp, ##__VA_ARGS__)
/**
*******************************************************************************
* AMF_ASSERT
*
* @brief
* Checks expression != 0, otherwise trace error and debug break
*
* Could be used: A) with just expression B) with optinal descriptive message C) message + args for printf
*******************************************************************************
*/
#define AMF_ASSERT(exp, ...) AMF_BASE_ASSERT(exp, int, amf::AMFCheckExpression, amf::AMFFormatAssert, AMF_TRACE_ERROR, AMF_FACILITY, AMF_FAIL, L###exp, ##__VA_ARGS__)
/**
*******************************************************************************
* AMF_RETURN_IF_FAILED
*
* @brief
* Checks expression != 0, otherwise trace error, debug break and return that error to upper level
*
* Could be used: A) with just expression B) with optinal descriptive message C) message + args for printf
*******************************************************************************
*/
#define AMF_RETURN_IF_FAILED(exp, ...) AMF_BASE_RETURN(exp, AMF_RESULT, amf::AMFResultIsOK, amf::AMFFormatResult, AMF_TRACE_ERROR, AMF_FACILITY, exp_res, L###exp, ##__VA_ARGS__)
/**
*******************************************************************************
* ASSERT_RETURN_IF_CL_FAILED
*
* @brief
* Checks cl error is ok, otherwise trace error, debug break and return that error to upper level
*
* Could be used: A) with just expression B) with optinal descriptive message C) message + args for printf
*******************************************************************************
*/
#define ASSERT_RETURN_IF_CL_FAILED(exp, /*optional format, args,*/...) AMF_BASE_RETURN(exp, int, amf::AMFOpenCLSucceeded, amf::AMFFormatOpenCLError, AMF_TRACE_ERROR, AMF_FACILITY, AMF_OPENCL_FAILED, L###exp, ##__VA_ARGS__)
#define AMF_RETURN_IF_CL_FAILED(exp, /*optional format, args,*/...) AMF_BASE_RETURN(exp, int, amf::AMFOpenCLSucceeded, amf::AMFFormatOpenCLError, AMF_TRACE_ERROR, AMF_FACILITY, AMF_OPENCL_FAILED, L###exp, ##__VA_ARGS__)
/**
*******************************************************************************
* ASSERT_RETURN_IF_HR_FAILED
*
* @brief
* Obsolete macro: Checks HRESULT if succeeded, otherwise trace error, debug break and return specified error to upper level
*
* Other macroses below are also obsolete
*******************************************************************************
*/
#define ASSERT_RETURN_IF_HR_FAILED(exp, reterr, /*optional format, args,*/...) AMF_BASE_RETURN(exp, HRESULT, amf::AMFHResultSucceded, amf::AMFFormatHResult, AMF_TRACE_ERROR, AMF_FACILITY, reterr, L###exp, ##__VA_ARGS__)
/**
*******************************************************************************
* ASSERT_RETURN_IF_VK_FAILED
*
* @brief
* Checks VkResult if succeeded, otherwise trace error, debug break and return specified error to upper level
*
* Could be used: A) with just expression B) with optinal descriptive message C) message + args for printf
*******************************************************************************
*/
#define ASSERT_RETURN_IF_VK_FAILED(exp, reterr, /*optional format, args,*/...) AMF_BASE_RETURN(exp, int, amf::AMFVkResultSucceeded, amf::AMFFormatVkResult, AMF_TRACE_ERROR, AMF_FACILITY, reterr, L###exp, ##__VA_ARGS__)
/**
*******************************************************************************
* AMF_RETURN_IF_FALSE
*
* @brief
* Checks expression != 0, otherwise trace error, debug break and return that error to upper level
*
* Could be used: A) with just expression B) with optinal descriptive message C) message + args for printf
*******************************************************************************
*/
#define AMF_RETURN_IF_FALSE(exp, ret_value, /*optional message,*/ ...) AMF_BASE_RETURN(exp, int, amf::AMFCheckExpression, amf::AMFFormatAssert, AMF_TRACE_ERROR, AMF_FACILITY, ret_value, L###exp, ##__VA_ARGS__)
/**
*******************************************************************************
* AMF_RETURN_IF_INVALID_POINTER
*
* @brief
* Checks ptr != NULL, otherwise trace error, debug break and return that error to upper level
*
*******************************************************************************
*/
#define AMF_RETURN_IF_INVALID_POINTER(ptr, /*optional message,*/ ...) AMF_BASE_RETURN(ptr != NULL, int, amf::AMFCheckExpression, amf::AMFFormatAssert, AMF_TRACE_ERROR, AMF_FACILITY, AMF_INVALID_POINTER, L"invalid pointer : " L###ptr, ##__VA_ARGS__)
/**
*******************************************************************************
* AMFTestEventObserver
*
* @brief
* Interface to subscribe on test events
*******************************************************************************
*/
extern "C"
{
/**
*******************************************************************************
* AMFTraceSetPath
*
* @brief
* Set Trace path
*
* Returns AMF_OK if succeeded
*******************************************************************************
*/
AMF_RESULT AMF_CDECL_CALL AMFTraceSetPath(const wchar_t* path);
/**
*******************************************************************************
* AMFTraceGetPath
*
* @brief
* Get Trace path
*
* Returns AMF_OK if succeeded
*******************************************************************************
*/
AMF_RESULT AMF_CDECL_CALL AMFTraceGetPath(
wchar_t* path, ///< [out] buffer able to hold *pSize symbols; path is copied there, at least part fitting the buffer, always terminator is copied
amf_size* pSize ///< [in, out] size of buffer, returned needed size of buffer including zero terminator
);
/**
*******************************************************************************
* AMFTraceEnableWriter
*
* @brief
* Disable trace to registered writer
*
* Returns previous state
*******************************************************************************
*/
bool AMF_CDECL_CALL AMFTraceEnableWriter(const wchar_t* writerID, bool enable);
/**
*******************************************************************************
* AMFTraceWriterEnabled
*
* @brief
* Return flag if writer enabled
*******************************************************************************
*/
bool AMF_CDECL_CALL AMFTraceWriterEnabled(const wchar_t* writerID);
/**
*******************************************************************************
* AMFTraceSetGlobalLevel
*
* @brief
* Sets trace level for writer and scope
*
* Returns previous setting
*******************************************************************************
*/
amf_int32 AMF_CDECL_CALL AMFTraceSetGlobalLevel(amf_int32 level);
/**
*******************************************************************************
* AMFTraceGetGlobalLevel
*
* @brief
* Returns global level
*******************************************************************************
*/
amf_int32 AMF_CDECL_CALL AMFTraceGetGlobalLevel();
/**
*******************************************************************************
* AMFTraceSetWriterLevel
*
* @brief
* Sets trace level for writer
*
* Returns previous setting
*******************************************************************************
*/
amf_int32 AMF_CDECL_CALL AMFTraceSetWriterLevel(const wchar_t* writerID, amf_int32 level);
/**
*******************************************************************************
* AMFTraceGetWriterLevel
*
* @brief
* Gets trace level for writer
*******************************************************************************
*/
amf_int32 AMF_CDECL_CALL AMFTraceGetWriterLevel(const wchar_t* writerID);
/**
*******************************************************************************
* AMFTraceSetWriterLevelForScope
*
* @brief
* Sets trace level for writer and scope
*
* Returns previous setting
*******************************************************************************
*/
amf_int32 AMF_CDECL_CALL AMFTraceSetWriterLevelForScope(const wchar_t* writerID, const wchar_t* scope, amf_int32 level);
/**
*******************************************************************************
* AMFTraceGetWriterLevelForScope
*
* @brief
* Gets trace level for writer and scope
*******************************************************************************
*/
amf_int32 AMF_CDECL_CALL AMFTraceGetWriterLevelForScope(const wchar_t* writerID, const wchar_t* scope);
/**
*******************************************************************************
* AMFTraceRegisterWriter
*
* @brief
* Register custom trace writer
*
*******************************************************************************
*/
void AMF_CDECL_CALL AMFTraceRegisterWriter(const wchar_t* writerID, AMFTraceWriter* pWriter);
/**
*******************************************************************************
* AMFTraceUnregisterWriter
*
* @brief
* Register custom trace writer
*
*******************************************************************************
*/
void AMF_CDECL_CALL AMFTraceUnregisterWriter(const wchar_t* writerID);
/*
*******************************************************************************
* AMFAssertsEnable
*
* @brief
* Enable asserts in checks
*
*******************************************************************************
*/
void AMF_CDECL_CALL AMFAssertsEnable(bool enable);
/**
*******************************************************************************
* AMFAssertsEnabled
*
* @brief
* Returns true if asserts in checks enabled
*
*******************************************************************************
*/
bool AMF_CDECL_CALL AMFAssertsEnabled();
const wchar_t* AMF_STD_CALL AMFGetResultText(AMF_RESULT res);
const wchar_t* AMF_STD_CALL AMFSurfaceGetFormatName(const AMF_SURFACE_FORMAT eSurfaceFormat);
AMF_SURFACE_FORMAT AMF_STD_CALL AMFSurfaceGetFormatByName(const wchar_t* pwName);
const wchar_t* AMF_STD_CALL AMFGetMemoryTypeName(const AMF_MEMORY_TYPE memoryType);
AMF_MEMORY_TYPE AMF_STD_CALL AMFGetMemoryTypeByName(const wchar_t* name);
} //extern "C"
} // namespace amf
#endif // AMF_TraceAdapter_h

View File

@@ -0,0 +1,230 @@
//
// 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.
//
#include "VirtualMicrophoneAudioInput.h"
#include "public/common/TraceAdapter.h"
#if defined(_WIN32)
//-------------------------------------------------------------------------------------------------
#define AMF_FACILITY L"VirtualMicrophoneAudioInput"
//-------------------------------------------------------------------------------------------------
VirtualMicrophoneAudioInput::VirtualMicrophoneAudioInput():
m_pAudioManager (nullptr),
m_pVirtualAudioInput (nullptr)
#ifdef WIN32
, m_bCoInitializeSucceeded(false)
#endif
{
}
//-------------------------------------------------------------------------------------------------
VirtualMicrophoneAudioInput::~VirtualMicrophoneAudioInput()
{
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::Init()
{
AMF_RESULT res = AMF_FAIL;
#ifdef WIN32
HRESULT hr = CoInitialize(nullptr);
m_bCoInitializeSucceeded = SUCCEEDED(hr);
AMFCreateVirtualAudioManager_Fn pAudioFun = (AMFCreateVirtualAudioManager_Fn)amf_get_proc_address(g_AMFFactory.GetAMFDLLHandle(), AMF_CREATE_VIRTUAL_AUDIO_MANAGER_FUNCTION_NAME);
AMF_RETURN_IF_FALSE(pAudioFun != nullptr, AMF_FAIL, L"AMFCreateVirtualAudioManager() is not availalbe in AMF DLL");
res = pAudioFun(AMF_FULL_VERSION, nullptr, &m_pAudioManager);
AMF_RETURN_IF_FAILED(res, L"AMFCreateVirtualAudioManager() failed");
#endif
if (res == AMF_OK)
{
res = CreateVirtualAudioInput();
}
if (res != AMF_OK)
{
Terminate();
}
return res;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::CreateVirtualAudioInput()
{
AMF_RESULT res = AMF_OK;
res = m_pAudioManager->CreateInput(&m_pVirtualAudioInput);
AMF_RETURN_IF_FAILED(res, L"CreateInput() failed");
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::DestroyVirtualAudioInput()
{
AMF_RESULT res = AMF_OK;
if (nullptr != m_pVirtualAudioInput)
{
m_pVirtualAudioInput.Release();
}
AMF_RETURN_IF_FAILED(res, L"CreateInput() failed");
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::Terminate()
{
DestroyVirtualAudioInput();
if (nullptr != m_pAudioManager)
{
m_pAudioManager.Release();
}
#ifdef WIN32
if (m_bCoInitializeSucceeded)
{
::CoUninitialize();
m_bCoInitializeSucceeded = false;
}
#endif
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::EnableInput()
{
AMF_RESULT res = AMF_OK;
res = m_pVirtualAudioInput->SetStatus(amf::AMF_VAS_CONNECTED);
AMF_RETURN_IF_FAILED(res, L"SetStatus(amf::AMF_VAS_CONNECTED) failed");
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::CheckStatus()
{
amf::AMF_VIRTUAL_AUDIO_STATUS status = m_pVirtualAudioInput->GetStatus();
switch (status)
{
case amf::AMF_VAS_UNKNOWN:
AMFTraceInfo(AMF_FACILITY, L"Virtual Audio Input status: UNKNOWN");
break;
case amf::AMF_VAS_CONNECTED:
AMFTraceInfo(AMF_FACILITY, L"Virtual Audio Input status: CONNECTED");
break;
case amf::AMF_VAS_DISCONNECTED:
AMFTraceInfo(AMF_FACILITY, L"Virtual Audio Input status: DISCONNECTED");
break;
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::CheckFormat()
{
AMF_RESULT res = AMF_OK;
amf::AMFVirtualAudioFormat format = {};
res = m_pVirtualAudioInput->GetFormat(&format);
AMF_RETURN_IF_FAILED(res, L"GetFormat() failed");
AMFTraceInfo(AMF_FACILITY, L"Virtual Audio Input format: SampleRate=%d channels=%d sampleSize=%d", format.sampleRate, format.channelCount, format.sampleSize);
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::ChangeInputParameters(amf_int64 sampleRate, amf_int64 channelCount, amf_int64 audioFormat)
{
amf_int32 bytesInSample = 2;
switch (audioFormat)
{
case AMFAF_U8: bytesInSample = 1; break;
case AMFAF_S16: bytesInSample = 2; break;
case AMFAF_S32: bytesInSample = 4; break;
case AMFAF_FLT: bytesInSample = 4; break;
case AMFAF_DBL: bytesInSample = 8; break;
case AMFAF_U8P: bytesInSample = 1; break;
case AMFAF_S16P: bytesInSample = 2; break;
case AMFAF_S32P: bytesInSample = 4; break;
case AMFAF_FLTP: bytesInSample = 4; break;
case AMFAF_DBLP: bytesInSample = 8; break;
}
amf::AMFVirtualAudioFormat audioformat = {
static_cast<amf_int32>(sampleRate & 0xFFFFFFFF),
static_cast<amf_int32>(channelCount & 0xFFFFFFFF),
bytesInSample };
return ChangeInputParameters(&audioformat);
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::ChangeInputParameters(amf::AMFVirtualAudioFormat* format)
{
AMF_RESULT res = AMF_OK;
res = m_pVirtualAudioInput->SetFormat(format);
AMF_RETURN_IF_FAILED(res, L"SetFormat() failed");
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::VerifyInputParameters(amf::AMFVirtualAudioFormat* formatVer)
{
AMF_RESULT res = AMF_OK;
amf::AMFVirtualAudioFormat format = {};
res = m_pVirtualAudioInput->GetFormat(&format);
AMF_RETURN_IF_FAILED(res, L"GetFormat() failed");
// AMF_RETURN_IF_FALSE(format.sampleRate == formatVer->sampleRate && format.channelCount == formatVer->channelCount && format.sampleSize == formatVer->sampleSize, AMF_FAIL, L"Formats dont match" );
if (format.sampleRate == formatVer->sampleRate && format.channelCount == formatVer->channelCount && format.sampleSize == formatVer->sampleSize)
{
return AMF_OK;
}
AMFTraceError(AMF_FACILITY, L"Formats dont match");
return AMF_FAIL;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::DisableInput()
{
AMF_RESULT res = AMF_OK;
res = m_pVirtualAudioInput->SetStatus(amf::AMF_VAS_DISCONNECTED);
AMF_RETURN_IF_FAILED(res, L"SetStatus(amf::AMF_VAS_DISCONNECTED) failed");
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::SubmitInput(amf::AMFAudioBufferPtr pAudioBuffer)
{
return SubmitData(pAudioBuffer->GetNative(), pAudioBuffer->GetSize());
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VirtualMicrophoneAudioInput::SubmitData(const void* data, amf_size sizeInBytes)
{
AMF_RESULT res = AMF_OK;
if (nullptr != m_pVirtualAudioInput)
{
return m_pVirtualAudioInput->SubmitData(data, sizeInBytes);
}
return res;
}
#endif // #if defined(_WIN32)

View File

@@ -0,0 +1,87 @@
//
// 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.
//
#pragma once
#if defined(_WIN32)
#include <tchar.h>
#if defined(WIN32)
#include <conio.h>
#endif
#include <memory>
#include "public/include/core/Debug.h"
#include "public/common/TraceAdapter.h"
#include "public/common/AMFFactory.h"
#include "public/common/AMFMath.h"
#include "public/common/Thread.h"
#include "protected/include/components/VirtualAudio.h"
#include "public/common/ByteArray.h"
using namespace amf;
class VirtualMicrophoneAudioInput
{
public:
VirtualMicrophoneAudioInput();
~VirtualMicrophoneAudioInput();
AMF_RESULT Init();
AMF_RESULT Terminate();
AMF_RESULT EnableInput();
AMF_RESULT CheckStatus();
AMF_RESULT CheckFormat();
AMF_RESULT ChangeInputParameters(amf_int64 sampleRate,
amf_int64 channelCount,
amf_int64 audioFormat);
AMF_RESULT ChangeInputParameters(amf::AMFVirtualAudioFormat* format);
AMF_RESULT VerifyInputParameters(amf::AMFVirtualAudioFormat* format);
AMF_RESULT DisableInput();
AMF_RESULT SubmitInput(amf::AMFAudioBufferPtr pAudioBuffer);
AMF_RESULT SubmitData(const void* data, amf_size sizeInBytes);
protected:
amf::AMFVirtualAudioManagerPtr m_pAudioManager;
amf::AMFVirtualAudioInputPtr m_pVirtualAudioInput;
AMF_RESULT CreateVirtualAudioInput();
AMF_RESULT DestroyVirtualAudioInput();
#ifdef WIN32
bool m_bCoInitializeSucceeded;
#endif
};
typedef std::shared_ptr<VirtualMicrophoneAudioInput> VirtualMicrophoneAudioInputPtr;
#endif

View File

@@ -0,0 +1,451 @@
//
// 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 VulkanImportTable.cpp
/// @brief Vulkan import table
///-------------------------------------------------------------------------
#include "VulkanImportTable.h"
#include "public/common/TraceAdapter.h"
#include "Thread.h"
using namespace amf;
//-------------------------------------------------------------------------------------------------
//
#define GET_DLL_ENTRYPOINT(h, w) w = reinterpret_cast<PFN_##w>(amf_get_proc_address(h, #w)); if(w==nullptr) \
{ AMFTraceError(L"VulkanImportTable", L"Failed to aquire entrypoint %S", #w); return AMF_FAIL; };
#define GET_INSTANCE_ENTRYPOINT(i, w) w = reinterpret_cast<PFN_##w>(vkGetInstanceProcAddr(i, #w)); if(w==nullptr) \
{ AMFTraceError(L"VulkanImportTable", L"Failed to aquire entrypoint %S", #w); return AMF_FAIL; };
#define GET_INSTANCE_ENTRYPOINT_NORETURN(i, w) w = reinterpret_cast<PFN_##w>(vkGetInstanceProcAddr(i, #w));
#define GET_DEVICE_ENTRYPOINT(i, w) w = reinterpret_cast<PFN_##w>(vkGetDeviceProcAddr(i, #w)); if(w==nullptr) \
{ AMFTraceError(L"VulkanImportTable", L"Failed to aquire entrypoint %S", #w); return AMF_FAIL; };
#define GET_DEVICE_ENTRYPOINT_NORETURN(i, w) w = reinterpret_cast<PFN_##w>(vkGetDeviceProcAddr(i, #w)); if(w==nullptr) \
{ AMFTraceDebug(L"VulkanImportTable", L"Failed to aquire entrypoint %S", #w); };
VulkanImportTable::VulkanImportTable() :
m_hVulkanDll(nullptr),
vkCreateInstance(nullptr),
vkDestroyInstance(nullptr),
vkEnumeratePhysicalDevices(nullptr),
vkGetPhysicalDeviceFeatures(nullptr),
vkGetPhysicalDeviceFormatProperties(nullptr),
vkGetPhysicalDeviceImageFormatProperties(nullptr),
vkGetPhysicalDeviceProperties(nullptr),
vkGetPhysicalDeviceExternalSemaphoreProperties(nullptr),
vkGetPhysicalDeviceProperties2KHR(nullptr),
vkGetPhysicalDeviceQueueFamilyProperties(nullptr),
vkGetPhysicalDeviceQueueFamilyProperties2(nullptr),
vkGetPhysicalDeviceMemoryProperties(nullptr),
vkGetInstanceProcAddr(nullptr),
vkGetDeviceProcAddr(nullptr),
vkCreateDevice(nullptr),
vkDestroyDevice(nullptr),
vkEnumerateInstanceExtensionProperties(nullptr),
vkEnumerateDeviceExtensionProperties(nullptr),
vkEnumerateInstanceLayerProperties(nullptr),
vkEnumerateDeviceLayerProperties(nullptr),
vkGetDeviceQueue(nullptr),
vkQueueSubmit(nullptr),
vkQueueWaitIdle(nullptr),
vkDeviceWaitIdle(nullptr),
vkAllocateMemory(nullptr),
vkFreeMemory(nullptr),
vkMapMemory(nullptr),
vkUnmapMemory(nullptr),
vkFlushMappedMemoryRanges(nullptr),
vkInvalidateMappedMemoryRanges(nullptr),
vkGetDeviceMemoryCommitment(nullptr),
vkBindBufferMemory(nullptr),
vkBindImageMemory(nullptr),
vkGetBufferMemoryRequirements(nullptr),
vkGetImageMemoryRequirements(nullptr),
vkGetImageSparseMemoryRequirements(nullptr),
vkGetPhysicalDeviceSparseImageFormatProperties(nullptr),
vkQueueBindSparse(nullptr),
vkCreateFence(nullptr),
vkDestroyFence(nullptr),
vkResetFences(nullptr),
vkGetFenceStatus(nullptr),
vkWaitForFences(nullptr),
vkCreateSemaphore(nullptr),
vkDestroySemaphore(nullptr),
vkCreateEvent(nullptr),
vkDestroyEvent(nullptr),
vkGetEventStatus(nullptr),
vkSetEvent(nullptr),
vkResetEvent(nullptr),
vkCreateQueryPool(nullptr),
vkDestroyQueryPool(nullptr),
vkGetQueryPoolResults(nullptr),
vkCreateBuffer(nullptr),
vkDestroyBuffer(nullptr),
vkCreateBufferView(nullptr),
vkDestroyBufferView(nullptr),
vkCreateImage(nullptr),
vkDestroyImage(nullptr),
vkGetImageSubresourceLayout(nullptr),
vkCreateImageView(nullptr),
vkDestroyImageView(nullptr),
vkCreateShaderModule(nullptr),
vkDestroyShaderModule(nullptr),
vkCreatePipelineCache(nullptr),
vkDestroyPipelineCache(nullptr),
vkGetPipelineCacheData(nullptr),
vkMergePipelineCaches(nullptr),
vkCreateGraphicsPipelines(nullptr),
vkCreateComputePipelines(nullptr),
vkDestroyPipeline(nullptr),
vkCreatePipelineLayout(nullptr),
vkDestroyPipelineLayout(nullptr),
vkCreateSampler(nullptr),
vkDestroySampler(nullptr),
vkCreateDescriptorSetLayout(nullptr),
vkDestroyDescriptorSetLayout(nullptr),
vkCreateDescriptorPool(nullptr),
vkDestroyDescriptorPool(nullptr),
vkResetDescriptorPool(nullptr),
vkAllocateDescriptorSets(nullptr),
vkFreeDescriptorSets(nullptr),
vkUpdateDescriptorSets(nullptr),
vkCreateFramebuffer(nullptr),
vkDestroyFramebuffer(nullptr),
vkCreateRenderPass(nullptr),
vkDestroyRenderPass(nullptr),
vkGetRenderAreaGranularity(nullptr),
vkCreateCommandPool(nullptr),
vkDestroyCommandPool(nullptr),
vkResetCommandPool(nullptr),
vkAllocateCommandBuffers(nullptr),
vkFreeCommandBuffers(nullptr),
vkBeginCommandBuffer(nullptr),
vkEndCommandBuffer(nullptr),
vkResetCommandBuffer(nullptr),
vkCmdBindPipeline(nullptr),
vkCmdSetViewport(nullptr),
vkCmdSetScissor(nullptr),
vkCmdSetLineWidth(nullptr),
vkCmdSetDepthBias(nullptr),
vkCmdSetBlendConstants(nullptr),
vkCmdSetDepthBounds(nullptr),
vkCmdSetStencilCompareMask(nullptr),
vkCmdSetStencilWriteMask(nullptr),
vkCmdSetStencilReference(nullptr),
vkCmdBindDescriptorSets(nullptr),
vkCmdBindIndexBuffer(nullptr),
vkCmdBindVertexBuffers(nullptr),
vkCmdDraw(nullptr),
vkCmdDrawIndexed(nullptr),
vkCmdDrawIndirect(nullptr),
vkCmdDrawIndexedIndirect(nullptr),
vkCmdDispatch(nullptr),
vkCmdDispatchIndirect(nullptr),
vkCmdCopyBuffer(nullptr),
vkCmdCopyImage(nullptr),
vkCmdBlitImage(nullptr),
vkCmdCopyBufferToImage(nullptr),
vkCmdCopyImageToBuffer(nullptr),
vkCmdUpdateBuffer(nullptr),
vkCmdFillBuffer(nullptr),
vkCmdClearColorImage(nullptr),
vkCmdClearDepthStencilImage(nullptr),
vkCmdClearAttachments(nullptr),
vkCmdResolveImage(nullptr),
vkCmdSetEvent(nullptr),
vkCmdResetEvent(nullptr),
vkCmdWaitEvents(nullptr),
vkCmdPipelineBarrier(nullptr),
vkCmdBeginQuery(nullptr),
vkCmdEndQuery(nullptr),
vkCmdResetQueryPool(nullptr),
vkCmdWriteTimestamp(nullptr),
vkCmdCopyQueryPoolResults(nullptr),
vkCmdPushConstants(nullptr),
vkCmdBeginRenderPass(nullptr),
vkCmdNextSubpass(nullptr),
vkCmdEndRenderPass(nullptr),
vkCmdExecuteCommands(nullptr),
vkGetPhysicalDeviceFeatures2(nullptr),
vkDestroySurfaceKHR(nullptr),
vkGetPhysicalDeviceSurfaceSupportKHR(nullptr),
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(nullptr),
vkGetPhysicalDeviceSurfaceFormatsKHR(nullptr),
vkGetPhysicalDeviceSurfacePresentModesKHR(nullptr),
vkCreateSwapchainKHR(nullptr),
vkDestroySwapchainKHR(nullptr),
vkGetSwapchainImagesKHR(nullptr),
vkAcquireNextImageKHR(nullptr),
vkQueuePresentKHR(nullptr),
#if defined(__linux)
vkGetMemoryFdKHR(nullptr),
vkImportSemaphoreFdKHR(nullptr),
vkGetSemaphoreFdKHR(nullptr),
#endif
#if defined(VK_USE_PLATFORM_WIN32_KHR)
vkCreateWin32SurfaceKHR(nullptr),
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
vkCreateXlibSurfaceKHR(nullptr),
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
vkCreateAndroidSurfaceKHR(nullptr),
#endif
vkGetMemoryHostPointerPropertiesEXT(nullptr),
vkCreateDebugReportCallbackEXT(nullptr),
vkDebugReportMessageEXT(nullptr),
vkDestroyDebugReportCallbackEXT(nullptr)
{
}
VulkanImportTable::~VulkanImportTable()
{
if (m_hVulkanDll != nullptr)
{
amf_free_library(m_hVulkanDll);
}
m_hVulkanDll = nullptr;
}
AMF_RESULT VulkanImportTable::LoadFunctionsTable()
{
if (m_hVulkanDll != nullptr)
{
return AMF_OK;
}
#if defined(_WIN32)
m_hVulkanDll = amf_load_library(L"vulkan-1.dll");
#elif defined(__ANDROID__)
m_hVulkanDll = amf_load_library1(L"libvulkan.so", true);
#elif defined(__linux__)
m_hVulkanDll = amf_load_library1(L"libvulkan.so.1", true);
#endif
if (m_hVulkanDll == nullptr)
{
AMFTraceError(L"VulkanImportTable", L"amf_load_library() failed to load vulkan dll!");
return AMF_FAIL;
}
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateInstance);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateInstance);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyInstance);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkEnumeratePhysicalDevices);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceFeatures);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceFormatProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceImageFormatProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceExternalSemaphoreProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceQueueFamilyProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceQueueFamilyProperties2);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceMemoryProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetInstanceProcAddr);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetDeviceProcAddr);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateDevice);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyDevice);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkEnumerateInstanceExtensionProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkEnumerateDeviceExtensionProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkEnumerateInstanceLayerProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkEnumerateDeviceLayerProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetDeviceQueue);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkQueueSubmit);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkQueueWaitIdle);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDeviceWaitIdle);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkAllocateMemory);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkFreeMemory);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkMapMemory);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkUnmapMemory);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkFlushMappedMemoryRanges);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkInvalidateMappedMemoryRanges);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetDeviceMemoryCommitment);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkBindBufferMemory);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkBindImageMemory);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetBufferMemoryRequirements);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetImageMemoryRequirements);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetImageSparseMemoryRequirements);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceSparseImageFormatProperties);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkQueueBindSparse);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateFence);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyFence);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkResetFences);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetFenceStatus);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkWaitForFences);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateSemaphore);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroySemaphore);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateEvent);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyEvent);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetEventStatus);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkSetEvent);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkResetEvent);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateQueryPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyQueryPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetQueryPoolResults);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateBufferView);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyBufferView);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateImage);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyImage);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetImageSubresourceLayout);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateImageView);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyImageView);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateShaderModule);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyShaderModule);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreatePipelineCache);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyPipelineCache);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPipelineCacheData);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkMergePipelineCaches);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateGraphicsPipelines);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateComputePipelines);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyPipeline);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreatePipelineLayout);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyPipelineLayout);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateSampler);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroySampler);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateDescriptorSetLayout);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyDescriptorSetLayout);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateDescriptorPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyDescriptorPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkResetDescriptorPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkAllocateDescriptorSets);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkFreeDescriptorSets);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkUpdateDescriptorSets);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateFramebuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyFramebuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateRenderPass);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyRenderPass);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetRenderAreaGranularity);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateCommandPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroyCommandPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkResetCommandPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkAllocateCommandBuffers);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkFreeCommandBuffers);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkBeginCommandBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkEndCommandBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkResetCommandBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdBindPipeline);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetViewport);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetScissor);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetLineWidth);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetDepthBias);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetBlendConstants);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetDepthBounds);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetStencilCompareMask);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetStencilWriteMask);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetStencilReference);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdBindDescriptorSets);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdBindIndexBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdBindVertexBuffers);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdDraw);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdDrawIndexed);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdDrawIndirect);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdDrawIndexedIndirect);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdDispatch);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdDispatchIndirect);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdCopyBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdCopyImage);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdBlitImage);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdCopyBufferToImage);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdCopyImageToBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdUpdateBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdFillBuffer);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdClearColorImage);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdClearDepthStencilImage);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdClearAttachments);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdResolveImage);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdSetEvent);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdResetEvent);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdWaitEvents);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdPipelineBarrier);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdBeginQuery);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdEndQuery);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdResetQueryPool);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdWriteTimestamp);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdCopyQueryPoolResults);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdPushConstants);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdBeginRenderPass);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdNextSubpass);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdEndRenderPass);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCmdExecuteCommands);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceFeatures2);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceSurfaceSupportKHR);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceSurfaceFormatsKHR);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetPhysicalDeviceSurfacePresentModesKHR);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkDestroySurfaceKHR);
#if defined(VK_USE_PLATFORM_XLIB_KHR)
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateXlibSurfaceKHR);
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateAndroidSurfaceKHR);
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkGetAndroidHardwareBufferPropertiesANDROID);
#endif
return AMF_OK;
}
AMF_RESULT VulkanImportTable::LoadInstanceFunctionsTableExt(VkInstance instance, bool bDebug)
{
GET_INSTANCE_ENTRYPOINT(instance, vkGetPhysicalDeviceProperties2KHR);
if(bDebug)
{
GET_INSTANCE_ENTRYPOINT(instance, vkCreateDebugReportCallbackEXT);
GET_INSTANCE_ENTRYPOINT(instance, vkDebugReportMessageEXT);
GET_INSTANCE_ENTRYPOINT(instance, vkDestroyDebugReportCallbackEXT);
}
return AMF_OK;
}
//-------------------------------------------------------------------------------------------------
AMF_RESULT VulkanImportTable::LoadDeviceFunctionsTableExt(VkDevice device)
{
GET_DEVICE_ENTRYPOINT(device, vkCreateSwapchainKHR);
GET_DEVICE_ENTRYPOINT(device, vkDestroySwapchainKHR);
GET_DEVICE_ENTRYPOINT(device, vkGetSwapchainImagesKHR);
GET_DEVICE_ENTRYPOINT(device, vkAcquireNextImageKHR);
GET_DEVICE_ENTRYPOINT(device, vkQueuePresentKHR);
#if defined(VK_USE_PLATFORM_WIN32_KHR)
GET_DLL_ENTRYPOINT(m_hVulkanDll, vkCreateWin32SurfaceKHR);
#endif
#if defined(__linux)
GET_DEVICE_ENTRYPOINT(device, vkGetMemoryFdKHR);
GET_DEVICE_ENTRYPOINT(device, vkImportSemaphoreFdKHR);
GET_DEVICE_ENTRYPOINT(device, vkGetSemaphoreFdKHR);
#endif
GET_DEVICE_ENTRYPOINT_NORETURN(device, vkGetMemoryHostPointerPropertiesEXT); //< requires VK_EXT_external_memory_host
return AMF_OK;
}
#undef GET_DEVICE_ENTRYPOINT
#undef GET_INSTANCE_ENTRYPOINT
#undef GET_INSTANCE_ENTRYPOINT_NORETURN

View File

@@ -0,0 +1,246 @@
//
// 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 VulkanImportTable.h
/// @brief Vulkan import table
///-------------------------------------------------------------------------
#pragma once
#include "../include/core/Result.h"
#define VK_NO_PROTOTYPES
#ifdef _WIN32
#define VK_USE_PLATFORM_WIN32_KHR
#elif defined(__ANDROID__)
#define VK_USE_PLATFORM_ANDROID_KHR
#elif defined(__linux)
#if !defined(AMF_DISABLE_VK_USE_PLATFORM_XLIB_KHR)
#define VK_USE_PLATFORM_XLIB_KHR
#endif
#endif
#include "public/include/core/VulkanAMF.h"
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
#include "vulkan/vulkan_android.h"
#endif
//#define ENABLE_VALIDATION
struct VulkanImportTable
{
VulkanImportTable();
~VulkanImportTable();
AMF_RESULT LoadFunctionsTable();
AMF_RESULT LoadInstanceFunctionsTableExt(VkInstance instance, bool bDebug);
AMF_RESULT LoadDeviceFunctionsTableExt(VkDevice device);
// core Vulkan
PFN_vkCreateInstance vkCreateInstance;
PFN_vkDestroyInstance vkDestroyInstance;
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
PFN_vkGetPhysicalDeviceExternalSemaphoreProperties vkGetPhysicalDeviceExternalSemaphoreProperties;
PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
PFN_vkGetPhysicalDeviceQueueFamilyProperties2 vkGetPhysicalDeviceQueueFamilyProperties2;
PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
PFN_vkCreateDevice vkCreateDevice;
PFN_vkDestroyDevice vkDestroyDevice;
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
PFN_vkGetDeviceQueue vkGetDeviceQueue;
PFN_vkQueueSubmit vkQueueSubmit;
PFN_vkQueueWaitIdle vkQueueWaitIdle;
PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
PFN_vkAllocateMemory vkAllocateMemory;
PFN_vkFreeMemory vkFreeMemory;
PFN_vkMapMemory vkMapMemory;
PFN_vkUnmapMemory vkUnmapMemory;
PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
PFN_vkBindBufferMemory vkBindBufferMemory;
PFN_vkBindImageMemory vkBindImageMemory;
PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
PFN_vkQueueBindSparse vkQueueBindSparse;
PFN_vkCreateFence vkCreateFence;
PFN_vkDestroyFence vkDestroyFence;
PFN_vkResetFences vkResetFences;
PFN_vkGetFenceStatus vkGetFenceStatus;
PFN_vkWaitForFences vkWaitForFences;
PFN_vkCreateSemaphore vkCreateSemaphore;
PFN_vkDestroySemaphore vkDestroySemaphore;
PFN_vkCreateEvent vkCreateEvent;
PFN_vkDestroyEvent vkDestroyEvent;
PFN_vkGetEventStatus vkGetEventStatus;
PFN_vkSetEvent vkSetEvent;
PFN_vkResetEvent vkResetEvent;
PFN_vkCreateQueryPool vkCreateQueryPool;
PFN_vkDestroyQueryPool vkDestroyQueryPool;
PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
PFN_vkCreateBuffer vkCreateBuffer;
PFN_vkDestroyBuffer vkDestroyBuffer;
PFN_vkCreateBufferView vkCreateBufferView;
PFN_vkDestroyBufferView vkDestroyBufferView;
PFN_vkCreateImage vkCreateImage;
PFN_vkDestroyImage vkDestroyImage;
PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
PFN_vkCreateImageView vkCreateImageView;
PFN_vkDestroyImageView vkDestroyImageView;
PFN_vkCreateShaderModule vkCreateShaderModule;
PFN_vkDestroyShaderModule vkDestroyShaderModule;
PFN_vkCreatePipelineCache vkCreatePipelineCache;
PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
PFN_vkMergePipelineCaches vkMergePipelineCaches;
PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
PFN_vkCreateComputePipelines vkCreateComputePipelines;
PFN_vkDestroyPipeline vkDestroyPipeline;
PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
PFN_vkCreateSampler vkCreateSampler;
PFN_vkDestroySampler vkDestroySampler;
PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
PFN_vkResetDescriptorPool vkResetDescriptorPool;
PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
PFN_vkCreateFramebuffer vkCreateFramebuffer;
PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
PFN_vkCreateRenderPass vkCreateRenderPass;
PFN_vkDestroyRenderPass vkDestroyRenderPass;
PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
PFN_vkCreateCommandPool vkCreateCommandPool;
PFN_vkDestroyCommandPool vkDestroyCommandPool;
PFN_vkResetCommandPool vkResetCommandPool;
PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
PFN_vkEndCommandBuffer vkEndCommandBuffer;
PFN_vkResetCommandBuffer vkResetCommandBuffer;
PFN_vkCmdBindPipeline vkCmdBindPipeline;
PFN_vkCmdSetViewport vkCmdSetViewport;
PFN_vkCmdSetScissor vkCmdSetScissor;
PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
PFN_vkCmdDraw vkCmdDraw;
PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
PFN_vkCmdDispatch vkCmdDispatch;
PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
PFN_vkCmdCopyImage vkCmdCopyImage;
PFN_vkCmdBlitImage vkCmdBlitImage;
PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
PFN_vkCmdFillBuffer vkCmdFillBuffer;
PFN_vkCmdClearColorImage vkCmdClearColorImage;
PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
PFN_vkCmdClearAttachments vkCmdClearAttachments;
PFN_vkCmdResolveImage vkCmdResolveImage;
PFN_vkCmdSetEvent vkCmdSetEvent;
PFN_vkCmdResetEvent vkCmdResetEvent;
PFN_vkCmdWaitEvents vkCmdWaitEvents;
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
PFN_vkCmdBeginQuery vkCmdBeginQuery;
PFN_vkCmdEndQuery vkCmdEndQuery;
PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
PFN_vkCmdPushConstants vkCmdPushConstants;
PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
PFN_vkCmdNextSubpass vkCmdNextSubpass;
PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2;
// public extensions
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
PFN_vkQueuePresentKHR vkQueuePresentKHR;
#ifdef __linux
PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR;
PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR;
PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR;
#endif
#if defined(VK_USE_PLATFORM_WIN32_KHR)
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID;
#endif
PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT;
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT;
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
amf_handle m_hVulkanDll;
};

View File

@@ -0,0 +1,462 @@
//
// 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.
//
#include "../Thread.h"
#ifdef _WIN32
#include <timeapi.h>
#include <windows.h>
#include <memory>
//----------------------------------------------------------------------------------------
// threading
//----------------------------------------------------------------------------------------
amf_long AMF_CDECL_CALL amf_atomic_inc(amf_long* X)
{
return InterlockedIncrement((long*)X);
}
//----------------------------------------------------------------------------------------
amf_long AMF_CDECL_CALL amf_atomic_dec(amf_long* X)
{
return InterlockedDecrement((long*)X);
}
//----------------------------------------------------------------------------------------
amf_handle AMF_CDECL_CALL amf_create_critical_section()
{
CRITICAL_SECTION* cs = new CRITICAL_SECTION;
#if defined(METRO_APP)
::InitializeCriticalSectionEx(cs, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
#else
::InitializeCriticalSection(cs);
#endif
return (amf_handle)cs; // in Win32 - no errors
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_delete_critical_section(amf_handle cs)
{
if(cs == NULL)
{
return false;
}
::DeleteCriticalSection((CRITICAL_SECTION*)cs);
delete (CRITICAL_SECTION*)cs;
return true; // in Win32 - no errors
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_enter_critical_section(amf_handle cs)
{
if(cs == NULL)
{
return false;
}
::EnterCriticalSection((CRITICAL_SECTION*)cs);
return true; // in Win32 - no errors
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_wait_critical_section(amf_handle cs, amf_ulong ulTimeout)
{
if(cs == NULL)
{
return false;
}
while (true)
{
const BOOL success = ::TryEnterCriticalSection((CRITICAL_SECTION*)cs);
if (success == TRUE)
{
return true; // in Win32 - no errors
}
if (ulTimeout == 0)
{
return false;
}
amf_sleep(1);
ulTimeout--;
}
return false;
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_leave_critical_section(amf_handle cs)
{
if(cs == NULL)
{
return false;
}
::LeaveCriticalSection((CRITICAL_SECTION*)cs);
return true; // in Win32 - no errors
}
//----------------------------------------------------------------------------------------
amf_handle AMF_CDECL_CALL amf_create_event(bool bInitiallyOwned, bool bManualReset, const wchar_t* pName)
{
#if defined(METRO_APP)
DWORD flags = ((bManualReset) ? CREATE_EVENT_MANUAL_RESET : 0) |
((bInitiallyOwned) ? CREATE_EVENT_INITIAL_SET : 0);
return ::CreateEventEx(NULL, pName, flags, STANDARD_RIGHTS_ALL | EVENT_MODIFY_STATE);
#else
return ::CreateEventW(NULL, bManualReset == true, bInitiallyOwned == true, pName);
#endif
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_delete_event(amf_handle hevent)
{
if(hevent == NULL)
{
return false;
}
return ::CloseHandle(hevent) != FALSE;
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_set_event(amf_handle hevent)
{
if(hevent == NULL)
{
return false;
}
return ::SetEvent(hevent) != FALSE;
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_reset_event(amf_handle hevent)
{
if(hevent == NULL)
{
return false;
}
return ::ResetEvent(hevent) != FALSE;
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_wait_for_event(amf_handle hevent, amf_ulong ulTimeout)
{
if(hevent == NULL)
{
return false;
}
#if defined(METRO_APP)
return ::WaitForSingleObjectEx(hevent, ulTimeout, FALSE) == WAIT_OBJECT_0;
#else
return ::WaitForSingleObject(hevent, ulTimeout) == WAIT_OBJECT_0;
#endif
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_wait_for_event_timeout(amf_handle hevent, amf_ulong ulTimeout)
{
if(hevent == NULL)
{
return false;
}
DWORD ret;
#if defined(METRO_APP)
ret = ::WaitForSingleObjectEx(hevent, ulTimeout, FALSE);
#else
ret = ::WaitForSingleObject(hevent, ulTimeout);
#endif
return ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT;
}
//----------------------------------------------------------------------------------------
amf_handle AMF_CDECL_CALL amf_create_mutex(bool bInitiallyOwned, const wchar_t* pName)
{
#if defined(METRO_APP)
DWORD flags = (bInitiallyOwned) ? CREATE_MUTEX_INITIAL_OWNER : 0;
return ::CreateMutexEx(NULL, pName, flags, STANDARD_RIGHTS_ALL);
#else
return ::CreateMutexW(NULL, bInitiallyOwned == true, pName);
#endif
}
//----------------------------------------------------------------------------------------
amf_handle AMF_CDECL_CALL amf_open_mutex(const wchar_t* pName)
{
return ::OpenMutexW(MUTEX_ALL_ACCESS, FALSE, pName);
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_delete_mutex(amf_handle hmutex)
{
if(hmutex == NULL)
{
return false;
}
return ::CloseHandle(hmutex) != FALSE;
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_wait_for_mutex(amf_handle hmutex, amf_ulong ulTimeout)
{
if(hmutex == NULL)
{
return false;
}
#if defined(METRO_APP)
return ::WaitForSingleObjectEx(hmutex, ulTimeout, FALSE) == WAIT_OBJECT_0;
#else
return ::WaitForSingleObject(hmutex, ulTimeout) == WAIT_OBJECT_0;
#endif
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_release_mutex(amf_handle hmutex)
{
if(hmutex == NULL)
{
return false;
}
return ::ReleaseMutex(hmutex) != FALSE;
}
//----------------------------------------------------------------------------------------
amf_handle AMF_CDECL_CALL amf_create_semaphore(amf_long iInitCount, amf_long iMaxCount, const wchar_t* pName)
{
if(iMaxCount == NULL || iInitCount > iMaxCount)
{
return NULL;
}
#if defined(METRO_APP)
return ::CreateSemaphoreEx(NULL, iInitCount, iMaxCount, pName, 0, STANDARD_RIGHTS_ALL | SEMAPHORE_MODIFY_STATE);
#else
return ::CreateSemaphoreW(NULL, iInitCount, iMaxCount, pName);
#endif
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_delete_semaphore(amf_handle hsemaphore)
{
if(hsemaphore == NULL)
{
return false;
}
return ::CloseHandle(hsemaphore) != FALSE;
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_wait_for_semaphore(amf_handle hsemaphore, amf_ulong timeout)
{
if(hsemaphore == NULL)
{
return true;
}
#if defined(METRO_APP)
return ::WaitForSingleObjectEx(hsemaphore, timeout, false) == WAIT_OBJECT_0;
#else
return ::WaitForSingleObject(hsemaphore, timeout) == WAIT_OBJECT_0;
#endif
}
//----------------------------------------------------------------------------------------
bool AMF_CDECL_CALL amf_release_semaphore(amf_handle hsemaphore, amf_long iCount, amf_long* iOldCount)
{
if(hsemaphore == NULL)
{
return false;
}
return ::ReleaseSemaphore(hsemaphore, iCount, iOldCount) != FALSE;
}
//------------------------------------------------------------------------------
void AMF_CDECL_CALL amf_sleep(amf_ulong delay)
{
#if defined(METRO_APP)
Concurrency::wait(delay);
#else
Sleep(delay);
#endif
}
//----------------------------------------------------------------------------------------
amf_pts AMF_CDECL_CALL amf_high_precision_clock()
{
static int state = 0;
static LARGE_INTEGER Frequency;
static LARGE_INTEGER StartCount;
static amf_pts offset = 0;
if(state == 0)
{
if(QueryPerformanceFrequency(&Frequency))
{
state = 1;
QueryPerformanceCounter(&StartCount);
}
else
{
state = 2;
}
}
if(state == 1)
{
LARGE_INTEGER PerformanceCount;
if(QueryPerformanceCounter(&PerformanceCount))
{
amf_pts elapsed = static_cast<amf_pts>((PerformanceCount.QuadPart - StartCount.QuadPart) * 10000000LL / Frequency.QuadPart);
// periodically reset StartCount in order to avoid overflow
if (elapsed > (3600LL * AMF_SECOND))
{
offset += elapsed;
StartCount = PerformanceCount;
return offset;
}
else
{
return offset + elapsed;
}
}
}
#if defined(METRO_APP)
return GetTickCount64() * 10;
#else
return GetTickCount() * 10;
#endif
}
//-------------------------------------------------------------------------------------------------
#pragma comment (lib, "Winmm.lib")
static amf_uint32 timerPrecision = 1;
void AMF_CDECL_CALL amf_increase_timer_precision()
{
#if !defined(METRO_APP)
while (timeBeginPeriod(timerPrecision) == TIMERR_NOCANDO)
{
++timerPrecision;
}
/*
typedef NTSTATUS (CALLBACK * NTSETTIMERRESOLUTION)(IN ULONG DesiredTime,IN BOOLEAN SetResolution,OUT PULONG ActualTime);
typedef NTSTATUS (CALLBACK * NTQUERYTIMERRESOLUTION)(OUT PULONG MaximumTime,OUT PULONG MinimumTime,OUT PULONG CurrentTime);
HINSTANCE hNtDll = LoadLibrary(L"NTDLL.dll");
if(hNtDll != NULL)
{
ULONG MinimumResolution=0;
ULONG MaximumResolution=0;
ULONG ActualResolution=0;
NTQUERYTIMERRESOLUTION NtQueryTimerResolution = (NTQUERYTIMERRESOLUTION)GetProcAddress(hNtDll, "NtQueryTimerResolution");
NTSETTIMERRESOLUTION NtSetTimerResolution = (NTSETTIMERRESOLUTION)GetProcAddress(hNtDll, "NtSetTimerResolution");
if(NtQueryTimerResolution != NULL && NtSetTimerResolution != NULL)
{
NtQueryTimerResolution (&MinimumResolution, &MaximumResolution, &ActualResolution);
if(MaximumResolution != 0)
{
NtSetTimerResolution (MaximumResolution, TRUE, &ActualResolution);
NtQueryTimerResolution (&MinimumResolution, &MaximumResolution, &ActualResolution);
// if call NtQueryTimerResolution() again it will return the same values but precision is actually increased
}
}
FreeLibrary(hNtDll);
}
*/
#endif
}
void AMF_CDECL_CALL amf_restore_timer_precision()
{
#if !defined(METRO_APP)
timeEndPeriod(timerPrecision);
#endif
}
//----------------------------------------------------------------------------------------
amf_handle AMF_CDECL_CALL amf_load_library1(const wchar_t* filename, bool /*bGlobal*/)
{
return amf_load_library(filename);
}
//----------------------------------------------------------------------------------------
amf_handle AMF_CDECL_CALL amf_load_library(const wchar_t* filename)
{
#if defined(METRO_APP)
return LoadPackagedLibrary(filename, 0);
#else
return ::LoadLibraryExW(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS);
#endif
}
//----------------------------------------------------------------------------------------
void* AMF_CDECL_CALL amf_get_proc_address(amf_handle module, const char* procName)
{
return (void*)::GetProcAddress((HMODULE)module, procName);
}
//----------------------------------------------------------------------------------------
int AMF_CDECL_CALL amf_free_library(amf_handle module)
{
return ::FreeLibrary((HMODULE)module)==TRUE;
}
#if !defined(METRO_APP)
//----------------------------------------------------------------------------------------
// memory
//----------------------------------------------------------------------------------------
void* AMF_CDECL_CALL amf_virtual_alloc(size_t size)
{
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
}
//----------------------------------------------------------------------------------------
void AMF_CDECL_CALL amf_virtual_free(void* ptr)
{
VirtualFree(ptr, NULL, MEM_RELEASE);
}
#endif //#if !defined(METRO_APP)
//----------------------------------------------------------------------------------------
// cpu
//----------------------------------------------------------------------------------------
amf_int32 AMF_STD_CALL amf_get_cpu_cores()
{
//query the number of CPU HW cores
DWORD len = 0;
GetLogicalProcessorInformation(NULL, &len);
amf_uint32 count = len / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
std::unique_ptr<SYSTEM_LOGICAL_PROCESSOR_INFORMATION[]> pBuffer(new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[count]);
if (pBuffer)
{
GetLogicalProcessorInformation(pBuffer.get(), &len);
count = len / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
amf_int32 iCores = 0;
for (amf_uint32 idx = 0; idx < count; idx++)
{
if (pBuffer[idx].Relationship == RelationProcessorCore)
{
iCores++;
}
}
return iCores;
}
return 1;
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
#endif // _WIN32

View File

@@ -0,0 +1,119 @@
//
// 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.
//
#include "UtilsWindows.h"
#include <public/common/TraceAdapter.h>
#ifdef _WIN32
#define AMF_FACILITY L"UtilWindows"
amf_bool OSIsVersionOrGreater(DWORD major, DWORD minor, DWORD build)
{
// This function is to replace "IsWindowsVersionOrGreater" since
// it seems to be broken since windows 8
HMODULE hModule = GetModuleHandleW(L"ntdll");
if (hModule == nullptr)
{
AMFTraceError(AMF_FACILITY, L"OSIsVersionOrGreater() - Could not get ntdll handle");
return false;
}
NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW);
*(FARPROC*)&RtlGetVersion = GetProcAddress(hModule, "RtlGetVersion");
if (RtlGetVersion == nullptr)
{
AMFTraceError(AMF_FACILITY, L"OSIsVersionOrGreater() - Could not get RtlGetVersion procedure handle from ntdll");
return false;
}
OSVERSIONINFOEXW osVersionInfo = {};
NTSTATUS status = RtlGetVersion(&osVersionInfo);
if (status != 0)
{
AMFTraceError(AMF_FACILITY, L"OSIsVersionOrGreater() - RtlGetVersion failed");
return false;
}
const DWORD versions[] = { osVersionInfo.dwMajorVersion, osVersionInfo.dwMinorVersion, osVersionInfo.dwBuildNumber };
const DWORD checkVersions[] = { major, minor, build };
constexpr amf_uint count = amf_countof(versions);
for (amf_uint i = 0; i < count; ++i)
{
if (versions[i] == checkVersions[i])
{
continue;
}
return versions[i] > checkVersions[i];
}
return versions[count - 1] == checkVersions[count - 1];
}
AMF_RESULT GetDisplayInfo(amf_handle hwnd, DisplayInfo& displayInfo)
{
AMF_RETURN_IF_FALSE(hwnd != nullptr, AMF_INVALID_ARG, L"GetDisplayInfoFromWindow() - hwnd is NULL");
displayInfo = {};
// Get display information (specifically name)
displayInfo.hMonitor = MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST);
AMF_RETURN_IF_FALSE(displayInfo.hMonitor != nullptr, AMF_FAIL, L"GetDisplayInfoFromWindow() - MonitorFromWindow() returned NULL");
MONITORINFOEX monitorInfo = {};
monitorInfo.cbSize = sizeof(monitorInfo);
BOOL ret = GetMonitorInfoW(displayInfo.hMonitor, &monitorInfo);
AMF_RETURN_IF_FALSE(ret != 0, AMF_FAIL, L"GetDisplayInfoFromWindow() - GetMonitorInfoW() failed, code=%d", ret);
// Save the windowed DEVMODE
DEVMODEW devMode = {};
devMode.dmSize = sizeof(devMode);
ret = EnumDisplaySettingsW(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
AMF_RETURN_IF_FALSE(ret != 0, AMF_FAIL, L"GetDisplayInfoFromWindow() - EnumDisplaySettingsW() failed to get Window Mode DEVMODE, code=%d", ret);
displayInfo.deviceName = monitorInfo.szDevice;
displayInfo.primary = (monitorInfo.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY;
displayInfo.workRect = AMFConstructRect(monitorInfo.rcWork.left, monitorInfo.rcWork.top, monitorInfo.rcWork.right, monitorInfo.rcWork.bottom);
displayInfo.monitorRect = AMFConstructRect(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorInfo.rcMonitor.right, monitorInfo.rcMonitor.bottom);
displayInfo.deviceRect = AMFConstructRect(devMode.dmPosition.x, devMode.dmPosition.y, devMode.dmPosition.x + devMode.dmPelsWidth, devMode.dmPosition.y + devMode.dmPelsHeight);
displayInfo.frequency = AMFConstructRate(devMode.dmDisplayFrequency, 1);
displayInfo.bitsPerPixel = devMode.dmBitsPerPel;
return AMF_OK;
}
#endif // _WIN32

View File

@@ -0,0 +1,55 @@
//
// 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.
//
#ifdef _WIN32
#include "public/include/core/Platform.h"
#include "public/include/core/Result.h"
#include "../AMFSTL.h"
amf_bool OSIsVersionOrGreater(DWORD major, DWORD minor, DWORD build);
struct DisplayInfo
{
HMONITOR hMonitor;
amf_wstring deviceName;
amf_bool primary;
AMFRect monitorRect;
AMFRect workRect;
AMFRect deviceRect;
AMFRate frequency;
amf_uint bitsPerPixel;
};
AMF_RESULT GetDisplayInfo(amf_handle hwnd, DisplayInfo& displayInfo);
#endif // _WIN32