1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

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
This commit is contained in:
Sergey
2022-05-12 11:42:38 +03:00
committed by GitHub
parent 2010de9104
commit eff5605be5
34 changed files with 662 additions and 184 deletions
@@ -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