Revision: 8308
          http://playerstage.svn.sourceforge.net/playerstage/?rev=8308&view=rev
Author:   thjc
Date:     2009-10-18 15:17:32 +0000 (Sun, 18 Oct 2009)

Log Message:
-----------
applied patch 2871554: Player SVN trunk: changes to camerav4l2

Modified Paths:
--------------
    code/player/trunk/server/drivers/camera/v4l2/camerav4l2.cc
    code/player/trunk/server/drivers/camera/v4l2/v4l2.c

Modified: code/player/trunk/server/drivers/camera/v4l2/camerav4l2.cc
===================================================================
--- code/player/trunk/server/drivers/camera/v4l2/camerav4l2.cc  2009-10-18 
15:01:34 UTC (rev 8307)
+++ code/player/trunk/server/drivers/camera/v4l2/camerav4l2.cc  2009-10-18 
15:17:32 UTC (rev 8308)
@@ -83,6 +83,7 @@
     - BGR3, RGB3 (24-bit RGB)
     - BGR4, RGB4 (32-bit RGB; will produce 24-bit color images)
     - BA81 (for sn9c1xx-based USB webcams)
+    - MJPG (for webcams producing MJPEG streams not decompressed by V4L2 
driver)
   - Note that not all capture modes are supported by Player's internal image
   format; in these modes, images will be translated to the closest matching
   internal format (e.g., BGR4 -> RGB888).
@@ -202,7 +203,7 @@
 
 #define MAX_CHANNELS 10
 
-extern PlayerTime * GlobalTime;
+#define IS_JPEG(ptr) ((((ptr)[0]) == 0xff) && (((ptr)[1]) == 0xd8))
 
 class CameraV4L2: public ThreadedDriver
 {
@@ -243,6 +244,7 @@
     int skip_frames;
     uint32_t format;
     int failsafe;
+    int jpeg;
 };
 
 CameraV4L2::CameraV4L2(ConfigFile * cf, int section)
@@ -267,6 +269,7 @@
   this->skip_frames = 0;
   this->format = 0;
   this->failsafe = 0;
+  this->jpeg = 0;
   memset(this->sources, 0, sizeof this->sources);
   memset(this->camera_addrs, 0, sizeof this->camera_addrs);
   this->sources_count = cf->GetTupleCount(section, "sources");
