From cc6e6aa028d507731831b2b6e987d5dd0d5b20f7 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Thu, 25 Sep 2014 14:40:54 +0400 Subject: [PATCH 1/3] Fixed query of basic VideoCapture properties. Added tests for them. --- modules/videoio/src/cap_gstreamer.cpp | 98 ++++++++-------- modules/videoio/test/test_basic_props.cpp | 130 ++++++++++++++++++++++ 2 files changed, 175 insertions(+), 53 deletions(-) create mode 100644 modules/videoio/test/test_basic_props.cpp diff --git a/modules/videoio/src/cap_gstreamer.cpp b/modules/videoio/src/cap_gstreamer.cpp index 5fc7c55233..da3beaca93 100644 --- a/modules/videoio/src/cap_gstreamer.cpp +++ b/modules/videoio/src/cap_gstreamer.cpp @@ -150,9 +150,11 @@ protected: #endif GstBuffer* buffer; GstCaps* caps; - GstCaps* buffer_caps; IplImage* frame; gint64 duration; + gint width; + gint height; + double fps; }; /*! @@ -171,9 +173,11 @@ void CvCapture_GStreamer::init() #endif buffer = NULL; caps = NULL; - buffer_caps = NULL; frame = NULL; duration = -1; + width = -1; + height = -1; + fps = -1; } /*! @@ -192,6 +196,9 @@ void CvCapture_GStreamer::close() } duration = -1; + width = -1; + height = -1; + fps = -1; } /*! @@ -249,16 +256,10 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int) //construct a frame header if we did not have any yet if(!frame) { - gint height, width; - - //reuse the caps ptr - if (buffer_caps) - gst_caps_unref(buffer_caps); - #if GST_VERSION_MAJOR == 0 - buffer_caps = gst_buffer_get_caps(buffer); + GstCaps* buffer_caps = gst_buffer_get_caps(buffer); #else - buffer_caps = gst_sample_get_caps(sample); + GstCaps* buffer_caps = gst_sample_get_caps(sample); #endif // bail out in no caps assert(gst_caps_get_size(buffer_caps) == 1); @@ -268,10 +269,10 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int) if(!gst_structure_get_int(structure, "width", &width) || !gst_structure_get_int(structure, "height", &height)) { + gst_caps_unref(buffer_caps); return 0; } - int depth = 3; #if GST_VERSION_MAJOR > 0 depth = 0; @@ -304,9 +305,12 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int) #endif if (depth > 0) { frame = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, depth); - }else{ + } else { + gst_caps_unref(buffer_caps); return 0; } + + gst_caps_unref(buffer_caps); } // gstreamer expects us to handle the memory at this point @@ -782,12 +786,36 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) handleMessage(pipeline); CV_WARN("GStreamer: unable to query duration of stream"); duration = -1; - return true; } + + GstPad* pad = gst_element_get_pad(color, "src"); + GstCaps* buffer_caps = gst_pad_get_caps(pad); + const GstStructure *structure = gst_caps_get_structure (buffer_caps, 0); + + if (!gst_structure_get_int (structure, "width", &width)) + CV_WARN("Cannot query video width\n"); + + if (!gst_structure_get_int (structure, "height", &height)) + CV_WARN("Cannot query video heigth\n"); + + if (!gst_structure_get_int (structure, "height", &height)) + CV_WARN("Cannot query video heigth\n"); + + gint num = 0, denom=1; + if(!gst_structure_get_fraction(structure, "framerate", &num, &denom)) + CV_WARN("Cannot query video fps\n"); + + fps = (double)num/(double)denom; + + + // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); } else { duration = -1; + width = -1; + height = -1; + fps = -1; } __END__; @@ -846,48 +874,12 @@ double CvCapture_GStreamer::getProperty( int propId ) return false; } return ((double) value) / GST_FORMAT_PERCENT_MAX; - case CV_CAP_PROP_FRAME_WIDTH: { - if (!buffer_caps){ - CV_WARN("GStreamer: unable to query width of frame; no frame grabbed yet"); - return 0; - } - GstStructure* structure = gst_caps_get_structure(buffer_caps, 0); - gint width = 0; - if(!gst_structure_get_int(structure, "width", &width)){ - CV_WARN("GStreamer: unable to query width of frame"); - return 0; - } + case CV_CAP_PROP_FRAME_WIDTH: return width; - break; - } - case CV_CAP_PROP_FRAME_HEIGHT: { - if (!buffer_caps){ - CV_WARN("GStreamer: unable to query height of frame; no frame grabbed yet"); - return 0; - } - GstStructure* structure = gst_caps_get_structure(buffer_caps, 0); - gint height = 0; - if(!gst_structure_get_int(structure, "height", &height)){ - CV_WARN("GStreamer: unable to query height of frame"); - return 0; - } + case CV_CAP_PROP_FRAME_HEIGHT: return height; - break; - } - case CV_CAP_PROP_FPS: { - if (!buffer_caps){ - CV_WARN("GStreamer: unable to query framerate of stream; no frame grabbed yet"); - return 0; - } - GstStructure* structure = gst_caps_get_structure(buffer_caps, 0); - gint num = 0, denom=1; - if(!gst_structure_get_fraction(structure, "framerate", &num, &denom)){ - CV_WARN("GStreamer: unable to query framerate of stream"); - return 0; - } - return (double)num/(double)denom; - break; - } + case CV_CAP_PROP_FPS: + return fps; case CV_CAP_PROP_FOURCC: break; case CV_CAP_PROP_FRAME_COUNT: diff --git a/modules/videoio/test/test_basic_props.cpp b/modules/videoio/test/test_basic_props.cpp new file mode 100644 index 0000000000..76d4d8fd18 --- /dev/null +++ b/modules/videoio/test/test_basic_props.cpp @@ -0,0 +1,130 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include "opencv2/videoio.hpp" +#include "opencv2/ts.hpp" +#include + +#if BUILD_WITH_VIDEO_INPUT_SUPPORT + +using namespace cv; +using namespace std; +using namespace cvtest; + +const string ext[] = {"avi"}; //, "mov", "mp4"}; + +TEST(Videoio_Video, prop_resolution) +{ + const size_t n = sizeof(ext)/sizeof(ext[0]); + const string src_dir = TS::ptr()->get_data_path(); + + TS::ptr()->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); + + for (size_t i = 0; i < n; ++i) + { + string file_path = src_dir+"video/big_buck_bunny."+ext[i]; + VideoCapture cap(file_path); + if (!cap.isOpened()) + { + TS::ptr()->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); + TS::ptr()->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); + TS::ptr()->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + + ASSERT_EQ(672, cap.get(CAP_PROP_FRAME_WIDTH)); + ASSERT_EQ(384, cap.get(CAP_PROP_FRAME_HEIGHT)); + } +} + +TEST(Videoio_Video, actual_resolution) +{ + const size_t n = sizeof(ext)/sizeof(ext[0]); + const string src_dir = TS::ptr()->get_data_path(); + + TS::ptr()->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); + + for (size_t i = 0; i < n; ++i) + { + string file_path = src_dir+"video/big_buck_bunny."+ext[i]; + VideoCapture cap(file_path); + if (!cap.isOpened()) + { + TS::ptr()->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); + TS::ptr()->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); + TS::ptr()->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + + Mat frame; + cap >> frame; + + ASSERT_EQ(672, frame.cols); + ASSERT_EQ(384, frame.rows); + } +} + +TEST(Videoio_Video, prop_fps) +{ + const size_t n = sizeof(ext)/sizeof(ext[0]); + const string src_dir = TS::ptr()->get_data_path(); + + TS::ptr()->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); + + for (size_t i = 0; i < n; ++i) + { + string file_path = src_dir+"video/big_buck_bunny."+ext[i]; + VideoCapture cap(file_path); + if (!cap.isOpened()) + { + TS::ptr()->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); + TS::ptr()->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); + TS::ptr()->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + + ASSERT_EQ(24, cap.get(CAP_PROP_FPS)); + } +} + +#endif From 15251056ba7b345f2d7de973637da3ec5816662b Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Thu, 25 Sep 2014 14:51:34 +0400 Subject: [PATCH 2/3] Fixed compatibility with GStreamer 1.x --- modules/videoio/src/cap_gstreamer.cpp | 19 ++++++++++++++----- modules/videoio/test/test_basic_props.cpp | 6 +++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/modules/videoio/src/cap_gstreamer.cpp b/modules/videoio/src/cap_gstreamer.cpp index da3beaca93..cae719996e 100644 --- a/modules/videoio/src/cap_gstreamer.cpp +++ b/modules/videoio/src/cap_gstreamer.cpp @@ -788,26 +788,32 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) duration = -1; } - GstPad* pad = gst_element_get_pad(color, "src"); + GstPad* pad = gst_element_get_static_pad(color, "src"); +#if GST_VERSION_MAJOR == 0 GstCaps* buffer_caps = gst_pad_get_caps(pad); +#else + GstCaps* buffer_caps = gst_pad_get_current_caps(pad); +#endif const GstStructure *structure = gst_caps_get_structure (buffer_caps, 0); if (!gst_structure_get_int (structure, "width", &width)) + { CV_WARN("Cannot query video width\n"); + } if (!gst_structure_get_int (structure, "height", &height)) + { CV_WARN("Cannot query video heigth\n"); - - if (!gst_structure_get_int (structure, "height", &height)) - CV_WARN("Cannot query video heigth\n"); + } gint num = 0, denom=1; if(!gst_structure_get_fraction(structure, "framerate", &num, &denom)) + { CV_WARN("Cannot query video fps\n"); + } fps = (double)num/(double)denom; - // GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); } else @@ -1217,8 +1223,11 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc, gboolean done = FALSE; GstElement *element = NULL; gchar* name = NULL; + +#if GST_VERSION_MAJOR == 0 GstElement* splitter = NULL; GstElement* combiner = NULL; +#endif // we first try to construct a pipeline from the given string. // if that fails, we assume it is an ordinary filename diff --git a/modules/videoio/test/test_basic_props.cpp b/modules/videoio/test/test_basic_props.cpp index 76d4d8fd18..516b7b0fce 100644 --- a/modules/videoio/test/test_basic_props.cpp +++ b/modules/videoio/test/test_basic_props.cpp @@ -51,7 +51,11 @@ using namespace cv; using namespace std; using namespace cvtest; -const string ext[] = {"avi"}; //, "mov", "mp4"}; +#ifdef HAVE_GSTREAMER +const string ext[] = {"avi"}; +#else +const string ext[] = {"avi", "mov", "mp4"}; +#endif TEST(Videoio_Video, prop_resolution) { From 23456d67e5384dcff9ad94ef949a184daf311b62 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 26 Sep 2014 10:50:22 +0400 Subject: [PATCH 3/3] Added test on CAP_PROP_FRAMECOUNT option for cv::VideoCapture --- modules/videoio/test/test_basic_props.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/modules/videoio/test/test_basic_props.cpp b/modules/videoio/test/test_basic_props.cpp index 516b7b0fce..3f92876c5d 100644 --- a/modules/videoio/test/test_basic_props.cpp +++ b/modules/videoio/test/test_basic_props.cpp @@ -131,4 +131,27 @@ TEST(Videoio_Video, prop_fps) } } +TEST(Videoio_Video, prop_framecount) +{ + const size_t n = sizeof(ext)/sizeof(ext[0]); + const string src_dir = TS::ptr()->get_data_path(); + + TS::ptr()->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); + + for (size_t i = 0; i < n; ++i) + { + string file_path = src_dir+"video/big_buck_bunny."+ext[i]; + VideoCapture cap(file_path); + if (!cap.isOpened()) + { + TS::ptr()->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); + TS::ptr()->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); + TS::ptr()->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + return; + } + + ASSERT_EQ(125, cap.get(CAP_PROP_FRAME_COUNT)); + } +} + #endif