Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
8b664d61
Commit
8b664d61
authored
Jun 20, 2017
by
Maksim Shabunin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8825 from mshabunin:media-sdk-support
parents
43b03b65
c06f3d63
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1063 additions
and
1 deletion
+1063
-1
CMakeLists.txt
CMakeLists.txt
+5
-0
OpenCVDetectMediaSDK.cmake
cmake/OpenCVDetectMediaSDK.cmake
+38
-0
OpenCVFindLibsVideo.cmake
cmake/OpenCVFindLibsVideo.cmake
+4
-0
cvconfig.h.in
cmake/templates/cvconfig.h.in
+3
-0
CMakeLists.txt
modules/videoio/CMakeLists.txt
+10
-0
videoio.hpp
modules/videoio/include/opencv2/videoio.hpp
+2
-1
cap.cpp
modules/videoio/src/cap.cpp
+23
-0
cap_mfx_common.cpp
modules/videoio/src/cap_mfx_common.cpp
+183
-0
cap_mfx_common.hpp
modules/videoio/src/cap_mfx_common.hpp
+0
-0
cap_mfx_reader.cpp
modules/videoio/src/cap_mfx_reader.cpp
+273
-0
cap_mfx_reader.hpp
modules/videoio/src/cap_mfx_reader.hpp
+41
-0
cap_mfx_writer.cpp
modules/videoio/src/cap_mfx_writer.cpp
+272
-0
cap_mfx_writer.hpp
modules/videoio/src/cap_mfx_writer.hpp
+48
-0
test_mfx.cpp
modules/videoio/test/test_mfx.cpp
+161
-0
No files found.
CMakeLists.txt
View file @
8b664d61
...
...
@@ -252,6 +252,7 @@ OCV_OPTION(WITH_IPP_A "Include Intel IPP_A 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_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
)
)
...
...
@@ -1228,6 +1229,10 @@ if(DEFINED WITH_INTELPERC)
status
(
" Intel PerC:"
HAVE_INTELPERC THEN
"YES"
ELSE NO
)
endif
(
DEFINED WITH_INTELPERC
)
if
(
DEFINED WITH_MFX
)
status
(
" Intel Media SDK:"
HAVE_MFX THEN
"YES (
${
MFX_LIBRARY
}
)"
ELSE NO
)
endif
()
if
(
DEFINED WITH_GPHOTO2
)
status
(
" gPhoto2:"
HAVE_GPHOTO2 THEN
"YES"
ELSE NO
)
endif
(
DEFINED WITH_GPHOTO2
)
...
...
cmake/OpenCVDetectMediaSDK.cmake
0 → 100644
View file @
8b664d61
set
(
root
"$ENV{MFX_HOME}"
)
find_path
(
MFX_INCLUDE mfxdefs.h PATHS
"
${
root
}
/include"
NO_DEFAULT_PATH
)
# TODO: ICC? MINGW? ARM? IOS?
if
(
WIN32
)
if
(
X86_64
)
set
(
arch
"x64"
)
else
()
set
(
arch
"win32"
)
endif
()
elseif
(
UNIX
)
set
(
arch
"lin_x64"
)
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
)
if
(
MFX_INCLUDE AND MFX_LIBRARY AND MFX_VA_LIBRARY AND MFX_VA_DRM_LIBRARY
)
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
)
endif
()
cmake/OpenCVFindLibsVideo.cmake
View file @
8b664d61
...
...
@@ -294,6 +294,10 @@ if(WITH_INTELPERC)
include
(
"
${
OpenCV_SOURCE_DIR
}
/cmake/OpenCVFindIntelPerCSDK.cmake"
)
endif
(
WITH_INTELPERC
)
if
(
WITH_MFX
)
include
(
"
${
OpenCV_SOURCE_DIR
}
/cmake/OpenCVDetectMediaSDK.cmake"
)
endif
()
# --- gPhoto2 ---
ocv_clear_vars
(
HAVE_GPHOTO2
)
if
(
WITH_GPHOTO2
)
...
...
cmake/templates/cvconfig.h.in
View file @
8b664d61
...
...
@@ -205,6 +205,9 @@
/* Intel VA-API/OpenCL */
#cmakedefine HAVE_VA_INTEL
/* Intel Media SDK */
#cmakedefine HAVE_MFX
/* Lapack */
#cmakedefine HAVE_LAPACK
...
...
modules/videoio/CMakeLists.txt
View file @
8b664d61
...
...
@@ -61,6 +61,16 @@ if(DEFINED WINRT AND NOT DEFINED WINRT_8_0 AND NOT DEFINED ENABLE_WINRT_MODE_NAT
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_winrt/MediaStreamSink.hpp
)
endif
()
if
(
HAVE_MFX
)
list
(
APPEND videoio_srcs
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_mfx_common.cpp
)
list
(
APPEND videoio_hdrs
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_mfx_common.hpp
)
list
(
APPEND videoio_srcs
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_mfx_reader.cpp
)
list
(
APPEND videoio_hdrs
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_mfx_reader.hpp
)
list
(
APPEND videoio_srcs
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_mfx_writer.cpp
)
list
(
APPEND videoio_hdrs
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_mfx_writer.hpp
)
list
(
APPEND VIDEOIO_LIBRARIES mfx
)
endif
()
if
(
WIN32 AND NOT ARM
)
list
(
APPEND videoio_srcs
${
CMAKE_CURRENT_LIST_DIR
}
/src/cap_cmu.cpp
)
endif
()
...
...
modules/videoio/include/opencv2/videoio.hpp
View file @
8b664d61
...
...
@@ -115,7 +115,8 @@ enum VideoCaptureAPIs {
CAP_FFMPEG
=
1900
,
//!< Open and record video file or stream using the FFMPEG library
CAP_IMAGES
=
2000
,
//!< OpenCV Image Sequence (e.g. img_%02d.jpg)
CAP_ARAVIS
=
2100
,
//!< Aravis SDK
CAP_OCV_MJPEG
=
2200
//!< Built-in MotionJPEG codec
CAP_OCV_MJPEG
=
2200
,
//!< Built-in MotionJPEG codec
CAP_INTEL_MFX
=
2300
//!< Intel MediaSDK
};
/** @brief %VideoCapture generic properties identifier.
...
...
modules/videoio/src/cap.cpp
View file @
8b664d61
...
...
@@ -43,6 +43,11 @@
#include "cap_intelperc.hpp"
#include "cap_dshow.hpp"
#ifdef HAVE_MFX
#include "cap_mfx_reader.hpp"
#include "cap_mfx_writer.hpp"
#endif
// All WinRT versions older than 8.0 should provide classes used for video support
#if defined(WINRT) && !defined(WINRT_8_0) && defined(__cplusplus_winrt)
# include "cap_winrt_capture.hpp"
...
...
@@ -525,6 +530,9 @@ static Ptr<IVideoCapture> IVideoCapture_create(const String& filename)
CV_CAP_ANY
,
#ifdef HAVE_GPHOTO2
CV_CAP_GPHOTO2
,
#endif
#ifdef HAVE_MFX
CAP_INTEL_MFX
,
#endif
-
1
,
-
1
};
...
...
@@ -543,6 +551,11 @@ static Ptr<IVideoCapture> IVideoCapture_create(const String& filename)
case
CV_CAP_GPHOTO2
:
capture
=
createGPhoto2Capture
(
filename
);
break
;
#endif
#ifdef HAVE_MFX
case
CAP_INTEL_MFX
:
capture
=
makePtr
<
VideoCapture_IntelMFX
>
(
filename
);
break
;
#endif
}
...
...
@@ -558,9 +571,19 @@ static Ptr<IVideoCapture> IVideoCapture_create(const String& filename)
static
Ptr
<
IVideoWriter
>
IVideoWriter_create
(
int
apiPreference
,
const
String
&
filename
,
int
_fourcc
,
double
fps
,
Size
frameSize
,
bool
isColor
)
{
Ptr
<
IVideoWriter
>
iwriter
;
#ifdef HAVE_MFX
if
(
apiPreference
==
CAP_INTEL_MFX
||
apiPreference
==
CAP_ANY
)
{
iwriter
=
VideoWriter_IntelMFX
::
create
(
filename
,
_fourcc
,
fps
,
frameSize
,
isColor
);
if
(
!
iwriter
.
empty
())
return
iwriter
;
}
#endif
if
(
(
apiPreference
==
CAP_OCV_MJPEG
||
apiPreference
==
CAP_ANY
)
&&
_fourcc
==
CV_FOURCC
(
'M'
,
'J'
,
'P'
,
'G'
)
)
iwriter
=
createMotionJpegWriter
(
filename
,
fps
,
frameSize
,
isColor
);
return
iwriter
;
}
...
...
modules/videoio/src/cap_mfx_common.cpp
0 → 100644
View file @
8b664d61
// 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
#include "cap_mfx_common.hpp"
// Linux specific
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using
namespace
std
;
using
namespace
cv
;
bool
DeviceHandler
::
init
(
MFXVideoSession
&
session
)
{
mfxStatus
res
=
MFX_ERR_NONE
;
mfxIMPL
impl
=
MFX_IMPL_AUTO
;
mfxVersion
ver
=
{
{
19
,
1
}
};
res
=
session
.
Init
(
impl
,
&
ver
);
DBG
(
cout
<<
"MFX SessionInit: "
<<
res
<<
endl
);
res
=
session
.
QueryIMPL
(
&
impl
);
DBG
(
cout
<<
"MFX QueryIMPL: "
<<
res
<<
" => "
<<
asHex
(
impl
)
<<
endl
);
res
=
session
.
QueryVersion
(
&
ver
);
DBG
(
cout
<<
"MFX QueryVersion: "
<<
res
<<
" => "
<<
ver
.
Major
<<
"."
<<
ver
.
Minor
<<
endl
);
if
(
res
!=
MFX_ERR_NONE
)
return
false
;
return
initDeviceSession
(
session
);
}
//==================================================================================================
VAHandle
::
VAHandle
()
{
// TODO: provide a way of modifying this path
const
string
filename
=
"/dev/dri/card0"
;
file
=
open
(
filename
.
c_str
(),
O_RDWR
);
if
(
file
<
0
)
CV_Error
(
Error
::
StsError
,
"Can't open file: "
+
filename
);
display
=
vaGetDisplayDRM
(
file
);
}
VAHandle
::~
VAHandle
()
{
if
(
display
)
{
vaTerminate
(
display
);
}
if
(
file
>=
0
)
{
close
(
file
);
}
}
bool
VAHandle
::
initDeviceSession
(
MFXVideoSession
&
session
)
{
int
majorVer
=
0
,
minorVer
=
0
;
VAStatus
va_res
=
vaInitialize
(
display
,
&
majorVer
,
&
minorVer
);
DBG
(
cout
<<
"vaInitialize: "
<<
va_res
<<
endl
<<
majorVer
<<
'.'
<<
minorVer
<<
endl
);
if
(
va_res
==
VA_STATUS_SUCCESS
)
{
mfxStatus
mfx_res
=
session
.
SetHandle
(
static_cast
<
mfxHandleType
>
(
MFX_HANDLE_VA_DISPLAY
),
display
);
DBG
(
cout
<<
"MFX SetHandle: "
<<
mfx_res
<<
endl
);
if
(
mfx_res
==
MFX_ERR_NONE
)
{
return
true
;
}
}
return
false
;
}
//==================================================================================================
SurfacePool
::
SurfacePool
(
ushort
width_
,
ushort
height_
,
ushort
count
,
const
mfxFrameInfo
&
frameInfo
,
uchar
bpp
)
:
width
(
alignSize
(
width_
,
32
)),
height
(
alignSize
(
height_
,
32
)),
oneSize
(
width
*
height
*
bpp
/
8
),
buffers
(
count
*
oneSize
),
surfaces
(
count
)
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
mfxFrameSurface1
&
surface
=
surfaces
[
i
];
uint8_t
*
dataPtr
=
buffers
+
oneSize
*
i
;
memset
(
&
surface
,
0
,
sizeof
(
mfxFrameSurface1
));
surface
.
Info
=
frameInfo
;
surface
.
Data
.
Y
=
dataPtr
;
surface
.
Data
.
UV
=
dataPtr
+
width
*
height
;
surface
.
Data
.
Pitch
=
width
;
DBG
(
cout
<<
"allocate surface "
<<
(
void
*
)
&
surface
<<
", Y = "
<<
(
void
*
)
dataPtr
<<
" ("
<<
width
<<
"x"
<<
height
<<
")"
<<
endl
);
}
DBG
(
cout
<<
"Allocated: "
<<
endl
<<
"- surface data: "
<<
buffers
.
size
()
<<
" bytes"
<<
endl
<<
"- surface headers: "
<<
surfaces
.
size
()
*
sizeof
(
mfxFrameSurface1
)
<<
" bytes"
<<
endl
);
}
SurfacePool
::~
SurfacePool
()
{
}
mfxFrameSurface1
*
SurfacePool
::
getFreeSurface
()
{
for
(
std
::
vector
<
mfxFrameSurface1
>::
iterator
i
=
surfaces
.
begin
();
i
!=
surfaces
.
end
();
++
i
)
if
(
!
i
->
Data
.
Locked
)
return
&
(
*
i
);
return
0
;
}
//==================================================================================================
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
.
Data
=
new
mfxU8
[
stream
.
MaxLength
];
CV_Assert
(
stream
.
Data
);
}
ReadBitstream
::~
ReadBitstream
()
{
delete
[]
stream
.
Data
;
}
bool
ReadBitstream
::
isOpened
()
const
{
return
input
.
is_open
();
}
bool
ReadBitstream
::
isDone
()
const
{
return
input
.
eof
();
}
bool
ReadBitstream
::
read
()
{
memmove
(
stream
.
Data
,
stream
.
Data
+
stream
.
DataOffset
,
stream
.
DataLength
);
stream
.
DataOffset
=
0
;
input
.
read
((
char
*
)(
stream
.
Data
+
stream
.
DataLength
),
stream
.
MaxLength
-
stream
.
DataLength
);
if
(
input
.
eof
()
||
input
.
good
())
{
mfxU32
bytesRead
=
input
.
gcount
();
if
(
bytesRead
>
0
)
{
stream
.
DataLength
+=
bytesRead
;
DBG
(
cout
<<
"read "
<<
bytesRead
<<
" bytes"
<<
endl
);
return
true
;
}
}
return
false
;
}
//==================================================================================================
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
.
Data
=
new
mfxU8
[
stream
.
MaxLength
];
DBG
(
cout
<<
"BS Allocate "
<<
maxSize
<<
" bytes ("
<<
((
float
)
maxSize
/
(
1
<<
20
))
<<
" Mb)"
<<
endl
);
CV_Assert
(
stream
.
Data
);
}
WriteBitstream
::~
WriteBitstream
()
{
delete
[]
stream
.
Data
;
}
bool
WriteBitstream
::
write
()
{
output
.
write
((
char
*
)(
stream
.
Data
+
stream
.
DataOffset
),
stream
.
DataLength
);
stream
.
DataLength
=
0
;
return
output
.
good
();
}
bool
WriteBitstream
::
isOpened
()
const
{
return
output
.
is_open
();
}
//==================================================================================================
modules/videoio/src/cap_mfx_common.hpp
0 → 100644
View file @
8b664d61
This diff is collapsed.
Click to expand it.
modules/videoio/src/cap_mfx_reader.cpp
0 → 100644
View file @
8b664d61
// 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
#include "cap_mfx_reader.hpp"
#include "opencv2/core/base.hpp"
#include "cap_mfx_common.hpp"
using
namespace
cv
;
using
namespace
std
;
inline
bool
hasExtension
(
const
String
&
filename
,
const
String
&
ext
)
{
if
(
filename
.
size
()
<=
ext
.
size
())
return
false
;
const
size_t
diff
=
filename
.
size
()
-
ext
.
size
();
const
size_t
found_at
=
filename
.
rfind
(
ext
);
return
found_at
==
diff
;
}
inline
mfxU32
determineCodecId
(
const
String
&
filename
)
{
if
(
hasExtension
(
filename
,
".h264"
)
||
hasExtension
(
filename
,
".264"
))
return
MFX_CODEC_AVC
;
else
if
(
hasExtension
(
filename
,
".mp2"
)
||
hasExtension
(
filename
,
".mpeg2"
))
return
MFX_CODEC_MPEG2
;
else
if
(
hasExtension
(
filename
,
".265"
)
||
hasExtension
(
filename
,
".hevc"
))
return
MFX_CODEC_HEVC
;
else
return
(
mfxU32
)
-
1
;
}
//==========================================================================
VideoCapture_IntelMFX
::
VideoCapture_IntelMFX
(
const
cv
::
String
&
filename
)
:
session
(
0
),
plugin
(
0
),
deviceHandler
(
0
),
bs
(
0
),
decoder
(
0
),
pool
(
0
),
outSurface
(
0
),
good
(
false
)
{
mfxStatus
res
=
MFX_ERR_NONE
;
// Init device and session
deviceHandler
=
new
VAHandle
();
session
=
new
MFXVideoSession
();
if
(
!
deviceHandler
->
init
(
*
session
))
{
MSG
(
cerr
<<
"MFX: Can't initialize session"
<<
endl
);
return
;
}
// Load appropriate plugin
mfxU32
codecId
=
determineCodecId
(
filename
);
if
(
codecId
==
(
mfxU32
)
-
1
)
{
MSG
(
cerr
<<
"MFX: Unsupported extension: "
<<
filename
<<
endl
);
return
;
}
plugin
=
Plugin
::
loadDecoderPlugin
(
*
session
,
codecId
);
if
(
plugin
&&
!
plugin
->
isGood
())
{
MSG
(
cerr
<<
"MFX: LoadPlugin failed for codec: "
<<
codecId
<<
" ("
<<
filename
<<
")"
<<
endl
);
return
;
}
// Read some content from file
bs
=
new
ReadBitstream
(
filename
.
c_str
());
if
(
!
bs
->
read
())
{
MSG
(
cerr
<<
"MFX: Failed to read bitstream"
<<
endl
);
return
;
}
// Create decoder and decode stream header
decoder
=
new
MFXVideoDECODE
(
*
session
);
mfxVideoParam
params
;
memset
(
&
params
,
0
,
sizeof
(
params
));
params
.
mfx
.
CodecId
=
codecId
;
params
.
IOPattern
=
MFX_IOPATTERN_OUT_SYSTEM_MEMORY
;
res
=
decoder
->
DecodeHeader
(
&
bs
->
stream
,
&
params
);
DBG
(
cout
<<
"DecodeHeader: "
<<
res
<<
endl
<<
params
.
mfx
<<
params
.
mfx
.
FrameInfo
<<
endl
);
if
(
res
<
MFX_ERR_NONE
)
{
MSG
(
cerr
<<
"MFX: Failed to decode stream header: "
<<
res
<<
endl
);
return
;
}
// Adjust parameters
res
=
decoder
->
Query
(
&
params
,
&
params
);
DBG
(
cout
<<
"MFX Query: "
<<
res
<<
endl
<<
params
.
mfx
<<
params
.
mfx
.
FrameInfo
);
CV_Assert
(
res
>=
MFX_ERR_NONE
);
// Init surface pool
pool
=
SurfacePool
::
create
(
decoder
,
params
);
if
(
!
pool
)
{
MSG
(
cerr
<<
"MFX: Failed to create surface pool"
<<
endl
);
return
;
}
// Init decoder
res
=
decoder
->
Init
(
&
params
);
DBG
(
cout
<<
"MFX Init: "
<<
res
<<
endl
<<
params
.
mfx
.
FrameInfo
);
if
(
res
<
MFX_ERR_NONE
)
{
MSG
(
cerr
<<
"MFX: Failed to init decoder: "
<<
res
<<
endl
);
return
;
}
good
=
true
;
}
VideoCapture_IntelMFX
::~
VideoCapture_IntelMFX
()
{
cleanup
(
plugin
);
cleanup
(
bs
);
cleanup
(
decoder
);
cleanup
(
pool
);
session
->
Close
();
cleanup
(
session
);
cleanup
(
deviceHandler
);
}
double
VideoCapture_IntelMFX
::
getProperty
(
int
)
const
{
MSG
(
cerr
<<
"MFX: getProperty() is not implemented"
<<
endl
);
return
0
;
}
bool
VideoCapture_IntelMFX
::
setProperty
(
int
,
double
)
{
MSG
(
cerr
<<
"MFX: setProperty() is not implemented"
<<
endl
);
return
false
;
}
bool
VideoCapture_IntelMFX
::
grabFrame
()
{
mfxStatus
res
;
mfxFrameSurface1
*
workSurface
=
0
;
mfxSyncPoint
sync
;
workSurface
=
pool
->
getFreeSurface
();
while
(
true
)
{
if
(
!
workSurface
)
{
// not enough surfaces
MSG
(
cerr
<<
"MFX: Failed to get free surface"
<<
endl
);
return
false
;
}
outSurface
=
0
;
res
=
decoder
->
DecodeFrameAsync
(
bs
->
drain
?
0
:
&
bs
->
stream
,
workSurface
,
(
mfxFrameSurface1
**
)
&
outSurface
,
&
sync
);
if
(
res
==
MFX_ERR_NONE
)
{
res
=
session
->
SyncOperation
(
sync
,
1000
);
// 1 sec, TODO: provide interface to modify timeout
if
(
res
==
MFX_ERR_NONE
)
{
// ready to retrieve
DBG
(
cout
<<
"Frame ready to retrieve"
<<
endl
);
return
true
;
}
else
{
MSG
(
cerr
<<
"MFX: Sync error: "
<<
res
<<
endl
);
return
false
;
}
}
else
if
(
res
==
MFX_ERR_MORE_DATA
)
{
if
(
bs
->
isDone
())
{
if
(
bs
->
drain
)
{
// finish
DBG
(
cout
<<
"Drain finished"
<<
endl
);
return
false
;
}
else
{
DBG
(
cout
<<
"Bitstream finished - Drain started"
<<
endl
);
bs
->
drain
=
true
;
continue
;
}
}
else
{
bool
read_res
=
bs
->
read
();
if
(
!
read_res
)
{
// failed to read
MSG
(
cerr
<<
"MFX: Bitstream read failure"
<<
endl
);
return
false
;
}
else
{
DBG
(
cout
<<
"Bitstream read success"
<<
endl
);
continue
;
}
}
}
else
if
(
res
==
MFX_ERR_MORE_SURFACE
)
{
DBG
(
cout
<<
"Getting another surface"
<<
endl
);
workSurface
=
pool
->
getFreeSurface
();
continue
;
}
else
if
(
res
==
MFX_WRN_DEVICE_BUSY
)
{
DBG
(
cout
<<
"Waiting for device"
<<
endl
);
sleep
(
1
);
continue
;
}
else
if
(
res
==
MFX_WRN_VIDEO_PARAM_CHANGED
)
{
DBG
(
cout
<<
"Video param changed"
<<
endl
);
continue
;
}
else
{
MSG
(
cerr
<<
"MFX: Bad status: "
<<
res
<<
endl
);
return
false
;
}
return
false
;
}
}
bool
VideoCapture_IntelMFX
::
retrieveFrame
(
int
,
OutputArray
out
)
{
if
(
!
outSurface
)
{
MSG
(
cerr
<<
"MFX: No frame ready to retrieve"
<<
endl
);
return
false
;
}
mfxFrameSurface1
*
s
=
(
mfxFrameSurface1
*
)
outSurface
;
mfxFrameInfo
&
info
=
s
->
Info
;
mfxFrameData
&
data
=
s
->
Data
;
const
int
cols
=
info
.
CropW
;
const
int
rows
=
info
.
CropH
;
Mat
nv12
(
rows
*
3
/
2
,
cols
,
CV_8UC1
);
Mat
Y
(
rows
,
cols
,
CV_8UC1
,
data
.
Y
,
data
.
Pitch
);
Mat
UV
(
rows
/
2
,
cols
,
CV_8UC1
,
data
.
UV
,
data
.
Pitch
);
Y
.
copyTo
(
Mat
(
nv12
,
Rect
(
0
,
0
,
cols
,
rows
)));
UV
.
copyTo
(
Mat
(
nv12
,
Rect
(
0
,
rows
,
cols
,
rows
/
2
)));
Mat
u_and_v
[
2
];
split
(
UV
.
reshape
(
2
),
u_and_v
);
cvtColor
(
nv12
,
out
,
COLOR_YUV2BGR_NV12
);
return
true
;
}
bool
VideoCapture_IntelMFX
::
isOpened
()
const
{
return
good
;
}
int
VideoCapture_IntelMFX
::
getCaptureDomain
()
{
return
CAP_INTEL_MFX
;
}
//==================================================================================================
modules/videoio/src/cap_mfx_reader.hpp
0 → 100644
View file @
8b664d61
// 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 CAP_MFX_HPP
#define CAP_MFX_HPP
#include "precomp.hpp"
class
MFXVideoSession
;
class
Plugin
;
class
DeviceHandler
;
class
ReadBitstream
;
class
SurfacePool
;
class
MFXVideoDECODE
;
class
VideoCapture_IntelMFX
:
public
cv
::
IVideoCapture
{
public
:
VideoCapture_IntelMFX
(
const
cv
::
String
&
filename
);
virtual
~
VideoCapture_IntelMFX
();
virtual
double
getProperty
(
int
)
const
;
virtual
bool
setProperty
(
int
,
double
);
virtual
bool
grabFrame
();
virtual
bool
retrieveFrame
(
int
,
cv
::
OutputArray
out
);
virtual
bool
isOpened
()
const
;
virtual
int
getCaptureDomain
();
private
:
MFXVideoSession
*
session
;
Plugin
*
plugin
;
DeviceHandler
*
deviceHandler
;
ReadBitstream
*
bs
;
MFXVideoDECODE
*
decoder
;
SurfacePool
*
pool
;
void
*
outSurface
;
bool
good
;
};
#endif
modules/videoio/src/cap_mfx_writer.cpp
0 → 100644
View file @
8b664d61
// 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
#include "cap_mfx_writer.hpp"
#include "opencv2/core/base.hpp"
#include "cap_mfx_common.hpp"
using
namespace
std
;
using
namespace
cv
;
inline
mfxU32
codecIdByFourCC
(
int
fourcc
)
{
if
(
fourcc
==
CC_X264
||
fourcc
==
CC_H264
||
fourcc
==
CC_AVC
)
return
MFX_CODEC_AVC
;
else
if
(
fourcc
==
CC_H265
||
fourcc
==
CC_HEVC
)
return
MFX_CODEC_HEVC
;
else
if
(
fourcc
==
CC_MPG2
)
return
MFX_CODEC_MPEG2
;
else
return
(
mfxU32
)
-
1
;
}
VideoWriter_IntelMFX
::
VideoWriter_IntelMFX
(
const
String
&
filename
,
int
_fourcc
,
double
fps
,
Size
frameSize_
,
bool
)
:
session
(
0
),
plugin
(
0
),
deviceHandler
(
0
),
bs
(
0
),
encoder
(
0
),
pool
(
0
),
frameSize
(
frameSize_
),
good
(
false
)
{
mfxStatus
res
=
MFX_ERR_NONE
;
if
(
frameSize
.
width
%
2
||
frameSize
.
height
%
2
)
{
MSG
(
cerr
<<
"MFX: Invalid frame size passed to encoder"
<<
endl
);
return
;
}
// Init device and session
deviceHandler
=
new
VAHandle
();
session
=
new
MFXVideoSession
();
if
(
!
deviceHandler
->
init
(
*
session
))
{
MSG
(
cerr
<<
"MFX: Can't initialize session"
<<
endl
);
return
;
}
// Load appropriate plugin
mfxU32
codecId
=
codecIdByFourCC
(
_fourcc
);
if
(
codecId
==
(
mfxU32
)
-
1
)
{
MSG
(
cerr
<<
"MFX: Unsupported FourCC: "
<<
FourCC
(
_fourcc
)
<<
endl
);
return
;
}
plugin
=
Plugin
::
loadEncoderPlugin
(
*
session
,
codecId
);
if
(
plugin
&&
!
plugin
->
isGood
())
{
MSG
(
cerr
<<
"MFX: LoadPlugin failed for codec: "
<<
codecId
<<
" ("
<<
FourCC
(
_fourcc
)
<<
")"
<<
endl
);
return
;
}
// Init encoder
encoder
=
new
MFXVideoENCODE
(
*
session
);
mfxVideoParam
params
;
memset
(
&
params
,
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
.
RateControlMethod
=
MFX_RATECONTROL_VBR
;
params
.
mfx
.
FrameInfo
.
FrameRateExtN
=
cvRound
(
fps
*
1000
);
params
.
mfx
.
FrameInfo
.
FrameRateExtD
=
1000
;
params
.
mfx
.
FrameInfo
.
FourCC
=
MFX_FOURCC_NV12
;
params
.
mfx
.
FrameInfo
.
ChromaFormat
=
MFX_CHROMAFORMAT_YUV420
;
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
.
IOPattern
=
MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
res
=
encoder
->
Query
(
&
params
,
&
params
);
DBG
(
cout
<<
"MFX Query: "
<<
res
<<
endl
<<
params
.
mfx
<<
params
.
mfx
.
FrameInfo
);
if
(
res
<
MFX_ERR_NONE
)
{
MSG
(
cerr
<<
"MFX: Query failed: "
<<
res
<<
endl
);
return
;
}
// Init surface pool
pool
=
SurfacePool
::
create
(
encoder
,
params
);
if
(
!
pool
)
{
MSG
(
cerr
<<
"MFX: Failed to create surface pool"
<<
endl
);
return
;
}
// Init encoder
res
=
encoder
->
Init
(
&
params
);
DBG
(
cout
<<
"MFX Init: "
<<
res
<<
endl
<<
params
.
mfx
.
FrameInfo
);
if
(
res
<
MFX_ERR_NONE
)
{
MSG
(
cerr
<<
"MFX: Failed to init encoder: "
<<
res
<<
endl
);
return
;
}
// Open output bitstream
{
mfxVideoParam
par
;
memset
(
&
par
,
0
,
sizeof
(
par
));
res
=
encoder
->
GetVideoParam
(
&
par
);
DBG
(
cout
<<
"MFX GetVideoParam: "
<<
res
<<
endl
<<
"requested "
<<
par
.
mfx
.
BufferSizeInKB
<<
" kB"
<<
endl
);
CV_Assert
(
res
>=
MFX_ERR_NONE
);
bs
=
new
WriteBitstream
(
filename
.
c_str
(),
par
.
mfx
.
BufferSizeInKB
*
1024
*
2
);
if
(
!
bs
->
isOpened
())
{
MSG
(
cerr
<<
"MFX: Failed to open output file: "
<<
filename
<<
endl
);
return
;
}
}
good
=
true
;
}
VideoWriter_IntelMFX
::~
VideoWriter_IntelMFX
()
{
if
(
isOpened
())
{
DBG
(
cout
<<
"====== Drain bitstream..."
<<
endl
);
Mat
dummy
;
while
(
write_one
(
dummy
))
{}
DBG
(
cout
<<
"====== Drain Finished"
<<
endl
);
}
cleanup
(
bs
);
cleanup
(
pool
);
cleanup
(
encoder
);
cleanup
(
plugin
);
cleanup
(
session
);
cleanup
(
deviceHandler
);
}
double
VideoWriter_IntelMFX
::
getProperty
(
int
)
const
{
MSG
(
cerr
<<
"MFX: getProperty() is not implemented"
<<
endl
);
return
0
;
}
bool
VideoWriter_IntelMFX
::
setProperty
(
int
,
double
)
{
MSG
(
cerr
<<
"MFX: setProperty() is not implemented"
<<
endl
);
return
false
;
}
bool
VideoWriter_IntelMFX
::
isOpened
()
const
{
return
good
;
}
void
VideoWriter_IntelMFX
::
write
(
cv
::
InputArray
input
)
{
write_one
(
input
);
}
inline
static
void
to_nv12
(
cv
::
InputArray
bgr
,
cv
::
Mat
&
Y
,
cv
::
Mat
&
UV
)
{
const
int
height
=
bgr
.
rows
();
const
int
width
=
bgr
.
cols
();
Mat
yuv
;
cvtColor
(
bgr
,
yuv
,
CV_BGR2YUV_I420
);
CV_Assert
(
yuv
.
isContinuous
());
Mat
Y_
(
Y
,
Rect
(
0
,
0
,
width
,
height
));
yuv
.
rowRange
(
0
,
height
).
copyTo
(
Y_
);
Mat
UV_planar
(
height
,
width
/
2
,
CV_8UC1
,
yuv
.
ptr
(
height
));
Mat
u_and_v
[
2
]
=
{
UV_planar
.
rowRange
(
0
,
height
/
2
),
UV_planar
.
rowRange
(
height
/
2
,
height
),
};
Mat
uv
;
cv
::
merge
(
u_and_v
,
2
,
uv
);
Mat
UV_
(
UV
,
Rect
(
0
,
0
,
width
,
height
/
2
));
uv
.
reshape
(
1
).
copyTo
(
UV_
);
}
bool
VideoWriter_IntelMFX
::
write_one
(
cv
::
InputArray
bgr
)
{
mfxStatus
res
;
mfxFrameSurface1
*
workSurface
=
0
;
mfxSyncPoint
sync
;
if
(
!
bgr
.
empty
()
&&
(
bgr
.
dims
()
!=
2
||
bgr
.
type
()
!=
CV_8UC3
||
bgr
.
size
()
!=
frameSize
))
{
MSG
(
cerr
<<
"MFX: invalid frame passed to encoder: "
<<
"dims/depth/cn="
<<
bgr
.
dims
()
<<
"/"
<<
bgr
.
depth
()
<<
"/"
<<
bgr
.
channels
()
<<
", size="
<<
bgr
.
size
()
<<
endl
);
return
false
;
}
if
(
!
bgr
.
empty
())
{
workSurface
=
pool
->
getFreeSurface
();
if
(
!
workSurface
)
{
// not enough surfaces
MSG
(
cerr
<<
"MFX: Failed to get free surface"
<<
endl
);
return
false
;
}
const
int
rows
=
workSurface
->
Info
.
Height
;
const
int
cols
=
workSurface
->
Info
.
Width
;
Mat
Y
(
rows
,
cols
,
CV_8UC1
,
workSurface
->
Data
.
Y
,
workSurface
->
Data
.
Pitch
);
Mat
UV
(
rows
/
2
,
cols
,
CV_8UC1
,
workSurface
->
Data
.
UV
,
workSurface
->
Data
.
Pitch
);
to_nv12
(
bgr
,
Y
,
UV
);
CV_Assert
(
Y
.
ptr
()
==
workSurface
->
Data
.
Y
);
CV_Assert
(
UV
.
ptr
()
==
workSurface
->
Data
.
UV
);
}
while
(
true
)
{
outSurface
=
0
;
DBG
(
cout
<<
"Calling with surface: "
<<
workSurface
<<
endl
);
res
=
encoder
->
EncodeFrameAsync
(
NULL
,
workSurface
,
&
bs
->
stream
,
&
sync
);
if
(
res
==
MFX_ERR_NONE
)
{
res
=
session
->
SyncOperation
(
sync
,
1000
);
// 1 sec, TODO: provide interface to modify timeout
if
(
res
==
MFX_ERR_NONE
)
{
// ready to write
if
(
!
bs
->
write
())
{
MSG
(
cerr
<<
"MFX: Failed to write bitstream"
<<
endl
);
return
false
;
}
else
{
DBG
(
cout
<<
"Write bitstream"
<<
endl
);
return
true
;
}
}
else
{
MSG
(
cerr
<<
"MFX: Sync error: "
<<
res
<<
endl
);
return
false
;
}
}
else
if
(
res
==
MFX_ERR_MORE_DATA
)
{
DBG
(
cout
<<
"ERR_MORE_DATA"
<<
endl
);
return
false
;
}
else
if
(
res
==
MFX_WRN_DEVICE_BUSY
)
{
DBG
(
cout
<<
"Waiting for device"
<<
endl
);
sleep
(
1
);
continue
;
}
else
{
MSG
(
cerr
<<
"MFX: Bad status: "
<<
res
<<
endl
);
return
false
;
}
return
true
;
}
}
Ptr
<
VideoWriter_IntelMFX
>
VideoWriter_IntelMFX
::
create
(
const
String
&
filename
,
int
_fourcc
,
double
fps
,
Size
frameSize
,
bool
isColor
)
{
if
(
codecIdByFourCC
(
_fourcc
)
>
0
)
{
Ptr
<
VideoWriter_IntelMFX
>
a
=
makePtr
<
VideoWriter_IntelMFX
>
(
filename
,
_fourcc
,
fps
,
frameSize
,
isColor
);
if
(
a
->
isOpened
())
return
a
;
}
return
Ptr
<
VideoWriter_IntelMFX
>
();
}
modules/videoio/src/cap_mfx_writer.hpp
0 → 100644
View file @
8b664d61
// 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 CAP_MFX_WRITER_HPP
#define CAP_MFX_WRITER_HPP
#include "precomp.hpp"
class
MFXVideoSession
;
class
Plugin
;
class
DeviceHandler
;
class
WriteBitstream
;
class
SurfacePool
;
class
MFXVideoDECODE
;
class
MFXVideoENCODE
;
class
VideoWriter_IntelMFX
:
public
cv
::
IVideoWriter
{
public
:
VideoWriter_IntelMFX
(
const
cv
::
String
&
filename
,
int
_fourcc
,
double
fps
,
cv
::
Size
frameSize
,
bool
isColor
);
virtual
~
VideoWriter_IntelMFX
();
virtual
double
getProperty
(
int
)
const
;
virtual
bool
setProperty
(
int
,
double
);
virtual
bool
isOpened
()
const
;
virtual
void
write
(
cv
::
InputArray
input
);
static
cv
::
Ptr
<
VideoWriter_IntelMFX
>
create
(
const
cv
::
String
&
filename
,
int
_fourcc
,
double
fps
,
cv
::
Size
frameSize
,
bool
isColor
);
protected
:
bool
write_one
(
cv
::
InputArray
bgr
);
private
:
VideoWriter_IntelMFX
(
const
VideoWriter_IntelMFX
&
);
VideoWriter_IntelMFX
&
operator
=
(
const
VideoWriter_IntelMFX
&
);
private
:
MFXVideoSession
*
session
;
Plugin
*
plugin
;
DeviceHandler
*
deviceHandler
;
WriteBitstream
*
bs
;
MFXVideoENCODE
*
encoder
;
SurfacePool
*
pool
;
void
*
outSurface
;
cv
::
Size
frameSize
;
bool
good
;
};
#endif // CAP_MFX_WRITER_HPP
modules/videoio/test/test_mfx.cpp
0 → 100644
View file @
8b664d61
// 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
#include "test_precomp.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include <sstream>
#include <queue>
#include <cstdio>
#ifdef HAVE_MFX
using
namespace
cv
;
using
namespace
std
;
using
namespace
std
::
tr1
;
TEST
(
Videoio_MFX
,
read_invalid
)
{
VideoCapture
cap
;
ASSERT_NO_THROW
(
cap
.
open
(
"nonexistent-file"
,
CAP_INTEL_MFX
));
ASSERT_FALSE
(
cap
.
isOpened
());
Mat
img
;
ASSERT_NO_THROW
(
cap
>>
img
);
ASSERT_TRUE
(
img
.
empty
());
}
TEST
(
Videoio_MFX
,
write_invalid
)
{
const
string
filename
=
cv
::
tempfile
(
".264"
);
VideoWriter
writer
;
bool
res
;
ASSERT_NO_THROW
(
res
=
writer
.
open
(
CAP_INTEL_MFX
,
filename
,
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
),
1
,
Size
(
641
,
480
),
true
));
EXPECT_FALSE
(
res
);
EXPECT_FALSE
(
writer
.
isOpened
());
ASSERT_NO_THROW
(
res
=
writer
.
open
(
CAP_INTEL_MFX
,
filename
,
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
),
1
,
Size
(
640
,
481
),
true
));
EXPECT_FALSE
(
res
);
EXPECT_FALSE
(
writer
.
isOpened
());
ASSERT_NO_THROW
(
res
=
writer
.
open
(
CAP_INTEL_MFX
,
filename
,
VideoWriter
::
fourcc
(
'A'
,
'B'
,
'C'
,
'D'
),
1
,
Size
(
640
,
480
),
true
));
EXPECT_FALSE
(
res
);
EXPECT_FALSE
(
writer
.
isOpened
());
ASSERT_NO_THROW
(
res
=
writer
.
open
(
CAP_INTEL_MFX
,
String
(),
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
),
1
,
Size
(
640
,
480
),
true
));
EXPECT_FALSE
(
res
);
EXPECT_FALSE
(
writer
.
isOpened
());
ASSERT_NO_THROW
(
res
=
writer
.
open
(
CAP_INTEL_MFX
,
filename
,
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
),
0
,
Size
(
640
,
480
),
true
));
EXPECT_FALSE
(
res
);
EXPECT_FALSE
(
writer
.
isOpened
());
ASSERT_NO_THROW
(
res
=
writer
.
open
(
CAP_INTEL_MFX
,
filename
,
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
),
30
,
Size
(
640
,
480
),
true
));
ASSERT_TRUE
(
res
);
ASSERT_TRUE
(
writer
.
isOpened
());
Mat
t
;
// write some bad frames
t
=
Mat
(
Size
(
1024
,
768
),
CV_8UC3
);
EXPECT_NO_THROW
(
writer
<<
t
);
t
=
Mat
(
Size
(
320
,
240
),
CV_8UC3
);
EXPECT_NO_THROW
(
writer
<<
t
);
t
=
Mat
(
Size
(
640
,
480
),
CV_8UC2
);
EXPECT_NO_THROW
(
writer
<<
t
);
// cleanup
ASSERT_NO_THROW
(
writer
.
release
());
remove
(
filename
.
c_str
());
}
//==================================================================================================
const
int
FRAME_COUNT
=
20
;
inline
void
generateFrame
(
int
i
,
Mat
&
frame
)
{
frame
=
0
;
ostringstream
buf
;
buf
<<
"Frame "
<<
setw
(
2
)
<<
setfill
(
'0'
)
<<
i
+
1
;
int
baseLine
=
0
;
Size
box
=
getTextSize
(
buf
.
str
(),
FONT_HERSHEY_COMPLEX
,
2
,
5
,
&
baseLine
);
putText
(
frame
,
buf
.
str
(),
Point
((
frame
.
cols
-
box
.
width
)
/
2
,
(
frame
.
rows
-
box
.
height
)
/
2
+
baseLine
),
FONT_HERSHEY_COMPLEX
,
2
,
Scalar
(
255
,
255
,
255
),
5
,
LINE_AA
);
Point
p
(
i
*
frame
.
cols
/
(
FRAME_COUNT
-
1
),
i
*
frame
.
rows
/
(
FRAME_COUNT
-
1
));
circle
(
frame
,
p
,
20
,
Scalar
(
200
,
25
,
55
),
5
,
LINE_AA
);
}
inline
int
fourccByExt
(
const
String
&
ext
)
{
if
(
ext
==
".mpeg2"
)
return
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'G'
,
'2'
);
else
if
(
ext
==
".264"
)
return
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
);
else
if
(
ext
==
".265"
)
return
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'5'
);
return
-
1
;
}
//==================================================================================================
typedef
tuple
<
Size
,
double
,
const
char
*>
Size_FPS_Ext
;
typedef
testing
::
TestWithParam
<
Size_FPS_Ext
>
Videoio_MFX
;
TEST_P
(
Videoio_MFX
,
read_write_raw
)
{
const
Size
FRAME_SIZE
=
get
<
0
>
(
GetParam
());
const
double
FPS
=
get
<
1
>
(
GetParam
());
const
char
*
ext
=
get
<
2
>
(
GetParam
());
const
String
filename
=
cv
::
tempfile
(
ext
);
const
int
fourcc
=
fourccByExt
(
ext
);
bool
isColor
=
true
;
queue
<
Mat
>
goodFrames
;
// Write video
VideoWriter
writer
;
writer
.
open
(
CAP_INTEL_MFX
,
filename
,
fourcc
,
FPS
,
FRAME_SIZE
,
isColor
);
ASSERT_TRUE
(
writer
.
isOpened
());
Mat
frame
(
FRAME_SIZE
,
CV_8UC3
);
for
(
int
i
=
0
;
i
<
FRAME_COUNT
;
++
i
)
{
generateFrame
(
i
,
frame
);
goodFrames
.
push
(
frame
.
clone
());
writer
<<
frame
;
}
writer
.
release
();
EXPECT_FALSE
(
writer
.
isOpened
());
// Read video
VideoCapture
cap
;
cap
.
open
(
filename
,
CAP_INTEL_MFX
);
ASSERT_TRUE
(
cap
.
isOpened
());
for
(
int
i
=
0
;
i
<
FRAME_COUNT
;
++
i
)
{
ASSERT_TRUE
(
cap
.
read
(
frame
));
ASSERT_FALSE
(
frame
.
empty
());
ASSERT_EQ
(
FRAME_SIZE
.
width
,
frame
.
cols
);
ASSERT_EQ
(
FRAME_SIZE
.
height
,
frame
.
rows
);
// verify
ASSERT_NE
(
goodFrames
.
size
(),
0u
);
const
Mat
&
goodFrame
=
goodFrames
.
front
();
EXPECT_EQ
(
goodFrame
.
depth
(),
frame
.
depth
());
EXPECT_EQ
(
goodFrame
.
channels
(),
frame
.
channels
());
EXPECT_EQ
(
goodFrame
.
type
(),
frame
.
type
());
double
psnr
=
cvtest
::
PSNR
(
goodFrame
,
frame
);
if
(
fourcc
==
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'G'
,
'2'
))
EXPECT_GT
(
psnr
,
37
);
// experimentally chosen value
else
EXPECT_GT
(
psnr
,
43
);
// experimentally chosen value
goodFrames
.
pop
();
}
EXPECT_FALSE
(
cap
.
read
(
frame
));
EXPECT_TRUE
(
frame
.
empty
());
cap
.
release
();
EXPECT_FALSE
(
cap
.
isOpened
());
remove
(
filename
.
c_str
());
}
INSTANTIATE_TEST_CASE_P
(
videoio
,
Videoio_MFX
,
testing
::
Combine
(
testing
::
Values
(
Size
(
640
,
480
),
Size
(
638
,
478
),
Size
(
636
,
476
),
Size
(
1920
,
1080
)),
testing
::
Values
(
1
,
30
,
100
),
testing
::
Values
(
".mpeg2"
,
".264"
,
".265"
)));
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment