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 @@
...
@@ -4,444 +4,373 @@
#include "opencv2/highgui.hpp"
#include "opencv2/highgui.hpp"
#include <string>
#include <string>
#include <iostream>
#include <iostream>
#include <map>
using
namespace
std
;
using
namespace
std
;
using
namespace
cv
;
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
,
errorMessage
);
CV_Error
(
Error
::
StsBadArg
,
"Called help."
);
}
}
return
it
->
second
;
}
fast_measure
=
cmd_parser
->
has
(
"fast"
);
// fast measure fps
inline
map
<
string
,
Size
>
sizeByResolution
()
fix_fps
=
cmd_parser
->
get
<
int
>
(
"fps"
);
// fixed frame per second
{
pipeline
=
cmd_parser
->
get
<
string
>
(
"pipeline"
),
// gstreamer pipeline type
map
<
string
,
Size
>
res
;
mode
=
cmd_parser
->
get
<
string
>
(
"mode"
),
// coding mode
res
[
"720p"
]
=
Size
(
1280
,
720
);
codec
=
cmd_parser
->
get
<
string
>
(
"codec"
),
// codec type
res
[
"1080p"
]
=
Size
(
1920
,
1080
);
file_name
=
cmd_parser
->
get
<
string
>
(
"file"
),
// path to videofile
res
[
"4k"
]
=
Size
(
3840
,
2160
);
resolution
=
cmd_parser
->
get
<
string
>
(
"resolution"
);
// video resolution
return
res
;
}
size_t
found
=
file_name
.
rfind
(
"."
);
inline
map
<
string
,
int
>
fourccByCodec
()
if
(
found
!=
string
::
npos
)
{
{
map
<
string
,
int
>
res
;
container
=
file_name
.
substr
(
found
+
1
);
// container type
res
[
"h264"
]
=
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
);
}
res
[
"h265"
]
=
VideoWriter
::
fourcc
(
'H'
,
'E'
,
'V'
,
'C'
);
else
{
CV_Error
(
Error
::
StsBadArg
,
"Can not parse container extension."
);
}
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
())
inline
map
<
string
,
string
>
defaultEncodeElementByCodec
()
{
{
cmd_parser
->
printErrors
();
map
<
string
,
string
>
res
;
CV_Error
(
Error
::
StsBadArg
,
"Failed parse arguments."
);
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
inline
map
<
string
,
string
>
mfxDecodeElementByCodec
()
int
run
()
{
{
map
<
string
,
string
>
res
;
if
(
mode
==
"decode"
)
{
if
(
createDecodePipeline
()
<
0
)
return
-
1
;
}
res
[
"h264"
]
=
"parsebin ! mfxh264dec"
;
else
if
(
mode
==
"encode"
)
{
if
(
createEncodePipeline
()
<
0
)
return
-
1
;
}
res
[
"h265"
]
=
"parsebin ! mfxhevcdec"
;
else
res
[
"mpeg2"
]
=
"parsebin ! mfxmpeg2dec"
;
{
res
[
"mjpeg"
]
=
"parsebin ! mfxjpegdec"
;
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
return
res
;
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
;
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
;
inline
map
<
string
,
string
>
libavDecodeElementByCodec
()
cout
<<
" ("
<<
pipeline
<<
")"
<<
endl
;
{
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
)
inline
map
<
string
,
string
>
libavEncodeElementByCodec
()
{
{
int64
temp_count_tick
=
0
;
map
<
string
,
string
>
res
;
if
(
mode
==
"decode"
)
res
[
"h264"
]
=
"avenc_h264"
;
{
res
[
"h265"
]
=
"avenc_h265"
;
Mat
frame
;
res
[
"mpeg2"
]
=
"avenc_mpeg2video"
;
temp_count_tick
=
getTickCount
();
res
[
"mpeg4"
]
=
"avenc_mpeg4"
;
cap
>>
frame
;
res
[
"mjpeg"
]
=
"avenc_mjpeg"
;
temp_count_tick
=
getTickCount
()
-
temp_count_tick
;
res
[
"vp8"
]
=
"avenc_vp8"
;
if
(
frame
.
empty
())
{
break
;
}
return
res
;
}
}
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
;
}
tick_counts
.
push_back
(
static_cast
<
double
>
(
temp_count_tick
));
inline
map
<
string
,
string
>
demuxPluginByContainer
()
if
(((
mode
==
"decode"
)
&&
fast_measure
&&
(
tick_counts
.
size
()
>
1e3
))
||
{
((
mode
==
"encode"
)
&&
(
tick_counts
.
size
()
>
3e3
))
||
map
<
string
,
string
>
res
;
((
mode
==
"encode"
)
&&
fast_measure
&&
(
tick_counts
.
size
()
>
1e2
)))
res
[
"avi"
]
=
"avidemux"
;
{
break
;
}
res
[
"mp4"
]
=
"qtdemux"
;
res
[
"mov"
]
=
"qtdemux"
;
res
[
"mkv"
]
=
"matroskademux"
;
return
res
;
}
}
inline
map
<
string
,
string
>
muxPluginByContainer
()
double
time_fps
=
sum
(
tick_counts
)[
0
]
/
getTickFrequency
();
{
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
inline
string
containerByName
(
const
string
&
name
)
void
close
()
{
size_t
found
=
name
.
rfind
(
"."
);
if
(
found
!=
string
::
npos
)
{
{
cap
.
release
();
return
name
.
substr
(
found
+
1
);
// container type
wrt
.
release
();
}
}
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
)
inline
Ptr
<
VideoCapture
>
createCapture
(
const
string
&
backend
,
const
string
&
file_name
,
const
string
&
codec
)
{
{
stream_pipeline
<<
getGstDefaultCodePlugin
();
if
(
backend
==
"gst-default"
)
}
{
else
if
(
pipeline
.
find
(
"vaapi1710"
)
==
4
)
cout
<<
"Created GStreamer capture ( "
<<
file_name
<<
" )"
<<
endl
;
{
return
makePtr
<
VideoCapture
>
(
file_name
,
CAP_GSTREAMER
);
stream_pipeline
<<
getGstVaapiCodePlugin
();
}
}
else
if
(
backend
.
find
(
"gst"
)
==
0
)
else
if
(
pipeline
.
find
(
"libav"
)
==
4
)
{
{
ostringstream
line
;
stream_pipeline
<<
getGstAvCodePlugin
();
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
else
{
return
Ptr
<
VideoCapture
>
();
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
line
<<
" ! videoconvert n-threads="
<<
getNumThreads
();
cmd_parser
->
printErrors
();
line
<<
" ! appsink sync=false"
;
return
-
1
;
cout
<<
"Created GStreamer capture ( "
<<
line
.
str
()
<<
" )"
<<
endl
;
}
return
makePtr
<
VideoCapture
>
(
line
.
str
(),
CAP_GSTREAMER
);
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
;
}
}
else
else
if
(
backend
==
"ffmpeg"
)
{
{
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
cout
<<
"Created FFmpeg capture ( "
<<
file_name
<<
" )"
<<
endl
;
cmd_parser
->
printErrors
();
return
makePtr
<
VideoCapture
>
(
file_name
,
CAP_FFMPEG
);
return
-
1
;
}
return
0
;
}
}
return
Ptr
<
VideoCapture
>
();
}
// Choose the constructed GStreamer pipeline for encode
inline
Ptr
<
VideoCapture
>
createSynthSource
(
Size
sz
,
unsigned
fps
)
int
createEncodePipeline
()
{
{
ostringstream
line
;
if
(
checkConfiguration
()
<
0
)
return
-
1
;
line
<<
"videotestsrc pattern=smpte"
;
ostringstream
test_pipeline
;
line
<<
" ! video/x-raw"
;
test_pipeline
<<
"videotestsrc pattern=smpte"
;
line
<<
",width="
<<
sz
.
width
<<
",height="
<<
sz
.
height
;
test_pipeline
<<
" ! video/x-raw, "
<<
getVideoSettings
();
if
(
fps
>
0
)
test_pipeline
<<
" ! appsink sync=false"
;
line
<<
",framerate="
<<
fps
<<
"/1"
;
cap
=
VideoCapture
(
test_pipeline
.
str
(),
CAP_GSTREAMER
);
line
<<
" ! appsink sync=false"
;
cout
<<
"Created synthetic video source ( "
<<
line
.
str
()
<<
" )"
<<
endl
;
if
(
pipeline
==
"default"
)
{
return
makePtr
<
VideoCapture
>
(
line
.
str
(),
CAP_GSTREAMER
);
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
()
<<
" ! "
;
if
(
pipeline
.
find
(
"basic"
)
==
4
)
inline
Ptr
<
VideoWriter
>
createWriter
(
const
string
&
backend
,
const
string
&
file_name
,
const
string
&
codec
,
Size
sz
,
unsigned
fps
)
{
{
stream_pipeline
<<
getGstDefaultCodePlugin
();
if
(
backend
==
"gst-default"
)
}
{
else
if
(
pipeline
.
find
(
"vaapi1710"
)
==
4
)
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
);
stream_pipeline
<<
getGstVaapiCodePlugin
();
}
}
else
if
(
backend
.
find
(
"gst"
)
==
0
)
else
if
(
pipeline
.
find
(
"libav"
)
==
4
)
{
{
ostringstream
line
;
stream_pipeline
<<
getGstAvCodePlugin
();
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
else
{
return
Ptr
<
VideoWriter
>
();
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
line
<<
" ! "
;
cmd_parser
->
printErrors
();
line
<<
getValue
(
muxPluginByContainer
(),
containerByName
(
file_name
),
"Invalid container"
);
return
-
1
;
line
<<
" ! "
;
line
<<
"filesink location=
\"
"
<<
file_name
<<
"
\"
"
;
cout
<<
"Created GStreamer writer ( "
<<
line
.
str
()
<<
" )"
<<
endl
;
return
makePtr
<
VideoWriter
>
(
line
.
str
(),
CAP_GSTREAMER
,
0
,
fps
,
sz
,
true
);
}
}
else
if
(
backend
==
"ffmpeg"
)
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"
)
{
{
wrt
=
VideoWriter
(
file_name
,
CAP_FFMPEG
,
getFourccCode
(),
fix_fps
,
fix_size
,
true
);
cout
<<
"Created FFMpeg writer ( "
<<
file_name
<<
", FPS="
<<
fps
<<
", Size="
<<
sz
<<
" )"
<<
endl
;
stream_pipeline
<<
"default pipeline for ffmpeg"
<<
endl
;
return
makePtr
<
VideoWriter
>
(
file_name
,
CAP_FFMPEG
,
getValue
(
fourccByCodec
(),
codec
,
"Invalid codec"
),
fps
,
sz
,
true
);
}
else
{
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
}
return
0
;
}
}
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
);
}
int
main
(
int
argc
,
char
*
argv
[])
else
if
(
resolution
==
"1080p"
)
{
fix_size
=
Size
(
1920
,
1080
);
}
{
else
if
(
resolution
==
"4k"
)
{
fix_size
=
Size
(
3840
,
2160
);
}
const
string
keys
=
else
"{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
.
printMessage
();
cmd_parser
->
printErrors
();
return
0
;
return
string
();
}
video_size
<<
"width="
<<
fix_size
.
width
<<
", height="
<<
fix_size
.
height
;
return
video_size
.
str
();
}
}
bool
fast_measure
=
cmd_parser
.
has
(
"fast"
);
// fast measure fps
// Choose a video container
unsigned
fix_fps
=
cmd_parser
.
get
<
unsigned
>
(
"fps"
);
// fixed frame per second
string
getGstMuxPlugin
()
string
backend
=
cmd_parser
.
get
<
string
>
(
"backend"
);
// video backend
{
string
mode
=
cmd_parser
.
get
<
string
>
(
"mode"
);
// coding mode
ostringstream
plugin
;
string
codec
=
cmd_parser
.
get
<
string
>
(
"codec"
);
// codec type
if
(
container
==
"avi"
)
{
plugin
<<
"avi"
;
}
string
file_name
=
cmd_parser
.
get
<
string
>
(
"file"
);
// path to videofile
else
if
(
container
==
"mp4"
)
{
plugin
<<
"qt"
;
}
string
resolution
=
cmd_parser
.
get
<
string
>
(
"resolution"
);
// video resolution
else
if
(
container
==
"mov"
)
{
plugin
<<
"qt"
;
}
if
(
!
cmd_parser
.
check
())
else
if
(
container
==
"mkv"
)
{
plugin
<<
"matroska"
;
}
else
{
{
cout
<<
"Unsupported container: "
<<
container
<<
endl
;
cmd_parser
.
printErrors
();
cmd_parser
->
printErrors
();
return
-
1
;
return
string
();
}
}
if
(
mode
!=
"encode"
&&
mode
!=
"decode"
)
if
(
mode
==
"decode"
)
{
plugin
<<
"demux"
;
}
else
if
(
mode
==
"encode"
)
{
plugin
<<
"mux"
;
}
else
{
{
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
return
string
();
}
return
plugin
.
str
();
}
}
cout
<<
"Mode: "
<<
mode
<<
", Backend: "
<<
backend
<<
", File: "
<<
file_name
<<
", Codec: "
<<
codec
<<
endl
;
// Choose a libav codec
TickMeter
total
;
string
getGstAvCodePlugin
()
Ptr
<
VideoCapture
>
cap
;
Ptr
<
VideoWriter
>
wrt
;
try
{
{
ostringstream
plugin
;
if
(
mode
==
"decode"
)
if
(
mode
==
"decode"
)
{
{
if
(
codec
==
"h264"
)
{
plugin
<<
"h264parse ! "
;
}
cap
=
createCapture
(
backend
,
file_name
,
codec
);
else
if
(
codec
==
"h265"
)
{
plugin
<<
"h265parse ! "
;
}
if
(
!
cap
)
plugin
<<
"avdec_"
;
}
else
if
(
mode
==
"encode"
)
{
plugin
<<
"avenc_"
;
}
else
{
{
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
cout
<<
"Failed to create video capture"
<<
endl
;
cmd_parser
->
printErrors
();
return
-
3
;
return
string
();
}
}
if
(
!
cap
->
isOpened
())
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
{
{
cout
<<
"Unsupported libav codec: "
<<
codec
<<
endl
;
cout
<<
"Capture is not opened"
<<
endl
;
cmd_parser
->
printErrors
();
return
-
4
;
return
string
();
}
}
return
plugin
.
str
();
}
}
else
if
(
mode
==
"encode"
)
// Choose a vaapi codec
string
getGstVaapiCodePlugin
()
{
{
ostringstream
plugin
;
Size
sz
=
getValue
(
sizeByResolution
(),
resolution
,
"Invalid resolution"
);
if
(
mode
==
"decode"
)
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"
;
cout
<<
"Failed to create synthetic video source or video writer"
<<
endl
;
if
(
container
==
"mkv"
)
{
plugin
<<
" ! autovideoconvert"
;
}
return
-
3
;
else
{
plugin
<<
" ! video/x-raw, format=YV12"
;
}
}
}
else
if
(
mode
==
"encode"
)
if
(
!
cap
->
isOpened
()
||
!
wrt
->
isOpened
())
{
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
{
{
cout
<<
"Unsupported vaapi codec: "
<<
codec
<<
endl
;
cout
<<
"Synthetic video source or video writer is not opened"
<<
endl
;
cmd_parser
->
printErrors
();
return
-
4
;
return
string
();
}
}
}
}
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
TickMeter
tick
;
string
getGstDefaultCodePlugin
()
Mat
frame
;
Mat
element
;
total
.
start
();
while
(
true
)
{
{
ostringstream
plugin
;
if
(
mode
==
"decode"
)
if
(
mode
==
"decode"
)
{
{
plugin
<<
" ! decodebin"
;
tick
.
start
();
}
if
(
!
cap
->
grab
())
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
{
{
cout
<<
"Unsupported default codec: "
<<
codec
<<
endl
;
cout
<<
"No more frames - break"
<<
endl
;
cmd_parser
->
printErrors
();
break
;
return
string
();
}
}
if
(
!
cap
->
retrieve
(
frame
))
{
cout
<<
"Failed to retrieve frame - break"
<<
endl
;
break
;
}
}
else
if
(
frame
.
empty
())
{
{
cout
<<
"Unsupported mode: "
<<
resolution
<<
endl
;
cout
<<
"Empty frame received - break"
<<
endl
;
cmd_parser
->
printErrors
();
break
;
return
string
();
}
}
return
plugin
.
str
();
tick
.
stop
();
}
}
// Get fourcc for codec
else
if
(
mode
==
"encode"
)
int
getFourccCode
()
{
{
if
(
codec
==
"h264"
)
{
return
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
);
}
int
limit
=
100
;
else
if
(
codec
==
"h265"
)
{
return
VideoWriter
::
fourcc
(
'H'
,
'E'
,
'V'
,
'C'
);
}
while
(
!
cap
->
grab
()
&&
--
limit
!=
0
)
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
{
{
cout
<<
"Unsupported ffmpeg codec: "
<<
codec
<<
endl
;
cout
<<
"Skipping empty input frame - "
<<
limit
<<
endl
;
cmd_parser
->
printErrors
();
return
0
;
}
}
cap
->
retrieve
(
element
);
tick
.
start
();
*
wrt
<<
element
;
tick
.
stop
();
}
}
// Check bad configuration
if
(
fast_measure
&&
tick
.
getCounter
()
>=
1000
)
int
checkConfiguration
()
{
{
if
((
codec
==
"mpeg2"
&&
getGstMuxPlugin
()
==
"qtmux"
)
||
cout
<<
"Fast mode frame limit reached - break"
<<
endl
;
(
codec
==
"h265"
&&
getGstMuxPlugin
()
==
"avimux"
)
||
break
;
(
pipeline
==
"gst-libav"
&&
(
codec
==
"h264"
||
codec
==
"h265"
))
||
}
(
pipeline
==
"gst-vaapi1710"
&&
codec
==
"mpeg2"
&&
resolution
==
"4k"
)
||
if
(
mode
==
"encode"
&&
tick
.
getCounter
()
>=
1000
)
(
pipeline
==
"gst-vaapi1710"
&&
codec
==
"mpeg2"
&&
resolution
==
"1080p"
&&
fix_fps
>
30
))
{
{
cout
<<
"Unsupported configuration"
<<
endl
;
cout
<<
"Encode frame limit reached - break"
<<
endl
;
cmd_parser
->
printErrors
();
break
;
return
-
1
;
}
}
return
0
;
}
}
total
.
stop
();
bool
fast_measure
;
// fast measure fps
if
(
tick
.
getCounter
()
==
0
)
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
{
{
GStreamerPipeline
pipe
(
argc
,
argv
)
;
cout
<<
"No frames have been processed"
<<
endl
;
return
pipe
.
run
()
;
return
-
10
;
}
}
catch
(
const
Exception
&
e
)
else
{
{
cerr
<<
e
.
what
()
<<
endl
;
double
res_fps
=
tick
.
getCounter
()
/
tick
.
getTimeSec
()
;
return
1
;
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