【问题标题】:GStreamer multiple appsrc cause the application to crashGStreamer多个appsrc导致应用程序崩溃
【发布时间】:2015-07-10 04:56:25
【问题描述】:

当在同一管道中使用多个 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:

经过多次试验,似乎即使在 videomixer 中使用了一个 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

【问题讨论】:

  • 您可能遇到了某种类型的段错误。你能在调试器中运行程序并获得行号吗?您至少需要粘贴您的 appsrc 元素使用的相关源代码。
  • 我已经用我用来将数据推送到管道的代码更新了我的问题。关于调试应用程序,我尝试过多次调试,但应用程序只是退出而没有异常或报告任何消息,并且它不会在任何行代码甚至汇编代码处中断......我认为经过几次尝试与videomixer有关,因为即使我使用单个appsrc,应用程序也会崩溃

标签: c++ gstreamer


【解决方案1】:

我觉得唯一奇怪的是这里:

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 只用不同的颜色填充它们的缓冲区。

你用什么来调试?如果您的应用崩溃,调试器应该停止并允许您检查活动线程并找到有问题的行号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 2016-06-04
    • 2011-08-24
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多