diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e7ce39851..d4d1db0d98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -426,6 +426,34 @@ if(UNIX) endif() endif() +if(APPLE AND WITH_FFMPEG) + set(FFMPEG_DEFAULT_INCLUDE_DIRS "/usr/local/include/" "/usr/include/" "opt/include/") + + find_path(FFMPEG_INCLUDE_DIR "libavformat/avformat.h" PATHS ${FFMPEG_DEFAULT_INCLUDE_DIRS} DOC "The path to FFMPEG headers") + if(FFMPEG_INCLUDE_DIR) + set(HAVE_GENTOO_FFMPEG 1) + set(FFMPEG_LIB_DIR "${FFMPEG_INCLUDE_DIR}/../lib" CACHE PATH "Full path of FFMPEG library directory") + if(EXISTS "${FFMPEG_LIB_DIR}/libavcodec.a") + set(HAVE_FFMPEG_CODEC 1) + if(EXISTS "${FFMPEG_LIB_DIR}/libavformat.a") + set(HAVE_FFMPEG_FORMAT 1) + if(EXISTS "${FFMPEG_LIB_DIR}/libavutil.a") + set(HAVE_FFMPEG_UTIL 1) + if(EXISTS "${FFMPEG_LIB_DIR}/libswscale.a") + ocv_include_directories(${FFMPEG_INCLUDE_DIR}) + set(HAVE_FFMPEG_SWSCALE 1) + set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "${FFMPEG_LIB_DIR}/libavcodec.a" + "${FFMPEG_LIB_DIR}/libavformat.a" "${FFMPEG_LIB_DIR}/libavutil.a" + "${FFMPEG_LIB_DIR}/libswscale.a") + set(HAVE_FFMPEG 1) + set(NEW_FFMPEG 1) + endif() + endif() + endif() + endif() + endif() +endif() + #################### LATEX for dpf documentation ################## if(BUILD_DOCS) include(cmake/OpenCVFindLATEX.cmake REQUIRED) @@ -756,12 +784,16 @@ if(UNIX AND NOT APPLE) status(" Video I/O:") status(" DC1394 1.x:" HAVE_DC1394 THEN YES ELSE NO) status(" DC1394 2.x:" HAVE_DC1394_2 THEN YES ELSE NO) +endif() +if(UNIX) status(" FFMPEG:" HAVE_FFMPEG THEN YES ELSE NO) status(" codec:" HAVE_FFMPEG_CODEC THEN YES ELSE NO) status(" format:" HAVE_FFMPEG_FORMAT THEN YES ELSE NO) status(" util:" HAVE_FFMPEG_UTIL THEN YES ELSE NO) status(" swscale:" HAVE_FFMPEG_SWSCALE THEN YES ELSE NO) status(" gentoo-style:" HAVE_GENTOO_FFMPEG THEN YES ELSE NO) +endif() +if(UNIX AND NOT APPLE) status(" GStreamer:" HAVE_GSTREAMER THEN YES ELSE NO) status(" UniCap:" HAVE_UNICAP THEN YES ELSE NO) status(" PvAPI:" HAVE_PVAPI THEN YES ELSE NO) diff --git a/modules/highgui/CMakeLists.txt b/modules/highgui/CMakeLists.txt index cf16839de2..22ff07c528 100644 --- a/modules/highgui/CMakeLists.txt +++ b/modules/highgui/CMakeLists.txt @@ -59,6 +59,8 @@ set(highgui_srcs src/cap.cpp src/cap_images.cpp src/cap_ffmpeg_v2.cpp + src/cap_ffmpeg_impl_v2.hpp + src/cap_ffmpeg_impl.hpp src/loadsave.cpp src/precomp.cpp src/utils.cpp @@ -69,6 +71,8 @@ set(highgui_srcs src/cap.cpp src/cap_images.cpp src/cap_ffmpeg.cpp + src/cap_ffmpeg_impl_v2.hpp + src/cap_ffmpeg_impl.hpp src/loadsave.cpp src/precomp.cpp src/utils.cpp @@ -197,6 +201,10 @@ if(APPLE) set(highgui_srcs ${highgui_srcs} src/cap_qtkit.mm) endif() endif() + + if(HAVE_FFMPEG) + set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "-framework VideoDecodeAcceleration") + endif() endif(APPLE) if(HAVE_opencv_androidcamera) diff --git a/modules/highgui/src/cap_ffmpeg_impl_v2.hpp b/modules/highgui/src/cap_ffmpeg_impl_v2.hpp index 5dc4d89a25..6ba631c8b1 100755 --- a/modules/highgui/src/cap_ffmpeg_impl_v2.hpp +++ b/modules/highgui/src/cap_ffmpeg_impl_v2.hpp @@ -383,9 +383,7 @@ bool CvCapture_FFMPEG::open( const char* _filename ) /* register all codecs, demux and protocols */ av_register_all(); - #ifndef _DEBUG - // av_log_level = AV_LOG_QUIET; - #endif + //av_log_set_level(AV_LOG_ERROR); int err = avformat_open_input(&ic, _filename, NULL, NULL); if (err < 0) { @@ -1392,11 +1390,13 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, } #endif + #if 0 #if FF_API_DUMP_FORMAT dump_format(oc, 0, filename, 1); #else av_dump_format(oc, 0, filename, 1); #endif + #endif /* now that all the parameters are set, we can open the audio and video codecs and allocate the necessary encode buffers */ diff --git a/modules/highgui/test/test_ffmpeg.cpp b/modules/highgui/test/test_ffmpeg.cpp index fb5c5df5de..9d20b5a2a8 100644 --- a/modules/highgui/test/test_ffmpeg.cpp +++ b/modules/highgui/test/test_ffmpeg.cpp @@ -55,8 +55,8 @@ class CV_FFmpegWriteBigVideoTest : public cvtest::BaseTest public: void run(int) { - const int img_r = 4096; - const int img_c = 4096; + const int img_r = 480; + const int img_c = 640; Size frame_s = Size(img_c, img_r); const double fps = 30; const double time_sec = 2; @@ -69,25 +69,57 @@ public: for (size_t j = 0; j < n; ++j) { stringstream s; s << codec_bmp_tags[j].tag; + int tag = codec_bmp_tags[j].tag; + + if( tag != MKTAG('H', '2', '6', '3') && + tag != MKTAG('H', '2', '6', '1') && + tag != MKTAG('D', 'I', 'V', 'X') && + tag != MKTAG('D', 'X', '5', '0') && + tag != MKTAG('X', 'V', 'I', 'D') && + tag != MKTAG('m', 'p', '4', 'v') && + tag != MKTAG('D', 'I', 'V', '3') && + tag != MKTAG('W', 'M', 'V', '1') && + tag != MKTAG('W', 'M', 'V', '1') && + tag != MKTAG('m', 'p', 'g', '1') && + tag != MKTAG('W', 'M', 'V', '1') && + tag != MKTAG('W', 'M', 'V', '2') && + tag != MKTAG('m', 'p', 'g', '1') && + tag != MKTAG('m', 'p', 'g', '2') && + tag != MKTAG('M', 'P', 'E', 'G') && + tag != MKTAG('M', 'J', 'P', 'G') && + tag != MKTAG('L', 'J', 'P', 'G') && + tag != MKTAG('j', 'p', 'e', 'g') && + tag != 0 && + tag != MKTAG('I', '4', '2', '0') && + tag != MKTAG('Y', 'U', 'Y', '2') && + tag != MKTAG('F', 'L', 'V', '1') ) + continue; const string filename = "output_"+s.str()+".avi"; - Mat img(img_r, img_c, CV_8UC3, Scalar::all(0)); try { - VideoWriter writer(filename, codec_bmp_tags[j].tag, fps, frame_s); + + frame_s = Size(img_c, img_r); + if( tag == CV_FOURCC('H', '2', '6', '1') ) + frame_s = Size(352, 288); + else if( tag == CV_FOURCC('H', '2', '6', '3') ) + frame_s = Size(704, 576); + + VideoWriter writer(filename, tag, fps, frame_s); if (writer.isOpened() == false) { ts->printf(ts->LOG, "\n\nFile name: %s\n", filename.c_str()); - ts->printf(ts->LOG, "Codec id: %d Codec tag: %d\n", j, codec_bmp_tags[j].tag); + ts->printf(ts->LOG, "Codec id: %d Codec tag: %c%c%c%c\n", j, + tag & 255, (tag >> 8) & 255, (tag >> 16) & 255, (tag >> 24) & 255); ts->printf(ts->LOG, "Error: cannot create video file."); ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); } - else - { + Mat img(frame_s, CV_8UC3, Scalar::all(0)); + for (int i = 0 ; i < static_cast(fps * time_sec); i++ ) { //circle(img, Point2i(img_c / 2, img_r / 2), cv::min(img_r, img_c) / 2 * (i + 1), Scalar(255, 0, 0, 0), 2);