How to assign multiple MMAPs from a single file descriptor?

So, for my project last year, I use Video4Linux2 to pull YUV420 images from the camera, analyze them up to x264 (which uses these images initially), and then send the encoded stream via Live555 to an RTP / RTCP compatible video player on the client wirelessly. I'm trying to do all this in real time, so there will be a control algorithm, but this is not a question of this issue. All of this - except for Live555 - is recorded in C. Currently, I am nearing the end of video encoding, but I want to improve performance.

At least I fell into a trap ... I am trying to avoid User Space Pointers for V4L2 and use mmap (). I am encoding a video, but since this is YUV420, I was compiling new memory to store Y, U, and V planes in three different variables for reading x264. I would like to save these variables as pointers to a massive piece of memory.

However, the V4L2 device has one file descriptor for the buffered stream, and I need to split the stream into three mmap'ed variables that adhere to the YUV420 standard, for example ...

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));

Where "width" and "height" is the resolution of the video (for example, 640x480).

From what I understand ... MMAP is looking for a file like this (pseudo-code):

fd = v4l2_open(...);
lseek(fd, buf.m.offset + (2 * width * height) / 3);
read(fd, buffers[n_buffers].u_plane, width * height / 6);

Launchpad Repo ( ): http://bazaar.launchpad.net/~alex-stevens/+junk/spyPanda/files ( 11)

YUV420 Wiki: http://en.wikipedia.org/wiki/File:Yuv420.svg ( Y, U, V )

- mmap ? YUV420 x264?: P

! ^^

+3
2

mmap s. mmap , .

: - :

unsigned char *y = mmap(...); /* map total size of all 3 planes */
unsigned char *u = y + y_height*y_bytes_per_line;
unsigned char *v = u + u_height*u_bytes_per_line;
+3

, : mmap 'uninterleave' . mmap ?

(: , fd. , .)

+1

All Articles