2015-07-10 3 views
0

У меня проблема с GStreamer 1.0, когда в одном конвейере используется несколько appsrc. Конвейер получает данные из двух разных источников и смешивает их в одно видео, используя элемент видеомиксера. Трубопровод состоит в следующем:GStreamer multiple 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 \ 
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

Edit Вот код Я использую для запуска 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; 
} 

Я подтвердил, что размер и формат данных соответствуют просил один в крышках трубопроводов

Update 1:

После нескольких попыток, кажется, даже когда один appsrc используется в 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 \ 
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 
+0

Вероятно, у вас есть какой-то segfault. Можете ли вы запустить программу в отладчике и получить номер строки? Как минимум вам нужно вставить соответствующий источник, используемый вашими элементами appsrc. – mpr

+0

Я обновил свой вопрос кодом, который я использую, чтобы передать данные в конвейер. Об отладке приложения я попытался отлаживать его несколько раз, но приложение просто выходит без каких-либо исключений или сообщений, о которых сообщается, и не разбивается на какой-либо код строки или даже код сборки ... Я думаю, что после нескольких испытаний его связанный с видеомикшером, потому что, даже если бы я использовал один applicationrc, приложение сработало бы – yamens

ответ

0

Единственное, что я вижу, что это странно здесь:

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 и посмотреть, работает ли он? Сделайте каждый apprc просто заполнить свой буфер другим цветом.

Что вы используете для отладки? Если ваше приложение выходит из строя, отладчик должен остановиться и позволить вам изучить активные потоки и найти номер строки нарушения.

Смежные вопросы