From 83655ba9beb793486b85c4033a84d2b93d920773 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Tue, 10 Oct 2017 17:21:27 +0300 Subject: [PATCH] MediaSDK video backend: Windows support --- CMakeLists.txt | 2 +- cmake/OpenCVDetectMediaSDK.cmake | 55 ++++++++++++++++++-------- modules/videoio/src/cap_mfx_common.cpp | 26 ++++++++++-- modules/videoio/src/cap_mfx_common.hpp | 30 +++++++++++--- modules/videoio/src/cap_mfx_reader.cpp | 4 +- modules/videoio/src/cap_mfx_writer.cpp | 14 +++---- 6 files changed, 93 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e9bd0bbd4..47de63f529 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,7 +245,7 @@ OCV_OPTION(WITH_INTELPERC "Include Intel Perceptual Computing support" OFF OCV_OPTION(WITH_MATLAB "Include Matlab support" ON IF (NOT ANDROID AND NOT IOS AND NOT WINRT)) OCV_OPTION(WITH_VA "Include VA support" OFF IF (UNIX AND NOT ANDROID) ) OCV_OPTION(WITH_VA_INTEL "Include Intel VA-API/OpenCL support" OFF IF (UNIX AND NOT ANDROID) ) -OCV_OPTION(WITH_MFX "Include Intel Media SDK support" OFF IF (UNIX AND NOT ANDROID) ) +OCV_OPTION(WITH_MFX "Include Intel Media SDK support" OFF IF ((UNIX AND NOT ANDROID) OR (WIN32 AND NOT WINRT AND NOT MINGW)) ) OCV_OPTION(WITH_GDAL "Include GDAL Support" OFF IF (NOT ANDROID AND NOT IOS AND NOT WINRT) ) OCV_OPTION(WITH_GPHOTO2 "Include gPhoto2 library support" ON IF (UNIX AND NOT ANDROID) ) OCV_OPTION(WITH_LAPACK "Include Lapack library support" ON IF (NOT ANDROID AND NOT IOS) ) diff --git a/cmake/OpenCVDetectMediaSDK.cmake b/cmake/OpenCVDetectMediaSDK.cmake index bc0b2ed3ea..97f898cdf3 100644 --- a/cmake/OpenCVDetectMediaSDK.cmake +++ b/cmake/OpenCVDetectMediaSDK.cmake @@ -1,6 +1,10 @@ -set(root "$ENV{MFX_HOME}") +set(HAVE_MFX 0) -find_path(MFX_INCLUDE mfxdefs.h PATHS "${root}/include" NO_DEFAULT_PATH) +if (UNIX) + set(root "$ENV{MFX_HOME}") +elseif(WIN32) + set(root "$ENV{INTELMEDIASDKROOT}") +endif() # TODO: ICC? MINGW? ARM? IOS? if(WIN32) @@ -15,24 +19,41 @@ else() # ??? endif() -find_library(MFX_LIBRARY mfx PATHS "${root}/lib/${arch}" NO_DEFAULT_PATH) -find_library(MFX_VA_LIBRARY va) -find_library(MFX_VA_DRM_LIBRARY va-drm) +find_path(MFX_INCLUDE mfxdefs.h PATHS "${root}/include" NO_DEFAULT_PATH) +message(STATUS "MFX_INCLUDE: ${MFX_INCLUDE} (${root}/include)") +find_library(MFX_LIBRARY NAMES mfx PATHS "${root}/lib/${arch}" NO_DEFAULT_PATH) +if(MSVC) + if(MSVC14) + find_library(MFX_LIBRARY NAMES libmfx_vs2015.lib PATHS "${root}/lib/${arch}" NO_DEFAULT_PATH) + else() + find_library(MFX_LIBRARY NAMES libmfx.lib PATHS "${root}/lib/${arch}" NO_DEFAULT_PATH) + endif() +endif() + +if(NOT MFX_INCLUDE OR NOT MFX_LIBRARY) + return() +endif() -if(MFX_INCLUDE AND MFX_LIBRARY AND MFX_VA_LIBRARY AND MFX_VA_DRM_LIBRARY) +set(deps) + +if (UNIX) + find_library(MFX_VA_LIBRARY va) + find_library(MFX_VA_DRM_LIBRARY va-drm) + if (NOT MFX_VA_LIBRARY OR NOT MFX_VA_DRM_LIBRARY) + return() + endif() add_library(mfx-va UNKNOWN IMPORTED) set_target_properties(mfx-va PROPERTIES IMPORTED_LOCATION "${MFX_VA_LIBRARY}") - add_library(mfx-va-drm UNKNOWN IMPORTED) set_target_properties(mfx-va-drm PROPERTIES IMPORTED_LOCATION "${MFX_VA_DRM_LIBRARY}") - - add_library(mfx UNKNOWN IMPORTED) - set_target_properties(mfx PROPERTIES - IMPORTED_LOCATION "${MFX_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${MFX_INCLUDE}" - INTERFACE_LINK_LIBRARIES "mfx-va;mfx-va-drm;-Wl,--exclude-libs=libmfx" - ) - set(HAVE_MFX 1) -else() - set(HAVE_MFX 0) + list(APPEND deps mfx-va mfx-va-drm "-Wl,--exclude-libs=libmfx") endif() + +add_library(mfx UNKNOWN IMPORTED) +set_target_properties(mfx PROPERTIES + IMPORTED_LOCATION "${MFX_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${MFX_INCLUDE}" + INTERFACE_LINK_LIBRARIES "${deps}" +) + +set(HAVE_MFX 1) diff --git a/modules/videoio/src/cap_mfx_common.cpp b/modules/videoio/src/cap_mfx_common.cpp index dda0cc226c..49fb847c3f 100644 --- a/modules/videoio/src/cap_mfx_common.cpp +++ b/modules/videoio/src/cap_mfx_common.cpp @@ -5,10 +5,12 @@ #include "cap_mfx_common.hpp" // Linux specific +#ifdef __linux__ #include #include #include #include +#endif using namespace std; using namespace cv; @@ -36,6 +38,8 @@ bool DeviceHandler::init(MFXVideoSession &session) //================================================================================================== +#ifdef __linux__ + VAHandle::VAHandle() { // TODO: provide a way of modifying this path const string filename = "/dev/dri/card0"; @@ -68,6 +72,19 @@ bool VAHandle::initDeviceSession(MFXVideoSession &session) { return false; } +#endif // __linux__ + +DeviceHandler * createDeviceHandler() +{ +#if defined __linux__ + return new VAHandle(); +#elif defined _WIN32 + return new DXHandle(); +#else + return 0; +#endif +} + //================================================================================================== SurfacePool::SurfacePool(ushort width_, ushort height_, ushort count, const mfxFrameInfo &frameInfo, uchar bpp) @@ -85,7 +102,8 @@ SurfacePool::SurfacePool(ushort width_, ushort height_, ushort count, const mfxF surface.Info = frameInfo; surface.Data.Y = dataPtr; surface.Data.UV = dataPtr + width * height; - surface.Data.Pitch = width; + surface.Data.PitchLow = width & 0xFFFF; + surface.Data.PitchHigh = (width >> 16) & 0xFFFF; DBG(cout << "allocate surface " << (void*)&surface << ", Y = " << (void*)dataPtr << " (" << width << "x" << height << ")" << endl); } DBG(cout << "Allocated: " << endl @@ -112,7 +130,7 @@ ReadBitstream::ReadBitstream(const char *filename, size_t maxSize) : drain(false input.open(filename, std::ios::in | std::ios::binary); DBG(cout << "Open " << filename << " -> " << input.is_open() << std::endl); memset(&stream, 0, sizeof(stream)); - stream.MaxLength = maxSize; + stream.MaxLength = (mfxU32)maxSize; stream.Data = new mfxU8[stream.MaxLength]; CV_Assert(stream.Data); } @@ -139,7 +157,7 @@ bool ReadBitstream::read() input.read((char*)(stream.Data + stream.DataLength), stream.MaxLength - stream.DataLength); if (input.eof() || input.good()) { - mfxU32 bytesRead = input.gcount(); + mfxU32 bytesRead = (mfxU32)input.gcount(); if (bytesRead > 0) { stream.DataLength += bytesRead; @@ -157,7 +175,7 @@ WriteBitstream::WriteBitstream(const char * filename, size_t maxSize) output.open(filename, std::ios::out | std::ios::binary); DBG(cout << "BS Open " << filename << " -> " << output.is_open() << std::endl); memset(&stream, 0, sizeof(stream)); - stream.MaxLength = maxSize; + stream.MaxLength = (mfxU32)maxSize; stream.Data = new mfxU8[stream.MaxLength]; DBG(cout << "BS Allocate " << maxSize << " bytes (" << ((float)maxSize / (1 << 20)) << " Mb)" << endl); CV_Assert(stream.Data); diff --git a/modules/videoio/src/cap_mfx_common.hpp b/modules/videoio/src/cap_mfx_common.hpp index 1e97849bf3..f18eafe92f 100644 --- a/modules/videoio/src/cap_mfx_common.hpp +++ b/modules/videoio/src/cap_mfx_common.hpp @@ -168,7 +168,7 @@ inline void cleanup(T * &ptr) //================================================================================================== -struct Plugin +class Plugin { public: static Plugin * loadEncoderPlugin(MFXVideoSession &session, mfxU32 codecId) @@ -206,7 +206,7 @@ private: //================================================================================================== -struct ReadBitstream +class ReadBitstream { public: ReadBitstream(const char * filename, size_t maxSize = 10 * 1024 * 1024); @@ -225,7 +225,7 @@ public: //================================================================================================== -struct WriteBitstream +class WriteBitstream { public: WriteBitstream(const char * filename, size_t maxSize); @@ -268,7 +268,7 @@ private: SurfacePool(const SurfacePool &); SurfacePool &operator=(const SurfacePool &); public: - ushort width, height; + size_t width, height; size_t oneSize; cv::AutoBuffer buffers; std::vector surfaces; @@ -286,6 +286,7 @@ protected: // Linux specific +#ifdef __linux__ #include @@ -302,7 +303,26 @@ private: int file; }; -// TODO: Windows specific +#endif // __linux__ +// Windows specific +#ifdef _WIN32 + +#include +inline void sleep(unsigned long sec) { Sleep(1000 * sec); } + +class DXHandle : public DeviceHandler { +public: + DXHandle() {} + ~DXHandle() {} +private: + DXHandle(const DXHandle &); + DXHandle &operator=(const DXHandle &); + virtual bool initDeviceSession(MFXVideoSession &) { return true; } +}; + +#endif // _WIN32 + +DeviceHandler * createDeviceHandler(); #endif // MFXHELPER_H diff --git a/modules/videoio/src/cap_mfx_reader.cpp b/modules/videoio/src/cap_mfx_reader.cpp index b5c39cad50..c926611940 100644 --- a/modules/videoio/src/cap_mfx_reader.cpp +++ b/modules/videoio/src/cap_mfx_reader.cpp @@ -38,8 +38,7 @@ VideoCapture_IntelMFX::VideoCapture_IntelMFX(const cv::String &filename) mfxStatus res = MFX_ERR_NONE; // Init device and session - - deviceHandler = new VAHandle(); + deviceHandler = createDeviceHandler(); session = new MFXVideoSession(); if (!deviceHandler->init(*session)) { @@ -227,7 +226,6 @@ bool VideoCapture_IntelMFX::grabFrame() MSG(cerr << "MFX: Bad status: " << res << endl); return false; } - return false; } } diff --git a/modules/videoio/src/cap_mfx_writer.cpp b/modules/videoio/src/cap_mfx_writer.cpp index 6f8700a255..ccbf8e4a94 100644 --- a/modules/videoio/src/cap_mfx_writer.cpp +++ b/modules/videoio/src/cap_mfx_writer.cpp @@ -40,8 +40,7 @@ VideoWriter_IntelMFX::VideoWriter_IntelMFX(const String &filename, int _fourcc, } // Init device and session - - deviceHandler = new VAHandle(); + deviceHandler = createDeviceHandler(); session = new MFXVideoSession(); if (!deviceHandler->init(*session)) { @@ -71,7 +70,7 @@ VideoWriter_IntelMFX::VideoWriter_IntelMFX(const String &filename, int _fourcc, memset(¶ms, 0, sizeof(params)); params.mfx.CodecId = codecId; params.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED; - params.mfx.TargetKbps = frameSize.area() * fps / 500; // TODO: set in options + params.mfx.TargetKbps = (mfxU16)cvRound(frameSize.area() * fps / 500); // TODO: set in options params.mfx.RateControlMethod = MFX_RATECONTROL_VBR; params.mfx.FrameInfo.FrameRateExtN = cvRound(fps * 1000); params.mfx.FrameInfo.FrameRateExtD = 1000; @@ -80,10 +79,10 @@ VideoWriter_IntelMFX::VideoWriter_IntelMFX(const String &filename, int _fourcc, params.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; params.mfx.FrameInfo.CropX = 0; params.mfx.FrameInfo.CropY = 0; - params.mfx.FrameInfo.CropW = frameSize.width; - params.mfx.FrameInfo.CropH = frameSize.height; - params.mfx.FrameInfo.Width = alignSize(frameSize.width, 32); - params.mfx.FrameInfo.Height = alignSize(frameSize.height, 32); + params.mfx.FrameInfo.CropW = (mfxU16)frameSize.width; + params.mfx.FrameInfo.CropH = (mfxU16)frameSize.height; + params.mfx.FrameInfo.Width = (mfxU16)alignSize(frameSize.width, 32); + params.mfx.FrameInfo.Height = (mfxU16)alignSize(frameSize.height, 32); params.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; res = encoder->Query(¶ms, ¶ms); DBG(cout << "MFX Query: " << res << endl << params.mfx << params.mfx.FrameInfo); @@ -263,7 +262,6 @@ bool VideoWriter_IntelMFX::write_one(cv::InputArray bgr) MSG(cerr << "MFX: Bad status: " << res << endl); return false; } - return true; } }