[英]GStreamer multiple appsrc cause the application to crash
当在同一管道中使用多个appsrc时,GStreamer 1.0出现问题。 管道从两个不同的源接收数据,并使用videomixer元素将它们混合为单个视频。 管道如下:
videomixer name=mix \
appsrc name=src0 ! video/x-raw,format=RGB,width=640,height=480,framerate=60/1 ! videoconvert ! video/x-raw,format=I420 ! videobox left=-0 ! mix.sink_0 \
appsrc name=src1 ! video/x-raw,format=RGB,width=640,height=480,framerate=60/1 ! videoconvert ! video/x-raw,format=I420 ! videobox left=-640 ! mix.sink_1 \
mix. ! videoconvert ! autovideosink sync=false
每个appsrc使用以下命令注册回调函数:GstAppSrcCallbacks
当我运行该应用程序时,它在每个appsrc收到两三个帧后立即崩溃(随机崩溃)。 在控制台或管道总线消息侦听器中未报告任何错误。 我根本没有收到任何错误消息。
如果我尝试在没有混音器的情况下使用单个appsrc进行运行,则它可以毫无问题地运行:
appsrc name=src0 ! video/x-raw,format=RGB,width=640,height=480,framerate=60/1 ! videoconvert ! video/x-raw,format=I420 ! videoconvert ! autovideosink sync=false
GStreamer版本:1.5.2 / Windows
编辑这是我用来初始化appsrc的代码:
GstAppSrcCallbacks srcCB;
GstAppSrc* videoSrc;
videoSrc = GST_APP_SRC(gst_bin_get_by_name(GST_BIN(GetPipeline()), "src0"));
srcCB.need_data = &start_feed;
srcCB.enough_data = &stop_feed;
srcCB.seek_data = &seek_data;
gst_app_src_set_callbacks(videoSrc, &srcCB, this, NULL);
static void start_feed(GstAppSrc *source, guint size, gpointer data)
{
VideoSrcData* o = static_cast<VideoSrcData*>(data);
if (o->sourceID == 0) {
GST_DEBUG("start feeding");
o->sourceID = g_idle_add((GSourceFunc)read_data, o);
}
}
static gboolean read_data(VideoSrcData *d)
{
GstFlowReturn ret;
GstBuffer *buffer;
if (NeedBuffer(0, &buffer) == GST_FLOW_OK)
{
ret = gst_app_src_push_buffer(d->videoSrc, buffer);
if (ret != GST_FLOW_OK){
ret = gst_app_src_end_of_stream(d->videoSrc);
return FALSE;
}
}
return TRUE;
}
GstFlowReturn NeedBuffer(GstMySrc * sink, GstBuffer ** buffer)
{
if (!m_grabber->GrabFrame()) //ask video grabber to prepare image frame
{
return GST_FLOW_ERROR;
}
m_grabber->Lock();
//Get Image frame
const video::ImageInfo* ifo = m_grabber->GetLastFrame();
int len = ifo->imageDataSize;
GstMapInfo map;
GstBuffer* outbuf = gst_buffer_new_and_alloc(len);
gst_buffer_map(outbuf, &map, GST_MAP_WRITE);
memcpy(map.data, ifo->imageData, len);
gst_buffer_unmap(outbuf, &map);
m_grabber->Unlock();
*buffer = outbuf;
return GST_FLOW_OK;
}
我确认数据大小和格式与管道上限所要求的相匹配
更新1:
经过多次试验,似乎即使在混音器中使用了一个appsrc,该应用程序也会崩溃。 管道示例:
videomixer name=mix \
appsrc name=src0 ! video/x-raw,format=RGB,width=640,height=480,framerate=60/1 ! videoconvert ! video/x-raw,format=I420 ! videobox left=-0 ! mix.sink_0 \
videotestsrc ! video/x-raw,format=RGB,width=640,height=480,framerate=60/1 ! videoconvert ! video/x-raw,format=I420 ! videobox left=-640 ! mix.sink_1 \
mix. ! videoconvert ! autovideosink sync=false
我唯一奇怪的是在这里:
GstAppSrcCallbacks srcCB;
GstAppSrc* videoSrc;
videoSrc = GST_APP_SRC(gst_bin_get_by_name(GST_BIN(GetPipeline()), "src0"));
srcCB.need_data = &start_feed;
srcCB.enough_data = &stop_feed;
srcCB.seek_data = &seek_data;
您指向某个函数的地址的地方,实际上您应该只能够对其进行分配。
srcCB.need_data = start_feed;
srcCB.enough_data = stop_feed;
srcCB.seek_data = seek_data;
另外,您可以尝试不使用m_grabber对象,看看它是否有效吗? 使每个appsrc用不同的颜色填充其缓冲区。
您正在使用什么进行调试? 如果您的应用崩溃,调试器应停止运行,并允许您检查活动线程并查找有问题的行号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.