【发布时间】:2023-03-10 03:10:01
【问题描述】:
我使用 GStreamer 库向我的 C++ 应用程序添加了一个 start-offset 选项。它基本上告诉应用程序从中间视频开始,而不是从头开始播放。
管道是这样创建的:filesrc location="file_path" ! qtdemux ! h264parse ! mppvideodec ! waylandsink。这就是我在硬件上获得最佳结果的原因,而且我在 Weston (wayland) 下运行
我在管道上使用简单的gst_element_seek 进行搜索。首先,我尝试等到总线中的管道将状态更改为PLAYING 或PAUSED,然后再寻找一次。这行得通,但是在一些较大的视频上,它产生了一种效果,即在启动应用程序后,第一个视频帧会显示一秒钟,然后视频实际上会跳转到所需的位置。我不希望这样,我想直接跳到我想要的位置,而不显示任何其他内容。
因此,我什至在将管道设置为PLAYING 状态之前更改了我的搜索方法,如下所示:
// seek if needed
if(startTime > 0) {
// First set pipeline to PAUSED and wait for async state change
gst_element_set_state(m_pipeline, GST_STATE_PAUSED);
gst_element_get_state(m_pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE);
if (!gst_element_seek (m_pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, startTime, GST_SEEK_TYPE_NONE, -1)) {
g_print ("Seek failed!\n");
}
gst_element_get_state(m_pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE); // wait for seek to finish and then set to PLAYING
}
m_ret = gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
if (m_ret == GST_STATE_CHANGE_FAILURE) {
g_printerr("Unable to set the pipeline to the playing state.\n");
gst_object_unref(m_pipeline);
exit(0);
}
虽然这也有效,但不幸的是,它产生了与以前完全相同的效果......即使在管道启动之前搜索发生,第一帧仍在显示。
如何确保在真正完成搜索之前不显示任何内容?
更新
我无法获得任何方法来寻求我想要的工作,但是我通过在构建管道之前在 GstVideoSink 上设置show-preroll-frame 来实现效果,如下所示:
m_sink = gst_element_factory_make("waylandsink", "sink");
g_object_set(m_sink, "show-preroll-frame", FALSE, NULL); // prevent preroll frame when seeking
而且它有效!如果没有更好的方法,我会暂时使用它。搜索仍然在PAUSED 状态下完成,但视频直接从搜索点显示。
【问题讨论】:
-
看来用上面的方法搜索(播放前)使得第一帧看起来比状态改变后搜索更长...