1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 07:43:03 +04:00

Merge pull request #21688 from sivanov-work:vpp_ie_integration

G-API: VPP preprocessing GIEBackend integration

* Add ROI in VPP prepro

* Apply comments

* Integration to IE

* Removed extra invocations

* Fix no-vpl compilation

* Fix compilations

* Apply comments

* Use thin wrapper for device & ctx

* Implement Device/Context constructor functions

* Apply samples comment

* Fix compilation

* Fix compilation

* Fix build

* Separate Device&Context from selector, apply other comments

* Fix typo

* Intercept OV exception with pretty print out
This commit is contained in:
Sergey Ivanov
2022-04-01 13:06:47 +03:00
committed by GitHub
parent 7b582b71ba
commit f3945fbddb
18 changed files with 715 additions and 135 deletions
@@ -38,6 +38,20 @@ namespace gapi {
namespace wip {
namespace onevpl {
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;
default:
GAPI_DbgAssert(false && "Unexpected AccelType");
break;
}
return std::move(param_array);
}
CfgParamDeviceSelector::CfgParamDeviceSelector(const CfgParams& cfg_params) :
suggested_device(IDeviceSelector::create<Device>(nullptr, "CPU", AccelType::HOST)),
suggested_context(IDeviceSelector::create<Context>(nullptr, AccelType::HOST)) {
@@ -231,6 +245,52 @@ CfgParamDeviceSelector::CfgParamDeviceSelector(Device::Ptr device_ptr,
}
}
CfgParamDeviceSelector::CfgParamDeviceSelector(const Device &device,
const Context &ctx,
CfgParams) :
suggested_device(device),
suggested_context(ctx) {
switch(device.get_type()) {
case AccelType::DX11: {
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
ID3D11Device* dx_device_ptr =
reinterpret_cast<ID3D11Device*>(suggested_device.get_ptr());
dx_device_ptr->AddRef();
ID3D11DeviceContext* dx_ctx_ptr =
reinterpret_cast<ID3D11DeviceContext*>(suggested_context.get_ptr());
// oneVPL recommendation
{
ID3D11Multithread *pD11Multithread = nullptr;
dx_ctx_ptr->QueryInterface(IID_PPV_ARGS(&pD11Multithread));
pD11Multithread->SetMultithreadProtected(true);
pD11Multithread->Release();
}
dx_ctx_ptr->AddRef();
break;
#else
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
}
case AccelType::HOST:
break;
default:
throw std::logic_error(std::string("Unsupported \"") + CfgParam::acceleration_mode_name() +
"\" requested: " +
to_cstring(device.get_type()));
break;
}
}
CfgParamDeviceSelector::~CfgParamDeviceSelector() {
GAPI_LOG_INFO(nullptr, "release context: " << suggested_context.get_ptr());
AccelType ctype = suggested_context.get_type();
@@ -7,14 +7,14 @@
#ifndef GAPI_STREAMING_ONEVPL_CFG_PARAM_DEVICE_SELECTOR_HPP
#define GAPI_STREAMING_ONEVPL_CFG_PARAM_DEVICE_SELECTOR_HPP
#ifdef HAVE_ONEVPL
#include <opencv2/gapi/streaming/onevpl/device_selector_interface.hpp>
#include <opencv2/gapi/streaming/onevpl/cfg_params.hpp>
#include <opencv2/gapi/streaming/onevpl/source.hpp>
#include "opencv2/gapi/own/exports.hpp" // GAPI_EXPORTS
#ifdef HAVE_ONEVPL
namespace cv {
namespace gapi {
namespace wip {
@@ -26,6 +26,9 @@ struct GAPI_EXPORTS CfgParamDeviceSelector final: public IDeviceSelector {
const std::string& device_id,
Context::Ptr ctx_ptr,
const CfgParams& params);
CfgParamDeviceSelector(const Device &device_ptr,
const Context &ctx_ptr,
CfgParams params);
~CfgParamDeviceSelector();
DeviceScoreTable select_devices() const override;
@@ -81,6 +81,42 @@ IDeviceSelector::Score::Type IDeviceSelector::Score::get() const {
IDeviceSelector::~IDeviceSelector() {
}
namespace detail
{
struct DeviceContextCreator : public IDeviceSelector {
DeviceScoreTable select_devices() const override { return {};}
DeviceContexts select_context() override { return {};}
template<typename Entity, typename ...Args>
static Entity create_entity(Args &&...args) {
return IDeviceSelector::create<Entity>(std::forward<Args>(args)...);
}
};
}
Device create_host_device() {
return detail::DeviceContextCreator::create_entity<Device>(nullptr,
"CPU",
AccelType::HOST);
}
Context create_host_context() {
return detail::DeviceContextCreator::create_entity<Context>(nullptr,
AccelType::HOST);
}
Device create_dx11_device(Device::Ptr device_ptr,
const std::string& device_name) {
return detail::DeviceContextCreator::create_entity<Device>(device_ptr,
device_name,
AccelType::DX11);
}
Context create_dx11_context(Context::Ptr ctx_ptr) {
return detail::DeviceContextCreator::create_entity<Context>(ctx_ptr,
AccelType::DX11);
}
} // namespace onevpl
} // namespace wip
} // namespace gapi
@@ -4,30 +4,33 @@
//
// Copyright (C) 2022 Intel Corporation
#ifdef HAVE_ONEVPL
#include <algorithm>
#include <exception>
#include <opencv2/gapi/streaming/onevpl/data_provider_interface.hpp>
#include "streaming/onevpl/engine/preproc/preproc_dispatcher.hpp"
#ifdef HAVE_ONEVPL
#include "streaming/onevpl/onevpl_export.hpp"
#include "streaming/onevpl/engine/preproc/preproc_engine.hpp"
#include "streaming/onevpl/engine/preproc/preproc_session.hpp"
#include "streaming/onevpl/engine/preproc/preproc_dispatcher.hpp"
#include "streaming/onevpl/accelerators/accel_policy_interface.hpp"
#include "streaming/onevpl/accelerators/surface/surface.hpp"
#include "streaming/onevpl/cfg_params_parser.hpp"
#include "logger.hpp"
#endif // HAVE_ONEVPL
#include "logger.hpp"
namespace cv {
namespace gapi {
namespace wip {
namespace onevpl {
#ifdef HAVE_ONEVPL
cv::util::optional<pp_params> VPPPreprocDispatcher::is_applicable(const cv::MediaFrame& in_frame) {
cv::util::optional<pp_params> param;
GAPI_LOG_DEBUG(nullptr, "workers: " << workers.size());
bool worker_found = false;
for (const auto &w : workers) {
param = w->is_applicable(in_frame);
if (param.has_value()) {
@@ -42,11 +45,12 @@ cv::util::optional<pp_params> VPPPreprocDispatcher::is_applicable(const cv::Medi
if (worker_accel_type == adapter->accel_type()){
vpp_param.reserved = reinterpret_cast<void *>(w.get());
GAPI_LOG_DEBUG(nullptr, "selected worker: " << vpp_param.reserved);
worker_found = true;
break;
}
}
}
return param;
return worker_found ? param : cv::util::optional<pp_params>{};
}
pp_session VPPPreprocDispatcher::initialize_preproc(const pp_params& initial_frame_param,
@@ -78,8 +82,24 @@ cv::MediaFrame VPPPreprocDispatcher::run_sync(const pp_session &session_handle,
}
GAPI_Assert(false && "Cannot invoke VPP preproc in dispatcher, no suitable worker");
}
#else // HAVE_ONEVPL
cv::util::optional<pp_params> VPPPreprocDispatcher::is_applicable(const cv::MediaFrame&) {
return cv::util::optional<pp_params>{};
}
pp_session VPPPreprocDispatcher::initialize_preproc(const pp_params&,
const GFrameDesc&) {
GAPI_Assert(false && "Unsupported: G-API compiled without `WITH_GAPI_ONEVPL=ON`");
}
cv::MediaFrame VPPPreprocDispatcher::run_sync(const pp_session &,
const cv::MediaFrame&,
const cv::util::optional<cv::Rect> &) {
GAPI_Assert(false && "Unsupported: G-API compiled without `WITH_GAPI_ONEVPL=ON`");
}
#endif // HAVE_ONEVPL
} // namespace onevpl
} // namespace wip
} // namespace gapi
} // namespace cv
#endif // HAVE_ONEVPL
@@ -11,10 +11,6 @@
#include <vector>
#include "streaming/onevpl/engine/preproc_engine_interface.hpp"
#include "streaming/onevpl/engine/preproc_defines.hpp"
#ifdef HAVE_ONEVPL
#include "streaming/onevpl/onevpl_export.hpp"
namespace cv {
namespace gapi {
@@ -49,5 +45,4 @@ private:
} // namespace wip
} // namespace gapi
} // namespace cv
#endif // HAVE_ONEVPL
#endif // GAPI_STREAMING_ONEVPL_PREPROC_DISPATCHER_HPP
@@ -51,7 +51,7 @@ void apply_roi(mfxFrameSurface1* surface_handle,
VPPPreprocEngine::VPPPreprocEngine(std::unique_ptr<VPLAccelerationPolicy>&& accel) :
ProcessingEngineBase(std::move(accel)) {
GAPI_LOG_INFO(nullptr, "Create VPP preprocessing engine");
GAPI_LOG_DEBUG(nullptr, "Create VPP preprocessing engine");
preprocessed_frames_count = 0;
create_pipeline(
// 0) preproc decoded surface with VPP params
@@ -455,7 +455,7 @@ ProcessingEngineBase::ExecutionStatus VPPPreprocEngine::process_error(mfxStatus
"MFX_ERR_REALLOC_SURFACE is not processed");
break;
case MFX_WRN_IN_EXECUTION:
GAPI_LOG_WARNING(nullptr, "[" << sess.session << "] got MFX_WRN_IN_EXECUTION");
GAPI_LOG_DEBUG(nullptr, "[" << sess.session << "] got MFX_WRN_IN_EXECUTION");
return ExecutionStatus::Continue;
default:
GAPI_LOG_WARNING(nullptr, "Unknown status code: " << mfxstatus_to_string(status) <<
@@ -23,8 +23,8 @@ namespace wip {
#else // VPP_PREPROC_ENGINE
struct empty_pp_params {};
struct empty_pp_session {};
#define GAPI_BACKEND_PP_PARAMS cv::gapi::wip::empty_pp_params;
#define GAPI_BACKEND_PP_SESSIONS cv::gapi::wip::empty_pp_session;
#define GAPI_BACKEND_PP_PARAMS cv::gapi::wip::empty_pp_params
#define GAPI_BACKEND_PP_SESSIONS cv::gapi::wip::empty_pp_session
#endif // VPP_PREPROC_ENGINE
struct pp_params {
@@ -0,0 +1,83 @@
// 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.
//
// Copyright (C) 2022 Intel Corporation
#include <opencv2/gapi/streaming/onevpl/device_selector_interface.hpp>
#include "streaming/onevpl/engine/preproc_engine_interface.hpp"
#include "streaming/onevpl/engine/preproc/preproc_dispatcher.hpp"
#ifdef HAVE_ONEVPL
#include "streaming/onevpl/onevpl_export.hpp"
#include "streaming/onevpl/engine/preproc/preproc_engine.hpp"
#include "streaming/onevpl/accelerators/accel_policy_dx11.hpp"
#include "streaming/onevpl/accelerators/accel_policy_cpu.hpp"
#include "streaming/onevpl/accelerators/surface/surface.hpp"
#include "streaming/onevpl/cfg_param_device_selector.hpp"
#include "streaming/onevpl/cfg_params_parser.hpp"
#endif //HAVE_ONEVPL
#include "logger.hpp"
namespace cv {
namespace gapi {
namespace wip {
template<typename SpecificPreprocEngine, typename ...PreprocEngineArgs >
std::unique_ptr<SpecificPreprocEngine>
IPreprocEngine::create_preproc_engine_impl(const PreprocEngineArgs& ...) {
GAPI_Assert(false && "Unsupported ");
}
template <>
std::unique_ptr<onevpl::VPPPreprocDispatcher>
IPreprocEngine::create_preproc_engine_impl(const onevpl::Device &device,
const onevpl::Context &context) {
using namespace onevpl;
cv::util::suppress_unused_warning(device);
cv::util::suppress_unused_warning(context);
std::unique_ptr<VPPPreprocDispatcher> dispatcher(new VPPPreprocDispatcher);
#ifdef HAVE_ONEVPL
if (device.get_type() == onevpl::AccelType::DX11) {
bool gpu_pp_is_created = false;
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
GAPI_LOG_INFO(nullptr, "Creating DX11 VPP preprocessing engine");
// create GPU VPP preproc engine
dispatcher->insert_worker<VPPPreprocEngine>(
std::unique_ptr<VPLAccelerationPolicy>{
new VPLDX11AccelerationPolicy(
std::make_shared<CfgParamDeviceSelector>(
device, context, CfgParams{}))
});
GAPI_LOG_INFO(nullptr, "DX11 VPP preprocessing engine created");
gpu_pp_is_created = true;
#endif
#endif
GAPI_Assert(gpu_pp_is_created && "VPP preproc for GPU is requested, but it is avaiable only for DX11 at now");
} else {
GAPI_LOG_INFO(nullptr, "Creating CPU VPP preprocessing engine");
dispatcher->insert_worker<VPPPreprocEngine>(
std::unique_ptr<VPLAccelerationPolicy>{
new VPLCPUAccelerationPolicy(
std::make_shared<CfgParamDeviceSelector>(CfgParams{}))});
GAPI_LOG_INFO(nullptr, "CPU VPP preprocessing engine created");
}
#endif // HAVE_ONEVPL
return dispatcher;
}
// Force instantiation
template
std::unique_ptr<onevpl::VPPPreprocDispatcher>
IPreprocEngine::create_preproc_engine_impl<onevpl::VPPPreprocDispatcher,
const onevpl::Device &,const onevpl::Context &>
(const onevpl::Device &device,
const onevpl::Context &ctx);
} // namespace wip
} // namespace gapi
} // namespace cv
@@ -29,6 +29,16 @@ struct IPreprocEngine {
virtual cv::MediaFrame
run_sync(const pp_session &sess, const cv::MediaFrame& in_frame,
const cv::util::optional<cv::Rect> &opt_roi = {}) = 0;
template<typename SpecificPreprocEngine, typename ...PreprocEngineArgs >
static std::unique_ptr<IPreprocEngine> create_preproc_engine(const PreprocEngineArgs& ...args) {
static_assert(std::is_base_of<IPreprocEngine, SpecificPreprocEngine>::value,
"SpecificPreprocEngine must have reachable ancessor IPreprocEngine");
return create_preproc_engine_impl<SpecificPreprocEngine, PreprocEngineArgs...>(args...);
}
private:
template<typename SpecificPreprocEngine, typename ...PreprocEngineArgs >
static std::unique_ptr<SpecificPreprocEngine> create_preproc_engine_impl(const PreprocEngineArgs &...args);
};
} // namespace wip
} // namespace gapi
@@ -33,6 +33,13 @@ GSource::GSource(const std::string& filePath,
accel_ctx_ptr, cfg_params)) {
}
GSource::GSource(const std::string& filePath,
const CfgParams& cfg_params,
const Device &device, const Context &ctx) :
GSource(filePath, cfg_params,
std::make_shared<CfgParamDeviceSelector>(device, ctx, cfg_params)) {
}
GSource::GSource(const std::string& filePath,
const CfgParams& cfg_params,
std::shared_ptr<IDeviceSelector> selector) :
@@ -74,6 +81,10 @@ GSource::GSource(const std::string&, const CfgParams&, const std::string&,
GAPI_Assert(false && "Unsupported: G-API compiled without `WITH_GAPI_ONEVPL=ON`");
}
GSource::GSource(const std::string&, const CfgParams&, const Device &, const Context &) {
GAPI_Assert(false && "Unsupported: G-API compiled without `WITH_GAPI_ONEVPL=ON`");
}
GSource::GSource(const std::string&, const CfgParams&, std::shared_ptr<IDeviceSelector>) {
GAPI_Assert(false && "Unsupported: G-API compiled without `WITH_GAPI_ONEVPL=ON`");
}