From ff77f4d9ef7268a07f7c68095835719ca2de98cd Mon Sep 17 00:00:00 2001 From: Pavel Rojtberg Date: Wed, 2 Mar 2016 17:22:49 +0100 Subject: [PATCH] GStreamer: allow reading raw MJPEG data --- modules/videoio/src/cap_gstreamer.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/videoio/src/cap_gstreamer.cpp b/modules/videoio/src/cap_gstreamer.cpp index 41754ea..243aad1 100644 --- a/modules/videoio/src/cap_gstreamer.cpp +++ b/modules/videoio/src/cap_gstreamer.cpp @@ -292,18 +292,22 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int) const gchar* name = gst_structure_get_name(structure); const gchar* format = gst_structure_get_string(structure, "format"); - if (!name || !format) + if (!name) return 0; // we support 3 types of data: // video/x-raw, format=BGR -> 8bit, 3 channels // video/x-raw, format=GRAY8 -> 8bit, 1 channel // video/x-bayer -> 8bit, 1 channel + // image/jpeg -> 8bit, mjpeg: buffer_size x 1 x 1 // bayer data is never decoded, the user is responsible for that // everything is 8 bit, so we just test the caps for bit depth if (strcasecmp(name, "video/x-raw") == 0) { + if (!format) + return 0; + if (strcasecmp(format, "BGR") == 0) { depth = 3; } @@ -314,6 +318,9 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int) else if (strcasecmp(name, "video/x-bayer") == 0) { depth = 1; + } else if(strcasecmp(name, "image/jpeg") == 0) { + depth = 1; + // the correct size will be set once the first frame arrives } #endif if (depth > 0) { @@ -334,6 +341,13 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int) // info.data ptr is valid until next grabFrame where the associated sample is unref'd GstMapInfo info = GstMapInfo(); gboolean success = gst_buffer_map(buffer,&info, (GstMapFlags)GST_MAP_READ); + + // with MJPEG streams frame size can change arbitrarily + if(int(info.size) != frame->imageSize) { + cvReleaseImageHeader(&frame); + frame = cvCreateImageHeader(cvSize(info.size, 1), IPL_DEPTH_8U, 1); + } + if (!success){ //something weird went wrong here. abort. abort. //fprintf(stderr,"GStreamer: unable to map buffer"); @@ -797,7 +811,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) NULL); #else // support 1 and 3 channel 8 bit data, as well as bayer (also 1 channel, 8bit) - caps = gst_caps_from_string("video/x-raw, format=(string){BGR, GRAY8}; video/x-bayer,format=(string){rggb,bggr,grbg,gbrg}"); + caps = gst_caps_from_string("video/x-raw, format=(string){BGR, GRAY8}; video/x-bayer,format=(string){rggb,bggr,grbg,gbrg}; image/jpeg"); #endif gst_app_sink_set_caps(GST_APP_SINK(sink), caps); gst_caps_unref(caps); -- 2.7.4