2017-04-14 429 views
0

我使用OpenCV捕獲和處理視頻幀,我想將它們編寫爲h265視頻文件。我正努力從OpenCV獲得一個合適的Gstreamer管道。使用VideoWriter從OpenCV打開GStreamer管道

Gstreamer自行工作良好。特別是,我能夠運行這個命令,它很快編碼視頻(感謝GPU加速),並將其保存到一個MKV文件:

gst-launch-1.0 videotestsrc num-buffers=90 ! 'video/x-raw, format=(string)I420, width=(int)640, height=(int)480' ! omxh265enc ! matroskamux ! filesink location=test.mkv 

現在我想從我的OpenCV內做同樣的事情應用。我的代碼是這樣的:

Mat img_vid = Mat(1024, 1024, CV_8UC3); 

VideoWriter video; 
video.open("appsrc ! autovideoconvert ! omxh265enc ! matroskamux ! filesink location=test.mkv", 0, (double)25, cv::Size(1024, 1024), true); 

if (!video.isOpened()) { 
    printf("can't create writer\n"); 
    return -1; 
} 

while (...) { 

    // Capture frame into img_vid => That works fine 

    video.write(img_vid); 

    ... 
} 

乍一看,這似乎是工作,但它的作用是它創建了一個名爲"appsrc ! autovideoconvert ! omxh265enc ! matroskamux ! filesink location=test.mkv"文件並與未壓縮的視頻幀填充它,完全忽略了一個事實,這是一個Gstreamer管道

我已經嘗試過其他的管道,但他們造成的各種錯誤:

video.open("appsrc ! autovideoconvert ! omxh264enc ! 'video/x-h264, streamformat=(string)byte-stream' ! h264parse ! qtmux ! filesink location=test.mp4 -e", 0, (double)25, cv::Size(1024, 1024), true); 

導致:

(Test:5533): GStreamer-CRITICAL **: gst_element_make_from_uri: assertion 'gst_uri_is_valid (uri)' failed OpenCV Error: Unspecified error (GStreamer: cannot find appsrc in manual pipeline) in CvVideoWriter_GStreamer::open, file /home/ubuntu/opencv/modules/videoio/src/cap_gstreamer.cpp, line 1363 VIDEOIO(cvCreateVideoWriter_GStreamer(filename, fourcc, fps, frameSize, is_color)): raised OpenCV exception:

/home/ubuntu/opencv/modules/videoio/src/cap_gstreamer.cpp:1363: error: (-2) GStreamer: cannot find appsrc in manual pipeline in function CvVideoWriter_GStreamer::open

我也試過簡單:

video.open("appsrc ! autovideosink", 0, (double)25, cv::Size(1024, 1024), true); 

其產率如下:

GStreamer Plugin: Embedded video playback halted; module appsrc0 reported: Internal data flow error.

我正在使用OpenCV 3.1和Gstreamer支持。硬件是帶L4T 24.2.1的Jetson TX1。

回答

5

我以前遇到過類似的問題。由於管道/文件名以.mkv結尾,因此OpenCV將其解釋爲視頻文件而不是管道。

你可以嘗試用一個虛擬的空間像mkv

video.open("appsrc ! autovideoconvert ! omxh265enc ! matroskamux ! filesink location=test.mkv ", 0, (double)25, cv::Size(1024, 1024), true); 

後或類似

video.open("appsrc ! autovideoconvert ! omxh265enc ! matroskamux ! filesink location=test.mkv sync=false", 0, (double)25, cv::Size(1024, 1024), true); 
+0

它的工作原理虛擬財產的結局吧!!!!哦,男人,非常感謝你。我在這上面花了很多時間,不知道有什麼問題...... –

+0

嗨,先生!我如何將圖像寫入/推送到RTMP管道,而不是文件? –

+0

這不適合我。它仍然寫入一個文件,該文件的名稱是整個Gstreamer管道,無論末端是否有空格或虛擬屬性(GStreamer 1.12.4,Mac OSX 10.13.3)。 –