From 725231996600349b410543fd3307a7746a420fed Mon Sep 17 00:00:00 2001 From: Alexander Nesterov Date: Mon, 12 Mar 2018 13:08:15 +0000 Subject: [PATCH] Added gstreamer pipeline sample --- samples/cpp/gstreamer_pipeline.cpp | 151 +++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 samples/cpp/gstreamer_pipeline.cpp diff --git a/samples/cpp/gstreamer_pipeline.cpp b/samples/cpp/gstreamer_pipeline.cpp new file mode 100644 index 0000000000..4e3f108b48 --- /dev/null +++ b/samples/cpp/gstreamer_pipeline.cpp @@ -0,0 +1,151 @@ +#include "opencv2/core/utility.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/imgcodecs.hpp" +#include "opencv2/highgui.hpp" +#include +#include + +using namespace std; +using namespace cv; + +string getGstDemuxPlugin(string container); +string getGstAvDecodePlugin(string codec); + +int main(int argc, char *argv[]) +{ + const string keys = + "{h help usage ? | | print help messages }" + "{p pipeline |gst-default| pipeline name (supported: 'gst-default', 'gst-vaapi', 'gst-libav', 'ffmpeg') }" + "{ct container |mp4 | container name (supported: 'mp4', 'mov', 'avi', 'mkv') }" + "{cd codec |h264 | codec name (supported: 'h264', 'h265', 'mpeg2', 'mpeg4', 'mjpeg', 'vp8') }" + "{f file path | | path to file }" + "{fm fast | | fast measure fps }"; + + CommandLineParser parser(argc, argv, keys); + + parser.about("This program shows how to read a video file with GStreamer pipeline with OpenCV."); + + if (parser.has("help")) + { + parser.printMessage(); + return 0; + } + + bool arg_fast_measure = parser.has("fast"); // fast measure fps + string arg_pipeline = parser.get("pipeline"), // GStreamer pipeline type + arg_container = parser.get("container"), // container type + arg_codec = parser.get("codec"), // codec type + arg_file_name = parser.get("file"); // path to videofile + VideoCapture cap; + + if (!parser.check()) + { + parser.printErrors(); + return 0; + } + + // Choose the constructed GStreamer pipeline + if (arg_pipeline.find("gst") == 0) + { + ostringstream pipeline; + pipeline << "filesrc location=\"" << arg_file_name << "\""; + pipeline << " ! " << getGstDemuxPlugin(arg_container); + + if (arg_pipeline.find("default") == 4) { + pipeline << " ! decodebin"; + } + else if (arg_pipeline.find("vaapi1710") == 4) + { + pipeline << " ! vaapidecodebin"; + if (arg_container == "mkv") + { + pipeline << " ! autovideoconvert"; + } + else + { + pipeline << " ! video/x-raw, format=YV12"; + } + } + else if (arg_pipeline.find("libav") == 4) + { + pipeline << " ! " << getGstAvDecodePlugin(arg_codec); + } + else + { + parser.printMessage(); + cout << "Unsupported pipeline: " << arg_pipeline << endl; + return -4; + } + + pipeline << " ! videoconvert"; + pipeline << " n-threads=" << getNumThreads(); + pipeline << " ! appsink sync=false"; + cap = VideoCapture(pipeline.str(), CAP_GSTREAMER); + } + else if (arg_pipeline == "ffmpeg") + { + cap = VideoCapture(arg_file_name, CAP_FFMPEG); + } + else + { + parser.printMessage(); + cout << "Unsupported pipeline: " << arg_pipeline << endl; + return -4; + } + + // Choose a show video or only measure fps + cout << "_____________________________________" << '\n'; + cout << "Start measure frame per seconds (fps)" << '\n'; + cout << "Loading ..." << '\n'; + + Mat frame; + vector tick_counts; + + cout << "Start decoding: " << arg_file_name; + cout << " (" << arg_pipeline << ")" << endl; + + while(true) + { + int64 temp_count_tick = getTickCount(); + cap >> frame; + temp_count_tick = getTickCount() - temp_count_tick; + if (frame.empty()) { break; } + tick_counts.push_back(static_cast(temp_count_tick)); + if (arg_fast_measure && (tick_counts.size() > 1000)) { break; } + + } + double time_fps = sum(tick_counts)[0] / getTickFrequency(); + + 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 decoding: " << arg_file_name; + cout << " (" << arg_pipeline << ")" << endl; + return -5; + } + return 0; +} + +// Choose a video container +string getGstDemuxPlugin(string container) { + if (container == "avi") { return "avidemux"; } + else if (container == "mp4") { return "qtdemux"; } + else if (container == "mov") { return "qtdemux"; } + else if (container == "mkv") { return "matroskademux"; } + return string(); +} + +// Choose a codec +string getGstAvDecodePlugin(string codec) { + if (codec == "h264") { return "h264parse ! avdec_h264"; } + else if (codec == "h265") { return "h265parse ! avdec_h265"; } + else if (codec == "mpeg2") { return "avdec_mpeg2video"; } + else if (codec == "mpeg4") { return "avdec_mpeg4"; } + else if (codec == "mjpeg") { return "avdec_mjpeg"; } + else if (codec == "vp8") { return "avdec_vp8"; } + return string(); +}