2015-11-26 3 views
2

Я проектирую конвейер для кодирования видеофрагмента из приложения opencv (полученного из веб-камеры) в формат видео/x-h264, отправляя его по сети и декодируя его на другом устройстве (вероятно, малиновый pi) для правильного потока RGB для моего проекта.Gstreamer Appsink не получает данные из конвейера

Для этого я должен использовать аппаратный ускоритель и декодер. Поскольку весь сценарий огромен, текущая разработка выполняется на машине Intel с использованием плагинов gstreamer VAAPI (vaapiencode_h264 & vaapidecode). А также тот факт, что нам нужно не использовать какие-либо из сетевых модулей, таких как TCPServer или UDPServer

Для этого я использовал ниже трубопровод для моей цели: На стороне кодера:

appsrc name=applicationSource ! videoconvert ! video/x-raw, format=I420, width=640, height=480,framerate=30/1, pixel-aspect-ratio=1/1,interlace-mode=progressive ! vaapiencode_h264 bitrate=600 tune=high-compression ! h264parse config-interval=1 ! appsink name=applicationSink sync=false 

Часть Appsrc работает отлично, в то время как часть приложения имеет некоторые проблемы с ней.

appsink часть этого трубопровода установлена ​​с указанными ниже колпачками:

«видео/X-H264, формат = (строка) {АВК, avc3, байты-поток}, выравнивание = (строка) {аи, NAL}; видео/MPEG, mpegversion = (целое) 2, профиль = (строка) простая»

код для извлечения данных из моего appsink является

bool HWEncoder::grabData() 
{ 

    // initial checks.. 

    if (!cameraPipeline) 
    { 

     GST_ERROR("ERROR AS TO NO PIPE FOUND ... Stopping FRAME GRAB HERE !! "); 
     return false; 
    } 


    if (gst_app_sink_is_eos (GST_APP_SINK(applicationSink))) 
    { 

     GST_WARNING("APP SINK GAVE US AN EOS! BAILING OUT "); 
     return false; 
    } 

    if (sample) 
    { 
     cout << "sample available ... unrefing it ! "<< endl; 
     gst_sample_unref(sample); 
    } 


    sample = gst_app_sink_pull_sample (GST_APP_SINK(applicationSink)); 

    if (!sample) 
    { 
     GST_WARNING("No valid sample"); 
     return false; // no valid sample pulled ! 
    } 

    sink_buffer = gst_sample_get_buffer(sample); 

    if (!sink_buffer) 
    { 
     GST_ERROR("No Valid Buffer ");return false; 
    } 

    return true; 
} 

После того, как воспитывающего конвейер и проверка заполнения буфера в моих приложениях, я застреваю в t он ниже указанных линий ofmy код на неопределенный срок:

sample = gst_app_sink_pull_sample (GST_APP_SINK(applicationSink)); 

У меня есть следующие вопросы: 1) Является ли мой Кепки appsink правильно? Если нет, как я могу определить колпачки для них? 2) Что-то не так в моем конвейере выше?

Как исправить эту проблему с помощью Appsink?

Любая помощь была бы полезна!

Спасибо!

+0

, так что вы не можете использовать даже udpsrc? это должен быть appsrc? – nayana

+0

Да, поскольку я получаю ввод от приложения Opencv ... –

ответ

1

Просто угадать (у меня были схожие проблемы) проблема с appsink и appsrc в том же конвейере может заключаться в том, что при заполнении/оповещении одного из них он блокирует другой (подробнее об этом ниже).

appsink и appsrc блокируются, когда они полны/пусты - это нормальное желаемое поведение. Существует опция drop для приложений или для appsrc есть опция block - но с их помощью это может быть просто обходным путем, и вы получите сбои в своем потоке. Правильное решение - лучше всего синхронизировать между appsrc и appsink.

Вы можете реагировать на сигналы appsrc enough-data и need-data - это наш путь. Также мы повозился со свойствами appsrc: is-live, do-timestamp и размер буфера (это может быть или может не помочь):

g_object_set(src->appsrc, 
    "stream-type", GST_APP_STREAM_TYPE_STREAM, 
    "format", GST_FORMAT_TIME, 
    "do-timestamp", TRUE, 
    "is-live", TRUE, 
    "block", TRUE, 
    NULL); 

Почему они блокируют друг друга? Потому что (я предполагаю) вы обрабатываете приложения и в то же время appsrc в основном приложении.Когда один из приложений apps/appsrc блокирует поток, никто не будет обрабатывать обработку для другого. Поэтому, когда appsink заблокирован, потому что у него нет данных, нет никого, кто мог бы загружать appsrc новыми данными - таким образом, бесконечный тупик.

Мы также внедрили noblock версию appsink * pull_sample, но это было всего лишь обходным решением и привело к большему количеству проблем, чем решения.

Если вы хотите отлаживать, что происходит вы можете добавить запись GST_DEBUG для appsrc/appsink (я не помню, что они были), вы можете добавить функцию обратного вызова по указанным сигналам enough-data и need-data или вы можете добавить очереди и включить GST_DEBUG = queue_dataflow: 5, чтобы увидеть, какая очередь заполняется первой и т. д. Это всегда полезно при отладке «блокировки данных».

+0

Как добавить отладку, специфичную для моего appsrc, в моем коде? Я искал в Интернете, чтобы выполнить это, однако, не повезло ... Не могли бы вы мне помочь? –

+0

Спасибо большое! Это сработало ... Была проблема синхронизации с моим конвейером ... внесли изменения в следующий appsrc, и все сработало хорошо! :) –