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