从暂停到播放时 Gstreamer 管道失败?
Posted
技术标签:
【中文标题】从暂停到播放时 Gstreamer 管道失败?【英文标题】:Gstreamer pipeline failing when going from PAUSED TO PLAYING? 【发布时间】:2021-09-14 18:07:41 【问题描述】:首先,我运行以下命令将我的所有管道元素设置为暂停:int ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
接下来,我检查所有管道组件以确保它们处于暂停状态(它们是):
GstElement(imagesaver), status = PAUSED, pending = VOID_PENDING
GstElement(saveImageTee), status = PAUSED, pending = VOID_PENDING
GstElement(imagevideoconvert), status = PAUSED, pending = VOID_PENDING
GstElement(imagecapsfilter), status = PAUSED, pending = VOID_PENDING
GstElement(imagevideocrop), status = PAUSED, pending = VOID_PENDING
GstElement(videomuxer), status = PAUSED, pending = VOID_PENDING
GstElement(h264encoder), status = PAUSED, pending = VOID_PENDING
GstElement(imagequeue), status = PAUSED, pending = VOID_PENDING
GstElement(featurescanner), status = PAUSED, pending = PAUSED
GstElement(scannerqueue), status = PAUSED, pending = VOID_PENDING
GstElement(cfilter), status = PAUSED, pending = VOID_PENDING
GstElement(videoconversion), status = PAUSED, pending = VOID_PENDING
GstElement(convertqueue), status = PAUSED, pending = VOID_PENDING
GstElement(crop), status = PAUSED, pending = VOID_PENDING
GstElement(cropQueue), status = PAUSED, pending = VOID_PENDING
GstElement(source), status = PAUSED, pending = VOID_PENDING
然后我尝试播放我的管道:
int ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
这导致我的所有元素都设置为NULL
状态
GstElement(imagesaver), status = NULL, pending = VOID_PENDING
GstElement(saveImageTee), status = NULL, pending = VOID_PENDING
GstElement(imagevideoconvert), status = NULL, pending = VOID_PENDING
GstElement(imagecapsfilter), status = NULL, pending = VOID_PENDING
GstElement(imagevideocrop), status = NULL, pending = VOID_PENDING
GstElement(videomuxer), status = NULL, pending = VOID_PENDING
GstElement(h264encoder), status = NULL, pending = VOID_PENDING
GstElement(imagequeue), status = NULL, pending = VOID_PENDING
GstElement(featurescanner), status = NULL, pending = VOID_PENDING
GstElement(scannerqueue), status = NULL, pending = VOID_PENDING
GstElement(cfilter), status = NULL, pending = VOID_PENDING
GstElement(videoconversion), status = NULL, pending = VOID_PENDING
GstElement(convertqueue), status = NULL, pending = VOID_PENDING
GstElement(crop), status = NULL, pending = VOID_PENDING
GstElement(cropQueue), status = NULL, pending = VOID_PENDING
GstElement(source), status = NULL, pending = VOID_PENDING
我得到这个输出的错误信息是:
Setting pipeline to Play state
Pipeline would not play, returned 2
返回值 2 是:GST_STATE_CHANGE_ASYNC
,我认为可以通过将 fileSink 异步属性设置为 false 来修复它:
g_object_set(G_OBJECT (fileSink), "async", gboolean(FALSE), NULL);
这是我在暂停状态后调用来播放管道的函数:
void ScanningProcessor::PlayPipeline()
gst_element_set_state(GST_ELEMENT(fileSink), GST_STATE_PLAYING);
if(GST_STATE(pipeline) != GST_STATE_NULL)
MBPLog::Log(LM_CameraLibrary, LS_Informational, "Setting pipeline to Play state");
int ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if(ret != GST_STATE_PLAYING)
MBPLog::Log(LM_CameraLibrary, LS_Error, "Pipeline would not play, returned %d", ret);
gst_element_set_state (pipeline, GST_STATE_NULL);
【问题讨论】:
这可能需要一些调试才能看到根本情况。如果您提供Minimal, Reproducible Example 以便人们可以提供帮助,将会有所帮助。if(GST_STATE(pipeline) != GST_STATE_NULL)
- 您的代码不会抛出异常或弹出错误。放入一些显示错误的代码。
@moi 我的代码总是进入那部分代码,因为管道处于暂停状态。然后,当我播放管道时,我得到一个返回值 1,这意味着成功,但管道元素都是 NULL 而不是 PLAYING 所以它不工作
在gst_element_set_state(pipeline, GST_STATE_PLAYING);
之前尝试gst_element_set_state(pipeline, GST_STATE_NULL);
@moi 没有解决问题。有什么东西阻碍了我在管道中播放的过渡。
【参考方案1】:
根据您的管道的外观,进入 PLAYING 状态将始终异步发生(因此返回值 GST_STATE_CHANGE_ASYNC
)。这是有道理的(例如:在某些情况下,设置连接、获取数据等需要一些时间),但与您的预期不同。
换句话说,如果你真的想检查你是否进入播放状态,你应该调用gst_element_get_state()
,它实际上等待(并因此阻塞你的线程)状态改变发生。
GstStateChangeReturn ret;
GstState state;
GstState pending;
ret = gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
if (ret == GST_STATE_CHANGE_FAILURE)
MBPLog::Log(LM_CameraLibrary, LS_Error, "Pipeline would not play");
return; // or whatever cleanup you want
else
MBPLog::Log(LM_CameraLibrary, LS_Informational, "Pipeline is now in Playing state");
// If you specified an actual timeout instead of GST_CLOCK_TIME_NONE,
// you should check here if the return value is still
// GST_STATE_CHANGE_SUCCESS of course.
【讨论】:
将 async 参数设置为 false 不能解决这个问题吗?顺便说一句,在完成我刚才描述的操作后,我不再获得 GST_STATE_CHANGE_ASYNC 的返回值。我现在得到一个返回值 1,这意味着成功,但是当我检查我的管道元素时,它们都是 NULL 而不是 PLAYING以上是关于从暂停到播放时 Gstreamer 管道失败?的主要内容,如果未能解决你的问题,请参考以下文章