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
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
301 additions
and
372 deletions
+301
-372
gstreamer_pipeline.cpp
samples/cpp/gstreamer_pipeline.cpp
+301
-372
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
//================================================================================
template
<
typename
M
>
inline
typename
M
::
mapped_type
getValue
(
const
M
&
dict
,
const
typename
M
::
key_type
&
key
,
const
string
&
errorMessage
)
{
{
public
:
typename
M
::
const_iterator
it
=
dict
.
find
(
key
);
// Preprocessing arguments command line
if
(
it
==
dict
.
end
())
GStreamerPipeline
(
int
argc
,
char
*
argv
[])
{
{
const
string
keys
=
CV_Error
(
Error
::
StsBadArg
,
errorMessage
);
"{h help usage ? | | print help messages }"
}
"{m mode | | coding mode (supported: encode, decode) }"
return
it
->
second
;
"{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"
))
inline
map
<
string
,
Size
>
sizeByResolution
()
{
{
cmd_parser
->
printMessage
();
map
<
string
,
Size
>
res
;
CV_Error
(
Error
::
StsBadArg
,
"Called help."
);
res
[
"720p"
]
=
Size
(
1280
,
720
);
}
res
[
"1080p"
]
=
Size
(
1920
,
1080
);
res
[
"4k"
]
=
Size
(
3840
,
2160
);
return
res
;
}
fast_measure
=
cmd_parser
->
has
(
"fast"
);
// fast measure fps
inline
map
<
string
,
int
>
fourccByCodec
()
fix_fps
=
cmd_parser
->
get
<
int
>
(
"fps"
);
// fixed frame per second
{
pipeline
=
cmd_parser
->
get
<
string
>
(
"pipeline"
),
// gstreamer pipeline type
map
<
string
,
int
>
res
;
mode
=
cmd_parser
->
get
<
string
>
(
"mode"
),
// coding mode
res
[
"h264"
]
=
VideoWriter
::
fourcc
(
'H'
,
'2'
,
'6'
,
'4'
);
codec
=
cmd_parser
->
get
<
string
>
(
"codec"
),
// codec type
res
[
"h265"
]
=
VideoWriter
::
fourcc
(
'H'
,
'E'
,
'V'
,
'C'
);
file_name
=
cmd_parser
->
get
<
string
>
(
"file"
),
// path to videofile
res
[
"mpeg2"
]
=
VideoWriter
::
fourcc
(
'M'
,
'P'
,
'E'
,
'G'
);
resolution
=
cmd_parser
->
get
<
string
>
(
"resolution"
);
// video resolution
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
;
}
size_t
found
=
file_name
.
rfind
(
"."
);
inline
map
<
string
,
string
>
defaultEncodeElementByCodec
()
if
(
found
!=
string
::
npos
)
{
{
map
<
string
,
string
>
res
;
container
=
file_name
.
substr
(
found
+
1
);
// container type
res
[
"h264"
]
=
"x264enc"
;
}
res
[
"h265"
]
=
"x265enc"
;
else
{
CV_Error
(
Error
::
StsBadArg
,
"Can not parse container extension."
);
}
res
[
"mpeg2"
]
=
"mpeg2enc"
;
res
[
"mjpeg"
]
=
"jpegenc"
;
res
[
"vp8"
]
=
"vp8enc"
;
return
res
;
}
if
(
!
cmd_parser
->
check
())
inline
map
<
string
,
string
>
VAAPIEncodeElementByCodec
()
{
{
cmd_parser
->
printErrors
();
map
<
string
,
string
>
res
;
CV_Error
(
Error
::
StsBadArg
,
"Failed parse arguments."
);
res
[
"h264"
]
=
"parsebin ! vaapih264enc"
;
}
res
[
"h265"
]
=
"parsebin ! vaapih265enc"
;
}
res
[
"mpeg2"
]
=
"parsebin ! vaapimpeg2enc"
;
res
[
"mjpeg"
]
=
"parsebin ! vaapijpegenc"
;
res
[
"vp8"
]
=
"parsebin ! vaapivp8enc"
;
return
res
;
}
~
GStreamerPipeline
()
{
delete
cmd_parser
;
}
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
;
}
// Start pipeline
inline
map
<
string
,
string
>
mfxEncodeElementByCodec
()
int
run
()
{
{
map
<
string
,
string
>
res
;
if
(
mode
==
"decode"
)
{
if
(
createDecodePipeline
()
<
0
)
return
-
1
;
}
res
[
"h264"
]
=
"mfxh264enc"
;
else
if
(
mode
==
"encode"
)
{
if
(
createEncodePipeline
()
<
0
)
return
-
1
;
}
res
[
"h265"
]
=
"mfxhevcenc"
;
else
res
[
"mpeg2"
]
=
"mfxmpeg2enc"
;
{
res
[
"mjpeg"
]
=
"mfxjpegenc"
;
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
>
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
;
}
cout
<<
"Start "
<<
mode
<<
": "
<<
file_name
;
inline
map
<
string
,
string
>
libavEncodeElementByCodec
()
cout
<<
" ("
<<
pipeline
<<
")"
<<
endl
;
{
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
;
}
while
(
true
)
inline
map
<
string
,
string
>
demuxPluginByContainer
()
{
{
int64
temp_count_tick
=
0
;
map
<
string
,
string
>
res
;
if
(
mode
==
"decode"
)
res
[
"avi"
]
=
"avidemux"
;
{
res
[
"mp4"
]
=
"qtdemux"
;
Mat
frame
;
res
[
"mov"
]
=
"qtdemux"
;
temp_count_tick
=
getTickCount
();
res
[
"mkv"
]
=
"matroskademux"
;
cap
>>
frame
;
return
res
;
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
;
}
tick_counts
.
push_back
(
static_cast
<
double
>
(
temp_count_tick
));
inline
map
<
string
,
string
>
muxPluginByContainer
()
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"
]
=
"avimux"
;
{
break
;
}
res
[
"mp4"
]
=
"qtmux"
;
res
[
"mov"
]
=
"qtmux"
;
res
[
"mkv"
]
=
"matroskamux"
;
return
res
;
}
}
//================================================================================
double
time_fps
=
sum
(
tick_counts
)[
0
]
/
getTickFrequency
();
if
(
tick_counts
.
size
()
!=
0
)
inline
string
containerByName
(
const
string
&
name
)
{
{
cout
<<
"Finished: "
<<
tick_counts
.
size
()
<<
" in "
<<
time_fps
<<
" sec ~ "
;
size_t
found
=
name
.
rfind
(
"."
);
cout
<<
tick_counts
.
size
()
/
time_fps
<<
" fps "
<<
endl
;
if
(
found
!=
string
::
npos
)
}
{
else
return
name
.
substr
(
found
+
1
);
// container type
{
cout
<<
"Failed "
<<
mode
<<
": "
<<
file_name
;
cout
<<
" ("
<<
pipeline
<<
")"
<<
endl
;
return
-
1
;
}
return
0
;
}
}
return
string
();
}
//================================================================================
// Free video resource
inline
Ptr
<
VideoCapture
>
createCapture
(
const
string
&
backend
,
const
string
&
file_name
,
const
string
&
codec
)
void
close
()
{
if
(
backend
==
"gst-default"
)
{
{
c
ap
.
release
()
;
c
out
<<
"Created GStreamer capture ( "
<<
file_name
<<
" )"
<<
endl
;
wrt
.
release
(
);
return
makePtr
<
VideoCapture
>
(
file_name
,
CAP_GSTREAMER
);
}
}
else
if
(
backend
.
find
(
"gst"
)
==
0
)
private
:
// Choose the constructed GStreamer pipeline for decode
int
createDecodePipeline
()
{
{
if
(
pipeline
==
"default"
)
{
ostringstream
line
;
cap
=
VideoCapture
(
file_name
,
CAP_GSTREAMER
);
line
<<
"filesrc location=
\"
"
<<
file_name
<<
"
\"
"
;
}
line
<<
" ! "
;
else
if
(
pipeline
.
find
(
"gst"
)
==
0
)
line
<<
getValue
(
demuxPluginByContainer
(),
containerByName
(
file_name
),
"Invalid container"
);
{
line
<<
" ! "
;
stream_pipeline
<<
"filesrc location=
\"
"
<<
file_name
<<
"
\"
"
;
if
(
backend
.
find
(
"basic"
)
==
4
)
stream_pipeline
<<
" ! "
<<
getGstMuxPlugin
();
line
<<
"decodebin"
;
else
if
(
backend
.
find
(
"vaapi"
)
==
4
)
if
(
pipeline
.
find
(
"basic"
)
==
4
)
line
<<
"vaapidecodebin"
;
{
else
if
(
backend
.
find
(
"libav"
)
==
4
)
stream_pipeline
<<
getGstDefaultCodePlugin
();
line
<<
getValue
(
libavDecodeElementByCodec
(),
codec
,
"Invalid codec"
);
}
else
if
(
backend
.
find
(
"mfx"
)
==
4
)
else
if
(
pipeline
.
find
(
"vaapi1710"
)
==
4
)
line
<<
getValue
(
mfxDecodeElementByCodec
(),
codec
,
"Invalid or unsupported codec"
);
{
stream_pipeline
<<
getGstVaapiCodePlugin
();
}
else
if
(
pipeline
.
find
(
"libav"
)
==
4
)
{
stream_pipeline
<<
getGstAvCodePlugin
();
}
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
;
}
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
);
return
0
;
}
}
else
if
(
backend
==
"ffmpeg"
)
// Choose the constructed GStreamer pipeline for encode
int
createEncodePipeline
()
{
{
if
(
checkConfiguration
()
<
0
)
return
-
1
;
cout
<<
"Created FFmpeg capture ( "
<<
file_name
<<
" )"
<<
endl
;
ostringstream
test_pipeline
;
return
makePtr
<
VideoCapture
>
(
file_name
,
CAP_FFMPEG
);
test_pipeline
<<
"videotestsrc pattern=smpte"
;
}
test_pipeline
<<
" ! video/x-raw, "
<<
getVideoSettings
();
return
Ptr
<
VideoCapture
>
();
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
()
<<
" ! "
;
if
(
pipeline
.
find
(
"basic"
)
==
4
)
inline
Ptr
<
VideoCapture
>
createSynthSource
(
Size
sz
,
unsigned
fps
)
{
{
stream_pipeline
<<
getGstDefaultCodePlugin
();
ostringstream
line
;
}
line
<<
"videotestsrc pattern=smpte"
;
else
if
(
pipeline
.
find
(
"vaapi1710"
)
==
4
)
line
<<
" ! video/x-raw"
;
{
line
<<
",width="
<<
sz
.
width
<<
",height="
<<
sz
.
height
;
stream_pipeline
<<
getGstVaapiCodePlugin
();
if
(
fps
>
0
)
}
line
<<
",framerate="
<<
fps
<<
"/1"
;
else
if
(
pipeline
.
find
(
"libav"
)
==
4
)
line
<<
" ! appsink sync=false"
;
{
cout
<<
"Created synthetic video source ( "
<<
line
.
str
()
<<
" )"
<<
endl
;
stream_pipeline
<<
getGstAvCodePlugin
();
return
makePtr
<
VideoCapture
>
(
line
.
str
(),
CAP_GSTREAMER
);
}
}
else
{
cout
<<
"Unsupported pipeline: "
<<
pipeline
<<
endl
;
cmd_parser
->
printErrors
();
return
-
1
;
}
stream_pipeline
<<
" ! "
<<
getGstMuxPlugin
();
inline
Ptr
<
VideoWriter
>
createWriter
(
const
string
&
backend
,
const
string
&
file_name
,
const
string
&
codec
,
Size
sz
,
unsigned
fps
)
stream_pipeline
<<
" ! filesink location=
\"
"
<<
file_name
<<
"
\"
"
;
{
wrt
=
VideoWriter
(
stream_pipeline
.
str
(),
CAP_GSTREAMER
,
0
,
fix_fps
,
fix_size
,
true
);
if
(
backend
==
"gst-default"
)
}
{
else
if
(
pipeline
==
"ffmpeg"
)
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
);
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
;
}
}
else
if
(
backend
.
find
(
"gst"
)
==
0
)
// Choose video resolution for encoding
string
getVideoSettings
()
{
{
ostringstream
video_size
;
ostringstream
line
;
if
(
fix_fps
>
0
)
{
video_size
<<
"framerate="
<<
fix_fps
<<
"/1, "
;
}
line
<<
"appsrc ! videoconvert n-threads="
<<
getNumThreads
()
<<
" ! "
;
else
if
(
backend
.
find
(
"basic"
)
==
4
)
{
line
<<
getValue
(
defaultEncodeElementByCodec
(),
codec
,
"Invalid codec"
);
cout
<<
"Unsupported fps (< 0): "
<<
fix_fps
<<
endl
;
else
if
(
backend
.
find
(
"vaapi"
)
==
4
)
cmd_parser
->
printErrors
();
line
<<
getValue
(
VAAPIEncodeElementByCodec
(),
codec
,
"Invalid codec"
);
return
string
();
else
if
(
backend
.
find
(
"libav"
)
==
4
)
}
line
<<
getValue
(
libavEncodeElementByCodec
(),
codec
,
"Invalid codec"
);
else
if
(
backend
.
find
(
"mfx"
)
==
4
)
if
(
resolution
==
"720p"
)
{
fix_size
=
Size
(
1280
,
720
);
}
line
<<
getValue
(
mfxEncodeElementByCodec
(),
codec
,
"Invalid codec"
);
else
if
(
resolution
==
"1080p"
)
{
fix_size
=
Size
(
1920
,
1080
);
}
else
if
(
resolution
==
"4k"
)
{
fix_size
=
Size
(
3840
,
2160
);
}
else
else
{
return
Ptr
<
VideoWriter
>
();
cout
<<
"Unsupported video resolution: "
<<
resolution
<<
endl
;
line
<<
" ! "
;
cmd_parser
->
printErrors
();
line
<<
getValue
(
muxPluginByContainer
(),
containerByName
(
file_name
),
"Invalid container"
);
return
string
();
line
<<
" ! "
;
}
line
<<
"filesink location=
\"
"
<<
file_name
<<
"
\"
"
;
cout
<<
"Created GStreamer writer ( "
<<
line
.
str
()
<<
" )"
<<
endl
;
video_size
<<
"width="
<<
fix_size
.
width
<<
", height="
<<
fix_size
.
height
;
return
makePtr
<
VideoWriter
>
(
line
.
str
(),
CAP_GSTREAMER
,
0
,
fps
,
sz
,
true
);
return
video_size
.
str
();
}
}
else
if
(
backend
==
"ffmpeg"
)
// Choose a video container
string
getGstMuxPlugin
()
{
{
ostringstream
plugin
;
cout
<<
"Created FFMpeg writer ( "
<<
file_name
<<
", FPS="
<<
fps
<<
", Size="
<<
sz
<<
" )"
<<
endl
;
if
(
container
==
"avi"
)
{
plugin
<<
"avi"
;
}
return
makePtr
<
VideoWriter
>
(
file_name
,
CAP_FFMPEG
,
getValue
(
fourccByCodec
(),
codec
,
"Invalid codec"
),
fps
,
sz
,
true
);
else
if
(
container
==
"mp4"
)
{
plugin
<<
"qt"
;
}
}
else
if
(
container
==
"mov"
)
{
plugin
<<
"qt"
;
}
return
Ptr
<
VideoWriter
>
();
else
if
(
container
==
"mkv"
)
{
plugin
<<
"matroska"
;
}
}
else
{
cout
<<
"Unsupported container: "
<<
container
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
if
(
mode
==
"decode"
)
{
plugin
<<
"demux"
;
}
//================================================================================
else
if
(
mode
==
"encode"
)
{
plugin
<<
"mux"
;
}
else
{
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
return
plugin
.
str
();
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"
))
{
cmd_parser
.
printMessage
();
return
0
;
}
}
bool
fast_measure
=
cmd_parser
.
has
(
"fast"
);
// fast measure fps
// Choose a libav codec
unsigned
fix_fps
=
cmd_parser
.
get
<
unsigned
>
(
"fps"
);
// fixed frame per second
string
getGstAvCodePlugin
()
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
())
{
{
ostringstream
plugin
;
cmd_parser
.
printErrors
();
if
(
mode
==
"decode"
)
return
-
1
;
{
if
(
codec
==
"h264"
)
{
plugin
<<
"h264parse ! "
;
}
else
if
(
codec
==
"h265"
)
{
plugin
<<
"h265parse ! "
;
}
plugin
<<
"avdec_"
;
}
else
if
(
mode
==
"encode"
)
{
plugin
<<
"avenc_"
;
}
else
{
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
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
;
cmd_parser
->
printErrors
();
return
string
();
}
return
plugin
.
str
();
}
}
if
(
mode
!=
"encode"
&&
mode
!=
"decode"
)
{
cout
<<
"Unsupported mode: "
<<
mode
<<
endl
;
return
-
1
;
}
cout
<<
"Mode: "
<<
mode
<<
", Backend: "
<<
backend
<<
", File: "
<<
file_name
<<
", Codec: "
<<
codec
<<
endl
;
// Choose a vaapi codec
TickMeter
total
;
string
getGstVaapiCodePlugin
()
Ptr
<
VideoCapture
>
cap
;
Ptr
<
VideoWriter
>
wrt
;
try
{
{
ostringstream
plugin
;
if
(
mode
==
"decode"
)
if
(
mode
==
"decode"
)
{
{
plugin
<<
"vaapidecodebin"
;
cap
=
createCapture
(
backend
,
file_name
,
codec
);
if
(
container
==
"mkv"
)
{
plugin
<<
" ! autovideoconvert"
;
}
if
(
!
cap
)
else
{
plugin
<<
" ! video/x-raw, format=YV12"
;
}
{
cout
<<
"Failed to create video capture"
<<
endl
;
return
-
3
;
}
if
(
!
cap
->
isOpened
())
{
cout
<<
"Capture is not opened"
<<
endl
;
return
-
4
;
}
}
}
else
if
(
mode
==
"encode"
)
else
if
(
mode
==
"encode"
)
{
{
if
(
codec
==
"h264"
)
{
plugin
<<
"vaapih264enc"
;
}
Size
sz
=
getValue
(
sizeByResolution
(),
resolution
,
"Invalid resolution"
);
else
if
(
codec
==
"h265"
)
{
plugin
<<
"vaapih265enc"
;
}
cout
<<
"FPS: "
<<
fix_fps
<<
", Frame size: "
<<
sz
<<
endl
;
else
if
(
codec
==
"mpeg2"
)
{
plugin
<<
"vaapimpeg2enc"
;
}
cap
=
createSynthSource
(
sz
,
fix_fps
);
else
if
(
codec
==
"mjpeg"
)
{
plugin
<<
"vaapijpegenc"
;
}
wrt
=
createWriter
(
backend
,
file_name
,
codec
,
sz
,
fix_fps
);
else
if
(
codec
==
"vp8"
)
{
plugin
<<
"vaapivp8enc"
;
}
if
(
!
cap
||
!
wrt
)
else
{
{
cout
<<
"Unsupported vaapi codec: "
<<
codec
<<
endl
;
cout
<<
"Failed to create synthetic video source or video writer"
<<
endl
;
cmd_parser
->
printErrors
();
return
-
3
;
return
string
();
}
if
(
!
cap
->
isOpened
()
||
!
wrt
->
isOpened
())
{
cout
<<
"Synthetic video source or video writer is not opened"
<<
endl
;
return
-
4
;
}
}
}
}
else
}
{
catch
(...)
cout
<<
"Unsupported mode: "
<<
resolution
<<
endl
;
{
cmd_parser
->
printErrors
();
cout
<<
"Unsupported parameters"
<<
endl
;
return
string
();
return
-
2
;
}
return
plugin
.
str
();
}
}
// 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
())
{
cout
<<
"No more frames - break"
<<
endl
;
break
;
}
if
(
!
cap
->
retrieve
(
frame
))
{
cout
<<
"Failed to retrieve frame - break"
<<
endl
;
break
;
}
if
(
frame
.
empty
())
{
cout
<<
"Empty frame received - break"
<<
endl
;
break
;
}
tick
.
stop
();
}
}
else
if
(
mode
==
"encode"
)
else
if
(
mode
==
"encode"
)
{
{
if
(
codec
==
"h264"
)
{
plugin
<<
"x264enc"
;
}
int
limit
=
100
;
else
if
(
codec
==
"h265"
)
{
plugin
<<
"x265enc"
;
}
while
(
!
cap
->
grab
()
&&
--
limit
!=
0
)
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
<<
"Skipping empty input frame - "
<<
limit
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
}
cap
->
retrieve
(
element
);
tick
.
start
();
*
wrt
<<
element
;
tick
.
stop
();
}
}
else
{
if
(
fast_measure
&&
tick
.
getCounter
()
>=
1000
)
cout
<<
"Unsupported mode: "
<<
resolution
<<
endl
;
cmd_parser
->
printErrors
();
return
string
();
}
return
plugin
.
str
();
}
// Get fourcc for codec
int
getFourccCode
()
{
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
{
{
cout
<<
"Unsupported ffmpeg codec: "
<<
codec
<<
endl
;
cout
<<
"Fast mode frame limit reached - break"
<<
endl
;
cmd_parser
->
printErrors
();
break
;
return
0
;
}
}
}
if
(
mode
==
"encode"
&&
tick
.
getCounter
()
>=
1000
)
// Check bad configuration
int
checkConfiguration
()
{
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
<<
"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