gstreamer 没有刷新到文件接收器

gstreamer not flushing to the filesink

我有这个 gstreamer 管道,它从 coomand 行工作:

gst-launch-1.0 autovideosrc ! tee name = t ! queue ! omxh264enc ! 
'video/x-h264, stream-format=(string)byte-stream' ! h264parse ! qtmux 
! filesink name=fileSink location=test.mp4 t. ! queue ! videoscale ! 
video/x-raw, width=480,height=270 ! xvimagesink name=displaySink -e

现在,我在 C++ 端复制如下:

GstElement * pipeline = gst_parse_launch("autovideosrc ! tee name = t ! "
                    "queue ! omxh264enc ! video/x-h264, "
                    "stream-format=(string)byte-stream ! h264parse ! "
                    "qtmux ! filesink name=fileSink location=test.mp4 t. "
                    "! queue ! videoscale ! video/x-raw, width=480,height=270 ! "
                    "xvimagesink name=displaySink", &error);</raw>

我把它连接到 QT window 并按如下方式播放:

GstElement * displaySink = gst_bin_get_by_name (GST_BIN (pipeline), "displaySink");
qDebug() << displaySink;
// prepare the ui
QWidget window;
window.resize(480, 270);
window.show();

WId xwinid = window.winId();
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY(displaySink), xwinid);

// run the pipeline
qDebug() << "Calling run...";

GstStateChangeReturn sret = gst_element_set_state (pipeline,
                                                   GST_STATE_PLAYING);
if (sret == GST_STATE_CHANGE_FAILURE) {
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);
    // Exit application
    QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
}

int ret = app.exec();

window.hide();
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);

这将开始在我的 Qt window 上显示视频流,并且文件 test.mp4 已创建并且开始变大。但是,当我退出应用程序时,该文件无法播放。我有一种感觉,这是因为最后一位或某些 header 信息由于我调用而未写入:

gst_element_set_state (pipeline, GST_STATE_NULL);

我推测这可能会在未确保正确创建和完成文件的情况下关闭管道。有没有办法确保在关闭之前在管道上调用 EOF 或 EOS 并确保文件被正确写入?这也是我目前的猜测,但其他方面可能是错误的...

是的,发送 EOS 是必要的..

所以在管道的 NULLing 之前:

gst_element_send_event(pipeline, gst_event_new_eos());

编辑 检查 EOS 是否通过:

根据documentation

The EOS event will travel down to the sink elements in the pipeline which will then post the GST_MESSAGE_EOS on the bus after they have finished playing any buffered data.

这意味着要检查 EOS 事件是否成功通过管道,您可以使用 gst_bus_add_watch 添加总线监视回调并检查 GST_MESSAGE_EOS。