De plus, j'ai lu que le librairie v4l est censé détecter et renverser les cam. Mais pour la mienne cela ne marche pas.
Bref, voici un patch qui permet de palier au problème. En espérant que cela vous convienne.
Code : Tout sélectionner
--- uvc_video.c.orig 2009-12-03 04:51:21.000000000 +0100
+++ uvc_video.c 2010-01-07 17:55:49.000000000 +0100
@@ -460,6 +460,10 @@
if (len <= 0)
return;
+ /* Patch variables */
+ __u8 *mem_tmp, *ptr_tmp;
+ int i, k, row_size;
+
/* Copy the video data to the buffer. */
maxlen = buf->buf.length - buf->buf.bytesused;
mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
@@ -467,6 +471,51 @@
memcpy(mem, data, nbytes);
buf->buf.bytesused += nbytes;
+ /* Have the last copied bytes completed the current frame? */
+ if (nbytes == maxlen) {
+ /* Area where to save the upper half part of the original frame
+ * (just half in order to speed up the patch) before reversing.
+ */
+ mem_tmp = (__u8 *) kmalloc(buf->buf.bytesused / 2, GFP_ATOMIC);
+ if (mem_tmp != NULL ) {
+ /* Copy top-half part of frame in a temporary buffer */
+ memcpy(mem_tmp, queue->mem + buf->buf.m.offset,
+ buf->buf.bytesused / 2);
+ /* "row_size" does not depend only on the width of the
+ * frame, but also on the pixel color depth (bpp).
+ */
+ row_size = stream->cur_frame->wWidth * stream->format->bpp / 8;
+ /* The following cycle just copy full frame rows from
+ * the last one stored in "mem" (and going up) to the
+ * first one (and going down) stored in "mem" itself.
+ */
+ ptr_tmp = queue->mem + buf->buf.m.offset
+ + buf->buf.bytesused / 2;
+ /* When the top-half of the frame has been reversed,
+ * rows are copied from the last one stored in "mem_tmp"
+ * (and going up) into the bottom half part of "mem"
+ * buffer.
+ */
+ for (i = 0, k = buf->buf.bytesused / 2 - row_size;
+ i < buf->buf.bytesused;
+ i += row_size, k -= row_size) {
+ /* If the top-half of the frame has been
+ * revesed, then it is needed to split the
+ * source buffer from "mem" to "mem_tmp".
+ */
+ if (i == buf->buf.bytesused / 2) {
+ ptr_tmp = mem_tmp;
+ k = buf->buf.bytesused / 2 - row_size;
+ }
+ memcpy(queue->mem + buf->buf.m.offset + i,
+ ptr_tmp + k,
+ row_size);
+ }
+ /* For this frame "mem_tmp" is not needed any more. */
+ kfree(mem_tmp);
+ }
+ }
+
/* Complete the current frame if the buffer size was exceeded. */
if (len > maxlen) {
uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");