Всем привет!
Имею плату LeopardBoard с процессором dm368 от TI.
Задача: оцифровать видеопоток с аналоговой камеры и передать по сети.
Вторым этажем подключена плата АЦП tvp5146 для оцифровки аналогового видео формата PAL. Запускаю скрипт gstreamer'а, для захвата видеопотока с железки, кодирования в H.264 и стримминга его по RTP.
Работает отлично. Сам скрипт:
gst-launch -e v4l2src always-copy=FALSE input-src=composite chain-ipipe=true ! video/x-raw-yuv,format=\(fourcc\)NV12, width=1280, height=720 ! queue ! dmaiaccel ! dmaienc_h264 encodingpreset=2 ratecontrol=2 intraframeinterval=23 idrinterval=46 targetbitrate=3000000 ! rtph264pay ! udpsink port=$PORT host=$HOST_ADDR sync=false enable-last-buffer=false
Написал программу, использующая библиотеку gstreamer'a, «нативно» повторяющая скрипт, приведеный выше.
Отладил у себя на машине, на источнике данных videotestsrс - все отлично.
Поправил источник данных v4l2src, что бы захват делать с платы АЦП. Скомпилял под плату. Пишет segmentation. ну, думаю я где-то как обычно. После проверок вписываю источник данных videotestsrc и правлю капс под него, затем компиляю под плату - работает.
Включаю дебаг:
/home/user # export GST_DEBUG=2
/home/user # ./video-encode
.....
0:00:01.704663299 1205 0x12f160 WARN v4l2 ../../../src/sys/v4l2/gstv4l2bufferpool.c:203:gst_v4l2_buffer_new: Failed to mmap: Cannot allocate memory
Segmentation fault
Ну, вообщем понятно. Либа пыталась выделить память, не получилось. Обращение к левой стрицы памяти привело к падению.
Я не могу понять различия своего кода и скрипта. Чего я не учел?
Приведу часть своего кода:
/* Создание элементов */
GstCaps *video_caps = NULL;
e->pipeline = gst_pipeline_new ("pipeline");
//elements->v4l2src = gst_element_factory_make ("videotestsrc", "v4l2src");
e->v4l2src = gst_element_factory_make ("v4l2src", "v4l2src");
e->filter = gst_element_factory_make ("capsfilter", "filter");
e->accel = gst_element_factory_make ("dmaiaccel", "dmaiaccel");
e->encoder = gst_element_factory_make ("dmaienc_h264", "dmaienc_h264");
e->queue = gst_element_factory_make ("queue", "queue");
e->rtph264pay = gst_element_factory_make ("rtph264pay", "rtph264pay");
e->udpsink = gst_element_factory_make ("udpsink", "udpsink");
........
/* Video caps */
video_caps = gst_caps_new_simple("video/x-raw-yuv",
"format", G_TYPE_STRING, "NV12",
"width", G_TYPE_INT, DEFAULT_WIDTH,
"height", G_TYPE_INT, DEFAULT_HEIGHT,
NULL);
/* Инициализация свойств элементов */
g_object_set(G_OBJECT(e->filter), "caps", video_caps, NULL);
gst_caps_unref(video_caps);
........
/* Инициализация свойств элементов */
g_object_set(G_OBJECT(e->v4l2src),
//"device", "/dev/video0",
"input-src", "composite",
"always-copy", FALSE,
"chain-ipipe", TRUE,
//"num-buffers", 1,
NULL);
g_object_set(G_OBJECT(e->encoder),
//"profile", H264_BASE_LINE,
"encodingpreset", 2,
"ratecontrol", 2,
"intraframeinterval", DEFAULT_INTRAFRAME_INTERVAL,
"idrinterval", DEFAULT_IDRINTERVAL,
"targetbitrate", DEFAULT_BITRATE,
NULL);
g_object_set(G_OBJECT(e->udpsink),
"port", DEFAULT_PORT,
"host", DEFAULT_HOST_ADDR,
"sync", FALSE,
"enable-last-buffer", FALSE,
NULL);
.........
/* Добавляю и связываю */
gst_bin_add_many(GST_BIN(e->pipeline),
e->v4l2src, e->accel, e->encoder,
e->queue, e->rtph264pay, e->udpsink, NULL);
gst_element_link_many(e->v4l2src, e->accel, e->encoder,
e->queue, e->rtph264pay, e->udpsink, NULL);
.........
/* Запускаю */
gst_element_set_state(elements.pipeline, GST_STATE_PLAYING);
.........