Merge pull request #21883 from SergeyIvanov87:gapi_vpl_linux

G-API: VPL Source turn on Linux CPU version

* Turn on linux compilation

* Apply comments

* Change new files headline

* Add license header
pull/21981/head
Sergey 3 years ago committed by GitHub
parent 2010de9104
commit eff5605be5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      modules/gapi/CMakeLists.txt
  2. 1
      modules/gapi/include/opencv2/gapi/streaming/onevpl/accel_types.hpp
  3. 39
      modules/gapi/perf/streaming/gapi_streaming_source_perf_tests.cpp
  4. 38
      modules/gapi/src/streaming/onevpl/accelerators/accel_policy_cpu.cpp
  5. 53
      modules/gapi/src/streaming/onevpl/accelerators/accel_policy_dx11.cpp
  6. 14
      modules/gapi/src/streaming/onevpl/accelerators/accel_policy_dx11.hpp
  7. 150
      modules/gapi/src/streaming/onevpl/accelerators/accel_policy_va_api.cpp
  8. 62
      modules/gapi/src/streaming/onevpl/accelerators/accel_policy_va_api.hpp
  9. 2
      modules/gapi/src/streaming/onevpl/accelerators/surface/base_frame_adapter.cpp
  10. 2
      modules/gapi/src/streaming/onevpl/accelerators/surface/base_frame_adapter.hpp
  11. 4
      modules/gapi/src/streaming/onevpl/accelerators/surface/dx11_frame_adapter.cpp
  12. 9
      modules/gapi/src/streaming/onevpl/accelerators/surface/surface.cpp
  13. 1
      modules/gapi/src/streaming/onevpl/accelerators/surface/surface_pool.cpp
  14. 59
      modules/gapi/src/streaming/onevpl/cfg_param_device_selector.cpp
  15. 14
      modules/gapi/src/streaming/onevpl/cfg_params_parser.cpp
  16. 3
      modules/gapi/src/streaming/onevpl/demux/async_mfp_demux_data_provider.cpp
  17. 2
      modules/gapi/src/streaming/onevpl/demux/async_mfp_demux_data_provider.hpp
  18. 2
      modules/gapi/src/streaming/onevpl/device_selector_interface.cpp
  19. 4
      modules/gapi/src/streaming/onevpl/engine/decode/decode_engine_legacy.cpp
  20. 3
      modules/gapi/src/streaming/onevpl/engine/decode/decode_session.hpp
  21. 3
      modules/gapi/src/streaming/onevpl/engine/engine_session.hpp
  22. 7
      modules/gapi/src/streaming/onevpl/engine/preproc/preproc_engine.cpp
  23. 6
      modules/gapi/src/streaming/onevpl/engine/preproc/vpp_preproc_defines.hpp
  24. 1
      modules/gapi/src/streaming/onevpl/engine/processing_engine_base.hpp
  25. 5
      modules/gapi/src/streaming/onevpl/engine/transcode/transcode_engine_legacy.cpp
  26. 2
      modules/gapi/src/streaming/onevpl/engine/transcode/transcode_session.hpp
  27. 2
      modules/gapi/src/streaming/onevpl/onevpl_export.hpp
  28. 7
      modules/gapi/src/streaming/onevpl/source_priv.cpp
  29. 4
      modules/gapi/src/streaming/onevpl/utils.cpp
  30. 4
      modules/gapi/test/streaming/gapi_streaming_tests.cpp
  31. 142
      modules/gapi/test/streaming/gapi_streaming_vpl_core_test.cpp
  32. 2
      modules/gapi/test/streaming/gapi_streaming_vpl_data_provider.cpp
  33. 26
      modules/gapi/test/streaming/gapi_streaming_vpl_device_selector.cpp
  34. 152
      modules/gapi/test/streaming/gapi_streaming_vpp_preproc_test.cpp

