我有这个 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 并确保文件正确写入?这也是我目前的猜测,但其他可能是错误的......
是的,发送 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。