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 是否通过:
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。
我有这个 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 是否通过:
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。