From: Alexander Alekhin Date: Tue, 10 Mar 2020 22:44:14 +0000 (+0000) Subject: Merge remote-tracking branch 'upstream/3.4' into merge-3.4 X-Git-Tag: submit/tizen/20210224.033012~2^2~277 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d00e58cdb0f48e00deca7171a1ccb2a9449854b4;p=platform%2Fupstream%2Fopencv.git Merge remote-tracking branch 'upstream/3.4' into merge-3.4 --- d00e58cdb0f48e00deca7171a1ccb2a9449854b4 diff --cc modules/dnn/include/opencv2/dnn/version.hpp index 152c8b2,0000000..f5c7424 mode 100644,000000..100644 --- a/modules/dnn/include/opencv2/dnn/version.hpp +++ b/modules/dnn/include/opencv2/dnn/version.hpp @@@ -1,21 -1,0 +1,21 @@@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_DNN_VERSION_HPP +#define OPENCV_DNN_VERSION_HPP + +/// Use with major OpenCV version only. - #define OPENCV_DNN_API_VERSION 20200128 ++#define OPENCV_DNN_API_VERSION 20200310 + +#if !defined CV_DOXYGEN && !defined CV_STATIC_ANALYSIS && !defined CV_DNN_DONT_ADD_INLINE_NS +#define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION) +#define CV__DNN_INLINE_NS_BEGIN namespace CV__DNN_INLINE_NS { +#define CV__DNN_INLINE_NS_END } +namespace cv { namespace dnn { namespace CV__DNN_INLINE_NS { } using namespace CV__DNN_INLINE_NS; }} +#else +#define CV__DNN_INLINE_NS_BEGIN +#define CV__DNN_INLINE_NS_END +#endif + +#endif // OPENCV_DNN_VERSION_HPP diff --cc modules/videoio/src/cap_ffmpeg_impl.hpp index 0e0af39,fae8542..6dca724 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@@ -1425,6 -1433,8 +1425,8 @@@ double CvCapture_FFMPEG::getProperty( i if (rawMode) return -1; break; - case CV_FFMPEG_CAP_PROP_BITRATE: ++ case CAP_PROP_BITRATE: + return static_cast(get_bitrate()); default: break; } diff --cc modules/videoio/test/test_ffmpeg.cpp index 7b1bfe4,0251261..7fb8339 --- a/modules/videoio/test/test_ffmpeg.cpp +++ b/modules/videoio/test/test_ffmpeg.cpp @@@ -230,107 -353,288 +230,173 @@@ INSTANTIATE_TEST_CASE_P(/**/, videoio_s //========================================================================== -//////////////////////////////// Parallel VideoWriters and VideoCaptures //////////////////////////////////// - -class CreateVideoWriterInvoker : - public ParallelLoopBody +static void generateFrame(Mat &frame, unsigned int i, const Point ¢er, const Scalar &color) { -public: - const static Size FrameSize; - static std::string TmpDirectory; + frame = Scalar::all(i % 255); + stringstream buf(ios::out); + buf << "frame #" << i; + putText(frame, buf.str(), Point(50, center.y), FONT_HERSHEY_SIMPLEX, 5.0, color, 5, CV_AA); + circle(frame, center, i + 2, color, 2, CV_AA); +} - CreateVideoWriterInvoker(std::vector< cv::Ptr >& _writers, std::vector& _files) : - writers(_writers), files(_files) +TEST(videoio_ffmpeg, parallel) +{ + if (!videoio_registry::hasBackend(CAP_FFMPEG)) + throw SkipTestException("FFmpeg backend was not found"); + + const int NUM = 4; + const int GRAN = 4; + const Range R(0, NUM); + const Size sz(1020, 900); + const int frameNum = 300; + const Scalar color(Scalar::all(0)); + const Point center(sz.height / 2, sz.width / 2); + + // Generate filenames + vector files; + for (int i = 0; i < NUM; ++i) { + ostringstream stream; + stream << i << ".avi"; + files.push_back(tempfile(stream.str().c_str())); } - - virtual void operator() (const Range& range) const CV_OVERRIDE + // Write videos { - for (int i = range.start; i != range.end; ++i) + vector< Ptr > writers(NUM); + auto makeWriters = [&](const Range &r) { - std::ostringstream stream; - stream << i << ".avi"; - std::string fileName = tempfile(stream.str().c_str()); - - files[i] = fileName; - writers[i] = makePtr(fileName, CAP_FFMPEG, VideoWriter::fourcc('X','V','I','D'), 25.0f, FrameSize); - - CV_Assert(writers[i]->isOpened()); + for (int i = r.start; i != r.end; ++i) + writers[i] = makePtr(files[i], + CAP_FFMPEG, + VideoWriter::fourcc('X','V','I','D'), + 25.0f, + sz); + }; + parallel_for_(R, makeWriters, GRAN); + for(int i = 0; i < NUM; ++i) + { + ASSERT_TRUE(writers[i]); + ASSERT_TRUE(writers[i]->isOpened()); } - } - -private: - std::vector< cv::Ptr >& writers; - std::vector& files; -}; - -std::string CreateVideoWriterInvoker::TmpDirectory; -const Size CreateVideoWriterInvoker::FrameSize(1020, 900); - -class WriteVideo_Invoker : - public ParallelLoopBody -{ -public: - enum { FrameCount = 300 }; - - static const Scalar ObjectColor; - static const Point Center; - - WriteVideo_Invoker(const std::vector< cv::Ptr >& _writers) : - ParallelLoopBody(), writers(&_writers) - { - } - - static void GenerateFrame(Mat& frame, unsigned int i) - { - frame = Scalar::all(i % 255); - - std::string text = to_string(i); - putText(frame, text, Point(50, Center.y), FONT_HERSHEY_SIMPLEX, 5.0, ObjectColor, 5, CV_AA); - circle(frame, Center, i + 2, ObjectColor, 2, CV_AA); - } - - virtual void operator() (const Range& range) const CV_OVERRIDE - { - for (int j = range.start; j < range.end; ++j) + auto writeFrames = [&](const Range &r) { - VideoWriter* writer = writers->operator[](j); - CV_Assert(writer != NULL); - CV_Assert(writer->isOpened()); - - Mat frame(CreateVideoWriterInvoker::FrameSize, CV_8UC3); - for (unsigned int i = 0; i < FrameCount; ++i) + for (int j = r.start; j < r.end; ++j) { - GenerateFrame(frame, i); - writer->operator<< (frame); + Mat frame(sz, CV_8UC3); + for (int i = 0; i < frameNum; ++i) + { + generateFrame(frame, i, center, color); + writers[j]->write(frame); + } } - } - } - -protected: - static std::string to_string(unsigned int i) - { - std::stringstream stream(std::ios::out); - stream << "frame #" << i; - return stream.str(); - } - -private: - const std::vector< cv::Ptr >* writers; -}; - -const Scalar WriteVideo_Invoker::ObjectColor(Scalar::all(0)); -const Point WriteVideo_Invoker::Center(CreateVideoWriterInvoker::FrameSize.height / 2, - CreateVideoWriterInvoker::FrameSize.width / 2); - -class CreateVideoCaptureInvoker : - public ParallelLoopBody -{ -public: - CreateVideoCaptureInvoker(std::vector< cv::Ptr >& _readers, const std::vector& _files) : - ParallelLoopBody(), readers(&_readers), files(&_files) - { + }; + parallel_for_(R, writeFrames, GRAN); } - - virtual void operator() (const Range& range) const CV_OVERRIDE + // Read videos { - for (int i = range.start; i != range.end; ++i) + vector< Ptr > readers(NUM); + auto makeCaptures = [&](const Range &r) { - readers->operator[](i) = makePtr(files->operator[](i), CAP_FFMPEG); - CV_Assert(readers->operator[](i)->isOpened()); + for (int i = r.start; i != r.end; ++i) + readers[i] = makePtr(files[i], CAP_FFMPEG); + }; + parallel_for_(R, makeCaptures, GRAN); + for(int i = 0; i < NUM; ++i) + { + ASSERT_TRUE(readers[i]); + ASSERT_TRUE(readers[i]->isOpened()); } - } -private: - std::vector< cv::Ptr >* readers; - const std::vector* files; -}; - -class ReadImageAndTest : - public ParallelLoopBody -{ -public: - ReadImageAndTest(const std::vector< cv::Ptr >& _readers, cvtest::TS* _ts) : - ParallelLoopBody(), readers(&_readers), ts(_ts) - { - } - - virtual void operator() (const Range& range) const CV_OVERRIDE - { - for (int j = range.start; j < range.end; ++j) + auto readFrames = [&](const Range &r) { - VideoCapture* capture = readers->operator[](j).get(); - CV_Assert(capture != NULL); - CV_Assert(capture->isOpened()); - - const static double eps = 23.0; - unsigned int frameCount = static_cast(capture->get(CAP_PROP_FRAME_COUNT)); - CV_Assert(frameCount == WriteVideo_Invoker::FrameCount); - Mat reference(CreateVideoWriterInvoker::FrameSize, CV_8UC3); - - for (unsigned int i = 0; i < frameCount && next; ++i) + for (int j = r.start; j < r.end; ++j) { - SCOPED_TRACE(cv::format("frame=%d/%d", (int)i, (int)frameCount)); - - Mat actual; - (*capture) >> actual; - - WriteVideo_Invoker::GenerateFrame(reference, i); - - EXPECT_EQ(reference.cols, actual.cols); - EXPECT_EQ(reference.rows, actual.rows); - EXPECT_EQ(reference.depth(), actual.depth()); - EXPECT_EQ(reference.channels(), actual.channels()); - - double psnr = cvtest::PSNR(actual, reference); - if (psnr < eps) + Mat reference(sz, CV_8UC3); + for (int i = 0; i < frameNum; ++i) { - #define SUM cvtest::TS::SUMMARY - ts->printf(SUM, "\nPSNR: %lf\n", psnr); - ts->printf(SUM, "Video #: %d\n", range.start); - ts->printf(SUM, "Frame #: %d\n", i); - #undef SUM - ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); - ts->set_gtest_status(); - - Mat diff; - absdiff(actual, reference, diff); - - EXPECT_EQ(countNonZero(diff.reshape(1) > 1), 0); - - next = false; + Mat actual; + EXPECT_TRUE(readers[j]->read(actual)); + EXPECT_FALSE(actual.empty()); + generateFrame(reference, i, center, color); + EXPECT_EQ(reference.size(), actual.size()); + EXPECT_EQ(reference.depth(), actual.depth()); + EXPECT_EQ(reference.channels(), actual.channels()); + EXPECT_GE(cvtest::PSNR(actual, reference), 35.0) << "cap" << j << ", frame " << i; } } - } + }; + parallel_for_(R, readFrames, GRAN); } - - static bool next; - -private: - const std::vector< cv::Ptr >* readers; - cvtest::TS* ts; -}; - -bool ReadImageAndTest::next; - -TEST(Videoio_Video_parallel_writers_and_readers, accuracy) -{ - const unsigned int threadsCount = 4; - cvtest::TS* ts = cvtest::TS::ptr(); - - // creating VideoWriters - std::vector< cv::Ptr > writers(threadsCount); - Range range(0, threadsCount); - std::vector files(threadsCount); - CreateVideoWriterInvoker invoker1(writers, files); - parallel_for_(range, invoker1); - - // write a video - parallel_for_(range, WriteVideo_Invoker(writers)); - - // deleting the writers - writers.clear(); - - std::vector > readers(threadsCount); - CreateVideoCaptureInvoker invoker2(readers, files); - parallel_for_(range, invoker2); - - ReadImageAndTest::next = true; - - parallel_for_(range, ReadImageAndTest(readers, ts)); - - // deleting tmp video files - for (std::vector::const_iterator i = files.begin(), end = files.end(); i != end; ++i) + // Remove files + for(int i = 0; i < NUM; ++i) { - int code = remove(i->c_str()); - if (code == 1) - std::cerr << "Couldn't delete " << *i << std::endl; + remove(files[i].c_str()); } - - // delete the readers - readers.clear(); } + typedef std::pair cap_property_t; + typedef std::vector cap_properties_t; + typedef std::pair ffmpeg_cap_properties_param_t; + typedef testing::TestWithParam ffmpeg_cap_properties; + + #ifdef _WIN32 + namespace { + ::testing::AssertionResult IsOneOf(double value, double expected1, double expected2) + { + // internal floating point class is used to perform accurate floating point types comparison + typedef ::testing::internal::FloatingPoint FloatingPoint; + + FloatingPoint val(value); + if (val.AlmostEquals(FloatingPoint(expected1)) || val.AlmostEquals(FloatingPoint(expected2))) + { + return ::testing::AssertionSuccess(); + } + else + { + return ::testing::AssertionFailure() + << value << " is neither equal to " << expected1 << " nor " << expected2; + } + } + } + #endif + + TEST_P(ffmpeg_cap_properties, can_read_property) + { ++ if (!videoio_registry::hasBackend(CAP_FFMPEG)) ++ throw SkipTestException("FFmpeg backend was not found"); ++ + ffmpeg_cap_properties_param_t parameters = GetParam(); + const std::string path = parameters.first; + const cap_properties_t properties = parameters.second; + + VideoCapture cap(findDataFile(path), CAP_FFMPEG); + ASSERT_TRUE(cap.isOpened()) << "Can not open " << findDataFile(path); + + for (std::size_t i = 0; i < properties.size(); ++i) + { + const cap_property_t& prop = properties[i]; + const double actualValue = cap.get(static_cast(prop.first)); + #ifndef _WIN32 + EXPECT_DOUBLE_EQ(actualValue, prop.second) + << "Property " << static_cast(prop.first) << " has wrong value"; + #else + EXPECT_TRUE(IsOneOf(actualValue, prop.second, 0.0)) + << "Property " << static_cast(prop.first) << " has wrong value"; + #endif + } + } + + cap_properties_t loadBigBuckBunnyFFProbeResults() { + cap_property_t properties[] = { cap_property_t(CAP_PROP_BITRATE, 5851.), + cap_property_t(CAP_PROP_FPS, 24.), + cap_property_t(CAP_PROP_FRAME_HEIGHT, 384.), + cap_property_t(CAP_PROP_FRAME_WIDTH, 672.) }; + return cap_properties_t(properties, properties + sizeof(properties) / sizeof(cap_property_t)); + } + + const ffmpeg_cap_properties_param_t videoio_ffmpeg_properties[] = { + ffmpeg_cap_properties_param_t("video/big_buck_bunny.avi", loadBigBuckBunnyFFProbeResults()) + }; + + INSTANTIATE_TEST_CASE_P(videoio, ffmpeg_cap_properties, testing::ValuesIn(videoio_ffmpeg_properties)); + -#endif }} // namespace