Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:2
Поисковых ботовПоисковых ботов:2
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:5
Форум » starterkit.ru » Отладочные платы » Hola(Duo)-PC
VideoForLinux2 & HOLA-VCEB
muaddib
Добавлено 05.12.2014 11:58 Редактировалось 05.12.2014 11:58
0
Сообщение: 1
muaddib
0

Пункты: 1232
Регистрация: 20.11.2014
Программировал ли кто-нибудь захват изображения с HOLA-VCEB на С++ используя VideoForLinux2?

Выполняю команду modprobe mxc_v4l2_capture, для того чтобы /dev/video0 появился.
Использую стандартный код.
Привожу пример сокращенного кода:

//Открываю устройство
int vdev_fd = ::open(/dev/video0, O_RDWR);
//Задаю формат и разрешение
v4l2_format videopict;
videopict.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
videopict.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;
videopict.fmt.pix.width = 720;
videopict.fmt.pix.height = 576;
//Выделяю память
unsigned char *buf = new unsigned char[720 * 576 * 2];
//Читаю в цикле
read(vdev_fd, buf, 720 * 576 * 2);

В результате получаю 3 кадра/сек и вот такое изображение
http://savepic.su/4475971.jpg

Тот же самый код проверял для архитектуры x86 для платы Avermedia, все корректно работает и кадров/сек: 25.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 05.12.2014 12:38 Редактировалось 05.12.2014 12:43 Сообщение: 2
sasamy
4.71

Пункты: 83556
Регистрация: 14.08.2009
Если собираете в buildroot - включите в сборку

-> Target packages
-> Hardware handling
-> Freescale i.MX libraries
[*] imx-test

там есть примеры для захвата кадров с tv in, исходники после сборки можно найти в output/build/imx-test-xxx

Цитата

//Читаю в цикле
read(vdev_fd, buf, 720 * 576 * 2);
...
Тот же самый код проверял для архитектуры x86 для платы Avermedia, все корректно работает и кадров/сек: 25.


если надо отдельные кадры брать (1-2 в сек) можно и read использовать, а вообще о нем лучше забыть на arm-ах, используйте mmap или user-ptr
Спуститься к концу Подняться к началу
Персональная информация
muaddib
Добавлено 05.12.2014 12:45 Сообщение: 3
muaddib
0

Пункты: 1232
Регистрация: 20.11.2014
Спасибо попробую.
Спуститься к концу Подняться к началу
Персональная информация
muaddib
Добавлено 08.12.2014 08:50 Редактировалось 08.12.2014 08:52 Сообщение: 4
muaddib
0

Пункты: 1232
Регистрация: 20.11.2014
Не нашел imx-test, привожу скриншот

http://savepic.org/6617659.png
Спуститься к концу Подняться к началу
Персональная информация
muaddib
Добавлено 08.12.2014 11:52 Редактировалось 08.12.2014 12:08 Сообщение: 5
muaddib
0

