[webcam] Patch vflip pour uvcvideo

Reconnaissance et configuration du matériel / kernel linux
flx.foo
newbie
Messages : 1
Inscription : mar. 21 nov. 2006, 19:45

[webcam] Patch vflip pour uvcvideo

Message par flx.foo »

Mon Asus n10jc possède une webcam montée à l'envers. Jusqu'à présent un patch pour le module uvcvideo, me permettait de renverser l'image. Mais depuis que je tourne sous le noyau 2.6.32.2, le patch ne fonctionnait plus (la structure du module avait changé). Je pensais trouver rapidement une mide à jour du patch, mais sans succès. J'ai pris le décision de me pencher sur la question.
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");
Répondre