Gstreamer appsrc в файл пуст - PullRequest
       94

Gstreamer appsrc в файл пуст

0 голосов
/ 03 июля 2019

Я работаю с инструментами Xilinx Petalinux и Vivado 2018.2, ориентированными на устройство Zynqmp с (блоком видеокодека) VCU.

Я разрабатываю приложение на основе gstreamer в Vivado SDK, целью которого является создание следующего конвейера:

  1. Захват видеокадров RAW с камеры USB3 (не может использовать v4l2, он использует собственный API для захвата кадров). Оберните кадры в GstBuffer и поместите его в appsrc элемент конвейера.
  2. Сжатие видео с помощью аппаратного VCU (H.264 / H.265). (* 1 010 * omxh264enc )
  3. Сохраните его в файл. ( filesink )

В настоящий момент я могу подключить камеру, получить кадры и обернуть их в тип GstBuffer.

Проблема в том, что сгенерированный файл "output.h264" пуст.

Соответствующая часть кода:

    /* Create pipeline */
pipeline = gst_parse_launch("appsrc is-live=TRUE name=xsource  caps= video/x-raw,format=Y800,width=1280,height=1024 ! omxh264enc ! filesink location= media/test/output.h264", NULL);
if(!pipeline)
    goto finish;

/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus, bus_call, NULL);
gst_object_unref (bus);

appsrc=gst_bin_get_by_name(GST_BIN(pipeline), "xsource");

gst_element_set_state(pipeline, GST_STATE_PLAYING);

if(xiGetImage(xiH, 5000, &image) == XI_OK) //Get just one frame
{

    unsigned long buffer_size = image.width*image.height;

    buffer = gst_buffer_new();
    gst_buffer_insert_memory(buffer, -1, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, (guint8*)image.bp, buffer_size, 0, buffer_size, NULL, NULL));
    ret = gst_app_src_push_buffer(GST_APP_SRC(appsrc), buffer);
    if(ret != GST_FLOW_OK){
        break;
    }

}

gst_app_src_end_of_stream(GST_APP_SRC(appsrc));
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline));

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

Любые идеи / подсказки будут оценены.

EDIT:

Как и предполагалось, я попытался дождаться подтверждения EOS и проверки сообщения об ошибке в конце кода:

gst_app_src_end_of_stream(GST_APP_SRC(appsrc));

  /* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg =
gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
      GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(pipeline));

Также я попытался загрузить больше кадров, чтобы посмотреть, помогает ли это, я попытался загрузить 500 следующим образом:

    while(xiGetImage(xiH, 5000, &image) == XI_OK)
{
    unsigned long buffer_size = image.width*image.height;

    buffer = gst_buffer_new();
    gst_buffer_insert_memory(buffer, -1, gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, (guint8*)image.bp, buffer_size, 0, buffer_size, NULL, NULL));

    ret = gst_app_src_push_buffer(GST_APP_SRC(appsrc), buffer);
    if(ret != GST_FLOW_OK){
        break;
    }

    if(frames > 500)
    {
         break;
    }else{
        frames++;
    }

}

Но, к сожалению, это не помогло, все еще с пустым файлом и без ошибок.

Есть еще идеи / подсказки?

Спасибо.

1 Ответ

0 голосов
/ 03 июля 2019

Большинство видеокодеров не создают никаких буферов, просто давая им один кадр. Они хотят смотреть в будущее ... или имеют некоторую задержку в своих внутренних конвейерах.

Так что, возможно, поможет добавление большего количества буферов.

Иначе, видеокодер, вероятно, выдаст вам кадр, если вы правильно скажете ему, что больше кадров не будет. Это означает: отправьте и EOS в конвейер и дождитесь прибытия события EOS на шину. Надеемся, что к этому времени кодировщик должен вставить этот один кадр в ваш файл.

РЕДАКТИРОВАТЬ: Я заметил, что вы уже отправили EOS. Возможно, вы захотите подождать EOS на шине, прежде чем устанавливать состояние конвейера в NULL.

...