gstreamer 未刷新到文件接收器

Luc*_*uca 5 gstreamer

我有这个 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
Run Code Online (Sandbox Code Playgroud)

现在,我在 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>
Run Code Online (Sandbox Code Playgroud)

我将其连接到 QT 窗口并按如下方式播放:

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);
Run Code Online (Sandbox Code Playgroud)

这开始将视频流显示到我的 Qt 窗口上,文件test.mp4被创建并且大小开始增长。但是,当我退出应用程序时,该文件将无法播放。我有一种感觉,这是因为由于我调用而没有写入最后一位或一些标头信息:

gst_element_set_state (pipeline, GST_STATE_NULL);
Run Code Online (Sandbox Code Playgroud)

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

nay*_*ana 3

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

因此,在管道为空之前,请执行以下操作:

gst_element_send_event(pipeline, gst_event_new_eos());
Run Code Online (Sandbox Code Playgroud)

编辑检查 EOS 是否通过:

根据文件

EOS 事件将向下传输到管道中的接收器元素,然后在播放完所有缓冲数据后,将 GST_MESSAGE_EOS 发布到总线上。

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