Gstreamer Appsink не получает данные из конвейера

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

Для этого я должен использовать Encoder и Decoder с аппаратным ускорением.
Поскольку весь сценарий огромен, текущая разработка выполняется на машине Intel с использованием плагинов VAAPI gstreamer (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 имеет некоторые проблемы с ней.

Часть appsink этого конвейера была установлена ​​с помощью следующих заглавных букв:

«video / x-h264, format = (string) {avc, avc3, byte-stream}, выравнивание = (string) {au, nal}; video / mpeg, mpegversion = (int) 2, profile = (string) simple «

Код для извлечения данных моей 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;
}

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

sample = gst_app_sink_pull_sample (GST_APP_SINK(applicationSink));

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

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

Любая помощь будет полезна!

Спасибо !!

2

Решение

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

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

Вы можете реагировать на сигналы приложения 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);

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

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

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]