Пункты: 1232
Регистрация: 20.11.2014
Скачал исходники vl42_grab
http://www.twam.info/linux/v4l2grab-grabbing-jpegs-from-v4l2-devices
Собрал под арм статически с библиотекой jpeg
gcc v4l2grab.c -o v4l2grab -static -Wall -ljpeg -DIO_READ -DIO_MMAP -DIO_USERPTR
Получаю картинки, используя read
http://savepic.org/6596147.jpg
Используя mmap
http://savepic.su/4497143.jpg
UsePtr не прошел программа выдала ошибку:
v4l2_grab: v4l2_grab.c:302: frameRead: Assertion `i < n_buffers' failed.
Aborted

Может существуют какие-то особенности работы с этой платой?
Спуститься к концу Подняться к началу
Персональная информация
muaddib
Добавлено 08.12.2014 12:37 Сообщение: 6
muaddib
0

Пункты: 1232
Регистрация: 20.11.2014
Непонятно, также как менять номер видеовхода платы.
VIDIOC_S_INPUT выдает ошибку если задаешь номер больше 1.
На 0 и 1 визуально ничего не меняется.
Спуститься к концу Подняться к началу
Персональная информация
muaddib
Добавлено 09.12.2014 14:58 Сообщение: 7
muaddib
0

Пункты: 1232
Регистрация: 20.11.2014
Скачал пример работы с платой mxc_v4l2_capture.c
https://github.com/boundarydevices/imx-linux-test/tree/imx_jb4.2.2_1.0.0-ga/test/mxc_v4l2_test
Используются специфичные команды для работы с драйвером, потому у меня и не получалось.
Насчет VIDIOC_S_INPUT здесь переключаются не входы на самой плате, а так называемые режимы в режиме номер 0, отображаются две камеры одна снизу, другая вверху. В режиме 1 отображается полностью одна камера, скриншоты прилагаются.
http://savepic.org/6657437.jpg
http://savepic.org/6650269.jpg

Не пытайтесь читать в режиме 1 в формате RGB24, будут не соотвествовать цвета, я читал в формате YUYV.

Не понятно теперь как выбирать нужный видеовход, но этот вопрос я опубликую отдельной темой.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 09.12.2014 17:15 Сообщение: 8
sasamy
4.71

Пункты: 83556
Регистрация: 14.08.2009
Цитата

Скачал исходники vl42_grab


Смотрите примеры на сайте Freescale

https://community.freescale.com/message/368297#368297
Спуститься к концу Подняться к началу
Персональная информация
danilsl
Добавлено 13.01.2015 23:26 Сообщение: 9
danilsl
1

Пункты: 4201
Регистрация: 08.12.2010
Пол: Мужчина
Код
int cx25858_camera::camsrc_open_device(char * camdev, int w, int h) {
int index;
struct v4l2_input input;
v4l2_std_id std_id;
struct v4l2_standard standard;
struct v4l2_capability capability;
struct v4l2_format fmt;
struct v4l2_requestbuffers req;
struct v4l2_frequency freq;
unsigned int i;

if (capture_fd != 0)
return -1;

capture_fd = open(camdev, O_RDWR);
if (capture_fd <= 0) {
printf("Cannot open = %s device\n", camdev);
return -1;
}
printf("Opened device %s\n", camdev);

if (ioctl(capture_fd, VIDIOC_G_INPUT, &index) < 0) {
printf("Error VIDIOC_G_INPUT\n");
camsrc_close_device();
return -1;
}
printf("Active input is %d\n", index);

memset(&input, 0, sizeof (input));
input.index = index;
if (ioctl(capture_fd, VIDIOC_ENUMINPUT, &input) < 0) {
printf("Error VIDIOC_ENUMINPUT\n");
}
printf("%s: Current Input: %s\n", camdev, input.name);

if (ioctl(capture_fd, VIDIOC_QUERYSTD, &std_id) < 0) {
printf("Error VIDIOC_QUERYSTD\n");
}

std_id = V4L2_STD_PAL_BG;
if (ioctl(capture_fd, VIDIOC_S_STD, &std_id) < 0) {
printf("Error VIDIOC_G_STD\n");
} else
printf("std_id = %d\n", (int) std_id);

memset(&standard, 0, sizeof (standard));
standard.index = 0;
while (1) {
if (ioctl(capture_fd, VIDIOC_ENUMSTD, &standard) < 0) {
printf("Error VIDIOC_ENUMSTD\n");
break;
}
/* Store the name of the standard */
printf("std.id=%d std.name=%s\n", (int) standard.id, standard.name);
if (standard.id & std_id) {
printf("%s: Current standard: %s\n", camdev, standard.name);
//break;
}
standard.index++;
}

memset(&capability, 0, sizeof (capability));
if (ioctl(capture_fd, VIDIOC_QUERYCAP, &capability) < 0) {
printf("Error VIDIOC_QUERYCAP\n");
camsrc_close_device();
return -1;
}
if (capability.capabilities & V4L2_CAP_STREAMING)
printf("%s: Capable of streaming\n", camdev);
else {
printf("%s: Not capable of streaming\n", camdev);
camsrc_close_device();
return -1;
}

memset(&fmt, 0, sizeof (fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(capture_fd, VIDIOC_G_FMT, &fmt) < 0) {
printf("Error VIDIOC_G_FMT\n");
camsrc_close_device();
return -1;
}

printf("Video size is %dx%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height);

fmt.fmt.pix.width = w;
fmt.fmt.pix.height = h;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
//fmt.fmt.pix.field = V4L2_FIELD_NONE;
if (ioctl(capture_fd, VIDIOC_S_FMT, &fmt) < 0) {
printf("Error VIDIOC_S_FMT\n");
camsrc_close_device();
return -1;
}

if (ioctl(capture_fd, VIDIOC_G_FMT, &fmt) < 0) {
printf("Error VIDIOC_G_FMT\n");
camsrc_close_device();
return -1;
}
printf("Capture size is %dx%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
width = fmt.fmt.pix.width;
height = fmt.fmt.pix.height;
// if (fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
// printf("Pixel format is V4L2_PIX_FMT_YUYV\n");



memset(&req, 0, sizeof (req));
req.count = NUM_BUFFERS;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;

if (ioctl(capture_fd, VIDIOC_REQBUFS, &req) < 0) {
printf("Cannot allocate memory. Error VIDIOC_REQBUFS\n");
camsrc_close_device();
return -1;
}

printf("%s: Number of requested buffers = %d\n", camdev, req.count);

buffers = (buffer*) calloc(req.count, sizeof (*buffers));

for (i = 0; i < req.count; i++) {
struct v4l2_buffer buf;
memset(&buf, 0, sizeof (buf));
buf.type = req.type;
buf.memory = req.memory;
buf.index = i;
if (ioctl(capture_fd, VIDIOC_QUERYBUF, &buf) < 0) {
printf("Error VIDIOC_QUERYCAP\n");
allocbufs = i;
camsrc_close_device();
return -1;
}
buffers[i].length = buf.length;
buffers[i].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
MAP_SHARED, capture_fd, buf.m.offset);
if (buffers[i].start == MAP_FAILED) {
printf("Cannot mmap = %d buffer\n", i);
allocbufs = i;
camsrc_close_device();
return -1;
}
memset((void *) buffers[i].start, 0x80, buffers[i].length);
if (ioctl(capture_fd, VIDIOC_QBUF, &buf)) {
printf("Error VIDIOC_QBUF\n");
allocbufs = i;
camsrc_close_device();
return -1;
}
printf("Allocated buffer %d with length %d\n", i, buffers[i].length);
bufLenght = buffers[i].length;
}
allocbufs = NUM_BUFFERS;

return 0;
}

Код
int cx25858_camera::startCapturing() {
enum v4l2_buf_type type;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(capture_fd, VIDIOC_STREAMON, &type)) {
printf("Error VIDIOC_STREAMON\n");
return -1;
}
return 0;
}

Код
int cx25858_camera::getFrame() {
struct v4l2_buffer capture_buf;
memset(&capture_buf, 0, sizeof (capture_buf));
capture_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
capture_buf.memory = V4L2_MEMORY_MMAP;
if (ioctl(capture_fd, VIDIOC_DQBUF, &capture_buf)) {
printf("Error VIDIOC_DQBUF\n");
return -1;
}
if (capture_buf.index >= NUM_BUFFERS) {
printf("Invalid buffer\n");
return -1;
}

memcpy(rawBuffer, buffers[capture_buf.index].start,
buffers[capture_buf.index].length);

if (ioctl(capture_fd, VIDIOC_QBUF, &capture_buf)) {
printf("Error VIDIOC_QBUF\n");
return -1;
}
return 0;
}

Это кусок класса, но основное здесь есть. Код писался для коннексантовского захвата с кривым драйвером, с которым не захотели работать ни gstreamer, ни opencv. Но с тех пор этот код работал на любых аналоговых захватах, что мне попадали.
А read() использует слишком много ресурсов камня. А в камне не всё гладко с прямым чтением из CSI.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Отладочные платы » Hola(Duo)-PC