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
db48f7b5
Commit
db48f7b5
authored
Jun 27, 2018
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #11804 from mshabunin:gst-sample
parents
75ee536d
fe20fa83
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
287 additions
and
358 deletions
+287
-358
gstreamer_pipeline.cpp
samples/cpp/gstreamer_pipeline.cpp
+287
-358
No files found.
samples/cpp/gstreamer_pipeline.cpp
View file @
db48f7b5
...
...
@@ -4,444 +4,373 @@
#include "opencv2/highgui.hpp"
#include <string>
#include <iostream>
#include <map>
using
namespace
std
;
using
namespace
cv
;
class
GStreamerPipeline
{
public
:
// Preprocessing arguments command line
GStreamerPipeline
(
int
argc
,
char
*
argv
[])
{
const
string
keys
=
"{h help usage ? | | print help messages }"
"{m mode | | coding mode (supported: encode, decode) }"
"{p pipeline |default | pipeline name (supported: 'default', 'gst-basic', 'gst-vaapi', 'gst-libav', 'ffmpeg') }"
"{cd codec |h264 | codec name (supported: 'h264', 'h265', 'mpeg2', 'mpeg4', 'mjpeg', 'vp8') }"
"{f file path | | path to file }"
"{vr resolution |720p | video resolution for encoding (supported: '720p', '1080p', '4k') }"
"{fps |30 | fix frame per second for encoding (supported: fps > 0) }"
"{fm fast | | fast measure fps }"
;
cmd_parser
=
new
CommandLineParser
(
argc
,
argv
,
keys
);
cmd_parser
->
about
(
"This program shows how to read a video file with GStreamer pipeline with OpenCV."
);
//================================================================================
if
(
cmd_parser
->
has
(
"help"
))
template
<
typename
M
>
inline
typename
M
::
mapped_type
getValue
(
const
M
&
dict
,
const
typename
M
::
key_type
&
key
,
const
string
&
errorMessage
)
{
typename
M
::
const_iterator
it
=
dict
.
find
(
key
);
if
(
it
==
dict
.
end
())
{
cmd_parser
->
printMessage
();
CV_Error
(
Error
::
StsBadArg
,
"Called help."
);
CV_Error
(
Error
::
StsBadArg
,
errorMessage
);
}
return
it
->
second
;
}
fast_measure
=
cmd_parser
->
has
(
"fast"
);
// fast measure fps
fix_fps
=
cmd_parser
->
get
<
int
>
(
"fps"
);
// fixed frame per second
pipeline
=
cmd_parser
->
get
<
string
>
(
"pipeline"
),
// gstreamer pipeline type
mode
=
cmd_parser
->
get
<
string
>
(
"mode"
),
// coding mode
codec
=
cmd_parser
->
get
<
string
>
(
"codec"
),
// codec type
file_name
=
cmd_parser
->
get
<
string
>
(
"file"
),
// path to videofile
resolution
=
cmd_parser
->
get
<
string
>
(
"resolution"
);
// video resolution
inline
map
<
string
,
Size
>
sizeByResolution
()
{
map
<
string
,
Size
>
res
;
res
[
"720p"
]
=
Size
(
1280
,
720
);
res
[
"1080p"
]
=
Size
(
1920
,
1080
);
res
[
"4k"
]
=
Size
(
3840
,
2160
);
return
res
;
}
size_t
found
=
file_name
.
rfind
(
"."
);
if
(
found
!=
string
::
npos
)
{
container
=
file_name
.
substr
(
found
+
1
);
// container type
}
else
{
CV_Error
(
Error
::
StsBadArg
,
"Can not parse container extension."
);
}
inline
map
<
string
,
int
>
fourccByCodec
()
{
map
<
string
,
int
>
res
;
res
[
"h264"
]
=
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
);
res
[
"h265"
]
=
VideoWriter
::
fourcc
(
'H'
,
'E'
,
'V'
,
'C'
);
res
[
"mpeg2"
]
=
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'E'
,
'G'
);
res
[
"mpeg4"
]
=
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'4'
,
'2'
);
res
[
"mjpeg"
]
=
VideoWriter
::
fourcc
(
'M'
,
'J'
,
'P'
,
'G'
);
res
[
"vp8"
]
=
VideoWriter
::
fourcc
(
'V'
,
'P'
,
'8'
,
'0'
);
return
res
;
}
if
(
!
cmd_parser
->
check
())
{
cmd_parser
->
printErrors
();
CV_Error
(
Error
::
StsBadArg
,
"Failed parse arguments."
);
}
}
inline
map
<
string
,
string
>
defaultEncodeElementByCodec
()
{
map
<
string
,
string
>
res
;
res
[
"h264"
]
=
"x264enc"
;
res
[
"h265"
]
=
"x265enc"
;
res
[
"mpeg2"
]
=
"mpeg2enc"
;
res
[
"mjpeg"
]
=
"jpegenc"
;
res
[
"vp8"
]
=
"vp8enc"
;
return
res
;
}
~
GStreamerPipeline
()
{
delete
cmd_parser
;
}
inline
map
<
string
,
string
>
VAAPIEncodeElementByCodec
()
{
map
<
string
,
string
>
res
;
res
[
"h264"
]
=
"parsebin ! vaapih264enc"
;
res
[
"h265"
]
=
"parsebin ! vaapih265enc"
;
res
[
"mpeg2"
]
=
"parsebin ! vaapimpeg2enc"
;
res
[
"mjpeg"
]
=
"parsebin ! vaapijpegenc"
;
res
[
"vp8"
]
=
"parsebin ! vaapivp8enc"
;
return
res
;
}
// Start pipeline
int
run
()
{
if
(
mode
==
"decode"
)
{
if
(
createDecodePipeline
()
<
0
)
return
-
1
;
}
else
if
(
mode
==
"encode"
)
{
if
(
createEncodePipeline
()
<
0
)
return
-
1
;
}
else
{
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
}
cout
<<
"_____________________________________"
<<
endl
;
cout
<<
"Pipeline "
<<
mode
<<
":"
<<
endl
;
cout
<<
stream_pipeline
.
str
()
<<
endl
;
// Choose a show video or only measure fps
cout
<<
"_____________________________________"
<<
endl
;
cout
<<
"Start measure frame per seconds (fps)"
<<
endl
;
cout
<<
"Loading ..."
<<
endl
;
inline
map
<
string
,
string
>
mfxDecodeElementByCodec
()
{
map
<
string
,
string
>
res
;
res
[
"h264"
]
=
"parsebin ! mfxh264dec"
;
res
[
"h265"
]
=
"parsebin ! mfxhevcdec"
;
res
[
"mpeg2"
]
=
"parsebin ! mfxmpeg2dec"
;
res
[
"mjpeg"
]
=
"parsebin ! mfxjpegdec"
;
return
res
;
}
vector
<
double
>
tick_counts
;
inline
map
<
string
,
string
>
mfxEncodeElementByCodec
()
{
map
<
string
,
string
>
res
;
res
[
"h264"
]
=
"mfxh264enc"
;
res
[
"h265"
]
=
"mfxhevcenc"
;
res
[
"mpeg2"
]
=
"mfxmpeg2enc"
;
res
[
"mjpeg"
]
=
"mfxjpegenc"
;
return
res
;
}
cout
<<
"Start "
<<
mode
<<
": "
<<
file_name
;
cout
<<
" ("
<<
pipeline
<<
")"
<<
endl
;
inline
map
<
string
,
string
>
libavDecodeElementByCodec
()
{
map
<
string
,
string
>
res
;
res
[
"h264"
]
=
"parsebin ! avdec_h264"
;
res
[
"h265"
]
=
"parsebin ! avdec_h265"
;
res
[
"mpeg2"
]
=
"parsebin ! avdec_mpeg2video"
;
res
[
"mpeg4"
]
=
"parsebin ! avdec_mpeg4"
;
res
[
"mjpeg"
]
=
"parsebin ! avdec_mjpeg"
;
res
[
"vp8"
]
=
"parsebin ! avdec_vp8"
;
return
res
;
}
while
(
true
)
{
int64
temp_count_tick
=
0
;
if
(
mode
==
"decode"
)
{
Mat
frame
;
temp_count_tick
=
getTickCount
();
cap
>>
frame
;
temp_count_tick
=
getTickCount
()
-
temp_count_tick
;
if
(
frame
.
empty
())
{
break
;
}
}
else
if
(
mode
==
"encode"
)
{
Mat
element
;
while
(
!
cap
.
grab
());
cap
.
retrieve
(
element
);
temp_count_tick
=
getTickCount
();
wrt
<<
element
;
temp_count_tick
=
getTickCount
()
-
temp_count_tick
;
}
inline
map
<
string
,
string
>
libavEncodeElementByCodec
()
{
map
<
string
,
string
>
res
;
res
[
"h264"
]
=
"avenc_h264"
;
res
[
"h265"
]
=
"avenc_h265"
;
res
[
"mpeg2"
]
=
"avenc_mpeg2video"
;
res
[
"mpeg4"
]
=
"avenc_mpeg4"
;
res
[
"mjpeg"
]
=
"avenc_mjpeg"
;
res
[
"vp8"
]
=
"avenc_vp8"
;
return
res
;
}
tick_counts
.
push_back
(
static_cast
<
double
>
(
temp_count_tick
));
if
(((
mode
==
"decode"
)
&&
fast_measure
&&
(
tick_counts
.
size
()
>
1e3
))
||
((
mode
==
"encode"
)
&&
(
tick_counts
.
size
()
>
3e3
))
||
((
mode
==
"encode"
)
&&
fast_measure
&&
(
tick_counts
.
size
()
>
1e2
)))
{
break
;
}
inline
map
<
string
,
string
>
demuxPluginByContainer
()
{
map
<
string
,
string
>
res
;
res
[
"avi"
]
=
"avidemux"
;
res
[
"mp4"
]
=
"qtdemux"
;
res
[
"mov"
]
=
"qtdemux"
;
res
[
"mkv"
]
=
"matroskademux"
;
return
res
;
}
}
double
time_fps
=
sum
(
tick_counts
)[
0
]
/
getTickFrequency
();
inline
map
<
string
,
string
>
muxPluginByContainer
()
{
map
<
string
,
string
>
res
;
res
[
"avi"
]
=
"avimux"
;
res
[
"mp4"
]
=
"qtmux"
;
res
[
"mov"
]
=
"qtmux"
;
res
[
"mkv"
]
=
"matroskamux"
;
return
res
;
}
if
(
tick_counts
.
size
()
!=
0
)
{
cout
<<
"Finished: "
<<
tick_counts
.
size
()
<<
" in "
<<
time_fps
<<
" sec ~ "
;
cout
<<
tick_counts
.
size
()
/
time_fps
<<
" fps "
<<
endl
;
}
else
{
cout
<<
"Failed "
<<
mode
<<
": "
<<
file_name
;
cout
<<
" ("
<<
pipeline
<<
")"
<<
endl
;
return
-
1
;
}
return
0
;
}
//================================================================================
// Free video resource
void
close
()
inline
string
containerByName
(
const
string
&
name
)
{
size_t
found
=
name
.
rfind
(
"."
);
if
(
found
!=
string
::
npos
)
{
cap
.
release
();
wrt
.
release
();
return
name
.
substr
(
found
+
1
);
// container type
}
return
string
();
}
private
:
// Choose the constructed GStreamer pipeline for decode
int
createDecodePipeline
()
{
if
(
pipeline
==
"default"
)
{
cap
=
VideoCapture
(
file_name
,
CAP_GSTREAMER
);
}
else
if
(
pipeline
.
find
(
"gst"
)
==
0
)
{
stream_pipeline
<<
"filesrc location=
\"
"
<<
file_name
<<
"
\"
"
;
stream_pipeline
<<
" ! "
<<
getGstMuxPlugin
();
//================================================================================
if
(
pipeline
.
find
(
"basic"
)
==
4
)
{
stream_pipeline
<<
getGstDefaultCodePlugin
();
}
else
if
(
pipeline
.
find
(
"vaapi1710"
)
==
4
)
{
stream_pipeline
<<
getGstVaapiCodePlugin
();
}
else
if
(
pipeline
.
find
(
"libav"
)
==
4
)
{
stream_pipeline
<<
getGstAvCodePlugin
();
}
inline
Ptr
<
VideoCapture
>
createCapture
(
const
string
&
backend
,
const
string
&
file_name
,
const
string
&
codec
)
{
if
(
backend
==
"gst-default"
)
{
cout
<<
"Created GStreamer capture ( "
<<
file_name
<<
" )"
<<
endl
;
return
makePtr
<
VideoCapture
>
(
file_name
,
CAP_GSTREAMER
);
}
else
if
(
backend
.
find
(
"gst"
)
==
0
)
{
ostringstream
line
;
line
<<
"filesrc location=
\"
"
<<
file_name
<<
"
\"
"
;
line
<<
" ! "
;
line
<<
getValue
(
demuxPluginByContainer
(),
containerByName
(
file_name
),
"Invalid container"
);
line
<<
" ! "
;
if
(
backend
.
find
(
"basic"
)
==
4
)
line
<<
"decodebin"
;
else
if
(
backend
.
find
(
"vaapi"
)
==
4
)
line
<<
"vaapidecodebin"
;
else
if
(
backend
.
find
(
"libav"
)
==
4
)
line
<<
getValue
(
libavDecodeElementByCodec
(),
codec
,
"Invalid codec"
);
else
if
(
backend
.
find
(
"mfx"
)
==
4
)
line
<<
getValue
(
mfxDecodeElementByCodec
(),
codec
,
"Invalid or unsupported codec"
);
else
{
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
}
stream_pipeline
<<
" ! videoconvert n-threads="
<<
getNumThreads
();
stream_pipeline
<<
" ! appsink sync=false"
;
cap
=
VideoCapture
(
stream_pipeline
.
str
(),
CAP_GSTREAMER
);
}
else
if
(
pipeline
==
"ffmpeg"
)
{
cap
=
VideoCapture
(
file_name
,
CAP_FFMPEG
);
stream_pipeline
<<
"default pipeline for ffmpeg"
<<
endl
;
return
Ptr
<
VideoCapture
>
();
line
<<
" ! videoconvert n-threads="
<<
getNumThreads
();
line
<<
" ! appsink sync=false"
;
cout
<<
"Created GStreamer capture ( "
<<
line
.
str
()
<<
" )"
<<
endl
;
return
makePtr
<
VideoCapture
>
(
line
.
str
(),
CAP_GSTREAMER
);
}
else
else
if
(
backend
==
"ffmpeg"
)
{
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
}
return
0
;
cout
<<
"Created FFmpeg capture ( "
<<
file_name
<<
" )"
<<
endl
;
return
makePtr
<
VideoCapture
>
(
file_name
,
CAP_FFMPEG
);
}
return
Ptr
<
VideoCapture
>
();
}
// Choose the constructed GStreamer pipeline for encode
int
createEncodePipeline
()
{
if
(
checkConfiguration
()
<
0
)
return
-
1
;
ostringstream
test_pipeline
;
test_pipeline
<<
"videotestsrc pattern=smpte"
;
test_pipeline
<<
" ! video/x-raw, "
<<
getVideoSettings
();
test_pipeline
<<
" ! appsink sync=false"
;
cap
=
VideoCapture
(
test_pipeline
.
str
(),
CAP_GSTREAMER
);
if
(
pipeline
==
"default"
)
{
wrt
=
VideoWriter
(
file_name
,
CAP_GSTREAMER
,
getFourccCode
(),
fix_fps
,
fix_size
,
true
);
}
else
if
(
pipeline
.
find
(
"gst"
)
==
0
)
{
stream_pipeline
<<
"appsrc ! videoconvert n-threads="
<<
getNumThreads
()
<<
" ! "
;
inline
Ptr
<
VideoCapture
>
createSynthSource
(
Size
sz
,
unsigned
fps
)
{
ostringstream
line
;
line
<<
"videotestsrc pattern=smpte"
;
line
<<
" ! video/x-raw"
;
line
<<
",width="
<<
sz
.
width
<<
",height="
<<
sz
.
height
;
if
(
fps
>
0
)
line
<<
",framerate="
<<
fps
<<
"/1"
;
line
<<
" ! appsink sync=false"
;
cout
<<
"Created synthetic video source ( "
<<
line
.
str
()
<<
" )"
<<
endl
;
return
makePtr
<
VideoCapture
>
(
line
.
str
(),
CAP_GSTREAMER
);
}
if
(
pipeline
.
find
(
"basic"
)
==
4
)
{
stream_pipeline
<<
getGstDefaultCodePlugin
();
}
else
if
(
pipeline
.
find
(
"vaapi1710"
)
==
4
)
{
stream_pipeline
<<
getGstVaapiCodePlugin
();
}
else
if
(
pipeline
.
find
(
"libav"
)
==
4
)
{
stream_pipeline
<<
getGstAvCodePlugin
();
}
inline
Ptr
<
VideoWriter
>
createWriter
(
const
string
&
backend
,
const
string
&
file_name
,
const
string
&
codec
,
Size
sz
,
unsigned
fps
)
{
if
(
backend
==
"gst-default"
)
{
cout
<<
"Created GStreamer writer ( "
<<
file_name
<<
", FPS="
<<
fps
<<
", Size="
<<
sz
<<
")"
<<
endl
;
return
makePtr
<
VideoWriter
>
(
file_name
,
CAP_GSTREAMER
,
getValue
(
fourccByCodec
(),
codec
,
"Invalid codec"
),
fps
,
sz
,
true
);
}
else
if
(
backend
.
find
(
"gst"
)
==
0
)
{
ostringstream
line
;
line
<<
"appsrc ! videoconvert n-threads="
<<
getNumThreads
()
<<
" ! "
;
if
(
backend
.
find
(
"basic"
)
==
4
)
line
<<
getValue
(
defaultEncodeElementByCodec
(),
codec
,
"Invalid codec"
);
else
if
(
backend
.
find
(
"vaapi"
)
==
4
)
line
<<
getValue
(
VAAPIEncodeElementByCodec
(),
codec
,
"Invalid codec"
);
else
if
(
backend
.
find
(
"libav"
)
==
4
)
line
<<
getValue
(
libavEncodeElementByCodec
(),
codec
,
"Invalid codec"
);
else
if
(
backend
.
find
(
"mfx"
)
==
4
)
line
<<
getValue
(
mfxEncodeElementByCodec
(),
codec
,
"Invalid codec"
);
else
{
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
return
Ptr
<
VideoWriter
>
();
line
<<
" ! "
;
line
<<
getValue
(
muxPluginByContainer
(),
containerByName
(
file_name
),
"Invalid container"
);
line
<<
" ! "
;
line
<<
"filesink location=
\"
"
<<
file_name
<<
"
\"
"
;
cout
<<
"Created GStreamer writer ( "
<<
line
.
str
()
<<
" )"
<<
endl
;
return
makePtr
<
VideoWriter
>
(
line
.
str
(),
CAP_GSTREAMER
,
0
,
fps
,
sz
,
true
);
}
stream_pipeline
<<
" ! "
<<
getGstMuxPlugin
();
stream_pipeline
<<
" ! filesink location=
\"
"
<<
file_name
<<
"
\"
"
;
wrt
=
VideoWriter
(
stream_pipeline
.
str
(),
CAP_GSTREAMER
,
0
,
fix_fps
,
fix_size
,
true
);
}
else
if
(
pipeline
==
"ffmpeg"
)
else
if
(
backend
==
"ffmpeg"
)
{
wrt
=
VideoWriter
(
file_name
,
CAP_FFMPEG
,
getFourccCode
(),
fix_fps
,
fix_size
,
true
);
stream_pipeline
<<
"default pipeline for ffmpeg"
<<
endl
;
}
else
{
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
}
return
0
;
cout
<<
"Created FFMpeg writer ( "
<<
file_name
<<
", FPS="
<<
fps
<<
", Size="
<<
sz
<<
" )"
<<
endl
;
return
makePtr
<
VideoWriter
>
(
file_name
,
CAP_FFMPEG
,
getValue
(
fourccByCodec
(),
codec
,
"Invalid codec"
),
fps
,
sz
,
true
);
}
return
Ptr
<
VideoWriter
>
();
}
// Choose video resolution for encoding
string
getVideoSettings
()
{
ostringstream
video_size
;
if
(
fix_fps
>
0
)
{
video_size
<<
"framerate="
<<
fix_fps
<<
"/1, "
;
}
else
{
cout
<<
"Unsupported fps (< 0): "
<<
fix_fps
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
//================================================================================
if
(
resolution
==
"720p"
)
{
fix_size
=
Size
(
1280
,
720
);
}
else
if
(
resolution
==
"1080p"
)
{
fix_size
=
Size
(
1920
,
1080
);
}
else
if
(
resolution
==
"4k"
)
{
fix_size
=
Size
(
3840
,
2160
);
}
else
int
main
(
int
argc
,
char
*
argv
[])
{
const
string
keys
=
"{h help usage ? | | print help messages }"
"{m mode |decode | coding mode (supported: encode, decode) }"
"{b backend |default | video backend (supported: 'gst-default', 'gst-basic', 'gst-vaapi', 'gst-libav', 'gst-mfx', 'ffmpeg') }"
"{c codec |h264 | codec name (supported: 'h264', 'h265', 'mpeg2', 'mpeg4', 'mjpeg', 'vp8') }"
"{f file path | | path to file }"
"{r resolution |720p | video resolution for encoding (supported: '720p', '1080p', '4k') }"
"{fps |30 | fix frame per second for encoding (supported: fps > 0) }"
"{fast | | fast measure fps }"
;
CommandLineParser
cmd_parser
(
argc
,
argv
,
keys
);
cmd_parser
.
about
(
"This program measures performance of video encoding and decoding using different backends OpenCV."
);
if
(
cmd_parser
.
has
(
"help"
))
{
cout
<<
"Unsupported video resolution: "
<<
resolution
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
video_size
<<
"width="
<<
fix_size
.
width
<<
", height="
<<
fix_size
.
height
;
return
video_size
.
str
();
cmd_parser
.
printMessage
();
return
0
;
}
// Choose a video container
string
getGstMuxPlugin
()
{
ostringstream
plugin
;
if
(
container
==
"avi"
)
{
plugin
<<
"avi"
;
}
else
if
(
container
==
"mp4"
)
{
plugin
<<
"qt"
;
}
else
if
(
container
==
"mov"
)
{
plugin
<<
"qt"
;
}
else
if
(
container
==
"mkv"
)
{
plugin
<<
"matroska"
;
}
else
bool
fast_measure
=
cmd_parser
.
has
(
"fast"
);
// fast measure fps
unsigned
fix_fps
=
cmd_parser
.
get
<
unsigned
>
(
"fps"
);
// fixed frame per second
string
backend
=
cmd_parser
.
get
<
string
>
(
"backend"
);
// video backend
string
mode
=
cmd_parser
.
get
<
string
>
(
"mode"
);
// coding mode
string
codec
=
cmd_parser
.
get
<
string
>
(
"codec"
);
// codec type
string
file_name
=
cmd_parser
.
get
<
string
>
(
"file"
);
// path to videofile
string
resolution
=
cmd_parser
.
get
<
string
>
(
"resolution"
);
// video resolution
if
(
!
cmd_parser
.
check
())
{
cout
<<
"Unsupported container: "
<<
container
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
cmd_parser
.
printErrors
();
return
-
1
;
}
if
(
mode
==
"decode"
)
{
plugin
<<
"demux"
;
}
else
if
(
mode
==
"encode"
)
{
plugin
<<
"mux"
;
}
else
if
(
mode
!=
"encode"
&&
mode
!=
"decode"
)
{
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
return
plugin
.
str
();
return
-
1
;
}
cout
<<
"Mode: "
<<
mode
<<
", Backend: "
<<
backend
<<
", File: "
<<
file_name
<<
", Codec: "
<<
codec
<<
endl
;
// Choose a libav codec
string
getGstAvCodePlugin
()
TickMeter
total
;
Ptr
<
VideoCapture
>
cap
;
Ptr
<
VideoWriter
>
wrt
;
try
{
ostringstream
plugin
;
if
(
mode
==
"decode"
)
{
if
(
codec
==
"h264"
)
{
plugin
<<
"h264parse ! "
;
}
else
if
(
codec
==
"h265"
)
{
plugin
<<
"h265parse ! "
;
}
plugin
<<
"avdec_"
;
}
else
if
(
mode
==
"encode"
)
{
plugin
<<
"avenc_"
;
}
else
cap
=
createCapture
(
backend
,
file_name
,
codec
);
if
(
!
cap
)
{
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
cout
<<
"Failed to create video capture"
<<
endl
;
return
-
3
;
}
if
(
codec
==
"h264"
)
{
plugin
<<
"h264"
;
}
else
if
(
codec
==
"h265"
)
{
plugin
<<
"h265"
;
}
else
if
(
codec
==
"mpeg2"
)
{
plugin
<<
"mpeg2video"
;
}
else
if
(
codec
==
"mpeg4"
)
{
plugin
<<
"mpeg4"
;
}
else
if
(
codec
==
"mjpeg"
)
{
plugin
<<
"mjpeg"
;
}
else
if
(
codec
==
"vp8"
)
{
plugin
<<
"vp8"
;
}
else
if
(
!
cap
->
isOpened
())
{
cout
<<
"Unsupported libav codec: "
<<
codec
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
cout
<<
"Capture is not opened"
<<
endl
;
return
-
4
;
}
return
plugin
.
str
();
}
// Choose a vaapi codec
string
getGstVaapiCodePlugin
()
else
if
(
mode
==
"encode"
)
{
ostringstream
plugin
;
if
(
mode
==
"decode"
)
Size
sz
=
getValue
(
sizeByResolution
(),
resolution
,
"Invalid resolution"
);
cout
<<
"FPS: "
<<
fix_fps
<<
", Frame size: "
<<
sz
<<
endl
;
cap
=
createSynthSource
(
sz
,
fix_fps
);
wrt
=
createWriter
(
backend
,
file_name
,
codec
,
sz
,
fix_fps
);
if
(
!
cap
||
!
wrt
)
{
plugin
<<
"vaapidecodebin"
;
if
(
container
==
"mkv"
)
{
plugin
<<
" ! autovideoconvert"
;
}
else
{
plugin
<<
" ! video/x-raw, format=YV12"
;
}
cout
<<
"Failed to create synthetic video source or video writer"
<<
endl
;
return
-
3
;
}
else
if
(
mode
==
"encode"
)
{
if
(
codec
==
"h264"
)
{
plugin
<<
"vaapih264enc"
;
}
else
if
(
codec
==
"h265"
)
{
plugin
<<
"vaapih265enc"
;
}
else
if
(
codec
==
"mpeg2"
)
{
plugin
<<
"vaapimpeg2enc"
;
}
else
if
(
codec
==
"mjpeg"
)
{
plugin
<<
"vaapijpegenc"
;
}
else
if
(
codec
==
"vp8"
)
{
plugin
<<
"vaapivp8enc"
;
}
else
if
(
!
cap
->
isOpened
()
||
!
wrt
->
isOpened
())
{
cout
<<
"Unsupported vaapi codec: "
<<
codec
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
cout
<<
"Synthetic video source or video writer is not opened"
<<
endl
;
return
-
4
;
}
}
else
{
cout
<<
"Unsupported mode: "
<<
resolution
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
return
plugin
.
str
();
catch
(...)
{
cout
<<
"Unsupported parameters"
<<
endl
;
return
-
2
;
}
// Choose a default codec
string
getGstDefaultCodePlugin
()
TickMeter
tick
;
Mat
frame
;
Mat
element
;
total
.
start
();
while
(
true
)
{
ostringstream
plugin
;
if
(
mode
==
"decode"
)
{
plugin
<<
" ! decodebin"
;
}
else
if
(
mode
==
"encode"
)
{
if
(
codec
==
"h264"
)
{
plugin
<<
"x264enc"
;
}
else
if
(
codec
==
"h265"
)
{
plugin
<<
"x265enc"
;
}
else
if
(
codec
==
"mpeg2"
)
{
plugin
<<
"mpeg2enc"
;
}
else
if
(
codec
==
"mjpeg"
)
{
plugin
<<
"jpegenc"
;
}
else
if
(
codec
==
"vp8"
)
{
plugin
<<
"vp8enc"
;
}
else
tick
.
start
();
if
(
!
cap
->
grab
())
{
cout
<<
"Unsupported default codec: "
<<
codec
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
cout
<<
"No more frames - break"
<<
endl
;
break
;
}
if
(
!
cap
->
retrieve
(
frame
))
{
cout
<<
"Failed to retrieve frame - break"
<<
endl
;
break
;
}
else
if
(
frame
.
empty
())
{
cout
<<
"Unsupported mode: "
<<
resolution
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
cout
<<
"Empty frame received - break"
<<
endl
;
break
;
}
return
plugin
.
str
();
tick
.
stop
();
}
// Get fourcc for codec
int
getFourccCode
()
else
if
(
mode
==
"encode"
)
{
if
(
codec
==
"h264"
)
{
return
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
);
}
else
if
(
codec
==
"h265"
)
{
return
VideoWriter
::
fourcc
(
'H'
,
'E'
,
'V'
,
'C'
);
}
else
if
(
codec
==
"mpeg2"
)
{
return
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'E'
,
'G'
);
}
else
if
(
codec
==
"mpeg4"
)
{
return
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'4'
,
'2'
);
}
else
if
(
codec
==
"mjpeg"
)
{
return
VideoWriter
::
fourcc
(
'M'
,
'J'
,
'P'
,
'G'
);
}
else
if
(
codec
==
"vp8"
)
{
return
VideoWriter
::
fourcc
(
'V'
,
'P'
,
'8'
,
'0'
);
}
else
int
limit
=
100
;
while
(
!
cap
->
grab
()
&&
--
limit
!=
0
)
{
cout
<<
"Unsupported ffmpeg codec: "
<<
codec
<<
endl
;
cmd_parser
->
printErrors
();
return
0
;
cout
<<
"Skipping empty input frame - "
<<
limit
<<
endl
;
}
cap
->
retrieve
(
element
);
tick
.
start
();
*
wrt
<<
element
;
tick
.
stop
();
}
// Check bad configuration
int
checkConfiguration
()
if
(
fast_measure
&&
tick
.
getCounter
()
>=
1000
)
{
if
((
codec
==
"mpeg2"
&&
getGstMuxPlugin
()
==
"qtmux"
)
||
(
codec
==
"h265"
&&
getGstMuxPlugin
()
==
"avimux"
)
||
(
pipeline
==
"gst-libav"
&&
(
codec
==
"h264"
||
codec
==
"h265"
))
||
(
pipeline
==
"gst-vaapi1710"
&&
codec
==
"mpeg2"
&&
resolution
==
"4k"
)
||
(
pipeline
==
"gst-vaapi1710"
&&
codec
==
"mpeg2"
&&
resolution
==
"1080p"
&&
fix_fps
>
30
))
cout
<<
"Fast mode frame limit reached - break"
<<
endl
;
break
;
}
if
(
mode
==
"encode"
&&
tick
.
getCounter
()
>=
1000
)
{
cout
<<
"Unsupported configuration"
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
cout
<<
"Encode frame limit reached - break"
<<
endl
;
break
;
}
return
0
;
}
bool
fast_measure
;
// fast measure fps
string
pipeline
,
// gstreamer pipeline type
container
,
// container type
mode
,
// coding mode
codec
,
// codec type
file_name
,
// path to videofile
resolution
;
// video resolution
int
fix_fps
;
// fixed frame per second
Size
fix_size
;
// fixed frame size
VideoWriter
wrt
;
VideoCapture
cap
;
ostringstream
stream_pipeline
;
CommandLineParser
*
cmd_parser
;
};
int
main
(
int
argc
,
char
*
argv
[])
{
try
total
.
stop
();
if
(
tick
.
getCounter
()
==
0
)
{
GStreamerPipeline
pipe
(
argc
,
argv
)
;
return
pipe
.
run
()
;
cout
<<
"No frames have been processed"
<<
endl
;
return
-
10
;
}
catch
(
const
Exception
&
e
)
else
{
cerr
<<
e
.
what
()
<<
endl
;
return
1
;
double
res_fps
=
tick
.
getCounter
()
/
tick
.
getTimeSec
()
;
cout
<<
tick
.
getCounter
()
<<
" frames in "
<<
tick
.
getTimeSec
()
<<
" sec ~ "
<<
res_fps
<<
" FPS"
<<
" (total time: "
<<
total
.
getTimeSec
()
<<
" sec)"
<<
endl
;
}
return
0
;
}
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