Итак, для моего проекта на последний год я использую Video4Linux2, чтобы извлекать изображения YUV420 с камеры, анализировать их до x264 (который использует эти изображения изначально), а затем отправлять закодированный поток через Live555 на RTP / RTCPсовместимый видеоплеер на клиенте по беспроводной сети.Все это я пытаюсь сделать в режиме реального времени, поэтому будет алгоритм управления, но это не является предметом этого вопроса.Все это, за исключением Live555, пишется на C. В настоящее время я близок к завершению кодирования видео, но хочу улучшить производительность.
По меньшей мере, я столкнулся с проблемой... Я пытаюсь избежать указателей пространства пользователя для V4L2 и использовать mmap ().Я кодирую видео, но так как это YUV420, я malloc'ing новую память для хранения плоскостей Y ', U и V в трех различных переменных для x264 для чтения.Я хотел бы сохранить эти переменные как указатели на часть памяти mmap.
Однако устройство V4L2 имеет один дескриптор файла для буферизованного потока, и мне нужно разделить поток на три mmap 'переменные ed, соответствующие стандарту YUV420, вот так ...
buffers[n_buffers].y_plane = mmap(NULL, (2 * width * height) / 3,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
buffers[n_buffers].u_plane = mmap(NULL, width * height / 6,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset +
((2 * width * height) / 3 + 1) /
sysconf(_SC_PAGE_SIZE));
buffers[n_buffers].v_plane = mmap(NULL, width * height / 6,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset +
((2 * width * height) / 3 +
width * height / 6 + 1) /
sysconf(_SC_PAGE_SIZE));
Где "ширина" и "высота" - это разрешение видео (например, 640x480).
Из чегоЯ понимаю ... MMAP просматривает файл, что-то вроде этого (псевдо-код):
fd = v4l2_open(...);
lseek(fd, buf.m.offset + (2 * width * height) / 3);
read(fd, buffers[n_buffers].u_plane, width * height / 6);
Мой код находится в репозитории панели запуска здесь (для дополнительной информации): http://bazaar.launchpad.net/~alex-stevens/+junk/spyPanda/files (Редакция 11)
И формат YUV420 хорошо виден из этой иллюстрации в вики: http://en.wikipedia.org/wiki/File:Yuv420.svg (я хочу разделить байты Y, U и V на каждый mmap'edпамять)
Кто-нибудь хочет объяснить способ преобразования трех переменных памяти в один дескриптор файла или почему я ошибся?Или даже намекнуть на лучшую идею для разбора буфера YUV420 на x264?: P
Ура!^^