mirror of
https://github.com/opencv/opencv.git
synced 2025-06-11 11:45:30 +08:00
Merge pull request #20570 from sivanov-work:vpl_source_data_adapter
G-API: oneVPL (simplification) Add data adapter & Cfg params * Add cfg_param & data_provider * Fix compilation after rebase * Apply some comments * Apply default ctor outside class definition comment * Apply cfg param in source * Fix compilation: add virtual dtor * Move cfg_params in regular gapi src list * Fix compilation: add export.hpp * Add errno.h * Add errno.h * Apply namespace comment * Add several Doxygen & rename cfg_param * Fix build * Update Doxygen docs for onevpl * Fix typo
This commit is contained in:
parent
b509a7060a
commit
65ef82a946
@ -164,8 +164,11 @@ set(gapi_srcs
|
||||
src/backends/python/gpythonbackend.cpp
|
||||
|
||||
# Streaming source
|
||||
src/streaming/onevpl/onevpl_source.cpp
|
||||
src/streaming/onevpl/onevpl_source_priv.cpp
|
||||
src/streaming/onevpl/source.cpp
|
||||
src/streaming/onevpl/source_priv.cpp
|
||||
src/streaming/onevpl/file_data_provider.cpp
|
||||
src/streaming/onevpl/cfg_params.cpp
|
||||
src/streaming/onevpl/data_provider_interface_exception.cpp
|
||||
|
||||
# Utils (ITT tracing)
|
||||
src/utils/itt.cpp
|
||||
|
@ -0,0 +1,88 @@
|
||||
// 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
|
||||
|
||||
#ifndef OPENCV_GAPI_STREAMING_ONEVPL_CFG_PARAMS_HPP
|
||||
#define OPENCV_GAPI_STREAMING_ONEVPL_CFG_PARAMS_HPP
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <opencv2/gapi/streaming/source.hpp>
|
||||
#include <opencv2/gapi/util/variant.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
|
||||
/**
|
||||
* @brief Public class is using for creation of onevpl::GSource instances.
|
||||
*
|
||||
* Class members availaible through methods @ref CfgParam::get_name() and @ref CfgParam::get_value() are used by
|
||||
* onevpl::GSource inner logic to create or find oneVPL particular implementation
|
||||
* (software/hardware, specific API version and etc.).
|
||||
*
|
||||
* @note Because oneVPL may provide several implementations which are satisfying with multiple (or single one) @ref CfgParam
|
||||
* criteria therefore it is possible to configure `preferred` parameters. This kind of CfgParams are created
|
||||
* using `is_major = false` argument in @ref CfgParam::create method and are not used by creating oneVPL particular implementations.
|
||||
* Instead they fill out a "score table" to select preferrable implementation from available list. Implementation are satisfying
|
||||
* with most of these optional params would be chosen.
|
||||
* If no one optional CfgParam params were present then first of available oneVPL implementation would be applied.
|
||||
* Please get on https://spec.oneapi.io/versions/latest/elements/oneVPL/source/API_ref/VPL_disp_api_func.html?highlight=mfxcreateconfig#mfxsetconfigfilterproperty
|
||||
* for using OneVPL configuration. In this schema `mfxU8 *name` represents @ref CfgParam::get_name() and
|
||||
* `mfxVariant value` is @ref CfgParam::get_value()
|
||||
*/
|
||||
struct GAPI_EXPORTS CfgParam {
|
||||
using name_t = std::string;
|
||||
using value_t = cv::util::variant<uint8_t, int8_t,
|
||||
uint16_t, int16_t,
|
||||
uint32_t, int32_t,
|
||||
uint64_t, int64_t,
|
||||
float_t,
|
||||
double_t,
|
||||
void*,
|
||||
std::string>;
|
||||
|
||||
/**
|
||||
* Create onevp::GSource configuration parameter.
|
||||
*
|
||||
*@param name name of parameter.
|
||||
*@param value value of parameter.
|
||||
*@param is_major TRUE if parameter MUST be provided by OneVPL inner implementation, FALSE for optional (for resolve multiple available implementations).
|
||||
*
|
||||
*/
|
||||
template<typename ValueType>
|
||||
static CfgParam create(const std::string& name, ValueType&& value, bool is_major = true) {
|
||||
CfgParam param(name, CfgParam::value_t(std::forward<ValueType>(value)), is_major);
|
||||
return param;
|
||||
}
|
||||
|
||||
struct Priv;
|
||||
|
||||
const name_t& get_name() const;
|
||||
const value_t& get_value() const;
|
||||
bool is_major() const;
|
||||
bool operator==(const CfgParam& rhs) const;
|
||||
bool operator< (const CfgParam& rhs) const;
|
||||
bool operator!=(const CfgParam& rhs) const;
|
||||
|
||||
CfgParam& operator=(const CfgParam& src);
|
||||
CfgParam& operator=(CfgParam&& src);
|
||||
CfgParam(const CfgParam& src);
|
||||
CfgParam(CfgParam&& src);
|
||||
~CfgParam();
|
||||
private:
|
||||
CfgParam(const std::string& param_name, value_t&& param_value, bool is_major_param);
|
||||
std::shared_ptr<Priv> m_priv;
|
||||
};
|
||||
|
||||
} //namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_GAPI_STREAMING_ONEVPL_CFG_PARAMS_HPP
|
@ -0,0 +1,74 @@
|
||||
// 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
|
||||
|
||||
#ifndef GAPI_STREAMING_ONEVPL_ONEVPL_DATA_PROVIDER_INTERFACE_HPP
|
||||
#define GAPI_STREAMING_ONEVPL_ONEVPL_DATA_PROVIDER_INTERFACE_HPP
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
#include <opencv2/gapi/own/exports.hpp> // GAPI_EXPORTS
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
|
||||
struct GAPI_EXPORTS DataProviderException : public std::exception {
|
||||
virtual ~DataProviderException() {};
|
||||
};
|
||||
|
||||
struct GAPI_EXPORTS DataProviderSystemErrorException : public DataProviderException {
|
||||
DataProviderSystemErrorException(int error_code, const std::string& desription = std::string());
|
||||
virtual ~DataProviderSystemErrorException();
|
||||
virtual const char* what() const noexcept override;
|
||||
|
||||
private:
|
||||
std::string reason;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Public interface allows to customize extraction of video stream data
|
||||
* used by onevpl::GSource instead of reading stream from file (by default).
|
||||
*
|
||||
* Interface implementation constructor MUST provide consistency and creates fully operable object.
|
||||
* If error happened implementation MUST throw `DataProviderException` kind exceptions
|
||||
*
|
||||
* @note Interface implementation MUST manage stream and other constructed resources by itself to avoid any kind of leak.
|
||||
* For simple interface implementation example please see `StreamDataProvider` in `tests/streaming/gapi_streaming_tests.cpp`
|
||||
*/
|
||||
struct GAPI_EXPORTS IDataProvider {
|
||||
using Ptr = std::shared_ptr<IDataProvider>;
|
||||
|
||||
virtual ~IDataProvider() {};
|
||||
|
||||
/**
|
||||
* The function is used by onevpl::GSource to extract binary data stream from @ref IDataProvider
|
||||
* implementation.
|
||||
*
|
||||
* It MUST throw `DataProviderException` kind exceptions in fail cases.
|
||||
* It MUST return 0 in EOF which considered as not-fail case.
|
||||
*
|
||||
* @param out_data_bytes_size the available capacity of out_data buffer.
|
||||
* @param out_data the output consumer buffer with capacity out_data_bytes_size.
|
||||
* @return fetched bytes count.
|
||||
*/
|
||||
virtual size_t fetch_data(size_t out_data_bytes_size, void* out_data) = 0;
|
||||
|
||||
/**
|
||||
* The function is used by onevpl::GSource to check more binary data availability.
|
||||
*
|
||||
* It MUST return TRUE in case of EOF and NO_THROW exceptions.
|
||||
*
|
||||
* @return boolean value which detects end of stream
|
||||
*/
|
||||
virtual bool empty() const = 0;
|
||||
};
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
|
||||
#endif // GAPI_STREAMING_ONEVPL_ONEVPL_DATA_PROVIDER_INTERFACE_HPP
|
@ -1,44 +0,0 @@
|
||||
// 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
|
||||
|
||||
#ifndef OPENCV_GAPI_STREAMING_ONEVPL_ONEVPL_SOURCE_HPP
|
||||
#define OPENCV_GAPI_STREAMING_ONEVPL_ONEVPL_SOURCE_HPP
|
||||
|
||||
#include <opencv2/gapi/garg.hpp>
|
||||
#include <opencv2/gapi/streaming/meta.hpp>
|
||||
#include <opencv2/gapi/streaming/source.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
|
||||
class GAPI_EXPORTS OneVPLSource : public IStreamSource
|
||||
{
|
||||
public:
|
||||
struct Priv;
|
||||
|
||||
explicit OneVPLSource(const std::string& filePath);
|
||||
~OneVPLSource() override;
|
||||
|
||||
bool pull(cv::gapi::wip::Data& data) override;
|
||||
GMetaArg descr_of() const override;
|
||||
|
||||
private:
|
||||
explicit OneVPLSource(std::unique_ptr<Priv>&& impl);
|
||||
std::unique_ptr<Priv> m_priv;
|
||||
};
|
||||
|
||||
template<class... Args>
|
||||
GAPI_EXPORTS_W cv::Ptr<IStreamSource> inline make_vpl_src(const std::string& filePath, Args&&... args)
|
||||
{
|
||||
return make_src<OneVPLSource>(filePath, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_GAPI_STREAMING_ONEVPL_ONEVPL_SOURCE_HPP
|
@ -0,0 +1,64 @@
|
||||
// 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
|
||||
|
||||
#ifndef OPENCV_GAPI_STREAMING_ONEVPL_ONEVPL_SOURCE_HPP
|
||||
#define OPENCV_GAPI_STREAMING_ONEVPL_ONEVPL_SOURCE_HPP
|
||||
|
||||
#include <opencv2/gapi/garg.hpp>
|
||||
#include <opencv2/gapi/streaming/meta.hpp>
|
||||
#include <opencv2/gapi/streaming/source.hpp>
|
||||
#include <opencv2/gapi/streaming/onevpl/cfg_params.hpp>
|
||||
#include <opencv2/gapi/streaming/onevpl/data_provider_interface.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
using CfgParams = std::vector<CfgParam>;
|
||||
|
||||
/**
|
||||
* @brief G-API streaming source based on OneVPL implementation.
|
||||
*
|
||||
* This class implements IStreamSource interface.
|
||||
* Its constructor takes source file path (in usual way) or @ref onevpl::IDataProvider
|
||||
* interface implementation (for not file-based sources). It also allows to pass-through
|
||||
* oneVPL configuration parameters by using several @ref onevpl::CfgParam.
|
||||
*
|
||||
* @note stream sources are passed to G-API via shared pointers, so
|
||||
* please gapi::make_onevpl_src<> to create objects and ptr() to pass a
|
||||
* GSource to cv::gin().
|
||||
*/
|
||||
class GAPI_EXPORTS GSource : public IStreamSource
|
||||
{
|
||||
public:
|
||||
struct Priv;
|
||||
|
||||
GSource(const std::string& filePath,
|
||||
const CfgParams& cfg_params = CfgParams{});
|
||||
GSource(std::shared_ptr<IDataProvider> source,
|
||||
const CfgParams& cfg_params = CfgParams{});
|
||||
~GSource() override;
|
||||
|
||||
bool pull(cv::gapi::wip::Data& data) override;
|
||||
GMetaArg descr_of() const override;
|
||||
|
||||
private:
|
||||
explicit GSource(std::unique_ptr<Priv>&& impl);
|
||||
std::unique_ptr<Priv> m_priv;
|
||||
};
|
||||
} // namespace onevpl
|
||||
|
||||
template<class... Args>
|
||||
GAPI_EXPORTS_W cv::Ptr<IStreamSource> inline make_onevpl_src(Args&&... args)
|
||||
{
|
||||
return make_src<onevpl::GSource>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_GAPI_STREAMING_ONEVPL_ONEVPL_SOURCE_HPP
|
@ -9,7 +9,7 @@
|
||||
#include <opencv2/gapi/cpu/gcpukernel.hpp>
|
||||
#include <opencv2/gapi/infer/ie.hpp>
|
||||
#include <opencv2/gapi/render.hpp>
|
||||
#include <opencv2/gapi/streaming/onevpl/onevpl_source.hpp>
|
||||
#include <opencv2/gapi/streaming/onevpl/source.hpp>
|
||||
#include <opencv2/highgui.hpp> // CommandLineParser
|
||||
|
||||
const std::string about =
|
||||
@ -19,7 +19,8 @@ const std::string keys =
|
||||
"{ input | | Path to the input demultiplexed video file }"
|
||||
"{ output | | Path to the output RAW video file. Use .avi extension }"
|
||||
"{ facem | face-detection-adas-0001.xml | Path to OpenVINO IE face detection model (.xml) }"
|
||||
"{ faced | CPU | Target device for face detection model (e.g. CPU, GPU, VPU, ...) }";
|
||||
"{ cfg_params | <prop name>:<value>;<prop name>:<value> | Semicolon separated list of oneVPL mfxVariants which is used for configuring source (see `MFXSetConfigFilterProperty` by https://spec.oneapi.io/versions/latest/elements/oneVPL/source/index.html) }";
|
||||
|
||||
|
||||
namespace {
|
||||
std::string get_weights_path(const std::string &model_path) {
|
||||
@ -155,6 +156,10 @@ GAPI_OCV_KERNEL(OCVBBoxes, BBoxes) {
|
||||
|
||||
} // namespace custom
|
||||
|
||||
namespace cfg {
|
||||
typename cv::gapi::wip::onevpl::CfgParam create_from_string(const std::string &line);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
cv::CommandLineParser cmd(argc, argv, keys);
|
||||
@ -178,10 +183,22 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// get oneVPL cfg params from cmd
|
||||
std::stringstream params_list(cmd.get<std::string>("cfg_params"));
|
||||
std::vector<cv::gapi::wip::onevpl::CfgParam> source_cfgs;
|
||||
try {
|
||||
std::string line;
|
||||
while (std::getline(params_list, line, ';')) {
|
||||
source_cfgs.push_back(cfg::create_from_string(line));
|
||||
}
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Invalid cfg parameter: " << ex.what() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto face_net = cv::gapi::ie::Params<custom::FaceDetector> {
|
||||
face_model_path, // path to topology IR
|
||||
get_weights_path(face_model_path), // path to weights
|
||||
cmd.get<std::string>("faced"), // device specifier
|
||||
get_weights_path(face_model_path) // path to weights
|
||||
};
|
||||
auto kernels = cv::gapi::kernels
|
||||
< custom::OCVLocateROI
|
||||
@ -192,7 +209,7 @@ int main(int argc, char *argv[]) {
|
||||
// Create source
|
||||
cv::Ptr<cv::gapi::wip::IStreamSource> cap;
|
||||
try {
|
||||
cap = cv::gapi::wip::make_vpl_src(file_path);
|
||||
cap = cv::gapi::wip::make_onevpl_src(file_path, source_cfgs);
|
||||
std::cout << "oneVPL source desription: " << cap->descr_of() << std::endl;
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Cannot create source: " << ex.what() << std::endl;
|
||||
@ -213,7 +230,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
cv::GStreamingCompiled pipeline;
|
||||
try {
|
||||
pipeline = cv::GComputation(cv::GIn(in), cv::GOut(out))
|
||||
pipeline = cv::GComputation(cv::GIn(in), cv::GOut(out))
|
||||
.compileStreaming(cv::compile_args(kernels, networks));
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << "Exception occured during pipeline construction: " << ex.what() << std::endl;
|
||||
@ -252,3 +269,25 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
namespace cfg {
|
||||
typename cv::gapi::wip::onevpl::CfgParam create_from_string(const std::string &line) {
|
||||
using namespace cv::gapi::wip;
|
||||
|
||||
if (line.empty()) {
|
||||
throw std::runtime_error("Cannot parse CfgParam from emply line");
|
||||
}
|
||||
|
||||
std::string::size_type name_endline_pos = line.find(':');
|
||||
if (name_endline_pos == std::string::npos) {
|
||||
throw std::runtime_error("Cannot parse CfgParam from: " + line +
|
||||
"\nExpected separator \":\"");
|
||||
}
|
||||
|
||||
std::string name = line.substr(0, name_endline_pos);
|
||||
std::string value = line.substr(name_endline_pos + 1);
|
||||
|
||||
return cv::gapi::wip::onevpl::CfgParam::create(name, value);
|
||||
}
|
||||
}
|
||||
|
137
modules/gapi/src/streaming/onevpl/cfg_params.cpp
Normal file
137
modules/gapi/src/streaming/onevpl/cfg_params.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
// 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 <opencv2/gapi/util/throw.hpp>
|
||||
|
||||
#include <opencv2/gapi/streaming/onevpl/cfg_params.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
|
||||
namespace util {
|
||||
struct variant_comparator : cv::util::static_visitor<bool, variant_comparator> {
|
||||
variant_comparator(const CfgParam::value_t& rhs_value) :
|
||||
rhs(rhs_value) {}
|
||||
|
||||
template<typename ValueType>
|
||||
bool visit(const ValueType& lhs) const {
|
||||
return lhs < cv::util::get<ValueType>(rhs);
|
||||
}
|
||||
private:
|
||||
const CfgParam::value_t& rhs;
|
||||
};
|
||||
} // namespace util
|
||||
|
||||
struct CfgParam::Priv {
|
||||
Priv(const std::string& param_name, CfgParam::value_t&& param_value, bool is_major_param) :
|
||||
name(param_name), value(std::forward<value_t>(param_value)), major_flag(is_major_param) {
|
||||
}
|
||||
|
||||
const CfgParam::name_t& get_name_impl() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
const CfgParam::value_t& get_value_impl() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
bool is_major_impl() const {
|
||||
return major_flag;
|
||||
}
|
||||
|
||||
// comparison implementation
|
||||
bool operator< (const Priv& rhs) const {
|
||||
// implement default pair comparison
|
||||
if (get_name_impl() < rhs.get_name_impl()) {
|
||||
return true;
|
||||
} else if (get_name_impl() > rhs.get_name_impl()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO implement operator < for cv::util::variant
|
||||
const CfgParam::value_t& lvar = get_value_impl();
|
||||
const CfgParam::value_t& rvar = rhs.get_value_impl();
|
||||
if (lvar.index() < rvar.index()) {
|
||||
return true;
|
||||
} else if (lvar.index() > rvar.index()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
util::variant_comparator comp(rvar);
|
||||
return cv::util::visit(comp, lvar);
|
||||
}
|
||||
|
||||
bool operator==(const Priv& rhs) const {
|
||||
return (get_name_impl() == rhs.get_name_impl())
|
||||
&& (get_value_impl() == rhs.get_value_impl());
|
||||
}
|
||||
|
||||
bool operator!=(const Priv& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
CfgParam::name_t name;
|
||||
CfgParam::value_t value;
|
||||
bool major_flag;
|
||||
};
|
||||
|
||||
CfgParam::CfgParam (const std::string& param_name, value_t&& param_value, bool is_major_param) :
|
||||
m_priv(new Priv(param_name, std::move(param_value), is_major_param)) {
|
||||
}
|
||||
|
||||
CfgParam::~CfgParam() = default;
|
||||
|
||||
CfgParam& CfgParam::operator=(const CfgParam& src) {
|
||||
if (this != &src) {
|
||||
m_priv = src.m_priv;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
CfgParam& CfgParam::operator=(CfgParam&& src) {
|
||||
if (this != &src) {
|
||||
m_priv = std::move(src.m_priv);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
CfgParam::CfgParam(const CfgParam& src) :
|
||||
m_priv(src.m_priv) {
|
||||
}
|
||||
|
||||
CfgParam::CfgParam(CfgParam&& src) :
|
||||
m_priv(std::move(src.m_priv)) {
|
||||
}
|
||||
|
||||
const CfgParam::name_t& CfgParam::get_name() const {
|
||||
return m_priv->get_name_impl();
|
||||
}
|
||||
|
||||
const CfgParam::value_t& CfgParam::get_value() const {
|
||||
return m_priv->get_value_impl();
|
||||
}
|
||||
|
||||
bool CfgParam::is_major() const {
|
||||
return m_priv->is_major_impl();
|
||||
}
|
||||
|
||||
bool CfgParam::operator< (const CfgParam& rhs) const {
|
||||
return *m_priv < *rhs.m_priv;
|
||||
}
|
||||
|
||||
bool CfgParam::operator==(const CfgParam& rhs) const {
|
||||
return *m_priv == *rhs.m_priv;
|
||||
}
|
||||
|
||||
bool CfgParam::operator!=(const CfgParam& rhs) const {
|
||||
return *m_priv != *rhs.m_priv;
|
||||
}
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
@ -0,0 +1,22 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <opencv2/gapi/streaming/onevpl/data_provider_interface.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
DataProviderSystemErrorException::DataProviderSystemErrorException(int error_code, const std::string& desription) {
|
||||
reason = desription + ", error: " + std::to_string(error_code) + ", desctiption: " + strerror(error_code);
|
||||
}
|
||||
|
||||
DataProviderSystemErrorException::~DataProviderSystemErrorException() = default;
|
||||
|
||||
const char* DataProviderSystemErrorException::what() const noexcept {
|
||||
return reason.c_str();
|
||||
}
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
47
modules/gapi/src/streaming/onevpl/file_data_provider.cpp
Normal file
47
modules/gapi/src/streaming/onevpl/file_data_provider.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
// 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 <errno.h>
|
||||
|
||||
#include "streaming/onevpl/file_data_provider.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
|
||||
FileDataProvider::FileDataProvider(const std::string& file_path) :
|
||||
source_handle(fopen(file_path.c_str(), "rb"), &fclose) {
|
||||
if (!source_handle) {
|
||||
throw DataProviderSystemErrorException(errno,
|
||||
"FileDataProvider: cannot open source file: " + file_path);
|
||||
}
|
||||
}
|
||||
|
||||
FileDataProvider::~FileDataProvider() = default;
|
||||
|
||||
size_t FileDataProvider::fetch_data(size_t out_data_bytes_size, void* out_data) {
|
||||
if (empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ret = fread(out_data, 1, out_data_bytes_size, source_handle.get());
|
||||
if (ret == 0) {
|
||||
if (feof(source_handle.get())) {
|
||||
source_handle.reset();
|
||||
} else {
|
||||
throw DataProviderSystemErrorException (errno, "FileDataProvider::fetch_data error read");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FileDataProvider::empty() const {
|
||||
return !source_handle;
|
||||
}
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
33
modules/gapi/src/streaming/onevpl/file_data_provider.hpp
Normal file
33
modules/gapi/src/streaming/onevpl/file_data_provider.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// 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
|
||||
|
||||
#ifndef GAPI_STREAMING_ONEVPL_ONEVPL_FILE_DATA_PROVIDER_HPP
|
||||
#define GAPI_STREAMING_ONEVPL_ONEVPL_FILE_DATA_PROVIDER_HPP
|
||||
#include <stdio.h>
|
||||
|
||||
#include <opencv2/gapi/streaming/onevpl/data_provider_interface.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
struct FileDataProvider : public IDataProvider {
|
||||
|
||||
using file_ptr = std::unique_ptr<FILE, decltype(&fclose)>;
|
||||
FileDataProvider(const std::string& file_path);
|
||||
~FileDataProvider();
|
||||
|
||||
size_t fetch_data(size_t out_data_bytes_size, void* out_data) override;
|
||||
bool empty() const override;
|
||||
private:
|
||||
file_ptr source_handle;
|
||||
};
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
|
||||
#endif // GAPI_STREAMING_ONEVPL_ONEVPL_FILE_DATA_PROVIDER_HPP
|
@ -1,48 +0,0 @@
|
||||
// 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 <opencv2/gapi/streaming/onevpl/onevpl_source.hpp>
|
||||
|
||||
#include "streaming/onevpl/onevpl_source_priv.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
|
||||
#ifdef HAVE_ONEVPL
|
||||
OneVPLSource::OneVPLSource(const std::string& filePath) :
|
||||
OneVPLSource(std::unique_ptr<Priv>(new OneVPLSource::Priv(filePath))) {
|
||||
|
||||
if (filePath.empty()) {
|
||||
util::throw_error(std::logic_error("Cannot create 'OneVPLSource' on empty source file name"));
|
||||
}
|
||||
}
|
||||
#else
|
||||
OneVPLSource::OneVPLSource(const std::string&) {
|
||||
GAPI_Assert(false && "Unsupported: G-API compiled without `WITH_GAPI_ONEVPL=ON`");
|
||||
}
|
||||
#endif
|
||||
|
||||
OneVPLSource::OneVPLSource(std::unique_ptr<Priv>&& impl) :
|
||||
IStreamSource(),
|
||||
m_priv(std::move(impl)) {
|
||||
}
|
||||
|
||||
OneVPLSource::~OneVPLSource() {
|
||||
}
|
||||
|
||||
bool OneVPLSource::pull(cv::gapi::wip::Data& data)
|
||||
{
|
||||
return m_priv->pull(data);
|
||||
}
|
||||
|
||||
GMetaArg OneVPLSource::descr_of() const
|
||||
{
|
||||
return m_priv->descr_of();
|
||||
}
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
58
modules/gapi/src/streaming/onevpl/source.cpp
Normal file
58
modules/gapi/src/streaming/onevpl/source.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
// 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 <opencv2/gapi/streaming/onevpl/source.hpp>
|
||||
|
||||
#include "streaming/onevpl/source_priv.hpp"
|
||||
#include "streaming/onevpl/file_data_provider.hpp"
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
|
||||
#ifdef HAVE_ONEVPL
|
||||
GSource::GSource(const std::string& filePath, const CfgParams& cfg_params) :
|
||||
GSource(std::unique_ptr<Priv>(new GSource::Priv(std::make_shared<FileDataProvider>(filePath),
|
||||
cfg_params))) {
|
||||
|
||||
if (filePath.empty()) {
|
||||
util::throw_error(std::logic_error("Cannot create 'GSource' on empty source file name"));
|
||||
}
|
||||
}
|
||||
|
||||
GSource::GSource(std::shared_ptr<IDataProvider> source, const CfgParams& cfg_params) :
|
||||
GSource(std::unique_ptr<Priv>(new GSource::Priv(source, cfg_params))) {
|
||||
}
|
||||
#else
|
||||
GSource::GSource(const std::string&, const CfgParams&) {
|
||||
GAPI_Assert(false && "Unsupported: G-API compiled without `WITH_GAPI_ONEVPL=ON`");
|
||||
}
|
||||
|
||||
GSource::GSource(std::shared_ptr<IDataProvider>, const CfgParams&) {
|
||||
GAPI_Assert(false && "Unsupported: G-API compiled without `WITH_GAPI_ONEVPL=ON`");
|
||||
}
|
||||
#endif
|
||||
|
||||
GSource::GSource(std::unique_ptr<Priv>&& impl) :
|
||||
IStreamSource(),
|
||||
m_priv(std::move(impl)) {
|
||||
}
|
||||
|
||||
GSource::~GSource() = default;
|
||||
|
||||
bool GSource::pull(cv::gapi::wip::Data& data)
|
||||
{
|
||||
return m_priv->pull(data);
|
||||
}
|
||||
|
||||
GMetaArg GSource::descr_of() const
|
||||
{
|
||||
return m_priv->descr_of();
|
||||
}
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
@ -7,19 +7,21 @@
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include "streaming/onevpl/onevpl_source_priv.hpp"
|
||||
#include "streaming/onevpl/source_priv.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#ifndef HAVE_ONEVPL
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
bool OneVPLSource::Priv::pull(cv::gapi::wip::Data&) {
|
||||
namespace onevpl {
|
||||
bool GSource::Priv::pull(cv::gapi::wip::Data&) {
|
||||
return true;
|
||||
}
|
||||
GMetaArg OneVPLSource::Priv::descr_of() const {
|
||||
GMetaArg GSource::Priv::descr_of() const {
|
||||
return {};
|
||||
}
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
@ -29,33 +31,35 @@ GMetaArg OneVPLSource::Priv::descr_of() const {
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
OneVPLSource::Priv::Priv() :
|
||||
namespace onevpl {
|
||||
GSource::Priv::Priv() :
|
||||
mfx_handle(MFXLoad())
|
||||
{
|
||||
GAPI_LOG_INFO(nullptr, "Initialized MFX handle: " << mfx_handle);
|
||||
description_is_valid = false;
|
||||
}
|
||||
|
||||
OneVPLSource::Priv::Priv(const std::string&) :
|
||||
OneVPLSource::Priv()
|
||||
GSource::Priv::Priv(std::shared_ptr<IDataProvider>, const std::vector<CfgParam>&) :
|
||||
GSource::Priv()
|
||||
{
|
||||
}
|
||||
|
||||
OneVPLSource::Priv::~Priv()
|
||||
GSource::Priv::~Priv()
|
||||
{
|
||||
GAPI_LOG_INFO(nullptr, "Unload MFX handle: " << mfx_handle);
|
||||
MFXUnload(mfx_handle);
|
||||
}
|
||||
|
||||
bool OneVPLSource::Priv::pull(cv::gapi::wip::Data&)
|
||||
bool GSource::Priv::pull(cv::gapi::wip::Data&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GMetaArg OneVPLSource::Priv::descr_of() const
|
||||
GMetaArg GSource::Priv::descr_of() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <opencv2/gapi/garg.hpp>
|
||||
#include <opencv2/gapi/streaming/meta.hpp>
|
||||
#include <opencv2/gapi/streaming/onevpl/onevpl_source.hpp>
|
||||
#include <opencv2/gapi/streaming/onevpl/source.hpp>
|
||||
|
||||
#ifdef HAVE_ONEVPL
|
||||
#if (MFX_VERSION >= 2000)
|
||||
@ -28,10 +28,12 @@
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
namespace onevpl {
|
||||
|
||||
struct OneVPLSource::Priv
|
||||
struct GSource::Priv
|
||||
{
|
||||
explicit Priv(const std::string& file_path);
|
||||
explicit Priv(std::shared_ptr<IDataProvider> provider,
|
||||
const std::vector<CfgParam>& params);
|
||||
~Priv();
|
||||
|
||||
bool pull(cv::gapi::wip::Data& data);
|
||||
@ -41,6 +43,7 @@ private:
|
||||
mfxLoader mfx_handle;
|
||||
bool description_is_valid;
|
||||
};
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
@ -50,11 +53,13 @@ private:
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace wip {
|
||||
struct OneVPLSource::Priv final
|
||||
namespace onevpl {
|
||||
struct GSource::Priv final
|
||||
{
|
||||
bool pull(cv::gapi::wip::Data&);
|
||||
GMetaArg descr_of() const;
|
||||
};
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
@ -25,6 +25,17 @@
|
||||
#include <opencv2/gapi/streaming/desync.hpp>
|
||||
#include <opencv2/gapi/streaming/format.hpp>
|
||||
|
||||
#include <opencv2/gapi/streaming/onevpl/source.hpp>
|
||||
|
||||
#ifdef HAVE_ONEVPL
|
||||
|
||||
#if (MFX_VERSION >= 2000)
|
||||
#include <vpl/mfxdispatcher.h>
|
||||
#endif
|
||||
|
||||
#include <vpl/mfx.h>
|
||||
#endif // HAVE_ONEVPL
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
namespace
|
||||
@ -273,6 +284,22 @@ void checkPullOverload(const cv::Mat& ref,
|
||||
EXPECT_EQ(0., cv::norm(ref, out_mat, cv::NORM_INF));
|
||||
}
|
||||
|
||||
struct StreamDataProvider : public cv::gapi::wip::onevpl::IDataProvider {
|
||||
|
||||
StreamDataProvider(std::istream& in) : data_stream (in) {
|
||||
EXPECT_TRUE(in);
|
||||
}
|
||||
|
||||
size_t fetch_data(size_t out_data_size, void* out_data_buf) override {
|
||||
data_stream.read(reinterpret_cast<char*>(out_data_buf), out_data_size);
|
||||
return data_stream.gcount();
|
||||
}
|
||||
bool empty() const override {
|
||||
return data_stream.eof() || data_stream.bad();
|
||||
}
|
||||
private:
|
||||
std::istream& data_stream;
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
TEST_P(GAPI_Streaming, SmokeTest_ConstInput_GMat)
|
||||
@ -2214,4 +2241,47 @@ TEST(GAPI_Streaming, TestPythonAPI)
|
||||
cc.stop();
|
||||
}
|
||||
|
||||
#ifdef HAVE_ONEVPL
|
||||
const unsigned char hevc_header[] = {
|
||||
0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x0C, 0x06, 0xFF, 0xFF, 0x01, 0x40, 0x00,
|
||||
0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x78, 0x00,
|
||||
0x00, 0x04, 0x02, 0x10, 0x30, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x03,
|
||||
0x01, 0xE5, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x06, 0x01, 0x40, 0x00, 0x00,
|
||||
0x03, 0x00, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x78, 0x00, 0x00,
|
||||
0xA0, 0x10, 0x20, 0x61, 0x63, 0x41, 0x00, 0x86, 0x49, 0x1B, 0x2B, 0x20, 0x00,
|
||||
0x00, 0x00, 0x01, 0x44, 0x01, 0xC0, 0x71, 0xC0, 0xD9, 0x20, 0x00, 0x00, 0x00,
|
||||
0x01, 0x26, 0x01, 0xAF, 0x0C
|
||||
};
|
||||
TEST(OneVPL_Source, Init)
|
||||
{
|
||||
using CfgParam = cv::gapi::wip::onevpl::CfgParam;
|
||||
|
||||
std::vector<CfgParam> src_params;
|
||||
src_params.push_back(CfgParam::create<uint32_t>("mfxImplDescription.Impl",
|
||||
MFX_IMPL_TYPE_HARDWARE));
|
||||
src_params.push_back(CfgParam::create<uint32_t>("mfxImplDescription.AccelerationMode",
|
||||
MFX_ACCEL_MODE_VIA_D3D11, false));
|
||||
src_params.push_back(CfgParam::create<uint32_t>("mfxImplDescription.mfxDecoderDescription.decoder.CodecID",
|
||||
MFX_CODEC_HEVC));
|
||||
std::stringstream stream(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
|
||||
EXPECT_TRUE(stream.write(reinterpret_cast<char*>(const_cast<unsigned char *>(hevc_header)),
|
||||
sizeof(hevc_header)));
|
||||
std::shared_ptr<cv::gapi::wip::onevpl::IDataProvider> stream_data_provider = std::make_shared<StreamDataProvider>(stream);
|
||||
|
||||
cv::Ptr<cv::gapi::wip::IStreamSource> cap;
|
||||
bool cap_created = false;
|
||||
try {
|
||||
cap = cv::gapi::wip::make_onevpl_src(stream_data_provider, src_params);
|
||||
cap_created = true;
|
||||
} catch (const std::exception&) {
|
||||
}
|
||||
ASSERT_TRUE(cap_created);
|
||||
|
||||
cv::gapi::wip::Data out;
|
||||
while (cap->pull(out)) {
|
||||
(void)out;
|
||||
}
|
||||
EXPECT_TRUE(stream_data_provider->empty());
|
||||
}
|
||||
#endif
|
||||
} // namespace opencv_test
|
||||
|
Loading…
Reference in New Issue
Block a user