Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit37339d2

Browse files
committed
Ported GStreamerSource to OpenCV
1 parent627be17 commit37339d2

18 files changed

+2403
-1
lines changed

‎modules/gapi/CMakeLists.txt‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ set(gapi_srcs
163163
src/backends/ie/bindings_ie.cpp
164164
src/backends/python/gpythonbackend.cpp
165165

166-
# Streaming source
166+
#OpenVPLStreaming source
167167
src/streaming/onevpl/source.cpp
168168
src/streaming/onevpl/source_priv.cpp
169169
src/streaming/onevpl/file_data_provider.cpp
@@ -179,6 +179,14 @@ set(gapi_srcs
179179
src/streaming/onevpl/engine/decode/decode_engine_legacy.cpp
180180
src/streaming/onevpl/engine/decode/decode_session.cpp
181181

182+
# GStreamer Streaming source
183+
src/streaming/gstreamer/gstreamer_pipeline_facade.cpp
184+
src/streaming/gstreamer/gstreamerpipeline.cpp
185+
src/streaming/gstreamer/gstreamersource.cpp
186+
src/streaming/gstreamer/gstreamer_buffer_utils.cpp
187+
src/streaming/gstreamer/gstreamer_media_adapter.cpp
188+
src/streaming/gstreamer/gstreamerenv.cpp
189+
182190
# Utils (ITT tracing)
183191
src/utils/itt.cpp
184192
)
@@ -265,6 +273,15 @@ if(HAVE_GAPI_ONEVPL)
265273
endif()
266274
endif()
267275

276+
if(HAVE_GSTREAMER)
277+
if(TARGET opencv_test_gapi)
278+
ocv_target_compile_definitions(opencv_test_gapiPRIVATE -DHAVE_GSTREAMER)
279+
ocv_target_link_libraries(opencv_test_gapiPRIVATE ocv.3rdparty.gstreamer)
280+
endif()
281+
ocv_target_compile_definitions(${the_module}PRIVATE -DHAVE_GSTREAMER)
282+
ocv_target_link_libraries(${the_module}PRIVATE ocv.3rdparty.gstreamer)
283+
endif()
284+
268285
if(WIN32)
269286
# Required for htonl/ntohl on Windows
270287
ocv_target_link_libraries(${the_module}PRIVATE wsock32 ws2_32)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
//
5+
// Copyright (C) 2021 Intel Corporation
6+
7+
#ifndef OPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMERPIPELINE_HPP
8+
#defineOPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMERPIPELINE_HPP
9+
10+
#include<opencv2/gapi/streaming/gstreamer/gstreamersource.hpp>
11+
#include<opencv2/gapi/own/exports.hpp>
12+
13+
#include<string>
14+
#include<unordered_map>
15+
#include<memory>
16+
17+
namespacecv {
18+
namespacegapi {
19+
namespacewip {
20+
namespacegst {
21+
22+
classGAPI_EXPORTS GStreamerPipeline
23+
{
24+
public:
25+
classPriv;
26+
27+
explicitGStreamerPipeline(const std::string& pipeline);
28+
IStreamSource::PtrgetStreamingSource(const std::string& appsinkName,
29+
const GStreamerSource::OutputType outputType =
30+
GStreamerSource::OutputType::MAT);
31+
virtual~GStreamerPipeline();
32+
33+
protected:
34+
explicitGStreamerPipeline(std::unique_ptr<Priv> priv);
35+
36+
std::unique_ptr<Priv> m_priv;
37+
};
38+
39+
}// namespace gst
40+
41+
using GStreamerPipeline = gst::GStreamerPipeline;
42+
43+
}// namespace wip
44+
}// namespace gapi
45+
}// namespace cv
46+
47+
#endif// OPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMERPIPELINE_HPP
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
//
5+
// Copyright (C) 2021 Intel Corporation
6+
7+
#ifndef OPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMERSOURCE_HPP
8+
#defineOPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMERSOURCE_HPP
9+
10+
#include<opencv2/gapi/streaming/source.hpp>
11+
#include<opencv2/gapi/garg.hpp>
12+
13+
#include<memory>
14+
15+
namespacecv {
16+
namespacegapi {
17+
namespacewip {
18+
namespacegst {
19+
20+
/**
21+
* @brief OpenCV's GStreamer streaming source.
22+
* Streams cv::Mat-s/cv::MediaFrame from passed GStreamer pipeline.
23+
*
24+
* This class implements IStreamSource interface.
25+
*
26+
* To create GStreamerSource instance you need to pass 'pipeline' and, optionally, 'outputType'
27+
* arguments into constructor.
28+
* 'pipeline' should represent GStreamer pipeline in form of textual description.
29+
* Almost any custom pipeline is supported which can be successfully ran via gst-launch.
30+
* The only two limitations are:
31+
* - there should be __one__ appsink element in the pipeline to pass data to OpenCV app.
32+
* Pipeline can actually contain many sink elements, but it must have one and only one
33+
* appsink among them.
34+
*
35+
* - data passed to appsink should be video-frame in NV12 format.
36+
*
37+
* 'outputType' is used to select type of output data to produce: 'cv::MediaFrame' or 'cv::Mat'.
38+
* To produce 'cv::MediaFrame'-s you need to pass 'GStreamerSource::OutputType::FRAME' and,
39+
* correspondingly, 'GStreamerSource::OutputType::MAT' to produce 'cv::Mat'-s.
40+
* Please note, that in the last case, output 'cv::Mat' will be of BGR format, internal conversion
41+
* from NV12 GStreamer data will be happened.
42+
* Default value for 'outputType' is 'GStreamerSource::OutputType::MAT'.
43+
*
44+
* @note Stream sources are passed to G-API via shared pointers, so please use gapi::make_src<>
45+
* to create objects and ptr() to pass a GStreamerSource to cv::gin().
46+
*
47+
* @note You need to build OpenCV with GStreamer support to use this class.
48+
*/
49+
50+
classGStreamerPipelineFacade;
51+
52+
classGAPI_EXPORTS GStreamerSource : public IStreamSource
53+
{
54+
public:
55+
classPriv;
56+
57+
// Indicates what type of data should be produced by GStreamerSource: cv::MediaFrame or cv::Mat
58+
enumclassOutputType {
59+
FRAME,
60+
MAT
61+
};
62+
63+
GStreamerSource(const std::string& pipeline,
64+
const GStreamerSource::OutputType outputType =
65+
GStreamerSource::OutputType::MAT);
66+
GStreamerSource(std::shared_ptr<GStreamerPipelineFacade> pipeline,
67+
const std::string& appsinkName,
68+
const GStreamerSource::OutputType outputType =
69+
GStreamerSource::OutputType::MAT);
70+
71+
boolpull(cv::gapi::wip::Data& data)override;
72+
GMetaArgdescr_of()constoverride;
73+
~GStreamerSource()override;
74+
75+
protected:
76+
explicitGStreamerSource(std::unique_ptr<Priv> priv);
77+
78+
std::unique_ptr<Priv> m_priv;
79+
};
80+
81+
}// namespace gst
82+
83+
using GStreamerSource = gst::GStreamerSource;
84+
85+
}// namespace wip
86+
}// namespace gapi
87+
}// namespace cv
88+
89+
#endif// OPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMERSOURCE_HPP
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
//
5+
// Copyright (C) 2021 Intel Corporation
6+
7+
#include"gstreamer_buffer_utils.hpp"
8+
#include"gstreamerptr.hpp"
9+
#include<opencv2/gapi/own/assert.hpp>
10+
11+
#ifdef HAVE_GSTREAMER
12+
13+
namespacecv {
14+
namespacegapi {
15+
namespacewip {
16+
namespacegstreamer_utils {
17+
18+
voidmapBufferToFrame(GstBuffer& buffer, GstVideoInfo& info, GstVideoFrame& frame,
19+
GstMapFlags mapFlags) {
20+
bool mapped =gst_video_frame_map(&frame, &info, &buffer, mapFlags);
21+
GAPI_Assert(mapped &&"Failed to map GStreamer buffer to system memory as video-frame!");
22+
}
23+
24+
}// namespace gstreamer_utils
25+
}// namespace wip
26+
}// namespace gapi
27+
}// namespace cv
28+
29+
#endif// HAVE_GSTREAMER
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
//
5+
// Copyright (C) 2021 Intel Corporation
6+
7+
#ifndef OPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMER_BUFFER_UTILS_HPP
8+
#defineOPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMER_BUFFER_UTILS_HPP
9+
10+
#ifdef HAVE_GSTREAMER
11+
#include<gst/gstbuffer.h>
12+
#include<gst/video/video-frame.h>
13+
#endif// HAVE_GSTREAMER
14+
15+
#ifdef HAVE_GSTREAMER
16+
17+
namespacecv {
18+
namespacegapi {
19+
namespacewip {
20+
namespacegstreamer_utils {
21+
22+
voidmapBufferToFrame(GstBuffer& buffer, GstVideoInfo& info, GstVideoFrame& frame,
23+
GstMapFlags map_flags);
24+
25+
}// namespace gstreamer_utils
26+
}// namespace wip
27+
}// namespace gapi
28+
}// namespace cv
29+
30+
#endif// HAVE_GSTREAMER
31+
#endif// OPENCV_GAPI_STREAMING_GSTREAMER_GSTREAMER_BUFFER_UTILS_HPP
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
//
5+
// Copyright (C) 2021 Intel Corporation
6+
7+
#include"gstreamer_media_adapter.hpp"
8+
#include"gstreamer_buffer_utils.hpp"
9+
10+
#ifdef HAVE_GSTREAMER
11+
namespacecv {
12+
namespacegapi {
13+
namespacewip {
14+
namespacegst {
15+
16+
GStreamerMediaAdapter::GStreamerMediaAdapter(const cv::GFrameDesc& frameDesc,
17+
GstVideoInfo* videoInfo,
18+
GstBuffer* buffer) :
19+
m_frameDesc(frameDesc),
20+
m_videoInfo(gst_video_info_copy(videoInfo)),
21+
m_buffer(gst_buffer_ref(buffer)),
22+
m_isMapped(false)
23+
{
24+
#if GST_VERSION_MINOR >= 10
25+
// Check that GstBuffer has mono-view, so we can retrieve only one video-meta
26+
GAPI_Assert((gst_buffer_get_flags(m_buffer) & GST_VIDEO_BUFFER_FLAG_MULTIPLE_VIEW) ==0);
27+
#endif// GST_VERSION_MINOR >= 10
28+
29+
GstVideoMeta* videoMeta =gst_buffer_get_video_meta(m_buffer);
30+
if (videoMeta !=nullptr) {
31+
m_strides = { videoMeta->stride[0], videoMeta->stride[1] };
32+
m_offsets = { videoMeta->offset[0], videoMeta->offset[1] };
33+
}else {
34+
m_strides = {GST_VIDEO_INFO_PLANE_STRIDE(m_videoInfo.get(),0),
35+
GST_VIDEO_INFO_PLANE_STRIDE(m_videoInfo.get(),1) };
36+
m_offsets = {GST_VIDEO_INFO_PLANE_OFFSET(m_videoInfo.get(),0),
37+
GST_VIDEO_INFO_PLANE_OFFSET(m_videoInfo.get(),1) };
38+
}
39+
}
40+
41+
GStreamerMediaAdapter::~GStreamerMediaAdapter() {
42+
if (m_isMapped.load(std::memory_order_acquire)) {
43+
gst_video_frame_unmap(&m_videoFrame);
44+
m_isMapped.store(false, std::memory_order_release);
45+
m_mappedForWrite.store(false);
46+
}
47+
}
48+
49+
cv::GFrameDescGStreamerMediaAdapter::meta()const {
50+
return m_frameDesc;
51+
}
52+
53+
cv::MediaFrame::ViewGStreamerMediaAdapter::access(cv::MediaFrame::Access access) {
54+
GAPI_Assert(access == cv::MediaFrame::Access::R ||
55+
access == cv::MediaFrame::Access::W);
56+
static std::atomic<size_t> thread_counters { };
57+
++thread_counters;
58+
59+
// NOTE: Framework guarantees that there should be no parallel accesses to the frame
60+
// memory if is accessing for write.
61+
if (access == cv::MediaFrame::Access::W && !m_mappedForWrite.load(std::memory_order_acquire)) {
62+
GAPI_Assert(thread_counters >1 &&
63+
"Multiple access to view during mapping for write detected!");
64+
gst_video_frame_unmap(&m_videoFrame);
65+
m_isMapped.store(false);
66+
}
67+
68+
if (!m_isMapped.load(std::memory_order_acquire)) {
69+
70+
std::lock_guard<std::mutex>lock(m_mutex);
71+
72+
if(!m_isMapped.load(std::memory_order_relaxed)) {
73+
74+
GAPI_Assert(GST_VIDEO_INFO_N_PLANES(m_videoInfo.get()) ==2);
75+
GAPI_Assert(GST_VIDEO_INFO_FORMAT(m_videoInfo.get()) == GST_VIDEO_FORMAT_NV12);
76+
77+
// TODO: Use RAII for map/unmap
78+
if (access == cv::MediaFrame::Access::W) {
79+
gstreamer_utils::mapBufferToFrame(*m_buffer, *m_videoInfo, m_videoFrame,
80+
GST_MAP_WRITE);
81+
m_mappedForWrite.store(true, std::memory_order_release);
82+
}else {
83+
gstreamer_utils::mapBufferToFrame(*m_buffer, *m_videoInfo, m_videoFrame,
84+
GST_MAP_READ);
85+
}
86+
87+
GAPI_Assert(GST_VIDEO_FRAME_PLANE_STRIDE(&m_videoFrame,0) == m_strides[0]);
88+
GAPI_Assert(GST_VIDEO_FRAME_PLANE_STRIDE(&m_videoFrame,1) == m_strides[1]);
89+
GAPI_Assert(GST_VIDEO_FRAME_PLANE_OFFSET(&m_videoFrame,0) == m_offsets[0]);
90+
GAPI_Assert(GST_VIDEO_FRAME_PLANE_OFFSET(&m_videoFrame,1) == m_offsets[1]);
91+
92+
m_isMapped.store(true, std::memory_order_release);
93+
}
94+
}
95+
96+
cv::MediaFrame::View::Ptrs ps {
97+
static_cast<uint8_t*>(GST_VIDEO_FRAME_PLANE_DATA(&m_videoFrame,0)) + m_offsets[0],// Y-plane
98+
static_cast<uint8_t*>(GST_VIDEO_FRAME_PLANE_DATA(&m_videoFrame,0)) + m_offsets[1],// UV-plane
99+
nullptr,
100+
nullptr
101+
};
102+
103+
cv::MediaFrame::View::Strides ss = {
104+
static_cast<std::size_t>(m_strides[0]),// Y-plane stride
105+
static_cast<std::size_t>(m_strides[1]),// UV-plane stride
106+
0u,
107+
0u
108+
};
109+
110+
--thread_counters;
111+
returncv::MediaFrame::View(std::move(ps),std::move(ss));
112+
}
113+
114+
cv::util::anyGStreamerMediaAdapter::blobParams()const {
115+
GAPI_Assert(false &&"No implementation for GStreamerMediaAdapter::blobParams()");
116+
}
117+
118+
}// namespace gst
119+
}// namespace wip
120+
}// namespace gapi
121+
}// namespace cv
122+
#endif// HAVE_GSTREAMER

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp