Я работаю с инструментами Xilinx Petalinux и Vivado 2018.2, нацеленными на устройство Zynqmp с VCU (блок видеокодека).
Я разрабатываю приложение на основе gstreamer в Vivado SDK, целью которого является создание следующего конвейера:
- Захват видеокадров в формате RAW с камеры USB3 (не может использовать v4l2, он использует собственный API для захвата кадров). Перенос кадров в GstBuffer и отправка их в элемент конвейера appsrc.
- Сжимайте видео с помощью аппаратного VCU (H.264/H.265). (omxh264enc)
- Сохраните его в файл. (файлов)
На данный момент я могу подключить камеру, получить кадры и обернуть их в тип 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 работают нормально. Я подозреваю, что проблема может быть в определении цепочки конвейеров, но я безуспешно пробовал много конфигураций...
Буду признателен за любые идеи/подсказки.
ИЗМЕНИТЬ:
Как и было предложено, я попытался дождаться подтверждения 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++;
}
}
Но, к сожалению, это не помогло, файл по-прежнему пустой и ошибок нет.
Есть еще идеи/подсказки?
Спасибо.