@ -133,7 +133,7 @@ set(gapi_srcs
src/backends/fluid/gfluidimgproc.cpp
src/backends/fluid/gfluidimgproc_func.dispatch.cpp
src/backends/fluid/gfluidcore.cpp
src/backends/fluid/gfluidcore_func.dispatch.cpp
src/backends/fluid/gfluidcore_func.dispatch.cpp
# OAK Backend (optional)
src/backends/oak/goak.cpp
@ -194,6 +194,7 @@ set(gapi_srcs
src/streaming/onevpl/accelerators/utils/shared_lock.cpp
src/streaming/onevpl/accelerators/accel_policy_cpu.cpp
src/streaming/onevpl/accelerators/accel_policy_dx11.cpp
src/streaming/onevpl/accelerators/accel_policy_va_api.cpp
src/streaming/onevpl/accelerators/dx11_alloc_resource.cpp
src/streaming/onevpl/engine/engine_session.cpp
src/streaming/onevpl/engine/processing_engine_base.cpp
@ -310,12 +311,30 @@ if(HAVE_GAPI_ONEVPL)
ocv_target_include_directories(opencv_test_gapi SYSTEM PRIVATE ${OPENCL_INCLUDE_DIRS})
endif()
endif()
ocv_target_compile_definitions(${the_module} PRIVATE -DHAVE_ONEVPL)
ocv_target_link_libraries(${the_module} PRIVATE ${VPL_IMPORTED_TARGETS})
if(HAVE_D3D11 AND HAVE_OPENCL)
ocv_target_include_directories(${the_module} SYSTEM PRIVATE ${OPENCL_INCLUDE_DIRS})
endif()
if(UNIX)
find_package(PkgConfig)
if(PkgConfig_FOUND)
pkg_check_modules(PKG_LIBVA libva>=1.2 libva-drm>=1.2)
if(PKG_LIBVA_FOUND)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
else()
message(FATAL_ERROR "libva not found: building HAVE_GAPI_ONEVPL without libVA support is impossible on UNIX systems")
endif()
else()
message(FATAL_ERROR "PkgConfig not found: building HAVE_GAPI_ONEVPL without libVA support is impossible on UNIX systems")
endif()
ocv_target_link_libraries(${the_module} PRIVATE ${PKG_LIBVA_LIBRARIES} ${PKG_THREAD_LIBRARIES})
endif()
endif()
ocv_option(OPENCV_GAPI_GSTREAMER "Build G-API with GStreamer support" HAVE_GSTREAMER)

@ -20,6 +20,7 @@ namespace onevpl {
enum class AccelType: uint8_t {
HOST,
DX11,
VAAPI,
LAST_VALUE = std::numeric_limits<uint8_t>::max()
};

@ -17,6 +17,7 @@
#include "streaming/onevpl/cfg_param_device_selector.hpp"
#include "streaming/onevpl/accelerators/accel_policy_dx11.hpp"
#include "streaming/onevpl/accelerators/accel_policy_cpu.hpp"
#include "streaming/onevpl/accelerators/accel_policy_va_api.hpp"
namespace opencv_test
{
@ -89,6 +90,7 @@ PERF_TEST_P_(VideoCapSourcePerf_Test, TestPerformance)
SANITY_CHECK_NOTHING();
}
#ifdef __WIN32__
INSTANTIATE_TEST_CASE_P(Streaming, OneVPLSourcePerf_Test,
Values(source_description_t(files[0], codec[0], ""),
source_description_t(files[0], codec[0], "MFX_ACCEL_MODE_VIA_D3D11"),
@ -96,6 +98,11 @@ INSTANTIATE_TEST_CASE_P(Streaming, OneVPLSourcePerf_Test,
source_description_t(files[1], codec[1], "MFX_ACCEL_MODE_VIA_D3D11"),
source_description_t(files[2], codec[2], ""),
source_description_t(files[2], codec[2], "MFX_ACCEL_MODE_VIA_D3D11")));
#elif __linux__
INSTANTIATE_TEST_CASE_P(Streaming, OneVPLSourcePerf_Test,
Values(source_description_t(files[0], codec[0], "MFX_ACCEL_MODE_VIA_VAAPI"),
source_description_t(files[1], codec[1], "MFX_ACCEL_MODE_VIA_VAAPI")));
#endif
INSTANTIATE_TEST_CASE_P(Streaming, VideoCapSourcePerf_Test,
Values(files[0],
@ -152,6 +159,8 @@ static pp_out_param_t full_hd = pp_out_param_t {cv::MediaFormat::NV12,
static pp_out_param_t cif = pp_out_param_t {cv::MediaFormat::NV12,
{352, 288}};
#ifdef __WIN32__
INSTANTIATE_TEST_CASE_P(Streaming_Source_PP, OneVPLSourcePerf_PP_Test,
Values(source_description_preproc_t(files[0], codec[0], "", full_hd),
source_description_preproc_t(files[0], codec[0], "", cif),
@ -165,6 +174,13 @@ INSTANTIATE_TEST_CASE_P(Streaming_Source_PP, OneVPLSourcePerf_PP_Test,
source_description_preproc_t(files[2], codec[2], "", cif),
source_description_preproc_t(files[2], codec[2], "MFX_ACCEL_MODE_VIA_D3D11", full_hd),
source_description_preproc_t(files[2], codec[2], "MFX_ACCEL_MODE_VIA_D3D11", cif)));
#elif __linux__
INSTANTIATE_TEST_CASE_P(Streaming_Source_PP, OneVPLSourcePerf_PP_Test,
Values(source_description_preproc_t(files[0], codec[0], "MFX_ACCEL_MODE_VIA_VAAPI", full_hd),
source_description_preproc_t(files[0], codec[0], "MFX_ACCEL_MODE_VIA_VAAPI", cif),
source_description_preproc_t(files[1], codec[1], "MFX_ACCEL_MODE_VIA_VAAPI",full_hd),
source_description_preproc_t(files[1], codec[1], "MFX_ACCEL_MODE_VIA_VAAPI",cif)));
#endif
class OneVPLSourcePerf_PP_Engine_Test : public TestPerfParams<source_description_preproc_t> {};
@ -198,6 +214,8 @@ PERF_TEST_P_(OneVPLSourcePerf_PP_Engine_Test, TestPerformance)
std::unique_ptr<VPLAccelerationPolicy> policy;
if (mode == "MFX_ACCEL_MODE_VIA_D3D11") {
policy.reset(new VPLDX11AccelerationPolicy(device_selector));
} else if (mode == "MFX_ACCEL_MODE_VIA_VAAPI") {
policy.reset(new VPLVAAPIAccelerationPolicy(device_selector));
} else if (mode.empty()){
policy.reset(new VPLCPUAccelerationPolicy(device_selector));
} else {
@ -219,6 +237,7 @@ PERF_TEST_P_(OneVPLSourcePerf_PP_Engine_Test, TestPerformance)
SANITY_CHECK_NOTHING();
}
#ifdef __WIN32__
INSTANTIATE_TEST_CASE_P(Streaming_Engine_PP, OneVPLSourcePerf_PP_Engine_Test,
Values(source_description_preproc_t(files[0], codec[0], "", full_hd),
source_description_preproc_t(files[0], codec[0], "", cif),
@ -232,6 +251,13 @@ INSTANTIATE_TEST_CASE_P(Streaming_Engine_PP, OneVPLSourcePerf_PP_Engine_Test,
source_description_preproc_t(files[2], codec[2], "", cif),
source_description_preproc_t(files[2], codec[2], "MFX_ACCEL_MODE_VIA_D3D11", full_hd),
source_description_preproc_t(files[2], codec[2], "MFX_ACCEL_MODE_VIA_D3D11", cif)));
#elif __linux__
INSTANTIATE_TEST_CASE_P(Streaming_Engine_PP, OneVPLSourcePerf_PP_Engine_Test,
Values(source_description_preproc_t(files[0], codec[0], "MFX_ACCEL_MODE_VIA_VAAPI", full_hd),
source_description_preproc_t(files[0], codec[0], "MFX_ACCEL_MODE_VIA_VAAPI", cif),
source_description_preproc_t(files[1], codec[1], "MFX_ACCEL_MODE_VIA_VAAPI",full_hd),
source_description_preproc_t(files[1], codec[1], "MFX_ACCEL_MODE_VIA_VAAPI",cif)));
#endif
class OneVPLSourcePerf_PP_Engine_Bypass_Test : public TestPerfParams<source_description_preproc_t> {};
@ -265,8 +291,12 @@ PERF_TEST_P_(OneVPLSourcePerf_PP_Engine_Bypass_Test, TestPerformance)
std::unique_ptr<VPLAccelerationPolicy> policy;
if (mode == "MFX_ACCEL_MODE_VIA_D3D11") {
policy.reset(new VPLDX11AccelerationPolicy(device_selector));
} else {
} else if (mode == "MFX_ACCEL_MODE_VIA_VAAPI") {
policy.reset(new VPLVAAPIAccelerationPolicy(device_selector));
} else if (mode.empty()){
policy.reset(new VPLCPUAccelerationPolicy(device_selector));
} else {
ASSERT_TRUE(false && "Unsupported acceleration policy type");
}
VPPPreprocEngine preproc_engine(std::move(policy));
cv::gapi::wip::Data out;
@ -288,6 +318,8 @@ static pp_out_param_t res_672x384 = pp_out_param_t {cv::MediaFormat::NV12,
{672, 384}};
static pp_out_param_t res_336x256 = pp_out_param_t {cv::MediaFormat::NV12,
{336, 256}};
#ifdef __WIN32__
INSTANTIATE_TEST_CASE_P(Streaming_Engine_PP_Bypass, OneVPLSourcePerf_PP_Engine_Bypass_Test,
Values(source_description_preproc_t(files[0], codec[0], "", res_672x384),
source_description_preproc_t(files[0], codec[0], "MFX_ACCEL_MODE_VIA_D3D11", res_672x384),
@ -295,6 +327,11 @@ INSTANTIATE_TEST_CASE_P(Streaming_Engine_PP_Bypass, OneVPLSourcePerf_PP_Engine_B
source_description_preproc_t(files[1], codec[1], "MFX_ACCEL_MODE_VIA_D3D11", res_672x384),
source_description_preproc_t(files[2], codec[2], "", res_336x256),
source_description_preproc_t(files[2], codec[2], "MFX_ACCEL_MODE_VIA_D3D11", res_336x256)));
#elif __linux__
INSTANTIATE_TEST_CASE_P(Streaming_Engine_PP_Bypass, OneVPLSourcePerf_PP_Engine_Bypass_Test,
Values(source_description_preproc_t(files[0], codec[0], "MFX_ACCEL_MODE_VIA_VAAPI", res_672x384),
source_description_preproc_t(files[1], codec[1], "MFX_ACCEL_MODE_VIA_VAAPI", res_672x384)));
#endif
} // namespace opencv_test
#endif // HAVE_ONEVPL

@ -11,6 +11,7 @@
#include "streaming/onevpl/accelerators/accel_policy_cpu.hpp"
#include "streaming/onevpl/accelerators/surface/cpu_frame_adapter.hpp"
#include "streaming/onevpl/accelerators/surface/surface.hpp"
#include "streaming/onevpl/utils.hpp"
#include "logger.hpp"
#ifdef _WIN32
@ -22,7 +23,7 @@ namespace gapi {
namespace wip {
namespace onevpl {
namespace utils {
mfxU32 GetSurfaceSize_(mfxU32 FourCC, mfxU32 width, mfxU32 height) {
static mfxU32 GetSurfaceSize_(mfxU32 FourCC, mfxU32 width, mfxU32 height) {
mfxU32 nbytes = 0;
mfxU32 half_width = width / 2;
@ -47,10 +48,10 @@ mfxU32 GetSurfaceSize_(mfxU32 FourCC, mfxU32 width, mfxU32 height) {
return nbytes;
}
surface_ptr_t create_surface_RGB4_(mfxFrameInfo frameInfo,
std::shared_ptr<void> out_buf_ptr,
size_t out_buf_ptr_offset,
size_t out_buf_size)
static surface_ptr_t create_surface_RGB4_(mfxFrameInfo frameInfo,
std::shared_ptr<void> out_buf_ptr,
size_t out_buf_ptr_offset,
size_t out_buf_size)
{
mfxU8* buf = reinterpret_cast<mfxU8*>(out_buf_ptr.get());
mfxU16 surfW = frameInfo.Width * 4;
@ -80,10 +81,10 @@ surface_ptr_t create_surface_RGB4_(mfxFrameInfo frameInfo,
return Surface::create_surface(std::move(handle), out_buf_ptr);
}
surface_ptr_t create_surface_other_(mfxFrameInfo frameInfo,
std::shared_ptr<void> out_buf_ptr,
size_t out_buf_ptr_offset,
size_t out_buf_size)
static surface_ptr_t create_surface_other_(mfxFrameInfo frameInfo,
std::shared_ptr<void> out_buf_ptr,
size_t out_buf_ptr_offset,
size_t out_buf_size)
{
mfxU8* buf = reinterpret_cast<mfxU8*>(out_buf_ptr.get());
mfxU16 surfH = frameInfo.Height;
@ -155,8 +156,12 @@ VPLCPUAccelerationPolicy::create_surface_pool(size_t pool_size, size_t surface_s
GAPI_LOG_DEBUG(nullptr, "page size: " << page_size_bytes << ", preallocated_raw_bytes: " << preallocated_raw_bytes);
preallocated_pool_memory_ptr = _aligned_malloc(preallocated_raw_bytes, page_size_bytes);
#else
GAPI_Assert(false && "Compatibility is not tested for systems differ than \"_WIN32\". "
"Please feel free to set it up under OPENCV contribution policy");
int err = posix_memalign(&preallocated_pool_memory_ptr, page_size_bytes, preallocated_raw_bytes);
if (err) {
GAPI_LOG_WARNING(nullptr, "Cannot allocate aligned memory, size: " << preallocated_raw_bytes <<
", alignment: " << page_size_bytes << ", error: " <<
strerror(err));
}
#endif
if (!preallocated_pool_memory_ptr) {
@ -173,8 +178,9 @@ VPLCPUAccelerationPolicy::create_surface_pool(size_t pool_size, size_t surface_s
GAPI_LOG_INFO(nullptr, "Released workspace memory: " << ptr);
ptr = nullptr;
#else
GAPI_Assert(false && "Not implemented for systems differ than \"_WIN32\". "
"Please feel free to set it up under OPENCV contribution policy");
free(ptr);
GAPI_LOG_INFO(nullptr, "Released workspace memory: " << ptr);
ptr = nullptr;
#endif
});
@ -220,10 +226,8 @@ VPLCPUAccelerationPolicy::create_surface_pool(const mfxFrameAllocRequest& alloc_
info.Width,
info.Height);
if (!singleSurfaceSize) {
throw std::runtime_error("Cannot determine surface size for: fourCC: " +
std::to_string(info.FourCC) +
", width: " + std::to_string(info.Width) +
", height: " + std::to_string(info.Height));
throw std::runtime_error("Cannot determine surface size from frame: " +
mfx_frame_info_to_string(info));
}
auto surface_creator =

@ -13,8 +13,7 @@
#include "streaming/onevpl/utils.hpp"
#include "logger.hpp"
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
#pragma comment(lib,"d3d11.lib")
#define D3D11_NO_HELPERS
@ -441,6 +440,52 @@ mfxStatus VPLDX11AccelerationPolicy::on_free(mfxFrameAllocResponse *response) {
} // namespace wip
} // namespace gapi
} // namespace cv
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
#else // #if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
namespace cv {
namespace gapi {
namespace wip {
namespace onevpl {
VPLDX11AccelerationPolicy::VPLDX11AccelerationPolicy(device_selector_ptr_t selector) :
VPLAccelerationPolicy(selector) {
GAPI_Assert(false && "VPLDX11AccelerationPolicy unavailable in current configuration");
}
VPLDX11AccelerationPolicy::~VPLDX11AccelerationPolicy() = default;
void VPLDX11AccelerationPolicy::init(session_t ) {
GAPI_Assert(false && "VPLDX11AccelerationPolicy unavailable in current configuration");
}
void VPLDX11AccelerationPolicy::deinit(session_t) {
GAPI_Assert(false && "VPLDX11AccelerationPolicy unavailable in current configuration");
}
VPLDX11AccelerationPolicy::pool_key_t VPLDX11AccelerationPolicy::create_surface_pool(const mfxFrameAllocRequest&,
mfxFrameInfo&) {
GAPI_Assert(false && "VPLDX11AccelerationPolicy unavailable in current configuration");
}
VPLDX11AccelerationPolicy::surface_weak_ptr_t VPLDX11AccelerationPolicy::get_free_surface(pool_key_t) {
GAPI_Assert(false && "VPLDX11AccelerationPolicy unavailable in current configuration");
}
size_t VPLDX11AccelerationPolicy::get_free_surface_count(pool_key_t) const {
GAPI_Assert(false && "VPLDX11AccelerationPolicy unavailable in current configuration");
}
size_t VPLDX11AccelerationPolicy::get_surface_count(pool_key_t) const {
GAPI_Assert(false && "VPLDX11AccelerationPolicy unavailable in current configuration");
}
cv::MediaFrame::AdapterPtr VPLDX11AccelerationPolicy::create_frame_adapter(pool_key_t,
const FrameConstructorArgs &) {
GAPI_Assert(false && "VPLDX11AccelerationPolicy unavailable in current configuration");
}
} // namespace onevpl
} // namespace wip
} // namespace gapi
} // namespace cv
#endif // #if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
#endif // HAVE_ONEVPL

@ -15,8 +15,7 @@
#include "streaming/onevpl/accelerators/surface/surface_pool.hpp"
#include "streaming/onevpl/accelerators/dx11_alloc_resource.hpp"
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
#define D3D11_NO_HELPERS
#define NOMINMAX
#include <d3d11.h>
@ -24,7 +23,9 @@
#include "opencv2/core/directx.hpp"
#ifdef HAVE_OPENCL
#include <CL/cl_d3d11.h>
#endif
#endif // HAVE_OPENCL
#undef NOMINMAX
#endif // HAVE_DIRECTX && HAVE_D3D11
namespace cv {
namespace gapi {
@ -51,6 +52,8 @@ struct GAPI_EXPORTS VPLDX11AccelerationPolicy final: public VPLAccelerationPolic
cv::MediaFrame::AdapterPtr create_frame_adapter(pool_key_t key,
const FrameConstructorArgs &params) override;
private:
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
ID3D11Device *hw_handle;
ID3D11DeviceContext* device_context;
@ -75,14 +78,13 @@ private:
std::map<alloc_id_t, allocation_t> allocation_table;
std::map<pool_key_t, pool_t> pool_table;
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
};
} // namespace onevpl
} // namespace wip
} // namespace gapi
} // namespace cv
#undef NOMINMAX
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
#endif // HAVE_ONEVPL
#endif // GAPI_STREAMING_ONEVPL_ACCELERATORS_ACCEL_POLICY_DX11_HPP

@ -0,0 +1,150 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifdef HAVE_ONEVPL
#include <cstdlib>
#include <exception>
#include <stdint.h>
#ifdef __linux__
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif // __linux__
#include "streaming/onevpl/accelerators/accel_policy_va_api.hpp"
#include "streaming/onevpl/accelerators/accel_policy_cpu.hpp"
#include "streaming/onevpl/utils.hpp"
#include "logger.hpp"
namespace cv {
namespace gapi {
namespace wip {
namespace onevpl {
#ifdef __linux__
VPLVAAPIAccelerationPolicy::VPLVAAPIAccelerationPolicy(device_selector_ptr_t selector) :
VPLAccelerationPolicy(selector),
cpu_dispatcher(new VPLCPUAccelerationPolicy(selector)),
va_handle(),
device_fd(-1) {
#if defined(HAVE_VA) || defined(HAVE_VA_INTEL)
// TODO Move it out in device selector
device_fd = open("/dev/dri/renderD128", O_RDWR);
if (device_fd < 0) {
GAPI_LOG_WARNING(nullptr, "VAAPI device descriptor \"/dev/dri/renderD128\" has not found");
throw std::runtime_error("cannot open VAAPI device");
}
va_handle = vaGetDisplayDRM(device_fd);
if (!va_handle) {
GAPI_LOG_WARNING(nullptr, "VAAPI device vaGetDisplayDRM failed, error: " << strerror(errno));
close(device_fd);
throw std::runtime_error("vaGetDisplayDRM failed");
}
int major_version = 0, minor_version = 0;
VAStatus status {};
status = vaInitialize(va_handle, &major_version, &minor_version);
if (VA_STATUS_SUCCESS != status) {
GAPI_LOG_WARNING(nullptr, "Cannot initialize VAAPI device, error: " << vaErrorStr(status));
close(device_fd);
throw std::runtime_error("vaInitialize failed");
}
GAPI_LOG_INFO(nullptr, "created");
#else // defined(HAVE_VA) || defined(HAVE_VA_INTEL)
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
#endif // defined(HAVE_VA) || defined(HAVE_VA_INTEL)
}
VPLVAAPIAccelerationPolicy::~VPLVAAPIAccelerationPolicy() {
vaTerminate(va_handle);
close(device_fd);
GAPI_LOG_INFO(nullptr, "destroyed");
}
void VPLVAAPIAccelerationPolicy::init(session_t session) {
GAPI_LOG_INFO(nullptr, "session: " << session);
cpu_dispatcher->init(session);
mfxStatus sts = MFXVideoCORE_SetHandle(session,
static_cast<mfxHandleType>(MFX_HANDLE_VA_DISPLAY),
va_handle);
if (sts != MFX_ERR_NONE)
{
throw std::logic_error("Cannot create VPLVAAPIAccelerationPolicy, MFXVideoCORE_SetHandle error: " +
mfxstatus_to_string(sts));
}
GAPI_LOG_INFO(nullptr, "finished successfully, session: " << session);
}
void VPLVAAPIAccelerationPolicy::deinit(session_t session) {
GAPI_LOG_INFO(nullptr, "session: " << session);
}
VPLVAAPIAccelerationPolicy::pool_key_t
VPLVAAPIAccelerationPolicy::create_surface_pool(const mfxFrameAllocRequest& alloc_request, mfxFrameInfo& info) {
return cpu_dispatcher->create_surface_pool(alloc_request, info);
}
VPLVAAPIAccelerationPolicy::surface_weak_ptr_t VPLVAAPIAccelerationPolicy::get_free_surface(pool_key_t key) {
return cpu_dispatcher->get_free_surface(key);
}
size_t VPLVAAPIAccelerationPolicy::get_free_surface_count(pool_key_t key) const {
return cpu_dispatcher->get_free_surface_count(key);
}
size_t VPLVAAPIAccelerationPolicy::get_surface_count(pool_key_t key) const {
return cpu_dispatcher->get_surface_count(key);
}
cv::MediaFrame::AdapterPtr VPLVAAPIAccelerationPolicy::create_frame_adapter(pool_key_t key,
const FrameConstructorArgs &params) {
return cpu_dispatcher->create_frame_adapter(key, params);
}
#else // __linux__
VPLVAAPIAccelerationPolicy::VPLVAAPIAccelerationPolicy(device_selector_ptr_t selector) :
VPLAccelerationPolicy(selector) {
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
}
VPLVAAPIAccelerationPolicy::~VPLVAAPIAccelerationPolicy() = default;
void VPLVAAPIAccelerationPolicy::init(session_t ) {
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
}
void VPLVAAPIAccelerationPolicy::deinit(session_t) {
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
}
VPLVAAPIAccelerationPolicy::pool_key_t VPLVAAPIAccelerationPolicy::create_surface_pool(const mfxFrameAllocRequest&,
mfxFrameInfo&) {
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
}
VPLVAAPIAccelerationPolicy::surface_weak_ptr_t VPLVAAPIAccelerationPolicy::get_free_surface(pool_key_t) {
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
}
size_t VPLVAAPIAccelerationPolicy::get_free_surface_count(pool_key_t) const {
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
}
size_t VPLVAAPIAccelerationPolicy::get_surface_count(pool_key_t) const {
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
}
cv::MediaFrame::AdapterPtr VPLVAAPIAccelerationPolicy::create_frame_adapter(pool_key_t,
const FrameConstructorArgs &) {
GAPI_Assert(false && "VPLVAAPIAccelerationPolicy unavailable in current configuration");
}
#endif // __linux__
} // namespace onevpl
} // namespace wip
} // namespace gapi
} // namespace cv
#endif // HAVE_ONEVPL

@ -0,0 +1,62 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef GAPI_STREAMING_ONEVPL_ACCELERATORS_ACCEL_POLICY_VA_API_HPP
#define GAPI_STREAMING_ONEVPL_ACCELERATORS_ACCEL_POLICY_VA_API_HPP
#include <map>
#include <vector>
#include "opencv2/gapi/own/exports.hpp" // GAPI_EXPORTS
#ifdef HAVE_ONEVPL
#include "streaming/onevpl/accelerators/accel_policy_interface.hpp"
#include "streaming/onevpl/accelerators/surface/surface_pool.hpp"
#ifdef __linux__
#if defined(HAVE_VA) || defined(HAVE_VA_INTEL)
#include "va/va.h"
#include "va/va_drm.h"
#else
typedef void* VADisplay;
#endif // defined(HAVE_VA) || defined(HAVE_VA_INTEL)
#endif // __linux__
namespace cv {
namespace gapi {
namespace wip {
namespace onevpl {
// GAPI_EXPORTS for tests
struct GAPI_EXPORTS VPLVAAPIAccelerationPolicy final : public VPLAccelerationPolicy
{
VPLVAAPIAccelerationPolicy(device_selector_ptr_t selector);
~VPLVAAPIAccelerationPolicy();
using pool_t = CachedPool;
void init(session_t session) override;
void deinit(session_t session) override;
pool_key_t create_surface_pool(const mfxFrameAllocRequest& alloc_request, mfxFrameInfo& info) override;
surface_weak_ptr_t get_free_surface(pool_key_t key) override;
size_t get_free_surface_count(pool_key_t key) const override;
size_t get_surface_count(pool_key_t key) const override;
cv::MediaFrame::AdapterPtr create_frame_adapter(pool_key_t key,
const FrameConstructorArgs& args) override;
private:
std::unique_ptr<VPLAccelerationPolicy> cpu_dispatcher;
#ifdef __linux__
VADisplay va_handle;
int device_fd; // TODO Move it out in device selector
#endif // __linux__
};
} // namespace onevpl
} // namespace wip
} // namespace gapi
} // namespace cv
#endif // HAVE_ONEVPL
#endif // GAPI_STREAMING_ONEVPL_ACCELERATORS_ACCEL_POLICY_VA_API_HPP

@ -59,7 +59,7 @@ std::shared_ptr<Surface> BaseFrameAdapter::surface() {
return parent_surface_ptr;
}
const BaseFrameAdapter::SessionHandle BaseFrameAdapter::get_session_handle() const {
BaseFrameAdapter::SessionHandle BaseFrameAdapter::get_session_handle() const {
return parent_handle;
}

@ -23,7 +23,7 @@ public:
using SessionHandle = mfxSession;
const std::shared_ptr<Surface>& get_surface() const;
const SessionHandle get_session_handle() const;
SessionHandle get_session_handle() const;
cv::GFrameDesc meta() const override;
AccelType accel_type() const;

@ -12,6 +12,8 @@
#ifdef HAVE_ONEVPL
#include "streaming/onevpl/onevpl_export.hpp"
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#ifdef HAVE_INF_ENGINE
// For IE classes (ParamMap, etc)
#include <inference_engine.hpp>
@ -202,4 +204,6 @@ DXGI_FORMAT VPLMediaFrameDX11Adapter::get_dx11_color_format(uint32_t mfx_fourcc)
} // namespace wip
} // namespace gapi
} // namespace cv
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
#endif // HAVE_ONEVPL

@ -4,6 +4,7 @@
//
// Copyright (C) 2021 Intel Corporation
#include <opencv2/gapi/own/assert.hpp>
#include "streaming/onevpl/accelerators/surface/surface.hpp"
#include "logger.hpp"
@ -20,12 +21,12 @@ Surface::Surface(std::unique_ptr<handle_t>&& surf, std::shared_ptr<void> associa
mirrored_locked_count() {
GAPI_Assert(mfx_surface && "Surface is nullptr");
GAPI_LOG_DEBUG(nullptr, "create surface: " << mfx_surface <<
GAPI_LOG_DEBUG(nullptr, "create surface: " << get_handle() <<
", locked count: " << mfx_surface->Data.Locked);
}
Surface::~Surface() {
GAPI_LOG_DEBUG(nullptr, "destroy surface: " << mfx_surface <<
GAPI_LOG_DEBUG(nullptr, "destroy surface: " << get_handle() <<
", worspace memory counter: " <<
workspace_memory_ptr.use_count());
}
@ -60,7 +61,7 @@ size_t Surface::get_locks_count() const {
size_t Surface::obtain_lock() {
size_t locked_count = mirrored_locked_count.fetch_add(1);
GAPI_LOG_DEBUG(nullptr, "surface: " << mfx_surface.get() <<
GAPI_LOG_DEBUG(nullptr, "surface: " << get_handle() <<
", locked times: " << locked_count + 1);
return locked_count; // return preceding value
}
@ -68,7 +69,7 @@ size_t Surface::obtain_lock() {
size_t Surface::release_lock() {
size_t locked_count = mirrored_locked_count.fetch_sub(1);
GAPI_Assert(locked_count && "Surface lock counter is invalid");
GAPI_LOG_DEBUG(nullptr, "surface: " << mfx_surface.get() <<
GAPI_LOG_DEBUG(nullptr, "surface: " << get_handle() <<
", locked times: " << locked_count - 1);
return locked_count; // return preceding value
}

@ -1,3 +1,4 @@
#include <opencv2/gapi/own/assert.hpp>
#include "streaming/onevpl/accelerators/surface/surface_pool.hpp"
#include "streaming/onevpl/accelerators/surface/surface.hpp"
#include "logger.hpp"

@ -9,6 +9,7 @@
#include <opencv2/gapi/own/assert.hpp>
#include <opencv2/gapi/util/variant.hpp>
#include <opencv2/gapi/streaming/onevpl/device_selector_interface.hpp>
#include "streaming/onevpl/cfg_param_device_selector.hpp"
#include "streaming/onevpl/cfg_params_parser.hpp"
#include "streaming/onevpl/utils.hpp"
@ -26,25 +27,27 @@
#pragma comment(lib, "dxgi")
#undef D3D11_NO_HELPERS
#undef NOMINMAX
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
#include <codecvt>
#include "opencv2/core/directx.hpp"
#ifdef HAVE_OPENCL
#include <CL/cl_d3d11.h>
#endif
namespace cv {
namespace gapi {
namespace wip {
namespace onevpl {
std::vector<CfgParam> insertCfgparam(std::vector<CfgParam> &&param_array, AccelType type) {
static std::vector<CfgParam> insertCfgparam(std::vector<CfgParam> &&param_array, AccelType type) {
switch (type) {
case AccelType::HOST:
break;
case AccelType::DX11:
param_array.push_back(CfgParam::create_acceleration_mode(MFX_ACCEL_MODE_VIA_D3D11));
break;
case AccelType::VAAPI:
param_array.push_back(CfgParam::create_acceleration_mode(MFX_IMPL_VIA_VAAPI));
break;
default:
GAPI_DbgAssert(false && "Unexpected AccelType");
break;
@ -71,8 +74,7 @@ CfgParamDeviceSelector::CfgParamDeviceSelector(const CfgParams& cfg_params) :
switch(accel_mode.Data.U32) {
case MFX_ACCEL_MODE_VIA_D3D11: {
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
ID3D11Device *hw_handle = nullptr;
ID3D11DeviceContext* device_context = nullptr;
@ -141,14 +143,17 @@ CfgParamDeviceSelector::CfgParamDeviceSelector(const CfgParams& cfg_params) :
suggested_device = IDeviceSelector::create<Device>(hw_handle, "GPU", AccelType::DX11);
suggested_context = IDeviceSelector::create<Context>(device_context, AccelType::DX11);
#else
#else // defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
GAPI_LOG_WARNING(nullptr, "Unavailable \"" << CfgParam::acceleration_mode_name() << ": MFX_ACCEL_MODE_VIA_D3D11\""
"was chosen for current project configuration");
throw std::logic_error(std::string("Unsupported \"") +
CfgParam::acceleration_mode_name() +
": MFX_ACCEL_MODE_VIA_D3D11\"");
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
#endif // defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
break;
}
case MFX_IMPL_VIA_VAAPI : {
GAPI_LOG_WARNING(nullptr, "TODO MFX_IMPL_VIA_VAAPI falls back to CPU case")
break;
}
case MFX_ACCEL_MODE_NA: {
@ -198,10 +203,10 @@ CfgParamDeviceSelector::CfgParamDeviceSelector(Device::Ptr device_ptr,
}
mfxVariant accel_mode = cfg_param_to_mfx_variant(*accel_mode_it);
cv::util::suppress_unused_warning(device_id);
switch(accel_mode.Data.U32) {
case MFX_ACCEL_MODE_VIA_D3D11: {
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
suggested_device = IDeviceSelector::create<Device>(device_ptr, device_id, AccelType::DX11);
ID3D11Device* dx_device_ptr =
reinterpret_cast<ID3D11Device*>(suggested_device.get_ptr());
@ -220,14 +225,13 @@ CfgParamDeviceSelector::CfgParamDeviceSelector(Device::Ptr device_ptr,
}
dx_ctx_ptr->AddRef();
#else
#else // defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
GAPI_LOG_WARNING(nullptr, "Unavailable \"" << CfgParam::acceleration_mode_name() <<
": MFX_ACCEL_MODE_VIA_D3D11\""
"was chosen for current project configuration");
throw std::logic_error(std::string("Unsupported \"") +
CfgParam::acceleration_mode_name() + ": MFX_ACCEL_MODE_VIA_D3D11\"");
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
#endif // #if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
break;
}
case MFX_ACCEL_MODE_NA: {
@ -253,8 +257,7 @@ CfgParamDeviceSelector::CfgParamDeviceSelector(const Device &device,
switch(device.get_type()) {
case AccelType::DX11: {
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
ID3D11Device* dx_device_ptr =
reinterpret_cast<ID3D11Device*>(suggested_device.get_ptr());
dx_device_ptr->AddRef();
@ -272,15 +275,17 @@ CfgParamDeviceSelector::CfgParamDeviceSelector(const Device &device,
dx_ctx_ptr->AddRef();
break;
#else
#else // defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
GAPI_LOG_WARNING(nullptr, "Unavailable \"" << CfgParam::acceleration_mode_name() <<
": MFX_ACCEL_MODE_VIA_D3D11\""
"was chosen for current project configuration");
throw std::logic_error(std::string("Unsupported \"") +
CfgParam::acceleration_mode_name() + ": MFX_ACCEL_MODE_VIA_D3D11\"");
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
#endif // defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
}
case AccelType::VAAPI:
GAPI_LOG_WARNING(nullptr, "TODO MFX_IMPL_VIA_VAAPI falls back to CPU case")
break;
case AccelType::HOST:
break;
default:
@ -299,14 +304,12 @@ CfgParamDeviceSelector::~CfgParamDeviceSelector() {
//nothing to do
break;
case AccelType::DX11: {
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
ID3D11DeviceContext* device_ctx_ptr =
reinterpret_cast<ID3D11DeviceContext*>(suggested_context.get_ptr());
device_ctx_ptr->Release();
device_ctx_ptr = nullptr;
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
#endif // defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
break;
}
default:
@ -322,13 +325,11 @@ CfgParamDeviceSelector::~CfgParamDeviceSelector() {
//nothing to do
break;
case AccelType::DX11: {
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
ID3D11Device* device_ptr = reinterpret_cast<ID3D11Device*>(suggested_device.get_ptr());
device_ptr->Release();
device_ptr = nullptr;
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
#endif // defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
break;
}
default:
@ -337,7 +338,7 @@ CfgParamDeviceSelector::~CfgParamDeviceSelector() {
}
CfgParamDeviceSelector::DeviceScoreTable CfgParamDeviceSelector::select_devices() const {
return {std::make_pair(Score::MaxActivePriority, suggested_device)};
return {std::make_pair(Score::Type(Score::MaxActivePriority), suggested_device)};
}
CfgParamDeviceSelector::DeviceContexts CfgParamDeviceSelector::select_context() {
@ -348,6 +349,4 @@ CfgParamDeviceSelector::DeviceContexts CfgParamDeviceSelector::select_context()
} // namespace wip
} // namespace gapi
} // namespace cv
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
#endif // HAVE_ONEVPL

@ -87,15 +87,15 @@ std::vector<ValueType> get_params_from_string(const std::string& str) {
ParamCreator<ValueType> creator;
if (name == CfgParam::implementation_name()) {
ret.push_back(creator.create<mfxU32>(name, cstr_to_mfx_impl(value.c_str())));
ret.push_back(creator.template create<mfxU32>(name, cstr_to_mfx_impl(value.c_str())));
} else if (name == CfgParam::decoder_id_name()) {
ret.push_back(creator.create<mfxU32>(name, cstr_to_mfx_codec_id(value.c_str())));
ret.push_back(creator.template create<mfxU32>(name, cstr_to_mfx_codec_id(value.c_str())));
} else if (name == CfgParam::acceleration_mode_name()) {
ret.push_back(creator.create<mfxU32>(name, cstr_to_mfx_accel_mode(value.c_str())));
ret.push_back(creator.template create<mfxU32>(name, cstr_to_mfx_accel_mode(value.c_str())));
} else if (name == "mfxImplDescription.ApiVersion.Version") {
ret.push_back(creator.create<mfxU32>(name, cstr_to_mfx_version(value.c_str())));
ret.push_back(creator.template create<mfxU32>(name, cstr_to_mfx_version(value.c_str())));
} else if ((name == CfgParam::frames_pool_size_name()) || (name == CfgParam::vpp_frames_pool_size_name())) {
ret.push_back(creator.create(name, strtoull_or_throw(value.c_str()), false));
ret.push_back(creator.create(name, static_cast<mfxU32>(strtoull_or_throw(value.c_str()), false)));
} else if ((name == CfgParam::vpp_in_width_name()) || (name == CfgParam::vpp_in_height_name()) ||
(name == CfgParam::vpp_in_crop_w_name()) || (name == CfgParam::vpp_in_crop_h_name()) ||
(name == CfgParam::vpp_in_crop_x_name()) || (name == CfgParam::vpp_in_crop_y_name()) ||
@ -186,7 +186,7 @@ unsigned long strtoul_or_throw(const char* str) {
errno = 0;
unsigned long ret = strtoul(str, &end_ptr, 10);
if ((end_ptr == str) ||
((ret == ULONG_MAX || ret == LONG_MIN) && errno == ERANGE)) {
((ret == ULONG_MAX) && errno == ERANGE)) {
// nothing parsed from the string, handle errors or exit
GAPI_LOG_WARNING(nullptr, "strtoul failed for: " << str);
GAPI_Assert(false && "strtoul_or_throw");
@ -199,7 +199,7 @@ size_t strtoull_or_throw(const char* str) {
errno = 0;
size_t ret = strtoull(str, &end_ptr, 10);
if ((end_ptr == str) ||
((ret == LONG_MAX || ret == LONG_MIN) && errno == ERANGE)) {
((ret == ULLONG_MAX) && errno == ERANGE)) {
// nothing parsed from the string, handle errors or exit
GAPI_LOG_WARNING(nullptr, "strtoull failed for: " << str);
GAPI_Assert(false && "strtoull_or_throw");

@ -14,6 +14,7 @@
#pragma comment(lib, "mfreadwrite.lib")
#endif // _WIN32
#include <opencv2/gapi/own/assert.hpp>
#include "streaming/onevpl/demux/async_mfp_demux_data_provider.hpp"
#include "logger.hpp"
@ -807,7 +808,7 @@ bool MFPAsyncDemuxDataProvider::fetch_bitstream_data(std::shared_ptr<mfx_bitstre
return false;
}
bool MFPAsyncDemuxDataProvider::empty() const override {
bool MFPAsyncDemuxDataProvider::empty() const {
GAPI_Assert(false && "Unsupported: Microsoft Media Foundation is not available");
return true;
}

@ -14,6 +14,7 @@
#ifdef HAVE_ONEVPL
#include "streaming/onevpl/onevpl_export.hpp"
#include <opencv2/gapi/streaming/onevpl/data_provider_interface.hpp>
#ifdef _WIN32
#define NOMINMAX
@ -28,7 +29,6 @@
#include <wmcodecdsp.h>
#undef NOMINMAX
#include <opencv2/gapi/streaming/onevpl/data_provider_interface.hpp>
#include "streaming/onevpl/data_provider_defines.hpp"
#include "streaming/onevpl/utils.hpp"

@ -20,6 +20,8 @@ const char* to_cstring(AccelType type) {
return "HOST";
case AccelType::DX11:
return "DX11";
case AccelType::VAAPI:
return "VAAPI";
default:
GAPI_DbgAssert(false && "Unexpected AccelType");
break;

@ -175,6 +175,7 @@ VPLLegacyDecodeEngine::SessionParam VPLLegacyDecodeEngine::prepare_session_param
// Prepare video param
mfxVideoParam mfxDecParams {};
memset(&mfxDecParams, 0, sizeof(mfxDecParams));
mfxDecParams.mfx.CodecId = decoder_id_name;
// set memory stream direction according to acceleration policy device type
@ -253,7 +254,8 @@ VPLLegacyDecodeEngine::SessionParam VPLLegacyDecodeEngine::prepare_session_param
// Input parameters finished, now initialize decode
// create decoder for session according to header recovered from source file
GAPI_LOG_INFO(nullptr, "Initialize decoder for session: " << mfx_session <<
", frame info: " << mfx_frame_info_to_string(mfxDecParams.mfx.FrameInfo));
sts = MFXVideoDECODE_Init(mfx_session, &mfxDecParams);
if (MFX_ERR_NONE != sts) {
throw std::runtime_error("Error initializing Decode, error: " +

@ -21,6 +21,9 @@ namespace gapi {
namespace wip {
namespace onevpl {
class Surface;
struct VPLAccelerationPolicy;
class VPLLegacyDecodeEngine;
class GAPI_EXPORTS LegacyDecodeSession : public EngineSession {
public:
friend class VPLLegacyDecodeEngine;

@ -14,6 +14,7 @@
#include <utility>
#include <vector>
#include "opencv2/gapi/util/optional.hpp"
#include "opencv2/gapi/own/exports.hpp" // GAPI_EXPORTS
#include <opencv2/gapi/streaming/onevpl/data_provider_interface.hpp>
#include "streaming/onevpl/data_provider_defines.hpp"
@ -31,7 +32,7 @@ namespace onevpl {
struct GAPI_EXPORTS DecoderParams {
std::shared_ptr<IDataProvider::mfx_bitstream> stream;
mfxVideoParam param;
cv::optional<size_t> preallocated_frames_count;
cv::util::optional<size_t> preallocated_frames_count;
};
struct GAPI_EXPORTS TranscoderParams {

@ -34,8 +34,8 @@ bool FrameInfoComparator::equal_to(const mfxFrameInfo& lhs, const mfxFrameInfo&
return lhs == rhs;
}
void apply_roi(mfxFrameSurface1* surface_handle,
const cv::util::optional<cv::Rect> &opt_roi) {
static void apply_roi(mfxFrameSurface1* surface_handle,
const cv::util::optional<cv::Rect> &opt_roi) {
if (opt_roi.has_value()) {
const cv::Rect &roi = opt_roi.value();
surface_handle->Info.CropX = static_cast<mfxU16>(roi.x);
@ -176,7 +176,8 @@ pp_session VPPPreprocEngine::initialize_preproc(const pp_params& initial_frame_p
const vpp_pp_params &params = initial_frame_param.get<vpp_pp_params>();
// adjust preprocessing settings
mfxVideoParam mfxVPPParams{0};
mfxVideoParam mfxVPPParams{};
memset(&mfxVPPParams, 0, sizeof(mfxVideoParam));
// NB: IN params for VPP session must be equal to decoded surface params
mfxVPPParams.vpp.In = params.info;

@ -16,12 +16,18 @@ namespace gapi {
namespace wip {
namespace onevpl {
struct vpp_pp_params {
vpp_pp_params() : handle(), info(), reserved() {}
vpp_pp_params(mfxSession s, mfxFrameInfo i, void *r = nullptr) :
handle(s), info(i), reserved(r) {}
mfxSession handle;
mfxFrameInfo info;
void *reserved = nullptr;
};
struct vpp_pp_session {
vpp_pp_session() : handle(), reserved() {}
vpp_pp_session(std::shared_ptr<EngineSession> h, void *r = nullptr) :
handle(h), reserved(r) {}
std::shared_ptr<EngineSession> handle;
void *reserved = nullptr;
};

@ -9,6 +9,7 @@
#include <queue>
#include <opencv2/gapi/streaming/onevpl/cfg_params.hpp>
#include <opencv2/gapi/garg.hpp>
#include "streaming/onevpl/engine/engine_session.hpp"
#include "opencv2/gapi/own/exports.hpp" // GAPI_EXPORTS

@ -269,7 +269,8 @@ VPLLegacyTranscodeEngine::initialize_session(mfxSession mfx_session,
const auto& mfxDecParams = decode_params.decoder_params.param;
// NB: create transcode params: Out = In by default, In = initially decoded
mfxVideoParam mfxVPPParams{0};
mfxVideoParam mfxVPPParams{};
memset(&mfxVPPParams, 0, sizeof(mfxVPPParams));
mfxVPPParams.vpp.In = mfxDecParams.mfx.FrameInfo;
mfxVPPParams.vpp.Out = mfxVPPParams.vpp.In;
@ -366,6 +367,8 @@ VPLLegacyTranscodeEngine::initialize_session(mfxSession mfx_session,
VPLAccelerationPolicy::pool_key_t vpp_out_pool_key =
acceleration_policy->create_surface_pool(vppRequests[1], mfxVPPParams.vpp.Out);
GAPI_LOG_INFO(nullptr, "Initialize VPP for session: " << mfx_session <<
", out frame info: " << mfx_frame_info_to_string(mfxVPPParams.vpp.Out));
sts = MFXVideoVPP_Init(mfx_session, &mfxVPPParams);
if (MFX_ERR_NONE != sts) {
GAPI_LOG_WARNING(nullptr, "cannot Init VPP");

@ -15,7 +15,7 @@ namespace gapi {
namespace wip {
namespace onevpl {
class Surface;
class VPLLegacyTranscodeEngine;
class GAPI_EXPORTS LegacyTranscodeSession : public LegacyDecodeSession {
public:
friend class VPLLegacyTranscodeEngine;

@ -10,9 +10,11 @@
#endif // defined(_MSC_VER)
#ifdef HAVE_ONEVPL
#if defined(MFX_VERSION)
#if (MFX_VERSION >= 2000)
#include <vpl/mfxdispatcher.h>
#endif // MFX_VERSION
#endif // defined(MFX_VERSION)
#include <vpl/mfx.h>
#include <vpl/mfxvideo.h>

@ -11,6 +11,7 @@
#include "streaming/onevpl/engine/transcode/transcode_engine_legacy.hpp"
#include "streaming/onevpl/accelerators/accel_policy_dx11.hpp"
#include "streaming/onevpl/accelerators/accel_policy_cpu.hpp"
#include "streaming/onevpl/accelerators/accel_policy_va_api.hpp"
#include "streaming/onevpl/utils.hpp"
#include "streaming/onevpl/cfg_params_parser.hpp"
#include "streaming/onevpl/data_provider_defines.hpp"
@ -294,6 +295,12 @@ std::unique_ptr<VPLAccelerationPolicy> GSource::Priv::initializeHWAccel(std::sha
ret = std::move(cand);
break;
}
case MFX_ACCEL_MODE_VIA_VAAPI:
{
std::unique_ptr<VPLVAAPIAccelerationPolicy> cand(new VPLVAAPIAccelerationPolicy(selector));
ret = std::move(cand);
break;
}
case MFX_ACCEL_MODE_NA:
{
std::unique_ptr<VPLCPUAccelerationPolicy> cand(new VPLCPUAccelerationPolicy(selector));

@ -357,7 +357,7 @@ std::string mfxstatus_to_string(mfxStatus err) {
}
std::string ret("<unknown ");
ret += std::to_string(err) + ">";
ret += std::to_string(static_cast<size_t>(err)) + ">";
return ret;
}
@ -384,7 +384,7 @@ std::string mfx_frame_info_to_string(const mfxFrameInfo &info) {
return ss.str();
}
int compare(const mfxFrameInfo &lhs, const mfxFrameInfo &rhs) {
static int compare(const mfxFrameInfo &lhs, const mfxFrameInfo &rhs) {
//NB: mfxFrameInfo is a `packed` struct declared in VPL
return memcmp(&lhs, &rhs, sizeof(mfxFrameInfo));
}

@ -2440,7 +2440,11 @@ TEST(OneVPL_Source, Init)
std::vector<CfgParam> src_params;
src_params.push_back(CfgParam::create_implementation(MFX_IMPL_TYPE_HARDWARE));
#ifdef __WIN32
src_params.push_back(CfgParam::create_acceleration_mode(MFX_ACCEL_MODE_VIA_D3D11));
#elif defined(__linux__)
src_params.push_back(CfgParam::create_acceleration_mode(MFX_ACCEL_MODE_VIA_VAAPI));
#endif
src_params.push_back(CfgParam::create_decoder_id(MFX_CODEC_HEVC));
std::stringstream stream(std::ios_base::in | std::ios_base::out | std::ios_base::binary);

@ -36,6 +36,7 @@
#include "streaming/onevpl/accelerators/surface/cpu_frame_adapter.hpp"
#include "streaming/onevpl/accelerators/accel_policy_cpu.hpp"
#include "streaming/onevpl/accelerators/accel_policy_dx11.hpp"
#include "streaming/onevpl/accelerators/accel_policy_va_api.hpp"
#include "streaming/onevpl/accelerators/dx11_alloc_resource.hpp"
#include "streaming/onevpl/accelerators/utils/shared_lock.hpp"
#define private public
@ -79,7 +80,7 @@ struct TestProcessingSession : public cv::gapi::wip::onevpl::EngineSession {
struct TestProcessingEngine: public cv::gapi::wip::onevpl::ProcessingEngineBase {
size_t pipeline_stage_num = 0;
int pipeline_stage_num = 0;
TestProcessingEngine(std::unique_ptr<cv::gapi::wip::onevpl::VPLAccelerationPolicy>&& accel) :
cv::gapi::wip::onevpl::ProcessingEngineBase(std::move(accel)) {
@ -154,7 +155,7 @@ private:
mfxFrameAllocator m_allocator;
};
template <class LockProcessor, class UnlockProcessor>
std::map<mfxMemId, UnlockProcessor> TestLockableAllocator<LockProcessor, UnlockProcessor>::lock_processor_table {};
std::map<mfxMemId, LockProcessor> TestLockableAllocator<LockProcessor, UnlockProcessor>::lock_processor_table {};
template <class LockProcessor, class UnlockProcessor>
std::map<mfxMemId, UnlockProcessor> TestLockableAllocator<LockProcessor, UnlockProcessor>::unlock_processor_table {};
@ -194,11 +195,11 @@ TEST(OneVPL_Source_Surface, InitSurface)
// check self consistency
EXPECT_EQ(reinterpret_cast<void*>(surf->get_handle()),
reinterpret_cast<void*>(mfx_core_handle));
EXPECT_EQ(0, surf->get_locks_count());
EXPECT_EQ(0, surf->obtain_lock());
EXPECT_EQ(1, surf->get_locks_count());
EXPECT_EQ(1, surf->release_lock());
EXPECT_EQ(0, surf->get_locks_count());
EXPECT_TRUE(0 == surf->get_locks_count());
EXPECT_TRUE(0 == surf->obtain_lock());
EXPECT_TRUE(1 == surf->get_locks_count());
EXPECT_TRUE(1 == surf->release_lock());
EXPECT_TRUE(0 == surf->get_locks_count());
}
TEST(OneVPL_Source_Surface, ConcurrentLock)
@ -213,7 +214,7 @@ TEST(OneVPL_Source_Surface, ConcurrentLock)
auto surf = Surface::create_surface(std::move(handle), associated_memory);
// check self consistency
EXPECT_EQ(0, surf->get_locks_count());
EXPECT_TRUE(0 == surf->get_locks_count());
// MFX internal limitation: do not exceede U16 range
// so I16 is using here
@ -238,7 +239,7 @@ TEST(OneVPL_Source_Surface, ConcurrentLock)
}
worker_thread.join();
EXPECT_EQ(lock_counter * 2, surf->get_locks_count());
EXPECT_TRUE(static_cast<size_t>(lock_counter * 2) == surf->get_locks_count());
}
TEST(OneVPL_Source_Surface, MemoryLifeTime)
@ -271,7 +272,7 @@ TEST(OneVPL_Source_Surface, MemoryLifeTime)
}
// workspace memory must be alive
EXPECT_EQ(0, surfaces.size());
EXPECT_TRUE(0 == surfaces.size());
EXPECT_TRUE(associated_memory != nullptr);
EXPECT_TRUE(preallocated_memory_ptr.get() != nullptr);
@ -293,7 +294,7 @@ TEST(OneVPL_Source_Surface, MemoryLifeTime)
associated_memory.reset();
// workspace memory must be still alive
EXPECT_EQ(0, surfaces.size());
EXPECT_TRUE(0 == surfaces.size());
EXPECT_TRUE(associated_memory == nullptr);
EXPECT_TRUE(preallocated_memory_ptr.get() != nullptr);
@ -316,14 +317,14 @@ TEST(OneVPL_Source_CPU_FrameAdapter, InitFrameAdapter)
auto surf = Surface::create_surface(std::move(handle), associated_memory);
// check consistency
EXPECT_EQ(0, surf->get_locks_count());
EXPECT_TRUE(0 == surf->get_locks_count());
{
mfxSession stub_session = reinterpret_cast<mfxSession>(0x1);
VPLMediaFrameCPUAdapter adapter(surf, stub_session);
EXPECT_EQ(1, surf->get_locks_count());
EXPECT_TRUE(1 == surf->get_locks_count());
}
EXPECT_EQ(0, surf->get_locks_count());
EXPECT_TRUE(0 == surf->get_locks_count());
}
TEST(OneVPL_Source_CPU_Accelerator, InitDestroy)
@ -385,13 +386,13 @@ TEST(OneVPL_Source_CPU_Accelerator, PoolProduceConsume)
for (size_t i = 0; i < surface_count; i++) {
std::shared_ptr<Surface> surf = acceleration_policy->get_free_surface(key).lock();
EXPECT_TRUE(surf.get() != nullptr);
EXPECT_EQ(0, surf->obtain_lock());
EXPECT_TRUE(0 == surf->obtain_lock());
surfaces.push_back(std::move(surf));
}
// check consistency (no free surfaces)
EXPECT_EQ(acceleration_policy->get_surface_count(key), surface_count);
EXPECT_EQ(0, acceleration_policy->get_free_surface_count(key));
EXPECT_TRUE(0 == acceleration_policy->get_free_surface_count(key));
// fail consume non-free surfaces
for (size_t i = 0; i < surface_count; i++) {
@ -400,7 +401,7 @@ TEST(OneVPL_Source_CPU_Accelerator, PoolProduceConsume)
// release surfaces
for (auto& surf : surfaces) {
EXPECT_EQ(1, surf->release_lock());
EXPECT_TRUE(1 == surf->release_lock());
}
surfaces.clear();
@ -412,7 +413,7 @@ TEST(OneVPL_Source_CPU_Accelerator, PoolProduceConsume)
for (size_t i = 0; i < surface_count; i++) {
std::shared_ptr<Surface> surf = acceleration_policy->get_free_surface(key).lock();
EXPECT_TRUE(surf.get() != nullptr);
EXPECT_EQ(0, surf->obtain_lock());
EXPECT_TRUE(0 == surf->obtain_lock());
}
}
@ -444,7 +445,7 @@ TEST(OneVPL_Source_CPU_Accelerator, PoolProduceConcurrentConsume)
for (size_t i = 0; i < surface_count; i++) {
std::shared_ptr<Surface> surf = acceleration_policy->get_free_surface(key).lock();
EXPECT_TRUE(surf.get() != nullptr);
EXPECT_EQ(0, surf->obtain_lock());
EXPECT_TRUE(0 == surf->obtain_lock());
surfaces.push_back(std::move(surf));
}
@ -458,7 +459,7 @@ TEST(OneVPL_Source_CPU_Accelerator, PoolProduceConcurrentConsume)
// concurrent release surfaces
size_t surfaces_count = surfaces.size();
for (auto& surf : surfaces) {
EXPECT_EQ(1, surf->release_lock());
EXPECT_TRUE(1 == surf->release_lock());
std::this_thread::sleep_for(std::chrono::seconds(1));
}
surfaces.clear();
@ -492,7 +493,7 @@ TEST(OneVPL_Source_ProcessingEngine, Init)
mfxSession mfx_session{};
engine.initialize_session(mfx_session, {}, std::shared_ptr<IDataProvider>{});
EXPECT_EQ(0, engine.get_ready_frames_count());
EXPECT_TRUE(0 == engine.get_ready_frames_count());
ProcessingEngineBase::ExecutionStatus ret = engine.process(mfx_session);
EXPECT_EQ(ret, ProcessingEngineBase::ExecutionStatus::Continue);
EXPECT_EQ(0, engine.pipeline_stage_num);
@ -508,12 +509,12 @@ TEST(OneVPL_Source_ProcessingEngine, Init)
ret = engine.process(mfx_session);
EXPECT_EQ(ret, ProcessingEngineBase::ExecutionStatus::Processed);
EXPECT_EQ(3, engine.pipeline_stage_num);
EXPECT_EQ(1, engine.get_ready_frames_count());
EXPECT_TRUE(1 == engine.get_ready_frames_count());
ret = engine.process(mfx_session);
EXPECT_EQ(ret, ProcessingEngineBase::ExecutionStatus::SessionNotFound);
EXPECT_EQ(3, engine.pipeline_stage_num);
EXPECT_EQ(1, engine.get_ready_frames_count());
EXPECT_TRUE(1 == engine.get_ready_frames_count());
cv::gapi::wip::Data frame;
engine.get_frame(frame);
@ -603,7 +604,98 @@ TEST(OneVPL_Source_DX11_Accel, Init)
MFXClose(mfx_session);
MFXUnload(test_mfx_handle);
}
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
#ifdef __linux__
#if defined(HAVE_VA) || defined(HAVE_VA_INTEL)
TEST(OneVPL_Source_VAAPI_Accel, Init)
{
using namespace cv::gapi::wip::onevpl;
std::vector<CfgParam> cfg_params_w_vaapi;
cfg_params_w_vaapi.push_back(CfgParam::create_acceleration_mode(MFX_ACCEL_MODE_VIA_VAAPI));
VPLVAAPIAccelerationPolicy accel(std::make_shared<CfgParamDeviceSelector>(cfg_params_w_vaapi));
mfxLoader test_mfx_handle = MFXLoad();
mfxConfig cfg_inst_0 = MFXCreateConfig(test_mfx_handle);
EXPECT_TRUE(cfg_inst_0);
mfxVariant mfx_param_0;
mfx_param_0.Type = MFX_VARIANT_TYPE_U32;
mfx_param_0.Data.U32 = MFX_IMPL_TYPE_HARDWARE;
EXPECT_EQ(MFXSetConfigFilterProperty(cfg_inst_0,(mfxU8 *)CfgParam::implementation_name(),
mfx_param_0), MFX_ERR_NONE);
mfxConfig cfg_inst_1 = MFXCreateConfig(test_mfx_handle);
EXPECT_TRUE(cfg_inst_1);
mfxVariant mfx_param_1;
mfx_param_1.Type = MFX_VARIANT_TYPE_U32;
mfx_param_1.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI;
EXPECT_EQ(MFXSetConfigFilterProperty(cfg_inst_1,(mfxU8 *)CfgParam::acceleration_mode_name(),
mfx_param_1), MFX_ERR_NONE);
mfxConfig cfg_inst_2 = MFXCreateConfig(test_mfx_handle);
EXPECT_TRUE(cfg_inst_2);
mfxVariant mfx_param_2;
mfx_param_2.Type = MFX_VARIANT_TYPE_U32;
mfx_param_2.Data.U32 = MFX_CODEC_HEVC;
EXPECT_EQ(MFXSetConfigFilterProperty(cfg_inst_2,(mfxU8 *)CfgParam::decoder_id_name(),
mfx_param_2), MFX_ERR_NONE);
// create session
mfxSession mfx_session{};
mfxStatus sts = MFXCreateSession(test_mfx_handle, 0, &mfx_session);
EXPECT_EQ(MFX_ERR_NONE, sts);
// assign acceleration
EXPECT_NO_THROW(accel.init(mfx_session));
// create proper bitstream
mfxBitstream bitstream{};
const int BITSTREAM_BUFFER_SIZE = 2000000;
bitstream.MaxLength = BITSTREAM_BUFFER_SIZE;
bitstream.Data = (mfxU8 *)calloc(bitstream.MaxLength, sizeof(mfxU8));
EXPECT_TRUE(bitstream.Data);
// simulate read stream
bitstream.DataOffset = 0;
bitstream.DataLength = sizeof(streaming::onevpl::hevc_header) * sizeof(streaming::onevpl::hevc_header[0]);
memcpy(bitstream.Data, streaming::onevpl::hevc_header, bitstream.DataLength);
bitstream.CodecId = MFX_CODEC_HEVC;
// prepare dec params
mfxVideoParam mfxDecParams {};
mfxDecParams.mfx.CodecId = bitstream.CodecId;
mfxDecParams.IOPattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
sts = MFXVideoDECODE_DecodeHeader(mfx_session, &bitstream, &mfxDecParams);
EXPECT_EQ(MFX_ERR_NONE, sts);
mfxFrameAllocRequest request{};
memset(&request, 0, sizeof(request));
sts = MFXVideoDECODE_QueryIOSurf(mfx_session, &mfxDecParams, &request);
EXPECT_EQ(MFX_ERR_NONE, sts);
// Allocate surfaces for decoder
VPLAccelerationPolicy::pool_key_t key = accel.create_surface_pool(request,
mfxDecParams.mfx.FrameInfo);
auto cand_surface = accel.get_free_surface(key).lock();
sts = MFXVideoDECODE_Init(mfx_session, &mfxDecParams);
EXPECT_EQ(MFX_ERR_NONE, sts);
MFXVideoDECODE_Close(mfx_session);
EXPECT_EQ(MFX_ERR_NONE, sts);
EXPECT_NO_THROW(accel.deinit(mfx_session));
MFXClose(mfx_session);
MFXUnload(test_mfx_handle);
}
#endif // defined(HAVE_VA) || defined(HAVE_VA_INTEL)
#endif // __linux__
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
TEST(OneVPL_Source_DX11_Accel_VPL, Init)
{
using namespace cv::gapi::wip::onevpl;
@ -1024,8 +1116,6 @@ TEST(OneVPL_Source_DX11_Accel_VPL, preproc)
}
} while(frame_num < min_available_frames_count);
}
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
TEST(OneVPL_Source_DX11_FrameLockable, LockUnlock_without_Adaptee)
{
@ -1114,6 +1204,8 @@ TEST(OneVPL_Source_DX11_FrameLockable, LockUnlock_with_Adaptee)
EXPECT_EQ(w_lock_counter, exec_count);
EXPECT_EQ(w_unlock_counter, exec_count);
}
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
}
} // namespace opencv_test
#endif // HAVE_ONEVPL

@ -16,6 +16,7 @@
#include "streaming/onevpl/demux/async_mfp_demux_data_provider.hpp"
#include "streaming/onevpl/source_priv.hpp"
#ifdef _WIN32
namespace opencv_test
{
namespace
@ -299,4 +300,5 @@ TEST(OneVPL_Source_MFPAsyncDemux, produce_consume) {
}
} // namespace opencv_test
#endif // _WIN32
#endif // HAVE_ONEVPL

@ -69,11 +69,11 @@ TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDevice)
using namespace cv::gapi::wip::onevpl;
CfgParamDeviceSelector selector;
IDeviceSelector::DeviceScoreTable devs = selector.select_devices();
EXPECT_EQ(devs.size(), 1);
EXPECT_TRUE(devs.size() == 1);
test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority);
IDeviceSelector::DeviceContexts ctxs = selector.select_context();
EXPECT_EQ(ctxs.size(), 1);
EXPECT_TRUE(ctxs.size() == 1);
test_host_ctx_eq(*ctxs.begin());
}
@ -83,10 +83,10 @@ TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceWithEmptyCfgParam)
std::vector<CfgParam> empty_params;
CfgParamDeviceSelector selector(empty_params);
IDeviceSelector::DeviceScoreTable devs = selector.select_devices();
EXPECT_EQ(devs.size(), 1);
EXPECT_TRUE(devs.size() == 1);
test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority);
IDeviceSelector::DeviceContexts ctxs = selector.select_context();
EXPECT_EQ(ctxs.size(), 1);
EXPECT_TRUE(ctxs.size() == 1);
test_host_ctx_eq(*ctxs.begin());
}
@ -97,11 +97,11 @@ TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceWithAccelNACfgParam)
cfg_params_w_no_accel.push_back(CfgParam::create_acceleration_mode(MFX_ACCEL_MODE_NA));
CfgParamDeviceSelector selector(cfg_params_w_no_accel);
IDeviceSelector::DeviceScoreTable devs = selector.select_devices();
EXPECT_EQ(devs.size(), 1);
EXPECT_TRUE(devs.size() == 1);
test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority);
IDeviceSelector::DeviceContexts ctxs = selector.select_context();
EXPECT_EQ(ctxs.size(), 1);
EXPECT_TRUE(ctxs.size() == 1);
test_host_ctx_eq(*ctxs.begin());
}
@ -113,11 +113,11 @@ TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceWithEmptyCfgParam_DX11
std::vector<CfgParam> empty_params;
CfgParamDeviceSelector selector(empty_params);
IDeviceSelector::DeviceScoreTable devs = selector.select_devices();
EXPECT_EQ(devs.size(), 1);
EXPECT_TRUE(devs.size() == 1);
test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority);
IDeviceSelector::DeviceContexts ctxs = selector.select_context();
EXPECT_EQ(ctxs.size(), 1);
EXPECT_TRUE(ctxs.size() == 1);
test_host_ctx_eq(*ctxs.begin());
}
@ -130,13 +130,13 @@ TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceWithDX11AccelCfgParam_
EXPECT_NO_THROW(selector_ptr.reset(new CfgParamDeviceSelector(cfg_params_w_dx11)));
IDeviceSelector::DeviceScoreTable devs = selector_ptr->select_devices();
EXPECT_EQ(devs.size(), 1);
EXPECT_TRUE(devs.size() == 1);
test_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority,
AccelType::DX11,
std::get<1>(*devs.begin()).get_ptr() /* compare just type */);
IDeviceSelector::DeviceContexts ctxs = selector_ptr->select_context();
EXPECT_EQ(ctxs.size(), 1);
EXPECT_TRUE(ctxs.size() == 1);
EXPECT_TRUE(ctxs.begin()->get_ptr());
}
@ -182,12 +182,12 @@ TEST(OneVPL_Source_Device_Selector_CfgParam, ExternalDeviceWithDX11AccelCfgParam
cfg_params_w_dx11)));
IDeviceSelector::DeviceScoreTable devs = selector_ptr->select_devices();
EXPECT_EQ(devs.size(), 1);
EXPECT_TRUE(devs.size() == 1);
test_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority,
AccelType::DX11, device);
IDeviceSelector::DeviceContexts ctxs = selector_ptr->select_context();
EXPECT_EQ(ctxs.size(), 1);
EXPECT_TRUE(ctxs.size() == 1);
EXPECT_EQ(reinterpret_cast<ID3D11DeviceContext*>(ctxs.begin()->get_ptr()),
device_context);
}
@ -201,7 +201,7 @@ TEST(OneVPL_Source_Device_Selector_CfgParam, DX11DeviceFromCfgParamWithDX11Disab
{
using namespace cv::gapi::wip::onevpl;
std::vector<CfgParam> cfg_params_w_non_existed_dx11;
cfg_params_w_not_existed_dx11.push_back(CfgParam::create_acceleration_mode(MFX_ACCEL_MODE_VIA_D3D11));
cfg_params_w_non_existed_dx11.push_back(CfgParam::create_acceleration_mode(MFX_ACCEL_MODE_VIA_D3D11));
EXPECT_THROW(CfgParamDeviceSelector{cfg_params_w_non_existed_dx11},
std::logic_error);
}

@ -40,6 +40,7 @@
#include "streaming/onevpl/accelerators/surface/dx11_frame_adapter.hpp"
#include "streaming/onevpl/accelerators/accel_policy_cpu.hpp"
#include "streaming/onevpl/accelerators/accel_policy_dx11.hpp"
#include "streaming/onevpl/accelerators/accel_policy_va_api.hpp"
#include "streaming/onevpl/accelerators/dx11_alloc_resource.hpp"
#include "streaming/onevpl/accelerators/utils/shared_lock.hpp"
#define private public
@ -120,6 +121,28 @@ std::tuple<mfxLoader, mfxConfig> prepare_mfx(int mfx_codec, int mfx_accel_mode)
return std::make_tuple(mfx, cfg_inst_3);
}
static std::unique_ptr<cv::gapi::wip::onevpl::VPLAccelerationPolicy>
create_accel_policy_from_int(int accel,
std::shared_ptr<cv::gapi::wip::onevpl::IDeviceSelector> selector) {
using namespace cv::gapi::wip::onevpl;
std::unique_ptr<VPLAccelerationPolicy> decode_accel_policy;
if (accel == MFX_ACCEL_MODE_VIA_D3D11) {
decode_accel_policy.reset (new VPLDX11AccelerationPolicy(selector));
} else if (accel == MFX_ACCEL_MODE_VIA_VAAPI) {
decode_accel_policy.reset (new VPLVAAPIAccelerationPolicy(selector));
}
EXPECT_TRUE(decode_accel_policy.get());
return decode_accel_policy;
}
static std::unique_ptr<cv::gapi::wip::onevpl::VPLAccelerationPolicy>
create_accel_policy_from_int(int &accel,
std::vector<cv::gapi::wip::onevpl::CfgParam> &out_cfg_params) {
using namespace cv::gapi::wip::onevpl;
out_cfg_params.push_back(CfgParam::create_acceleration_mode(accel));
return create_accel_policy_from_int(accel, std::make_shared<CfgParamDeviceSelector>(out_cfg_params));
}
class SafeQueue {
public:
void push(cv::MediaFrame&& f) {
@ -186,26 +209,32 @@ static cv::util::optional<cv::Rect> empty_roi;
class VPPPreprocParams : public ::testing::TestWithParam<preproc_args_t> {};
#if defined(HAVE_DIRECTX) && defined(HAVE_D3D11)
#define UT_ACCEL_TYPE MFX_ACCEL_MODE_VIA_D3D11
#elif __linux__
#define UT_ACCEL_TYPE MFX_ACCEL_MODE_VIA_VAAPI
#else
#define UT_ACCEL_TYPE -1
#endif
preproc_args_t files[] = {
preproc_args_t {"highgui/video/big_buck_bunny.h264",
MFX_CODEC_AVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_AVC, UT_ACCEL_TYPE,
cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1080}}},
preproc_args_t {"highgui/video/big_buck_bunny.h265",
MFX_CODEC_HEVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_HEVC, UT_ACCEL_TYPE,
cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1280}}}
};
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
TEST(OneVPL_Source_PreprocEngine, functional_single_thread)
class OneVPL_PreproEngineTest : public ::testing::TestWithParam<acceleration_t> {};
TEST_P(OneVPL_PreproEngineTest, functional_single_thread)
{
using namespace cv::gapi::wip::onevpl;
using namespace cv::gapi::wip;
std::vector<CfgParam> cfg_params_w_dx11;
cfg_params_w_dx11.push_back(CfgParam::create_acceleration_mode(MFX_ACCEL_MODE_VIA_D3D11));
std::unique_ptr<VPLAccelerationPolicy> decode_accel_policy (
new VPLDX11AccelerationPolicy(std::make_shared<CfgParamDeviceSelector>(cfg_params_w_dx11)));
int accel_type = GetParam();
std::vector<CfgParam> cfg_params_w_accel;
std::unique_ptr<VPLAccelerationPolicy> decode_accel_policy = create_accel_policy_from_int(accel_type, cfg_params_w_accel);
// create file data provider
std::string file_path = findDataFile("highgui/video/big_buck_bunny.h265");
@ -214,7 +243,7 @@ TEST(OneVPL_Source_PreprocEngine, functional_single_thread)
mfxLoader mfx{};
mfxConfig mfx_cfg{};
std::tie(mfx, mfx_cfg) = prepare_mfx(MFX_CODEC_HEVC, MFX_ACCEL_MODE_VIA_D3D11);
std::tie(mfx, mfx_cfg) = prepare_mfx(MFX_CODEC_HEVC, accel_type);
// create decode session
mfxSession mfx_decode_session{};
@ -225,7 +254,7 @@ TEST(OneVPL_Source_PreprocEngine, functional_single_thread)
auto device_selector = decode_accel_policy->get_device_selector();
VPLLegacyDecodeEngine decode_engine(std::move(decode_accel_policy));
auto sess_ptr = decode_engine.initialize_session(mfx_decode_session,
cfg_params_w_dx11,
cfg_params_w_accel,
data_provider);
// simulate net info
@ -233,8 +262,7 @@ TEST(OneVPL_Source_PreprocEngine, functional_single_thread)
{1920, 1080}};
// create VPP preproc engine
VPPPreprocEngine preproc_engine(std::unique_ptr<VPLAccelerationPolicy>{
new VPLDX11AccelerationPolicy(device_selector)});
VPPPreprocEngine preproc_engine(create_accel_policy_from_int(accel_type, device_selector));
// launch pipeline
// 1) decode frame
@ -261,7 +289,7 @@ TEST(OneVPL_Source_PreprocEngine, functional_single_thread)
// make test in loop
bool in_progress = false;
size_t frames_processed_count = 1;
int frames_processed_count = 1;
const auto &first_pp_param_value_impl =
cv::util::get<cv::gapi::wip::onevpl::vpp_pp_params>(first_pp_params.value().value);
try {
@ -298,9 +326,12 @@ TEST(OneVPL_Source_PreprocEngine, functional_single_thread)
ASSERT_NE(frames_processed_count, 1);
}
void decode_function(cv::gapi::wip::onevpl::VPLLegacyDecodeEngine &decode_engine,
cv::gapi::wip::onevpl::ProcessingEngineBase::session_ptr sess_ptr,
SafeQueue &queue, size_t &decoded_number) {
INSTANTIATE_TEST_CASE_P(OneVPL_Source_PreprocEngine, OneVPL_PreproEngineTest,
testing::Values(UT_ACCEL_TYPE));
static void decode_function(cv::gapi::wip::onevpl::VPLLegacyDecodeEngine &decode_engine,
cv::gapi::wip::onevpl::ProcessingEngineBase::session_ptr sess_ptr,
SafeQueue &queue, int &decoded_number) {
// decode first frame
{
cv::MediaFrame decoded_frame;
@ -320,9 +351,9 @@ void decode_function(cv::gapi::wip::onevpl::VPLLegacyDecodeEngine &decode_engine
queue.push_stop();
}
void preproc_function(cv::gapi::wip::IPreprocEngine &preproc_engine, SafeQueue&queue,
size_t &preproc_number, const out_frame_info_t &required_frame_param,
const cv::util::optional<cv::Rect> &roi_rect = {}) {
static void preproc_function(cv::gapi::wip::IPreprocEngine &preproc_engine, SafeQueue&queue,
int &preproc_number, const out_frame_info_t &required_frame_param,
const cv::util::optional<cv::Rect> &roi_rect = {}) {
using namespace cv::gapi::wip;
using namespace cv::gapi::wip::onevpl;
// create preproc session based on frame description & network info
@ -385,10 +416,11 @@ void preproc_function(cv::gapi::wip::IPreprocEngine &preproc_engine, SafeQueue&q
ASSERT_NE(preproc_number, 1);
}
void multi_source_preproc_function(size_t source_num,
cv::gapi::wip::IPreprocEngine &preproc_engine, SafeQueue&queue,
size_t &preproc_number, const out_frame_info_t &required_frame_param,
const cv::util::optional<cv::Rect> &roi_rect = {}) {
#ifdef __WIN32__
static void multi_source_preproc_function(size_t source_num,
cv::gapi::wip::IPreprocEngine &preproc_engine, SafeQueue&queue,
int &preproc_number, const out_frame_info_t &required_frame_param,
const cv::util::optional<cv::Rect> &roi_rect = {}) {
using namespace cv::gapi::wip;
using namespace cv::gapi::wip::onevpl;
// create preproc session based on frame description & network info
@ -450,6 +482,8 @@ void multi_source_preproc_function(size_t source_num,
ASSERT_FALSE(in_progress);
ASSERT_NE(preproc_number, 1);
}
#endif // __WIN32__
using roi_t = cv::util::optional<cv::Rect>;
using preproc_roi_args_t = decltype(std::tuple_cat(std::declval<preproc_args_t>(),
std::declval<std::tuple<roi_t>>()));
@ -467,10 +501,8 @@ TEST_P(VPPPreprocROIParams, functional_roi_different_threads)
file_path = findDataFile(file_path);
std::vector<CfgParam> cfg_params_w_dx11;
cfg_params_w_dx11.push_back(CfgParam::create_acceleration_mode(accel));
std::unique_ptr<VPLAccelerationPolicy> decode_accel_policy (
new VPLDX11AccelerationPolicy(std::make_shared<CfgParamDeviceSelector>(cfg_params_w_dx11)));
std::vector<CfgParam> cfg_params_w_accel;
std::unique_ptr<VPLAccelerationPolicy> decode_accel_policy = create_accel_policy_from_int(accel, cfg_params_w_accel);
// create file data provider
std::shared_ptr<IDataProvider> data_provider(new FileDataProvider(file_path,
@ -489,17 +521,16 @@ TEST_P(VPPPreprocROIParams, functional_roi_different_threads)
auto device_selector = decode_accel_policy->get_device_selector();
VPLLegacyDecodeEngine decode_engine(std::move(decode_accel_policy));
auto sess_ptr = decode_engine.initialize_session(mfx_decode_session,
cfg_params_w_dx11,
cfg_params_w_accel,
data_provider);
// create VPP preproc engine
VPPPreprocEngine preproc_engine(std::unique_ptr<VPLAccelerationPolicy>{
new VPLDX11AccelerationPolicy(device_selector)});
VPPPreprocEngine preproc_engine(create_accel_policy_from_int(accel, device_selector));
// launch threads
SafeQueue queue;
size_t decoded_number = 1;
size_t preproc_number = 0;
int decoded_number = 1;
int preproc_number = 0;
std::thread decode_thread(decode_function, std::ref(decode_engine), sess_ptr,
std::ref(queue), std::ref(decoded_number));
@ -515,31 +546,31 @@ TEST_P(VPPPreprocROIParams, functional_roi_different_threads)
preproc_roi_args_t files_w_roi[] = {
preproc_roi_args_t {"highgui/video/big_buck_bunny.h264",
MFX_CODEC_AVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_AVC, UT_ACCEL_TYPE,
out_frame_info_t{cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1080}}},
roi_t{cv::Rect{0,0,50,50}}},
preproc_roi_args_t {"highgui/video/big_buck_bunny.h264",
MFX_CODEC_AVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_AVC, UT_ACCEL_TYPE,
out_frame_info_t{cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1080}}},
roi_t{}},
preproc_roi_args_t {"highgui/video/big_buck_bunny.h264",
MFX_CODEC_AVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_AVC, UT_ACCEL_TYPE,
out_frame_info_t{cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1080}}},
roi_t{cv::Rect{0,0,100,100}}},
preproc_roi_args_t {"highgui/video/big_buck_bunny.h264",
MFX_CODEC_AVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_AVC, UT_ACCEL_TYPE,
out_frame_info_t{cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1080}}},
roi_t{cv::Rect{100,100,200,200}}},
preproc_roi_args_t {"highgui/video/big_buck_bunny.h265",
MFX_CODEC_HEVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_HEVC, UT_ACCEL_TYPE,
out_frame_info_t{cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1280}}},
roi_t{cv::Rect{0,0,100,100}}},
preproc_roi_args_t {"highgui/video/big_buck_bunny.h265",
MFX_CODEC_HEVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_HEVC, UT_ACCEL_TYPE,
out_frame_info_t{cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1280}}},
roi_t{}},
preproc_roi_args_t {"highgui/video/big_buck_bunny.h265",
MFX_CODEC_HEVC, MFX_ACCEL_MODE_VIA_D3D11,
MFX_CODEC_HEVC, UT_ACCEL_TYPE,
out_frame_info_t{cv::GFrameDesc {cv::MediaFormat::NV12, {1920, 1280}}},
roi_t{cv::Rect{100,100,200,200}}}
};
@ -561,12 +592,10 @@ TEST_P(VPPInnerPreprocParams, functional_inner_preproc_size)
file_path = findDataFile(file_path);
std::vector<CfgParam> cfg_params_w_dx11_vpp;
std::vector<CfgParam> cfg_params_w_accel_vpp;
// create accel policy
cfg_params_w_dx11_vpp.push_back(CfgParam::create_acceleration_mode(accel));
std::unique_ptr<VPLAccelerationPolicy> accel_policy (
new VPLDX11AccelerationPolicy(std::make_shared<CfgParamDeviceSelector>(cfg_params_w_dx11_vpp)));
std::unique_ptr<VPLAccelerationPolicy> accel_policy = create_accel_policy_from_int(accel, cfg_params_w_accel_vpp);
// create file data provider
std::shared_ptr<IDataProvider> data_provider(new FileDataProvider(file_path,
@ -582,20 +611,20 @@ TEST_P(VPPInnerPreprocParams, functional_inner_preproc_size)
EXPECT_EQ(MFX_ERR_NONE, sts);
// fill vpp params beforehand: resolution
cfg_params_w_dx11_vpp.push_back(CfgParam::create_vpp_out_width(
cfg_params_w_accel_vpp.push_back(CfgParam::create_vpp_out_width(
static_cast<uint16_t>(required_frame_param.size.width)));
cfg_params_w_dx11_vpp.push_back(CfgParam::create_vpp_out_height(
cfg_params_w_accel_vpp.push_back(CfgParam::create_vpp_out_height(
static_cast<uint16_t>(required_frame_param.size.height)));
// create transcode engine
auto device_selector = accel_policy->get_device_selector();
VPLLegacyTranscodeEngine engine(std::move(accel_policy));
auto sess_ptr = engine.initialize_session(mfx_decode_session,
cfg_params_w_dx11_vpp,
cfg_params_w_accel_vpp,
data_provider);
// make test in loop
bool in_progress = false;
size_t frames_processed_count = 1;
int frames_processed_count = 1;
try {
while(true) {
cv::MediaFrame decoded_frame = extract_decoded_frame(sess_ptr->session, engine);
@ -618,7 +647,8 @@ TEST_P(VPPInnerPreprocParams, functional_inner_preproc_size)
INSTANTIATE_TEST_CASE_P(OneVPL_Source_PreprocInner, VPPInnerPreprocParams,
testing::ValuesIn(files));
// Dispatcher test suite
// enable only for WIN32 because there are not CPU processing on Linux by default
#ifdef __WIN32__
class VPPPreprocDispatcherROIParams : public ::testing::TestWithParam<preproc_roi_args_t> {};
TEST_P(VPPPreprocDispatcherROIParams, functional_roi_different_threads)
{
@ -626,17 +656,15 @@ TEST_P(VPPPreprocDispatcherROIParams, functional_roi_different_threads)
using namespace cv::gapi::wip::onevpl;
source_t file_path;
decoder_t decoder_id;
acceleration_t accel = MFX_ACCEL_MODE_VIA_D3D11;
acceleration_t accel = 0;
out_frame_info_t required_frame_param;
roi_t opt_roi;
std::tie(file_path, decoder_id, std::ignore, required_frame_param, opt_roi) = GetParam();
std::tie(file_path, decoder_id, accel, required_frame_param, opt_roi) = GetParam();
file_path = findDataFile(file_path);
std::vector<CfgParam> cfg_params_w_dx11;
cfg_params_w_dx11.push_back(CfgParam::create_acceleration_mode(accel));
std::unique_ptr<VPLAccelerationPolicy> decode_accel_policy (
new VPLDX11AccelerationPolicy(std::make_shared<CfgParamDeviceSelector>(cfg_params_w_dx11)));
std::vector<CfgParam> cfg_params_w_accel;
std::unique_ptr<VPLAccelerationPolicy> decode_accel_policy = create_accel_policy_from_int(accel, cfg_params_w_accel);
// create file data provider
std::shared_ptr<IDataProvider> data_provider(new FileDataProvider(file_path,
@ -661,7 +689,7 @@ TEST_P(VPPPreprocDispatcherROIParams, functional_roi_different_threads)
auto device_selector = decode_accel_policy->get_device_selector();
VPLLegacyDecodeEngine decode_engine(std::move(decode_accel_policy));
auto sess_ptr = decode_engine.initialize_session(mfx_decode_session,
cfg_params_w_dx11,
cfg_params_w_accel,
data_provider);
std::vector<CfgParam> cfg_params_cpu;
auto cpu_device_selector = std::make_shared<CfgParamDeviceSelector>(cfg_params_cpu);
@ -673,16 +701,15 @@ TEST_P(VPPPreprocDispatcherROIParams, functional_roi_different_threads)
// create VPP preproc engines
VPPPreprocDispatcher preproc_dispatcher;
preproc_dispatcher.insert_worker<VPPPreprocEngine>(std::unique_ptr<VPLAccelerationPolicy>{
new VPLDX11AccelerationPolicy(device_selector)});
preproc_dispatcher.insert_worker<VPPPreprocEngine>(create_accel_policy_from_int(accel, device_selector));
preproc_dispatcher.insert_worker<VPPPreprocEngine>(std::unique_ptr<VPLAccelerationPolicy>{
new VPLCPUAccelerationPolicy(cpu_device_selector)});
// launch threads
SafeQueue queue;
size_t decoded_number = 1;
size_t cpu_decoded_number = 1;
size_t preproc_number = 0;
int decoded_number = 1;
int cpu_decoded_number = 1;
int preproc_number = 0;
std::thread decode_thread(decode_function, std::ref(decode_engine), sess_ptr,
std::ref(queue), std::ref(decoded_number));
@ -704,7 +731,6 @@ TEST_P(VPPPreprocDispatcherROIParams, functional_roi_different_threads)
INSTANTIATE_TEST_CASE_P(OneVPL_Source_PreprocDispatcherROI, VPPPreprocDispatcherROIParams,
testing::ValuesIn(files_w_roi));
#endif // HAVE_DIRECTX
#endif // HAVE_D3D11
#endif // __WIN32__
} // namespace opencv_test
#endif // HAVE_ONEVPL

Loading…
Cancel
Save