Commit ec30b129 authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #11636 from alalek:cmake_ffmpeg_find_package

parents fc35c77f b934702c
...@@ -1250,7 +1250,9 @@ if(WITH_1394 OR HAVE_DC1394) ...@@ -1250,7 +1250,9 @@ if(WITH_1394 OR HAVE_DC1394)
endif() endif()
if(WITH_FFMPEG OR HAVE_FFMPEG) if(WITH_FFMPEG OR HAVE_FFMPEG)
if(WIN32) if(OPENCV_FFMPEG_USE_FIND_PACKAGE)
status(" FFMPEG:" HAVE_FFMPEG THEN "YES (find_package)" ELSE "NO (find_package)")
elseif(WIN32)
status(" FFMPEG:" HAVE_FFMPEG THEN "YES (prebuilt binaries)" ELSE NO) status(" FFMPEG:" HAVE_FFMPEG THEN "YES (prebuilt binaries)" ELSE NO)
else() else()
status(" FFMPEG:" HAVE_FFMPEG THEN YES ELSE NO) status(" FFMPEG:" HAVE_FFMPEG THEN YES ELSE NO)
......
...@@ -212,12 +212,23 @@ endif(WITH_XIMEA) ...@@ -212,12 +212,23 @@ endif(WITH_XIMEA)
# --- FFMPEG --- # --- FFMPEG ---
ocv_clear_vars(HAVE_FFMPEG) ocv_clear_vars(HAVE_FFMPEG)
if(WITH_FFMPEG) if(WITH_FFMPEG) # try FFmpeg autodetection
if(WIN32 AND NOT ARM) if(OPENCV_FFMPEG_USE_FIND_PACKAGE)
if(OPENCV_FFMPEG_USE_FIND_PACKAGE STREQUAL "1" OR OPENCV_FFMPEG_USE_FIND_PACKAGE STREQUAL "ON")
set(OPENCV_FFMPEG_USE_FIND_PACKAGE "FFMPEG")
endif()
find_package(${OPENCV_FFMPEG_USE_FIND_PACKAGE}) # Required components: AVCODEC AVFORMAT AVUTIL SWSCALE
if(FFMPEG_FOUND OR FFmpeg_FOUND)
set(HAVE_FFMPEG TRUE)
else()
message(STATUS "Can't find FFmpeg via find_package(${OPENCV_FFMPEG_USE_FIND_PACKAGE})")
endif()
elseif(WIN32 AND NOT ARM AND NOT OPENCV_FFMPEG_SKIP_DOWNLOAD)
include("${OpenCV_SOURCE_DIR}/3rdparty/ffmpeg/ffmpeg.cmake") include("${OpenCV_SOURCE_DIR}/3rdparty/ffmpeg/ffmpeg.cmake")
download_win_ffmpeg(FFMPEG_CMAKE_SCRIPT) download_win_ffmpeg(FFMPEG_CMAKE_SCRIPT)
if(FFMPEG_CMAKE_SCRIPT) if(FFMPEG_CMAKE_SCRIPT)
set(HAVE_FFMPEG TRUE) set(HAVE_FFMPEG TRUE)
set(HAVE_FFMPEG_WRAPPER 1)
include("${FFMPEG_CMAKE_SCRIPT}") include("${FFMPEG_CMAKE_SCRIPT}")
endif() endif()
elseif(PKG_CONFIG_FOUND) elseif(PKG_CONFIG_FOUND)
...@@ -226,27 +237,29 @@ if(WITH_FFMPEG) ...@@ -226,27 +237,29 @@ if(WITH_FFMPEG)
if(FFMPEG_libavresample_FOUND) if(FFMPEG_libavresample_FOUND)
ocv_append_build_options(FFMPEG FFMPEG_libavresample) ocv_append_build_options(FFMPEG FFMPEG_libavresample)
endif() endif()
if(HAVE_FFMPEG)
try_compile(__VALID_FFMPEG
"${OpenCV_BINARY_DIR}"
"${OpenCV_SOURCE_DIR}/cmake/checks/ffmpeg_test.cpp"
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${FFMPEG_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES:STRING=${FFMPEG_LIBRARY_DIRS}"
"-DLINK_LIBRARIES:STRING=${FFMPEG_LIBRARIES}"
OUTPUT_VARIABLE TRY_OUT
)
if(NOT __VALID_FFMPEG)
#message(FATAL_ERROR "FFMPEG: test check build log:\n${TRY_OUT}")
message(STATUS "WARNING: Can't build ffmpeg test code")
set(HAVE_FFMPEG FALSE)
else()
ocv_append_build_options(VIDEOIO FFMPEG)
endif()
endif()
else() else()
message(STATUS "Can't find ffmpeg - 'pkg-config' utility is missing") message(STATUS "Can't find ffmpeg - 'pkg-config' utility is missing")
endif() endif()
endif(WITH_FFMPEG) endif()
if(HAVE_FFMPEG
AND NOT HAVE_FFMPEG_WRAPPER
)
try_compile(__VALID_FFMPEG
"${OpenCV_BINARY_DIR}"
"${OpenCV_SOURCE_DIR}/cmake/checks/ffmpeg_test.cpp"
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${FFMPEG_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES:STRING=${FFMPEG_LIBRARY_DIRS}"
"-DLINK_LIBRARIES:STRING=${FFMPEG_LIBRARIES}"
OUTPUT_VARIABLE TRY_OUT
)
if(NOT __VALID_FFMPEG)
#message(FATAL_ERROR "FFMPEG: test check build log:\n${TRY_OUT}")
message(STATUS "WARNING: Can't build ffmpeg test code")
set(HAVE_FFMPEG FALSE)
else()
ocv_append_build_options(VIDEOIO FFMPEG)
endif()
endif()
# --- VideoInput/DirectShow --- # --- VideoInput/DirectShow ---
if(WITH_DSHOW) if(WITH_DSHOW)
......
...@@ -167,6 +167,9 @@ if(HAVE_FFMPEG) ...@@ -167,6 +167,9 @@ if(HAVE_FFMPEG)
if(APPLE) if(APPLE)
list(APPEND VIDEOIO_LIBRARIES "-framework VideoDecodeAcceleration" bz2) list(APPEND VIDEOIO_LIBRARIES "-framework VideoDecodeAcceleration" bz2)
endif() endif()
if(HAVE_FFMPEG_WRAPPER)
add_definitions(-DHAVE_FFMPEG_WRAPPER=1)
endif()
endif(HAVE_FFMPEG) endif(HAVE_FFMPEG)
if(HAVE_PVAPI) if(HAVE_PVAPI)
...@@ -230,12 +233,6 @@ if(IOS) ...@@ -230,12 +233,6 @@ if(IOS)
list(APPEND VIDEOIO_LIBRARIES "-framework Accelerate" "-framework AVFoundation" "-framework CoreGraphics" "-framework CoreImage" "-framework CoreMedia" "-framework CoreVideo" "-framework QuartzCore" "-framework UIKit") list(APPEND VIDEOIO_LIBRARIES "-framework Accelerate" "-framework AVFoundation" "-framework CoreGraphics" "-framework CoreImage" "-framework CoreMedia" "-framework CoreVideo" "-framework QuartzCore" "-framework UIKit")
endif() endif()
if(WIN32)
link_directories("${OpenCV_SOURCE_DIR}/3rdparty/lib") # for ffmpeg wrapper only
include_directories(AFTER SYSTEM "${OpenCV_SOURCE_DIR}/3rdparty/include") # for directshow in VS2005 and multi-monitor support on MinGW
include_directories(AFTER SYSTEM "${OpenCV_SOURCE_DIR}/3rdparty/include/ffmpeg_") # for tests
endif()
if(UNIX) if(UNIX)
#these variables are set by CHECK_MODULE macro #these variables are set by CHECK_MODULE macro
foreach(P ${VIDEOIO_INCLUDE_DIRS}) foreach(P ${VIDEOIO_INCLUDE_DIRS})
...@@ -268,7 +265,7 @@ endif() ...@@ -268,7 +265,7 @@ endif()
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated-declarations) ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated-declarations)
if(WIN32 AND HAVE_FFMPEG) if(WIN32 AND HAVE_FFMPEG_WRAPPER)
#copy ffmpeg dll to the output folder #copy ffmpeg dll to the output folder
if(MSVC64 OR MINGW64) if(MSVC64 OR MINGW64)
set(FFMPEG_SUFFIX _64) set(FFMPEG_SUFFIX _64)
......
...@@ -41,13 +41,28 @@ ...@@ -41,13 +41,28 @@
#include "precomp.hpp" #include "precomp.hpp"
#if defined(HAVE_FFMPEG)
#include <string> #include <string>
#if defined HAVE_FFMPEG && !defined _WIN32 #if !defined(HAVE_FFMPEG_WRAPPER)
#include "cap_ffmpeg_impl.hpp" #include "cap_ffmpeg_impl.hpp"
#define icvCreateFileCapture_FFMPEG_p cvCreateFileCapture_FFMPEG
#define icvReleaseCapture_FFMPEG_p cvReleaseCapture_FFMPEG
#define icvGrabFrame_FFMPEG_p cvGrabFrame_FFMPEG
#define icvRetrieveFrame_FFMPEG_p cvRetrieveFrame_FFMPEG
#define icvSetCaptureProperty_FFMPEG_p cvSetCaptureProperty_FFMPEG
#define icvGetCaptureProperty_FFMPEG_p cvGetCaptureProperty_FFMPEG
#define icvCreateVideoWriter_FFMPEG_p cvCreateVideoWriter_FFMPEG
#define icvReleaseVideoWriter_FFMPEG_p cvReleaseVideoWriter_FFMPEG
#define icvWriteFrame_FFMPEG_p cvWriteFrame_FFMPEG
#else #else
#include "cap_ffmpeg_api.hpp" #include "cap_ffmpeg_api.hpp"
#endif
namespace cv { namespace {
static CvCreateFileCapture_Plugin icvCreateFileCapture_FFMPEG_p = 0; static CvCreateFileCapture_Plugin icvCreateFileCapture_FFMPEG_p = 0;
static CvReleaseCapture_Plugin icvReleaseCapture_FFMPEG_p = 0; static CvReleaseCapture_Plugin icvReleaseCapture_FFMPEG_p = 0;
...@@ -99,7 +114,7 @@ private: ...@@ -99,7 +114,7 @@ private:
icvInitFFMPEG() icvInitFFMPEG()
{ {
#if defined _WIN32 #if defined _WIN32
const wchar_t* module_name_ = L"opencv_ffmpeg" const wchar_t* module_name_ = L"opencv_ffmpeg"
CVAUX_STRW(CV_MAJOR_VERSION) CVAUX_STRW(CV_MINOR_VERSION) CVAUX_STRW(CV_SUBMINOR_VERSION) CVAUX_STRW(CV_MAJOR_VERSION) CVAUX_STRW(CV_MINOR_VERSION) CVAUX_STRW(CV_SUBMINOR_VERSION)
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__) #if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__)
...@@ -161,7 +176,7 @@ private: ...@@ -161,7 +176,7 @@ private:
(CvReleaseVideoWriter_Plugin)GetProcAddress(icvFFOpenCV, "cvReleaseVideoWriter_FFMPEG"); (CvReleaseVideoWriter_Plugin)GetProcAddress(icvFFOpenCV, "cvReleaseVideoWriter_FFMPEG");
icvWriteFrame_FFMPEG_p = icvWriteFrame_FFMPEG_p =
(CvWriteFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvWriteFrame_FFMPEG"); (CvWriteFrame_Plugin)GetProcAddress(icvFFOpenCV, "cvWriteFrame_FFMPEG");
# endif // _WIN32
#if 0 #if 0
if( icvCreateFileCapture_FFMPEG_p != 0 && if( icvCreateFileCapture_FFMPEG_p != 0 &&
icvReleaseCapture_FFMPEG_p != 0 && icvReleaseCapture_FFMPEG_p != 0 &&
...@@ -181,21 +196,18 @@ private: ...@@ -181,21 +196,18 @@ private:
} }
#endif #endif
} }
#elif defined HAVE_FFMPEG
icvCreateFileCapture_FFMPEG_p = (CvCreateFileCapture_Plugin)cvCreateFileCapture_FFMPEG;
icvReleaseCapture_FFMPEG_p = (CvReleaseCapture_Plugin)cvReleaseCapture_FFMPEG;
icvGrabFrame_FFMPEG_p = (CvGrabFrame_Plugin)cvGrabFrame_FFMPEG;
icvRetrieveFrame_FFMPEG_p = (CvRetrieveFrame_Plugin)cvRetrieveFrame_FFMPEG;
icvSetCaptureProperty_FFMPEG_p = (CvSetCaptureProperty_Plugin)cvSetCaptureProperty_FFMPEG;
icvGetCaptureProperty_FFMPEG_p = (CvGetCaptureProperty_Plugin)cvGetCaptureProperty_FFMPEG;
icvCreateVideoWriter_FFMPEG_p = (CvCreateVideoWriter_Plugin)cvCreateVideoWriter_FFMPEG;
icvReleaseVideoWriter_FFMPEG_p = (CvReleaseVideoWriter_Plugin)cvReleaseVideoWriter_FFMPEG;
icvWriteFrame_FFMPEG_p = (CvWriteFrame_Plugin)cvWriteFrame_FFMPEG;
#endif
} }
}; };
}} // namespace
#endif // HAVE_FFMPEG_WRAPPER
namespace cv {
namespace {
class CvCapture_FFMPEG_proxy CV_FINAL : public cv::IVideoCapture class CvCapture_FFMPEG_proxy CV_FINAL : public cv::IVideoCapture
{ {
public: public:
...@@ -228,19 +240,20 @@ public: ...@@ -228,19 +240,20 @@ public:
} }
virtual bool open( const cv::String& filename ) virtual bool open( const cv::String& filename )
{ {
icvInitFFMPEG::Init();
close(); close();
if( !icvCreateFileCapture_FFMPEG_p )
return false;
ffmpegCapture = icvCreateFileCapture_FFMPEG_p( filename.c_str() ); ffmpegCapture = icvCreateFileCapture_FFMPEG_p( filename.c_str() );
return ffmpegCapture != 0; return ffmpegCapture != 0;
} }
virtual void close() virtual void close()
{ {
if( ffmpegCapture && icvReleaseCapture_FFMPEG_p ) if (ffmpegCapture
#if defined(HAVE_FFMPEG_WRAPPER)
&& icvReleaseCapture_FFMPEG_p
#endif
)
icvReleaseCapture_FFMPEG_p( &ffmpegCapture ); icvReleaseCapture_FFMPEG_p( &ffmpegCapture );
assert( ffmpegCapture == 0 ); CV_Assert(ffmpegCapture == 0);
ffmpegCapture = 0; ffmpegCapture = 0;
} }
...@@ -248,18 +261,26 @@ public: ...@@ -248,18 +261,26 @@ public:
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_FFMPEG; } virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_FFMPEG; }
protected: protected:
void* ffmpegCapture; CvCapture_FFMPEG* ffmpegCapture;
}; };
} // namespace
cv::Ptr<cv::IVideoCapture> cv::cvCreateFileCapture_FFMPEG_proxy(const cv::String& filename) cv::Ptr<cv::IVideoCapture> cvCreateFileCapture_FFMPEG_proxy(const cv::String& filename)
{ {
#if defined(HAVE_FFMPEG_WRAPPER)
icvInitFFMPEG::Init();
if (!icvCreateFileCapture_FFMPEG_p)
return cv::Ptr<cv::IVideoCapture>();
#endif
cv::Ptr<CvCapture_FFMPEG_proxy> capture = cv::makePtr<CvCapture_FFMPEG_proxy>(filename); cv::Ptr<CvCapture_FFMPEG_proxy> capture = cv::makePtr<CvCapture_FFMPEG_proxy>(filename);
if (capture && capture->isOpened()) if (capture && capture->isOpened())
return capture; return capture;
return cv::Ptr<cv::IVideoCapture>(); return cv::Ptr<cv::IVideoCapture>();
} }
namespace {
class CvVideoWriter_FFMPEG_proxy CV_FINAL : class CvVideoWriter_FFMPEG_proxy CV_FINAL :
public cv::IVideoWriter public cv::IVideoWriter
{ {
...@@ -278,19 +299,20 @@ public: ...@@ -278,19 +299,20 @@ public:
} }
virtual bool open( const cv::String& filename, int fourcc, double fps, cv::Size frameSize, bool isColor ) virtual bool open( const cv::String& filename, int fourcc, double fps, cv::Size frameSize, bool isColor )
{ {
icvInitFFMPEG::Init();
close(); close();
if( !icvCreateVideoWriter_FFMPEG_p )
return false;
ffmpegWriter = icvCreateVideoWriter_FFMPEG_p( filename.c_str(), fourcc, fps, frameSize.width, frameSize.height, isColor ); ffmpegWriter = icvCreateVideoWriter_FFMPEG_p( filename.c_str(), fourcc, fps, frameSize.width, frameSize.height, isColor );
return ffmpegWriter != 0; return ffmpegWriter != 0;
} }
virtual void close() virtual void close()
{ {
if( ffmpegWriter && icvReleaseVideoWriter_FFMPEG_p ) if (ffmpegWriter
#if defined(HAVE_FFMPEG_WRAPPER)
&& icvReleaseVideoWriter_FFMPEG_p
#endif
)
icvReleaseVideoWriter_FFMPEG_p( &ffmpegWriter ); icvReleaseVideoWriter_FFMPEG_p( &ffmpegWriter );
assert( ffmpegWriter == 0 ); CV_Assert(ffmpegWriter == 0);
ffmpegWriter = 0; ffmpegWriter = 0;
} }
...@@ -299,15 +321,25 @@ public: ...@@ -299,15 +321,25 @@ public:
virtual bool isOpened() const CV_OVERRIDE { return ffmpegWriter != 0; } virtual bool isOpened() const CV_OVERRIDE { return ffmpegWriter != 0; }
protected: protected:
void* ffmpegWriter; CvVideoWriter_FFMPEG* ffmpegWriter;
}; };
} // namespace
cv::Ptr<cv::IVideoWriter> cv::cvCreateVideoWriter_FFMPEG_proxy(const cv::String& filename, int fourcc, cv::Ptr<cv::IVideoWriter> cvCreateVideoWriter_FFMPEG_proxy(const cv::String& filename, int fourcc,
double fps, cv::Size frameSize, int isColor) double fps, cv::Size frameSize, int isColor)
{ {
#if defined(HAVE_FFMPEG_WRAPPER)
icvInitFFMPEG::Init();
if (!icvCreateVideoWriter_FFMPEG_p)
return cv::Ptr<cv::IVideoWriter>();
#endif
cv::Ptr<CvVideoWriter_FFMPEG_proxy> writer = cv::makePtr<CvVideoWriter_FFMPEG_proxy>(filename, fourcc, fps, frameSize, isColor != 0); cv::Ptr<CvVideoWriter_FFMPEG_proxy> writer = cv::makePtr<CvVideoWriter_FFMPEG_proxy>(filename, fourcc, fps, frameSize, isColor != 0);
if (writer && writer->isOpened()) if (writer && writer->isOpened())
return writer; return writer;
return cv::Ptr<cv::IVideoWriter>(); return cv::Ptr<cv::IVideoWriter>();
} }
} // namespace
#endif // defined(HAVE_FFMPEG)
...@@ -28,6 +28,8 @@ enum ...@@ -28,6 +28,8 @@ enum
CV_FFMPEG_CAP_PROP_SAR_DEN=41 CV_FFMPEG_CAP_PROP_SAR_DEN=41
}; };
typedef struct CvCapture_FFMPEG CvCapture_FFMPEG;
typedef struct CvVideoWriter_FFMPEG CvVideoWriter_FFMPEG;
OPENCV_FFMPEG_API struct CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG(const char* filename); OPENCV_FFMPEG_API struct CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG(const char* filename);
OPENCV_FFMPEG_API struct CvCapture_FFMPEG_2* cvCreateFileCapture_FFMPEG_2(const char* filename); OPENCV_FFMPEG_API struct CvCapture_FFMPEG_2* cvCreateFileCapture_FFMPEG_2(const char* filename);
...@@ -55,19 +57,19 @@ OPENCV_FFMPEG_API int cvWriteFrame_FFMPEG(struct CvVideoWriter_FFMPEG* writer, c ...@@ -55,19 +57,19 @@ OPENCV_FFMPEG_API int cvWriteFrame_FFMPEG(struct CvVideoWriter_FFMPEG* writer, c
OPENCV_FFMPEG_API void cvReleaseVideoWriter_FFMPEG(struct CvVideoWriter_FFMPEG** writer); OPENCV_FFMPEG_API void cvReleaseVideoWriter_FFMPEG(struct CvVideoWriter_FFMPEG** writer);
typedef void* (*CvCreateFileCapture_Plugin)( const char* filename ); typedef CvCapture_FFMPEG* (*CvCreateFileCapture_Plugin)( const char* filename );
typedef void* (*CvCreateCameraCapture_Plugin)( int index ); typedef CvCapture_FFMPEG* (*CvCreateCameraCapture_Plugin)( int index );
typedef int (*CvGrabFrame_Plugin)( void* capture_handle ); typedef int (*CvGrabFrame_Plugin)( CvCapture_FFMPEG* capture_handle );
typedef int (*CvRetrieveFrame_Plugin)( void* capture_handle, unsigned char** data, int* step, typedef int (*CvRetrieveFrame_Plugin)( CvCapture_FFMPEG* capture_handle, unsigned char** data, int* step,
int* width, int* height, int* cn ); int* width, int* height, int* cn );
typedef int (*CvSetCaptureProperty_Plugin)( void* capture_handle, int prop_id, double value ); typedef int (*CvSetCaptureProperty_Plugin)( CvCapture_FFMPEG* capture_handle, int prop_id, double value );
typedef double (*CvGetCaptureProperty_Plugin)( void* capture_handle, int prop_id ); typedef double (*CvGetCaptureProperty_Plugin)( CvCapture_FFMPEG* capture_handle, int prop_id );
typedef void (*CvReleaseCapture_Plugin)( void** capture_handle ); typedef void (*CvReleaseCapture_Plugin)( CvCapture_FFMPEG** capture_handle );
typedef void* (*CvCreateVideoWriter_Plugin)( const char* filename, int fourcc, typedef CvVideoWriter_FFMPEG* (*CvCreateVideoWriter_Plugin)( const char* filename, int fourcc,
double fps, int width, int height, int iscolor ); double fps, int width, int height, int iscolor );
typedef int (*CvWriteFrame_Plugin)( void* writer_handle, const unsigned char* data, int step, typedef int (*CvWriteFrame_Plugin)( CvVideoWriter_FFMPEG* writer_handle, const unsigned char* data, int step,
int width, int height, int cn, int origin); int width, int height, int cn, int origin);
typedef void (*CvReleaseVideoWriter_Plugin)( void** writer ); typedef void (*CvReleaseVideoWriter_Plugin)( CvVideoWriter_FFMPEG** writer );
/* /*
* For CUDA encoder * For CUDA encoder
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment