YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
GstreamerDecoder.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include "GstreamerDecoder.h"
7
8#include <yarp/os/LogStream.h>
9
10
11#include <gst/gst.h>
12#include <glib.h>
13
14#include <cstdio>
15#include <cstring>
16#include <mutex>
17
18//#define debug_time 1
19
20#ifdef debug_time
21 #include <yarp/os/Time.h>
22 #define DBG_TIME_PERIOD_PRINTS 10 //10 sec
23#endif
24
25using namespace yarp::sig;
26using namespace yarp::os;
27
29 "yarp.carrier.gstreamer.GstDecoder",
33 nullptr)
34
35//-------------------------------------------------------------------
36//--------------- CALLBACK FUNCTIONS -------------------------------
37//-------------------------------------------------------------------
38
40{
42#ifdef debug_time
43 static bool isFirst = true;
44 double start_time = Time::now();
45 double end_time=0;
46
47 static double last_call;
48 static double sumOf_timeBetweenCalls = 0;
49 static double sumOf_timeOfNewSampleFunc = 0;
50 static uint32_t count=0;
51 #define MAX_COUNT 100
52
53
54 if(!isFirst)
56
58#endif
59
61 dec_data->img_pointer = &curr_frame;
62 dec_data->sem_pointer_stream->wait();
63
65 if (!sample)
66 {
67 yCWarning(GSTREAMER_DECODER, "could not take a sample!");
68 return GST_FLOW_OK;
69 }
70
72 if(!caps)
73 {
74 yCError(GSTREAMER_DECODER, "could not get caps of sample!");
75 return GST_FLOW_OK;
76 }
78 if(!struc)
79 {
80 yCError(GSTREAMER_DECODER, "could not get struct of caps!");
81 return GST_FLOW_OK;
82 }
83 gint width, height;
85 res = gst_structure_get_int(struc, "width", &width);
86 if(!res)
87 {
88 yCError(GSTREAMER_DECODER, "could not get width!");
89 return GST_FLOW_ERROR;
90 }
91
92 res = gst_structure_get_int(struc, "height", &height);
93 if(!res)
94 {
95 yCError(GSTREAMER_DECODER, "GSTREAMER: could not get height!");
96 return GST_FLOW_ERROR;
97 }
98 yCTrace(GSTREAMER_DECODER, "Image has size %d x %d", width, height);
99
101 GstMapInfo map;
103 {
104 yCError(GSTREAMER_DECODER, "could not get map!");
105 return GST_FLOW_ERROR;
106 }
107
108 dec_data->mutex_pointer->lock();
109 curr_frame.resize(width, height);
110 size_t map_size = map.size;
111 size_t img_size = width * height * 3;
112 size_t img_size2 = curr_frame.getRawImageSize();
113 unsigned char* ydata_ptr = curr_frame.getRawImage();
114 memcpy(ydata_ptr, map.data, map_size);
115
116 dec_data->mutex_pointer->unlock();
118
119 gst_sample_unref(sample);
120 dec_data->sem_pointer_gst->post();
121
122#ifdef debug_time
125 count++;
126 isFirst=false;
127
128 if(count>=MAX_COUNT)
129 {
131 "On %d times: NewSampleFunc is long %.6f sec and sleeps %.6f sec",
132 MAX_COUNT,
135 count = 0;
136 isFirst = true;
139 }
140#endif
141
142 return GST_FLOW_OK;
143}
144
145
146
147
148//----------------------------------------------------------------------
149
151{
152 m_pointer_mutex = _m;
153 m_gst_cbk_data.mutex_pointer = m_pointer_mutex;
154 m_gst_cbk_data.sem_pointer_gst = &m_semaphore_reading_from_gst;
155 m_gst_cbk_data.sem_pointer_stream = &m_semaphore_reading_from_stream;
156}
157
158bool GstYarpDecoder::init(std::string pipeline_string)
159{
160 gst_init(nullptr, nullptr);
161
162 // Create the pipeline and add an appsink to it
163 pipeline_string += " ! videoconvert ! video/x-raw,format=RGB ! appsink name = myappsink ";
164
165 yCInfo(GSTREAMER_DECODER) << "Using the following pipeline string:" << pipeline_string;
166
167 GError* error_out = nullptr;
168 m_pipeline = gst_parse_launch(pipeline_string.c_str(), &error_out);
169 if (m_pipeline == nullptr)
170 {
171 yCError(GSTREAMER_DECODER) << "Pipeline syntax failure(1):" << pipeline_string;
172 return false;
173 }
174 if (error_out)
175 {
176 yCError(GSTREAMER_DECODER) << "Pipeline syntax failure(2):" << pipeline_string << error_out->message;
178 return false;
179 }
180
181 //configure to appsink to use the new_sample_func callback
182 GstElement* appsink = gst_bin_get_by_name(GST_BIN(m_pipeline), "myappsink");
183 if (appsink == nullptr)
184 {
185 yCError(GSTREAMER_DECODER) << "Pipeline syntax failure(3):" << pipeline_string;
186 return false;
187 }
188 g_object_set(appsink, "emit-signals", false, NULL);
189 GstAppSinkCallbacks callbacks = {nullptr, nullptr, new_sample_func};
190 gst_app_sink_set_callbacks(GST_APP_SINK(appsink), &callbacks, &m_gst_cbk_data, nullptr);
191
192 yCDebug(GSTREAMER_DECODER) << "init ok";
193 return true;
194}
195
197{
200 {
201 yCDebug(GSTREAMER_DECODER) << "pipeline failed to start!";
202 return false;
203 }
204 yCDebug(GSTREAMER_DECODER) << "pipeline started!";
205 this->prepareNextFrame();
206 return true;
207}
208
210{
212 gst_bus_set_sync_handler(gst_pipeline_get_bus(GST_PIPELINE(m_pipeline)), nullptr, nullptr, nullptr);
213 yCDebug(GSTREAMER_DECODER) << "deleting pipeline";
214 gst_object_unref(GST_OBJECT(m_pipeline));
215 return true;
216}
217
222
224{
225 m_semaphore_reading_from_gst.wait();
226 return m_gst_cbk_data.img_pointer;
227}
228
230{
231 m_semaphore_reading_from_stream.post();
232}
const yarp::os::LogComponent & GSTREAMER_DECODER()
GstFlowReturn new_sample_func(GstAppSink *appsink, gpointer user_data)
bool ret
yarp::sig::ImageOf< yarp::sig::PixelRgb > * getLastFrame()
bool init(std::string pipeline_string)
GstYarpDecoder(std::mutex *m, yarp::os::Semaphore *s, GstYarpDecoder_cfgParamters &config)
A mini-server for performing network communication in the background.
static LogCallback printCallback()
Get current print callback.
Definition Log.cpp:873
static LogType minimumPrintLevel()
Get current minimum print level.
Definition Log.cpp:833
@ LogTypeReserved
Definition Log.h:98
A class for thread synchronization and mutual exclusion.
Definition Semaphore.h:25
void wait()
Decrement the counter, even if we must wait to do that.
Definition Semaphore.cpp:96
void post()
Increment the counter.
Typed image class.
Definition Image.h:605
#define yCInfo(component,...)
#define yCError(component,...)
#define yCTrace(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition Time.cpp:121
An interface to the operating system, including Port based communication.
yarp::os::Semaphore * sem_pointer_stream
yarp::sig::ImageOf< yarp::sig::PixelRgb > * img_pointer
yarp::os::Semaphore * sem_pointer_gst