15 #include <gst/app/gstappsink.h>
24 #define DBG_TIME_PERIOD_PRINTS 10
35 std::mutex *m{
nullptr};
102 caps = gst_caps_new_simple(
"application/x-rtp",
103 "media", G_TYPE_STRING,
"video",
104 "encoding-name", G_TYPE_STRING,
"H264",
105 "payload", G_TYPE_INT, 96,
109 link_ok = gst_element_link_filtered(e1, e2, caps);
129 caps = gst_caps_new_simple(
"video/x-raw",
130 "format", G_TYPE_STRING,
"RGB",
134 link_ok = gst_element_link_filtered(e1, e2, caps);
149 GstFlowReturn
new_sample(GstAppSink *appsink, gpointer user_data)
152 static bool isFirst =
true;
156 static double last_call;
157 static double sumOf_timeBetweenCalls = 0;
158 static double sumOf_timeOfNewSampleFunc = 0;
159 static uint32_t count=0;
160 #define MAX_COUNT 100
164 sumOf_timeBetweenCalls+=(start_time -last_call);
166 last_call = start_time;
173 GstSample *sample =
nullptr;
174 g_signal_emit_by_name (appsink,
"pull-sample", &sample, NULL);
181 GstCaps *caps = gst_sample_get_caps (sample);
185 return GST_FLOW_ERROR;
187 GstStructure *struc = gst_caps_get_structure(caps, 0);
191 return GST_FLOW_ERROR;
195 res = gst_structure_get_int(struc,
"width", &width);
199 return GST_FLOW_ERROR;
202 res = gst_structure_get_int(struc,
"height", &height);
206 return GST_FLOW_ERROR;
210 GstBuffer *
buffer = gst_sample_get_buffer(sample);
212 if(!gst_buffer_map(
buffer, &map, GST_MAP_READ))
215 return GST_FLOW_ERROR;
221 dec_data->isNew =
true;
222 dec_data->img->resize(width, height);
224 unsigned char *ydata_ptr = dec_data->img->getRawImage();
225 memcpy(ydata_ptr, map.data, width*height*3);
227 dec_data->m->unlock();
228 gst_buffer_unmap(
buffer, &map);
230 gst_sample_unref(sample);
231 if (dec_data->isReq) {
238 sumOf_timeOfNewSampleFunc += (end_time-start_time);
245 "On %d times: NewSampleFunc is long %.6f sec and sleeps %.6f sec",
247 (sumOf_timeOfNewSampleFunc/MAX_COUNT),
248 (sumOf_timeBetweenCalls/MAX_COUNT) );
251 sumOf_timeBetweenCalls = 0;
252 sumOf_timeOfNewSampleFunc = 0;
309 sizeChanger(nullptr),
313 gst_cbk_data.
m = m_ptr;
314 gst_cbk_data.
img = &myframe;
315 gst_cbk_data.
s = s_ptr;
322 gst_init(
nullptr,
nullptr);
323 pipeline = gst_pipeline_new (
"video-player");
324 source = gst_element_factory_make (
"udpsrc",
"video-source");
325 rtpDepay = gst_element_factory_make (
"rtph264depay",
"rtp-depay");
326 parser = gst_element_factory_make (
"h264parse",
"parser");
327 decoder = gst_element_factory_make (
"avdec_h264",
"decoder");
328 sizeChanger = gst_element_factory_make (
"videocrop",
"cropper");
329 convert = gst_element_factory_make (
"videoconvert",
"convert");
330 sink = gst_element_factory_make (
"appsink",
"video-output");
332 if (!pipeline || !source || !rtpDepay || !parser || !decoder || !convert || !sink || !sizeChanger)
334 yCError(
H264CARRIER) <<
"H264Decoder-GSTREAMER: one element could not be created. Exiting.";
339 jitterBuff = gst_element_factory_make(
"rtpjitterbuffer",
"jitterBuffer");
342 yCError(
H264CARRIER) <<
"H264Decoder-GSTREAMER: rtpjitterbuffer could not be created. Exiting.";
356 g_object_set(source,
"port", cfgParams.
remotePort, NULL);
362 g_object_set( sink,
"emit-signals",
false, NULL );
364 GstAppSinkCallbacks cbs;
368 cbs.new_preroll =
nullptr;
370 gst_app_sink_set_callbacks( GST_APP_SINK( sink ), &cbs, &gst_cbk_data,
nullptr );
394 yCTrace(
H264CARRIER) <<
"H264Decoder-GSTREAMER: try to add elements to pipeline..... ";
396 gst_bin_add_many (GST_BIN (pipeline),
397 source, rtpDepay, parser, decoder, sizeChanger, convert, sink, NULL);
401 if (jitterBuff !=
nullptr)
403 result = gst_bin_add(GST_BIN(pipeline), jitterBuff);
404 if (!result) {
yCError(
H264CARRIER) <<
"H264Decoder: Error adding jitterBuff to the bin";
return false; }
407 yCTrace(
H264CARRIER) <<
"H264Decoder-GSTREAMER: elements have been added in pipeline!";
411 if (!result) {
yCError(
H264CARRIER) <<
"H264Decoder: Error linking converter to sink ";
return false; }
417 yCTrace(
H264CARRIER) <<
"H264Decoder-GSTREAMER: try to link videosrc to rtpjitterBuffer.....";
419 if (!result){
yCError(
H264CARRIER) <<
"H264Decoder: Error linking videosrc to rtpjitterBuffer ";
return false;}
421 yCTrace(
H264CARRIER) <<
"H264Decoder-GSTREAMER: try to link jitterBuff to rtpDapay.....";
422 result = gst_element_link(jitterBuff, rtpDepay);
423 if (!result) {
yCError(
H264CARRIER) <<
"H264Decoder: Error linking jitterBuff to rtpDapay ";
return false; }
430 if (!result) {
yCError(
H264CARRIER) <<
"H264Decoder: Error linking videosrc to rtpDepay ";
return false; }
435 gst_element_link_many(rtpDepay, parser, decoder, sizeChanger, convert, NULL);
446 #define GET_HELPER(x) (*((H264DecoderHelper*)(x)))
484 gst_element_set_state (helper.
pipeline, GST_STATE_PLAYING);
494 gst_element_set_state (helper.
pipeline, GST_STATE_NULL);
495 gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (helper.
pipeline)),
nullptr,
nullptr,
nullptr);
497 gst_object_unref (GST_OBJECT (helper.
pipeline));
static gboolean link_convert2next(GstElement *e1, GstElement *e2)
static gboolean link_videosrc2nextWithCaps(GstElement *e1, GstElement *e2)
GstFlowReturn new_sample(GstAppSink *appsink, gpointer user_data)
const yarp::os::LogComponent & H264CARRIER()
H264DecoderHelper(std::mutex *m_ptr, Semaphore *s_ptr)
data_for_gst_callback gst_cbk_data
bool istantiateElements(h264Decoder_cfgParamters &cfgParams)
bool configureElements(h264Decoder_cfgParamters &cfgParams)
ImageOf< PixelRgb > myframe
bool newFrameIsAvailable()
H264Decoder(h264Decoder_cfgParamters &config)
yarp::sig::ImageOf< yarp::sig::PixelRgb > & getLastFrame()
A class for thread synchronization and mutual exclusion.
size_t width() const
Gets width of image in pixels.
size_t height() const
Gets height of image in pixels.
#define yCError(component,...)
#define yCTrace(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
double now()
Return the current time in seconds, relative to an arbitrary starting point.
An interface to the operating system, including Port based communication.
ImageOf< PixelRgb > * img
data_for_gst_callback()=default
struct h264Decoder_cfgParamters::@91 crop