#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(); }