@@ -353,6 +356,11 @@
   {
     this->format = PLAYER_CAMERA_FORMAT_RGB888;
     this->bpp = 24;
+  } else if (!(strcmp(this->mode, "MJPG")))
+  {
+    this->format = PLAYER_CAMERA_FORMAT_RGB888;
+    this->bpp = 24;
+    this->jpeg = !0;
   } else
   {
     PLAYER_ERROR("Unknown pixel format");
@@ -487,6 +495,7 @@
   struct timespec tspec;
   const unsigned char * img;
   player_camera_data_t * data = NULL;
+  int i;
 
   for (;;)
   {
@@ -545,18 +554,45 @@
     data->fdiv        = 0;
     data->image_count = 0;
     data->image       = NULL;
-    data->compression = PLAYER_CAMERA_COMPRESS_RAW;
-    data->image_count = this->width * this->height * ((this->bpp) / 8);
-    assert(data->image_count > 0);
-    data->image = reinterpret_cast<uint8_t *>(malloc(data->image_count));
-    if (!(data->image))
+    if (!(this->jpeg))
     {
-      PLAYER_ERROR("Out of memory!");
-      free(data);
-      data = NULL;
-      continue;
+      data->compression = PLAYER_CAMERA_COMPRESS_RAW;
+      data->image_count = this->width * this->height * ((this->bpp) / 8);
+      assert(data->image_count > 0);
+      data->image = reinterpret_cast<uint8_t *>(malloc(data->image_count));
+      if (!(data->image))
+      {
+        PLAYER_ERROR("Out of memory!");
+        free(data);
+        data = NULL;
+        continue;
+      }
+      memcpy(data->image, img, data->image_count);
+    } else
+    {
+      data->compression = PLAYER_CAMERA_COMPRESS_JPEG;
+      memcpy(&i, img, sizeof(int));
+      data->image_count = i;
+      assert(data->image_count > 1);
+      if (!(IS_JPEG(img + sizeof(int))))
+      {
+        PLAYER_ERROR("Not a JPEG image...");
+        free(data);
+        data = NULL;
+        continue;
+      }
+      data->image = reinterpret_cast<uint8_t *>(malloc(data->image_count));
+      if (!(data->image))
+      {
+        PLAYER_ERROR("Out of memory!");
+        free(data);
+        data = NULL;
+        continue;
+      }
+      memcpy(data->image, img + sizeof(int), data->image_count);
     }
-    memcpy(data->image, img, data->image_count);
+    assert(data->image_count > 0);
+    assert(data->image);
     Publish(this->camera_addrs[this->current_source],
             PLAYER_MSGTYPE_DATA, PLAYER_CAMERA_DATA_STATE,
             reinterpret_cast<void *>(data), 0, NULL, false);

Modified: code/player/trunk/server/drivers/camera/v4l2/v4l2.c
===================================================================
--- code/player/trunk/server/drivers/camera/v4l2/v4l2.c 2009-10-18 15:01:34 UTC 
(rev 8307)
+++ code/player/trunk/server/drivers/camera/v4l2/v4l2.c 2009-10-18 15:17:32 UTC 
(rev 8308)
@@ -164,6 +164,7 @@
  int i, grabdepth;
  const unsigned char * buf;
  unsigned char * img;
+ int count, insize;
 
  if ((!(FG(fg)->grabbing)) || (!(FG(fg)->image))) return NULL;
  memset(&(FG(fg)->buffers[FG(fg)->grab_number].buffer), 0, sizeof 
FG(fg)->buffers[FG(fg)->grab_number].buffer);
@@ -189,7 +190,28 @@
   grabdepth = 3;
  }
  img = FG(fg)->image;
- for (i = 0; i < (FG(fg)->pixels); i++)
+ if ((FG(fg)->pixformat) == v4l2_fmtbyname("MJPG"))
+ { /* taken directly from v4lcapture.c (camerav4l driver code) */
+  insize = ((FG(fg)->pixels) * grabdepth) - sizeof(int);
+  count = insize - 1;
+  for (i = 1024; i < count; i++)
+  {
+   if (buf[i] == 0xff) if (buf[i + 1] == 0xd9)
+   {
+    insize = i + 10;
+    break;
+   }
+  }
+  if (insize > 1)
+  {
+    memcpy(img, &insize, sizeof(int));
+    memcpy(img + sizeof(int), buf, insize);
+  } else
+  {
+    fprintf(stderr, "Internal error\n");
+    return NULL;
+  }
+ } else for (i = 0; i < (FG(fg)->pixels); i++)
  {
   switch(FG(fg)->imgdepth)
   {
@@ -201,11 +223,11 @@
     img++; buf++;
     break;
    case 3:
-    img[0] = (unsigned char)((buf[FG(fg)->r] / 3) + (buf[FG(fg)->g] / 3) + 
(buf[FG(fg)->b] / 3));
+    img[0] = (unsigned char)((buf[FG(fg)->r] * 0.3) + (buf[FG(fg)->g] * 0.59) 
+ (buf[FG(fg)->b] * 0.11));
     img++; buf += 3;
     break;
    case 4:
-    img[0] = (unsigned char)((buf[FG(fg)->r] / 3) + (buf[FG(fg)->g] / 3) + 
(buf[FG(fg)->b] / 3));
+    img[0] = (unsigned char)((buf[FG(fg)->r] * 0.3) + (buf[FG(fg)->g] * 0.59) 
+ (buf[FG(fg)->b] * 0.11));
     img++; buf += 4;
     break;
    }
@@ -349,6 +371,10 @@
    free(fg);
    return NULL;
   }
+ } else if ((fg->pixformat) == v4l2_fmtbyname("MJPG"))
+ {
+  fg->r = 0; fg->g = 0; fg->b = 0;
+  fg->depth = 3;
  } else
  {
   fprintf(stderr, "unknown pixel format %s\n", pixformat);


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Playerstage-commit mailing list
Playerstage-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to