feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake
1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试 2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程 3.重整权利声明文件,重整代码工程,确保最小化侵权风险 Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
220
3rdparty/opencv-4.5.4/modules/gapi/test/streaming/gapi_streaming_sync_tests.cpp
vendored
Normal file
220
3rdparty/opencv-4.5.4/modules/gapi/test/streaming/gapi_streaming_sync_tests.cpp
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
// 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) 2021 Intel Corporation
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
|
||||
#include <opencv2/gapi/streaming/cap.hpp>
|
||||
#include <opencv2/gapi/core.hpp>
|
||||
#include <opencv2/gapi/fluid/imgproc.hpp>
|
||||
#include <opencv2/gapi/streaming/cap.hpp>
|
||||
#include <opencv2/gapi/streaming/sync.hpp>
|
||||
|
||||
namespace opencv_test {
|
||||
namespace {
|
||||
|
||||
using ts_t = int64_t;
|
||||
using ts_vec = std::vector<ts_t>;
|
||||
using cv::gapi::streaming::sync_policy;
|
||||
|
||||
ts_t calcLeastCommonMultiple(const ts_vec& values) {
|
||||
ts_t res = *std::max_element(values.begin(), values.end());
|
||||
auto isDivisor = [&](ts_t v) { return res % v == 0; };
|
||||
while(!std::all_of(values.begin(), values.end(), isDivisor)) {
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
struct TimestampGenerationParams {
|
||||
const ts_vec frame_times;
|
||||
sync_policy policy;
|
||||
ts_t end_time;
|
||||
TimestampGenerationParams(const ts_vec& ft, sync_policy sp, ts_t et = 25)
|
||||
: frame_times(ft), policy(sp), end_time(et) {
|
||||
}
|
||||
};
|
||||
|
||||
class MultiFrameSource {
|
||||
class SingleSource : public cv::gapi::wip::IStreamSource {
|
||||
MultiFrameSource& m_source;
|
||||
std::size_t m_idx;
|
||||
public:
|
||||
SingleSource(MultiFrameSource& s, std::size_t idx)
|
||||
: m_source(s)
|
||||
, m_idx(idx)
|
||||
{}
|
||||
virtual bool pull(cv::gapi::wip::Data& data) {
|
||||
return m_source.pull(data, m_idx);
|
||||
}
|
||||
virtual GMetaArg descr_of() const { return GMetaArg{m_source.desc()}; }
|
||||
};
|
||||
|
||||
TimestampGenerationParams p;
|
||||
ts_vec m_current_times;
|
||||
cv::Mat m_mat;
|
||||
|
||||
public:
|
||||
MultiFrameSource(const TimestampGenerationParams& params)
|
||||
: p(params)
|
||||
, m_current_times(p.frame_times.size(), 0u)
|
||||
, m_mat(8, 8, CV_8UC1) {
|
||||
}
|
||||
|
||||
bool pull(cv::gapi::wip::Data& data, std::size_t idx) {
|
||||
cv::randn(m_mat, 127, 32);
|
||||
GAPI_Assert(idx < p.frame_times.size());
|
||||
m_current_times[idx] += p.frame_times[idx];
|
||||
if (m_current_times[idx] >= p.end_time) {
|
||||
return false;
|
||||
}
|
||||
data = m_mat.clone();
|
||||
data.meta[cv::gapi::streaming::meta_tag::timestamp] = m_current_times[idx];
|
||||
return true;
|
||||
}
|
||||
|
||||
cv::gapi::wip::IStreamSource::Ptr getSource(std::size_t idx) {
|
||||
return cv::gapi::wip::IStreamSource::Ptr{new SingleSource(*this, idx)};
|
||||
}
|
||||
|
||||
GMatDesc desc() const { return cv::descr_of(m_mat); }
|
||||
};
|
||||
|
||||
class TimestampChecker {
|
||||
TimestampGenerationParams p;
|
||||
ts_t m_synced_time = 0u;
|
||||
ts_t m_synced_frame_time = 0u;
|
||||
public:
|
||||
TimestampChecker(const TimestampGenerationParams& params)
|
||||
: p(params)
|
||||
, m_synced_frame_time(calcLeastCommonMultiple(p.frame_times)) {
|
||||
}
|
||||
|
||||
void checkNext(const ts_vec& timestamps) {
|
||||
if (p.policy == sync_policy::dont_sync) {
|
||||
// don't check timestamps if the policy is dont_sync
|
||||
return;
|
||||
}
|
||||
m_synced_time += m_synced_frame_time;
|
||||
for (const auto& ts : timestamps) {
|
||||
EXPECT_EQ(m_synced_time, ts);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t nFrames() const {
|
||||
auto frame_time = p.policy == sync_policy::dont_sync
|
||||
? *std::max_element(p.frame_times.begin(), p.frame_times.end())
|
||||
: m_synced_frame_time;
|
||||
auto n_frames = p.end_time / frame_time;
|
||||
GAPI_Assert(n_frames > 0u);
|
||||
return (std::size_t)n_frames;
|
||||
}
|
||||
};
|
||||
|
||||
struct TimestampSyncTest : public ::testing::TestWithParam<sync_policy> {
|
||||
void run(cv::GProtoInputArgs&& ins, cv::GProtoOutputArgs&& outs,
|
||||
const ts_vec& frame_times) {
|
||||
auto video_in_n = frame_times.size();
|
||||
GAPI_Assert(video_in_n <= ins.m_args.size());
|
||||
// Assume that all remaining inputs are const
|
||||
auto const_in_n = ins.m_args.size() - video_in_n;
|
||||
auto out_n = outs.m_args.size();
|
||||
auto policy = GetParam();
|
||||
TimestampGenerationParams ts_params(frame_times, policy);
|
||||
MultiFrameSource source(ts_params);
|
||||
|
||||
GRunArgs gins;
|
||||
for (std::size_t i = 0; i < video_in_n; i++) {
|
||||
gins += cv::gin(source.getSource(i));
|
||||
}
|
||||
auto desc = source.desc();
|
||||
cv::Mat const_mat = cv::Mat::eye(desc.size.height,
|
||||
desc.size.width,
|
||||
CV_MAKE_TYPE(desc.depth, desc.chan));
|
||||
for (std::size_t i = 0; i < const_in_n; i++) {
|
||||
gins += cv::gin(const_mat);
|
||||
}
|
||||
ts_vec out_timestamps(out_n);
|
||||
cv::GRunArgsP gouts{};
|
||||
for (auto& t : out_timestamps) {
|
||||
gouts += cv::gout(t);
|
||||
}
|
||||
|
||||
auto pipe = cv::GComputation(std::move(ins), std::move(outs))
|
||||
.compileStreaming(cv::compile_args(policy));
|
||||
|
||||
pipe.setSource(std::move(gins));
|
||||
pipe.start();
|
||||
|
||||
std::size_t frames = 0u;
|
||||
TimestampChecker checker(ts_params);
|
||||
while(pipe.pull(std::move(gouts))) {
|
||||
checker.checkNext(out_timestamps);
|
||||
frames++;
|
||||
}
|
||||
|
||||
EXPECT_EQ(checker.nFrames(), frames);
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST_P(TimestampSyncTest, Basic)
|
||||
{
|
||||
cv::GMat in1, in2;
|
||||
auto out = cv::gapi::add(in1, in2);
|
||||
auto ts = cv::gapi::streaming::timestamp(out);
|
||||
|
||||
run(cv::GIn(in1, in2), cv::GOut(ts), {1,2});
|
||||
}
|
||||
|
||||
TEST_P(TimestampSyncTest, ThreeInputs)
|
||||
{
|
||||
cv::GMat in1, in2, in3;
|
||||
auto tmp = cv::gapi::add(in1, in2);
|
||||
auto out = cv::gapi::add(tmp, in3);
|
||||
auto ts = cv::gapi::streaming::timestamp(out);
|
||||
|
||||
run(cv::GIn(in1, in2, in3), cv::GOut(ts), {2,4,3});
|
||||
}
|
||||
|
||||
TEST_P(TimestampSyncTest, TwoOutputs)
|
||||
{
|
||||
cv::GMat in1, in2, in3;
|
||||
auto out1 = cv::gapi::add(in1, in3);
|
||||
auto out2 = cv::gapi::add(in2, in3);
|
||||
auto ts1 = cv::gapi::streaming::timestamp(out1);
|
||||
auto ts2 = cv::gapi::streaming::timestamp(out2);
|
||||
|
||||
run(cv::GIn(in1, in2, in3), cv::GOut(ts1, ts2), {1,4,2});
|
||||
}
|
||||
|
||||
TEST_P(TimestampSyncTest, ConstInput)
|
||||
{
|
||||
cv::GMat in1, in2, in3;
|
||||
auto out1 = cv::gapi::add(in1, in3);
|
||||
auto out2 = cv::gapi::add(in2, in3);
|
||||
auto ts1 = cv::gapi::streaming::timestamp(out1);
|
||||
auto ts2 = cv::gapi::streaming::timestamp(out2);
|
||||
|
||||
run(cv::GIn(in1, in2, in3), cv::GOut(ts1, ts2), {1,2});
|
||||
}
|
||||
|
||||
TEST_P(TimestampSyncTest, ChangeSource)
|
||||
{
|
||||
cv::GMat in1, in2, in3;
|
||||
auto out1 = cv::gapi::add(in1, in3);
|
||||
auto out2 = cv::gapi::add(in2, in3);
|
||||
auto ts1 = cv::gapi::streaming::timestamp(out1);
|
||||
auto ts2 = cv::gapi::streaming::timestamp(out2);
|
||||
|
||||
run(cv::GIn(in1, in2, in3), cv::GOut(ts1, ts2), {1,2});
|
||||
run(cv::GIn(in1, in2, in3), cv::GOut(ts1, ts2), {1,2});
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(InputSynchronization, TimestampSyncTest,
|
||||
Values(sync_policy::dont_sync,
|
||||
sync_policy::drop));
|
||||
} // namespace opencv_test
|
2353
3rdparty/opencv-4.5.4/modules/gapi/test/streaming/gapi_streaming_tests.cpp
vendored
Normal file
2353
3rdparty/opencv-4.5.4/modules/gapi/test/streaming/gapi_streaming_tests.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
446
3rdparty/opencv-4.5.4/modules/gapi/test/streaming/gapi_streaming_vpl_core_test.cpp
vendored
Normal file
446
3rdparty/opencv-4.5.4/modules/gapi/test/streaming/gapi_streaming_vpl_core_test.cpp
vendored
Normal file
@ -0,0 +1,446 @@
|
||||
// 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) 2021 Intel Corporation
|
||||
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
|
||||
#include "../common/gapi_tests_common.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
|
||||
#include <opencv2/gapi/media.hpp>
|
||||
#include <opencv2/gapi/cpu/core.hpp>
|
||||
#include <opencv2/gapi/cpu/imgproc.hpp>
|
||||
|
||||
#include <opencv2/gapi/fluid/core.hpp>
|
||||
#include <opencv2/gapi/fluid/imgproc.hpp>
|
||||
#include <opencv2/gapi/fluid/gfluidkernel.hpp>
|
||||
|
||||
#include <opencv2/gapi/ocl/core.hpp>
|
||||
#include <opencv2/gapi/ocl/imgproc.hpp>
|
||||
|
||||
#include <opencv2/gapi/streaming/cap.hpp>
|
||||
#include <opencv2/gapi/streaming/desync.hpp>
|
||||
#include <opencv2/gapi/streaming/format.hpp>
|
||||
|
||||
#include <opencv2/gapi/streaming/onevpl/source.hpp>
|
||||
|
||||
#ifdef HAVE_ONEVPL
|
||||
#include <opencv2/gapi/streaming/onevpl/data_provider_interface.hpp>
|
||||
|
||||
#include "streaming/onevpl/accelerators/surface/surface.hpp"
|
||||
#include "streaming/onevpl/accelerators/surface/cpu_frame_adapter.hpp"
|
||||
#include "streaming/onevpl/accelerators/accel_policy_cpu.hpp"
|
||||
#include "streaming/onevpl/engine/processing_engine_base.hpp"
|
||||
#include "streaming/onevpl/engine/engine_session.hpp"
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
struct EmptyDataProvider : public cv::gapi::wip::onevpl::IDataProvider {
|
||||
|
||||
size_t fetch_data(size_t, void*) override {
|
||||
return 0;
|
||||
}
|
||||
bool empty() const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct TestProcessingSession : public cv::gapi::wip::onevpl::EngineSession {
|
||||
TestProcessingSession(mfxSession mfx_session) :
|
||||
EngineSession(mfx_session, {}) {
|
||||
}
|
||||
};
|
||||
|
||||
struct TestProcessingEngine: public cv::gapi::wip::onevpl::ProcessingEngineBase {
|
||||
|
||||
size_t pipeline_stage_num = 0;
|
||||
|
||||
TestProcessingEngine(std::unique_ptr<cv::gapi::wip::onevpl::VPLAccelerationPolicy>&& accel) :
|
||||
cv::gapi::wip::onevpl::ProcessingEngineBase(std::move(accel)) {
|
||||
using cv::gapi::wip::onevpl::EngineSession;
|
||||
create_pipeline(
|
||||
// 0)
|
||||
[this] (EngineSession&) -> ExecutionStatus
|
||||
{
|
||||
pipeline_stage_num = 0;
|
||||
return ExecutionStatus::Continue;
|
||||
},
|
||||
// 1)
|
||||
[this] (EngineSession&) -> ExecutionStatus
|
||||
{
|
||||
pipeline_stage_num = 1;
|
||||
return ExecutionStatus::Continue;
|
||||
},
|
||||
// 2)
|
||||
[this] (EngineSession&) -> ExecutionStatus
|
||||
{
|
||||
pipeline_stage_num = 2;
|
||||
return ExecutionStatus::Continue;
|
||||
},
|
||||
// 3)
|
||||
[this] (EngineSession&) -> ExecutionStatus
|
||||
{
|
||||
pipeline_stage_num = 3;
|
||||
ready_frames.emplace(cv::MediaFrame());
|
||||
return ExecutionStatus::Processed;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void initialize_session(mfxSession mfx_session,
|
||||
cv::gapi::wip::onevpl::DecoderParams&&,
|
||||
std::shared_ptr<cv::gapi::wip::onevpl::IDataProvider>) override {
|
||||
|
||||
register_session<TestProcessingSession>(mfx_session);
|
||||
}
|
||||
};
|
||||
|
||||
cv::gapi::wip::onevpl::surface_ptr_t create_test_surface(std::shared_ptr<void> out_buf_ptr,
|
||||
size_t, size_t) {
|
||||
std::unique_ptr<mfxFrameSurface1> handle(new mfxFrameSurface1{});
|
||||
return cv::gapi::wip::onevpl::Surface::create_surface(std::move(handle), out_buf_ptr);
|
||||
}
|
||||
|
||||
TEST(OneVPL_Source_Surface, InitSurface)
|
||||
{
|
||||
using namespace cv::gapi::wip::onevpl;
|
||||
|
||||
// create raw MFX handle
|
||||
std::unique_ptr<mfxFrameSurface1> handle(new mfxFrameSurface1{});
|
||||
mfxFrameSurface1 *mfx_core_handle = handle.get();
|
||||
|
||||
// create preallocate surface memory: empty for test
|
||||
std::shared_ptr<void> associated_memory {};
|
||||
auto surf = Surface::create_surface(std::move(handle), associated_memory);
|
||||
|
||||
// check self consistency
|
||||
EXPECT_EQ(reinterpret_cast<void*>(surf->get_handle()),
|
||||
reinterpret_cast<void*>(mfx_core_handle));
|
||||
EXPECT_EQ(surf->get_locks_count(), 0);
|
||||
EXPECT_EQ(surf->obtain_lock(), 0);
|
||||
EXPECT_EQ(surf->get_locks_count(), 1);
|
||||
EXPECT_EQ(surf->release_lock(), 1);
|
||||
EXPECT_EQ(surf->get_locks_count(), 0);
|
||||
}
|
||||
|
||||
TEST(OneVPL_Source_Surface, ConcurrentLock)
|
||||
{
|
||||
using namespace cv::gapi::wip::onevpl;
|
||||
|
||||
// create raw MFX handle
|
||||
std::unique_ptr<mfxFrameSurface1> handle(new mfxFrameSurface1{});
|
||||
|
||||
// create preallocate surface memory: empty for test
|
||||
std::shared_ptr<void> associated_memory {};
|
||||
auto surf = Surface::create_surface(std::move(handle), associated_memory);
|
||||
|
||||
// check self consistency
|
||||
EXPECT_EQ(surf->get_locks_count(), 0);
|
||||
|
||||
// MFX internal limitation: do not exceede U16 range
|
||||
// so I16 is using here
|
||||
int16_t lock_counter = std::numeric_limits<int16_t>::max() - 1;
|
||||
std::promise<void> barrier;
|
||||
std::future<void> sync = barrier.get_future();
|
||||
|
||||
|
||||
std::thread worker_thread([&barrier, surf, lock_counter] () {
|
||||
barrier.set_value();
|
||||
|
||||
// concurrent lock
|
||||
for (int16_t i = 0; i < lock_counter; i ++) {
|
||||
surf->obtain_lock();
|
||||
}
|
||||
});
|
||||
sync.wait();
|
||||
|
||||
// concurrent lock
|
||||
for (int16_t i = 0; i < lock_counter; i ++) {
|
||||
surf->obtain_lock();
|
||||
}
|
||||
|
||||
worker_thread.join();
|
||||
EXPECT_EQ(surf->get_locks_count(), lock_counter * 2);
|
||||
}
|
||||
|
||||
TEST(OneVPL_Source_Surface, MemoryLifeTime)
|
||||
{
|
||||
using namespace cv::gapi::wip::onevpl;
|
||||
|
||||
// create preallocate surface memory
|
||||
std::unique_ptr<char> preallocated_memory_ptr(new char);
|
||||
std::shared_ptr<void> associated_memory (preallocated_memory_ptr.get(),
|
||||
[&preallocated_memory_ptr] (void* ptr) {
|
||||
EXPECT_TRUE(preallocated_memory_ptr);
|
||||
EXPECT_EQ(preallocated_memory_ptr.get(), ptr);
|
||||
preallocated_memory_ptr.reset();
|
||||
});
|
||||
|
||||
// generate surfaces
|
||||
constexpr size_t surface_num = 10000;
|
||||
std::vector<std::shared_ptr<Surface>> surfaces(surface_num);
|
||||
std::generate(surfaces.begin(), surfaces.end(), [surface_num, associated_memory](){
|
||||
std::unique_ptr<mfxFrameSurface1> handle(new mfxFrameSurface1{});
|
||||
return Surface::create_surface(std::move(handle), associated_memory);
|
||||
});
|
||||
|
||||
// destroy surfaces
|
||||
{
|
||||
std::thread deleter_thread([&surfaces]() {
|
||||
surfaces.clear();
|
||||
});
|
||||
deleter_thread.join();
|
||||
}
|
||||
|
||||
// workspace memory must be alive
|
||||
EXPECT_EQ(surfaces.size(), 0);
|
||||
EXPECT_TRUE(associated_memory != nullptr);
|
||||
EXPECT_TRUE(preallocated_memory_ptr.get() != nullptr);
|
||||
|
||||
// generate surfaces again + 1
|
||||
constexpr size_t surface_num_plus_one = 10001;
|
||||
surfaces.resize(surface_num_plus_one);
|
||||
std::generate(surfaces.begin(), surfaces.end(), [surface_num_plus_one, associated_memory](){
|
||||
std::unique_ptr<mfxFrameSurface1> handle(new mfxFrameSurface1{});
|
||||
return Surface::create_surface(std::move(handle), associated_memory);
|
||||
});
|
||||
|
||||
// remember one surface
|
||||
std::shared_ptr<Surface> last_surface = surfaces.back();
|
||||
|
||||
// destroy another surfaces
|
||||
surfaces.clear();
|
||||
|
||||
// destroy associated_memory
|
||||
associated_memory.reset();
|
||||
|
||||
// workspace memory must be still alive
|
||||
EXPECT_EQ(surfaces.size(), 0);
|
||||
EXPECT_TRUE(associated_memory == nullptr);
|
||||
EXPECT_TRUE(preallocated_memory_ptr.get() != nullptr);
|
||||
|
||||
// destroy last surface
|
||||
last_surface.reset();
|
||||
|
||||
// workspace memory must be freed
|
||||
EXPECT_TRUE(preallocated_memory_ptr.get() == nullptr);
|
||||
}
|
||||
|
||||
TEST(OneVPL_Source_CPU_FrameAdapter, InitFrameAdapter)
|
||||
{
|
||||
using namespace cv::gapi::wip::onevpl;
|
||||
|
||||
// create raw MFX handle
|
||||
std::unique_ptr<mfxFrameSurface1> handle(new mfxFrameSurface1{});
|
||||
|
||||
// create preallocate surface memory: empty for test
|
||||
std::shared_ptr<void> associated_memory {};
|
||||
auto surf = Surface::create_surface(std::move(handle), associated_memory);
|
||||
|
||||
// check consistency
|
||||
EXPECT_EQ(surf->get_locks_count(), 0);
|
||||
|
||||
{
|
||||
VPLMediaFrameCPUAdapter adapter(surf);
|
||||
EXPECT_EQ(surf->get_locks_count(), 1);
|
||||
}
|
||||
EXPECT_EQ(surf->get_locks_count(), 0);
|
||||
}
|
||||
|
||||
TEST(OneVPL_Source_CPU_Accelerator, InitDestroy)
|
||||
{
|
||||
using cv::gapi::wip::onevpl::VPLCPUAccelerationPolicy;
|
||||
using cv::gapi::wip::onevpl::VPLAccelerationPolicy;
|
||||
|
||||
auto acceleration_policy = std::make_shared<VPLCPUAccelerationPolicy>();
|
||||
|
||||
size_t surface_count = 10;
|
||||
size_t surface_size_bytes = 1024;
|
||||
size_t pool_count = 3;
|
||||
std::vector<VPLAccelerationPolicy::pool_key_t> pool_export_keys;
|
||||
pool_export_keys.reserve(pool_count);
|
||||
|
||||
// create several pools
|
||||
for (size_t i = 0; i < pool_count; i++)
|
||||
{
|
||||
VPLAccelerationPolicy::pool_key_t key =
|
||||
acceleration_policy->create_surface_pool(surface_count,
|
||||
surface_size_bytes,
|
||||
create_test_surface);
|
||||
// check consistency
|
||||
EXPECT_EQ(acceleration_policy->get_surface_count(key), surface_count);
|
||||
EXPECT_EQ(acceleration_policy->get_free_surface_count(key), surface_count);
|
||||
|
||||
pool_export_keys.push_back(key);
|
||||
}
|
||||
|
||||
EXPECT_NO_THROW(acceleration_policy.reset());
|
||||
}
|
||||
|
||||
TEST(OneVPL_Source_CPU_Accelerator, PoolProduceConsume)
|
||||
{
|
||||
using cv::gapi::wip::onevpl::VPLCPUAccelerationPolicy;
|
||||
using cv::gapi::wip::onevpl::VPLAccelerationPolicy;
|
||||
using cv::gapi::wip::onevpl::Surface;
|
||||
|
||||
auto acceleration_policy = std::make_shared<VPLCPUAccelerationPolicy>();
|
||||
|
||||
size_t surface_count = 10;
|
||||
size_t surface_size_bytes = 1024;
|
||||
|
||||
VPLAccelerationPolicy::pool_key_t key =
|
||||
acceleration_policy->create_surface_pool(surface_count,
|
||||
surface_size_bytes,
|
||||
create_test_surface);
|
||||
// check consistency
|
||||
EXPECT_EQ(acceleration_policy->get_surface_count(key), surface_count);
|
||||
EXPECT_EQ(acceleration_policy->get_free_surface_count(key), surface_count);
|
||||
|
||||
// consume available surfaces
|
||||
std::vector<std::shared_ptr<Surface>> surfaces;
|
||||
surfaces.reserve(surface_count);
|
||||
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(surf->obtain_lock(), 0);
|
||||
surfaces.push_back(std::move(surf));
|
||||
}
|
||||
|
||||
// check consistency (no free surfaces)
|
||||
EXPECT_EQ(acceleration_policy->get_surface_count(key), surface_count);
|
||||
EXPECT_EQ(acceleration_policy->get_free_surface_count(key), 0);
|
||||
|
||||
// fail consume non-free surfaces
|
||||
for (size_t i = 0; i < surface_count; i++) {
|
||||
EXPECT_THROW(acceleration_policy->get_free_surface(key), std::runtime_error);
|
||||
}
|
||||
|
||||
// release surfaces
|
||||
for (auto& surf : surfaces) {
|
||||
EXPECT_EQ(surf->release_lock(), 1);
|
||||
}
|
||||
surfaces.clear();
|
||||
|
||||
// check consistency
|
||||
EXPECT_EQ(acceleration_policy->get_surface_count(key), surface_count);
|
||||
EXPECT_EQ(acceleration_policy->get_free_surface_count(key), surface_count);
|
||||
|
||||
//check availability after release
|
||||
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(surf->obtain_lock(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OneVPL_Source_CPU_Accelerator, PoolProduceConcurrentConsume)
|
||||
{
|
||||
using cv::gapi::wip::onevpl::VPLCPUAccelerationPolicy;
|
||||
using cv::gapi::wip::onevpl::VPLAccelerationPolicy;
|
||||
using cv::gapi::wip::onevpl::Surface;
|
||||
|
||||
auto acceleration_policy = std::make_shared<VPLCPUAccelerationPolicy>();
|
||||
|
||||
size_t surface_count = 10;
|
||||
size_t surface_size_bytes = 1024;
|
||||
|
||||
VPLAccelerationPolicy::pool_key_t key =
|
||||
acceleration_policy->create_surface_pool(surface_count,
|
||||
surface_size_bytes,
|
||||
create_test_surface);
|
||||
|
||||
// check consistency
|
||||
EXPECT_EQ(acceleration_policy->get_surface_count(key), surface_count);
|
||||
EXPECT_EQ(acceleration_policy->get_free_surface_count(key), surface_count);
|
||||
|
||||
// consume available surfaces
|
||||
std::vector<std::shared_ptr<Surface>> surfaces;
|
||||
surfaces.reserve(surface_count);
|
||||
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(surf->obtain_lock(), 0);
|
||||
surfaces.push_back(std::move(surf));
|
||||
}
|
||||
|
||||
std::promise<void> launch_promise;
|
||||
std::future<void> sync = launch_promise.get_future();
|
||||
std::promise<size_t> surface_released_promise;
|
||||
std::future<size_t> released_result = surface_released_promise.get_future();
|
||||
std::thread worker_thread([&launch_promise, &surface_released_promise, &surfaces] () {
|
||||
launch_promise.set_value();
|
||||
|
||||
// concurrent release surfaces
|
||||
size_t surfaces_count = surfaces.size();
|
||||
for (auto& surf : surfaces) {
|
||||
EXPECT_EQ(surf->release_lock(), 1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
surfaces.clear();
|
||||
|
||||
surface_released_promise.set_value(surfaces_count);
|
||||
});
|
||||
sync.wait();
|
||||
|
||||
// check free surface concurrently
|
||||
std::future_status status;
|
||||
size_t free_surface_count = 0;
|
||||
size_t free_surface_count_prev = 0;
|
||||
do {
|
||||
status = released_result.wait_for(std::chrono::seconds(1));
|
||||
free_surface_count = acceleration_policy->get_free_surface_count(key);
|
||||
EXPECT_TRUE(free_surface_count >= free_surface_count_prev);
|
||||
free_surface_count_prev = free_surface_count;
|
||||
} while (status != std::future_status::ready);
|
||||
std::cerr<< "Ready" << std::endl;
|
||||
free_surface_count = acceleration_policy->get_free_surface_count(key);
|
||||
worker_thread.join();
|
||||
EXPECT_TRUE(free_surface_count >= free_surface_count_prev);
|
||||
}
|
||||
|
||||
TEST(OneVPL_Source_ProcessingEngine, Init)
|
||||
{
|
||||
using namespace cv::gapi::wip::onevpl;
|
||||
std::unique_ptr<VPLAccelerationPolicy> accel;
|
||||
TestProcessingEngine engine(std::move(accel));
|
||||
|
||||
mfxSession mfx_session{};
|
||||
engine.initialize_session(mfx_session, DecoderParams{}, std::shared_ptr<IDataProvider>{});
|
||||
|
||||
EXPECT_EQ(engine.get_ready_frames_count(), 0);
|
||||
ProcessingEngineBase::ExecutionStatus ret = engine.process(mfx_session);
|
||||
EXPECT_EQ(ret, ProcessingEngineBase::ExecutionStatus::Continue);
|
||||
EXPECT_EQ(engine.pipeline_stage_num, 0);
|
||||
|
||||
ret = engine.process(mfx_session);
|
||||
EXPECT_EQ(ret, ProcessingEngineBase::ExecutionStatus::Continue);
|
||||
EXPECT_EQ(engine.pipeline_stage_num, 1);
|
||||
|
||||
ret = engine.process(mfx_session);
|
||||
EXPECT_EQ(ret, ProcessingEngineBase::ExecutionStatus::Continue);
|
||||
EXPECT_EQ(engine.pipeline_stage_num, 2);
|
||||
|
||||
ret = engine.process(mfx_session);
|
||||
EXPECT_EQ(ret, ProcessingEngineBase::ExecutionStatus::Processed);
|
||||
EXPECT_EQ(engine.pipeline_stage_num, 3);
|
||||
EXPECT_EQ(engine.get_ready_frames_count(), 1);
|
||||
|
||||
ret = engine.process(mfx_session);
|
||||
EXPECT_EQ(ret, ProcessingEngineBase::ExecutionStatus::SessionNotFound);
|
||||
EXPECT_EQ(engine.pipeline_stage_num, 3);
|
||||
EXPECT_EQ(engine.get_ready_frames_count(), 1);
|
||||
|
||||
cv::gapi::wip::Data frame;
|
||||
engine.get_frame(frame);
|
||||
}
|
||||
}
|
||||
} // namespace opencv_test
|
||||
#endif // HAVE_ONEVPL
|
Reference in New Issue
Block a user