Revision: 8831
http://playerstage.svn.sourceforge.net/playerstage/?rev=8831&view=rev
Author: jpgr87
Date: 2010-07-25 20:00:24 +0000 (Sun, 25 Jul 2010)
Log Message:
-----------
Applied patch #3034305: Player SVN: more camera fixes
Modified Paths:
--------------
code/player/trunk/client_libs/libplayerc/dev_camera.c
code/player/trunk/server/drivers/camera/CMakeLists.txt
code/player/trunk/server/drivers/camera/compress/cameracompress.cc
Added Paths:
-----------
code/player/trunk/server/drivers/camera/camerareq/
code/player/trunk/server/drivers/camera/camerareq/CMakeLists.txt
code/player/trunk/server/drivers/camera/camerareq/camerareq.cc
Modified: code/player/trunk/client_libs/libplayerc/dev_camera.c
===================================================================
--- code/player/trunk/client_libs/libplayerc/dev_camera.c 2010-07-23
17:12:01 UTC (rev 8830)
+++ code/player/trunk/client_libs/libplayerc/dev_camera.c 2010-07-25
20:00:24 UTC (rev 8831)
@@ -121,12 +121,18 @@
device->fdiv = data->fdiv;
device->compression = data->compression;
device->image_count = data->image_count;
- device->image = realloc(device->image,
sizeof(device->image[0])*device->image_count);
-
- if (device->image)
- memcpy(device->image, data->image, device->image_count);
- else
- PLAYERC_ERR1("failed to allocate memory for image, needed %u bytes\n",
sizeof(device->image[0])*device->image_count);
+ if (device->image_count > 0)
+ {
+ device->image = realloc(device->image,
sizeof(device->image[0])*device->image_count);
+ if (device->image)
+ memcpy(device->image, data->image, device->image_count);
+ else
+ PLAYERC_ERR1("failed to allocate memory for image, needed %u bytes\n",
sizeof(device->image[0])*device->image_count);
+ } else
+ {
+ if (device->image) free(device->image);
+ device->image = NULL;
+ }
}
else
PLAYERC_WARN2("skipping camera message with unknown type/subtype: %s/%d\n",
@@ -278,11 +284,18 @@
device->fdiv = data->fdiv;
device->compression = data->compression;
device->image_count = data->image_count;
- device->image = realloc(device->image, (sizeof device->image[0]) *
device->image_count);
- if (device->image)
- memcpy(device->image, data->image, device->image_count);
- else
- PLAYERC_ERR1("failed to allocate memory for image, needed %u bytes\n",
(sizeof device->image[0]) * device->image_count);
+ if (device->image_count > 0)
+ {
+ device->image = realloc(device->image, (sizeof device->image[0]) *
device->image_count);
+ if (device->image)
+ memcpy(device->image, data->image, device->image_count);
+ else
+ PLAYERC_ERR1("failed to allocate memory for image, needed %u bytes\n",
(sizeof device->image[0]) * device->image_count);
+ } else
+ {
+ if (device->image) free(device->image);
+ device->image = NULL;
+ }
player_camera_data_t_free(data);
return 0;
}
Modified: code/player/trunk/server/drivers/camera/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/camera/CMakeLists.txt 2010-07-23
17:12:01 UTC (rev 8830)
+++ code/player/trunk/server/drivers/camera/CMakeLists.txt 2010-07-25
20:00:24 UTC (rev 8831)
@@ -1,6 +1,7 @@
ADD_SUBDIRECTORY (v4l)
ADD_SUBDIRECTORY (v4l2)
ADD_SUBDIRECTORY (1394)
+ADD_SUBDIRECTORY (camerareq)
ADD_SUBDIRECTORY (camfilter)
ADD_SUBDIRECTORY (compress)
ADD_SUBDIRECTORY (cvcam)
Added: code/player/trunk/server/drivers/camera/camerareq/CMakeLists.txt
===================================================================
--- code/player/trunk/server/drivers/camera/camerareq/CMakeLists.txt
(rev 0)
+++ code/player/trunk/server/drivers/camera/camerareq/CMakeLists.txt
2010-07-25 20:00:24 UTC (rev 8831)
@@ -0,0 +1,2 @@
+PLAYERDRIVER_OPTION (camerareq build_camerareq ON)
+PLAYERDRIVER_ADD_DRIVER (camerareq build_camerareq SOURCES camerareq.cc)
Added: code/player/trunk/server/drivers/camera/camerareq/camerareq.cc
===================================================================
--- code/player/trunk/server/drivers/camera/camerareq/camerareq.cc
(rev 0)
+++ code/player/trunk/server/drivers/camera/camerareq/camerareq.cc
2010-07-25 20:00:24 UTC (rev 8831)
@@ -0,0 +1,269 @@
+/*
+ * Player - One Hell of a Robot Server
+ * Copyright (C) 2000 Brian Gerkey et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+/////////////////////////////////////////////////////////////////////////////
+//
+// Desc: Keeps on emitting PLAYER_CAMERA_REQ_GET_IMAGE request with given
+// interval; all received image frames are published on provided camera
+// interface. Typically used with point-and-shoot digicam devices
+// to simulate live image.
+// Author: Paul Osmialowski
+// Date: 25 Jul 2010
+//
+/////////////////////////////////////////////////////////////////////////////
+
+/** @ingroup drivers */
+/** @{ */
+/** @defgroup driver_camerareq camerareq
+ * @brief PLAYER_CAMERA_REQ_GET_IMAGE request emitter
+
+The camerareq driver keeps on emitting PLAYER_CAMERA_REQ_GET_IMAGE request with
+given interval; all received image frames are published on provided camera
+interface. Typically used with point-and-shoot digicam devices to simulate live
+image.
+
+...@par Compile-time dependencies
+
+- none
+
+...@par Provides
+
+- @ref interface_camera
+
+...@par Requires
+
+- @ref interface_camera
+
+...@par Configuration requests
+
+- none
+
+...@par Configuration file options
+
+- interval (float)
+ - Default: 10.0 (seconds)
+
+- sleep_nsec (integer)
+ - Default: 100000000 (=100ms which gives max 10 fps)
+ - timespec value for nanosleep()
+
+...@par Example
+
+...@verbatim
+driver
+(
+ name "camerareq"
+ requires ["camera:1"]
+ provides ["camera:0"]
+)
+...@endverbatim
+
+...@author Paul Osmialowski
+
+*/
+/** @} */
+
+#include <stddef.h>
+#include <time.h>
+#include <assert.h>
+#include <string.h>
+#include <pthread.h>
+#include <libplayercore/playercore.h>
+
+class Camerareq : public ThreadedDriver
+{
+public:
+ // Constructor; need that
+ Camerareq(ConfigFile * cf, int section);
+ virtual ~Camerareq();
+
+ virtual int MainSetup();
+ virtual void MainQuit();
+
+ // This method will be invoked on each incoming message
+ virtual int ProcessMessage(QueuePointer & resp_queue,
+ player_msghdr * hdr,
+ void * data);
+
+private:
+ virtual void Main();
+ player_devaddr_t p_camera_addr;
+ player_devaddr_t r_camera_addr;
+ Device * r_camera_dev;
+ double interval;
+ int sleep_nsec;
+};
+
+Camerareq::Camerareq(ConfigFile * cf, int section)
+ : ThreadedDriver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN)
+{
+ memset(&(this->p_camera_addr), 0, sizeof(player_devaddr_t));
+ memset(&(this->r_camera_addr), 0, sizeof(player_devaddr_t));
+ this->r_camera_dev = NULL;
+ this->interval = 0.0;
+ this->sleep_nsec = 0;
+ if (cf->ReadDeviceAddr(&(this->p_camera_addr), section, "provides",
PLAYER_CAMERA_CODE, -1, NULL))
+ {
+ this->SetError(-1);
+ return;
+ }
+ if (this->AddInterface(this->p_camera_addr))
+ {
+ this->SetError(-1);
+ return;
+ }
+ if (cf->ReadDeviceAddr(&this->r_camera_addr, section, "requires",
PLAYER_CAMERA_CODE, -1, NULL) != 0)
+ {
+ this->SetError(-1);
+ return;
+ }
+ this->interval = cf->ReadFloat(section, "interval", 10.0);
+ this->sleep_nsec = cf->ReadInt(section, "sleep_nsec", 100000000);
+ if ((this->sleep_nsec) <= 0)
+ {
+ PLAYER_ERROR("Invalid sleep_nsec value");
+ this->SetError(-1);
+ return;
+ }
+}
+
+Camerareq::~Camerareq() { }
+
+int Camerareq::MainSetup()
+{
+ if (Device::MatchDeviceAddress(this->r_camera_addr, this->p_camera_addr))
+ {
+ PLAYER_ERROR("attempt to subscribe to self");
+ return -1;
+ }
+ this->r_camera_dev = deviceTable->GetDevice(this->r_camera_addr);
+ if (!this->r_camera_dev)
+ {
+ PLAYER_ERROR("unable to locate suitable camera device");
+ return -1;
+ }
+ if (this->r_camera_dev->Subscribe(this->InQueue) != 0)
+ {
+ PLAYER_ERROR("unable to subscribe to camera device");
+ this->r_camera_dev = NULL;
+ return -1;
+ }
+ return 0;
+}
+
+void Camerareq::MainQuit()
+{
+ if (this->r_camera_dev) this->r_camera_dev->Unsubscribe(this->InQueue);
+ this->r_camera_dev = NULL;
+}
+
+Driver * Camerareq_Init(ConfigFile * cf, int section)
+{
+ return reinterpret_cast<Driver *>(new Camerareq(cf, section));
+}
+
+void Camerareq::Main()
+{
+ struct timespec ts;
+ double last_time = 0.0;
+ double t;
+ Message * msg = NULL;
+ player_camera_data_t * img = NULL;
+
+ for (;;)
+ {
+ ts.tv_sec = 0;
+ ts.tv_nsec = this->sleep_nsec;
+ nanosleep(&ts, NULL);
+ pthread_testcancel();
+ this->ProcessMessages();
+ pthread_testcancel();
+ GlobalTime->GetTimeDouble(&t);
+ if ((t - last_time) > (this->interval))
+ {
+ msg = this->r_camera_dev->Request(this->InQueue, PLAYER_MSGTYPE_REQ,
PLAYER_CAMERA_REQ_GET_IMAGE, NULL, 0, NULL, true); // threaded = true
+ if (!msg)
+ {
+ PLAYER_WARN("failed to send request");
+ pthread_testcancel();
+ continue;
+ }
+ if (!(msg->GetDataSize() > 0))
+ {
+ PLAYER_ERROR("empty data received");
+ delete msg;
+ msg = NULL;
+ pthread_testcancel();
+ continue;
+ }
+ img = reinterpret_cast<player_camera_data_t *>(msg->GetPayload());
+ if (!img)
+ {
+ PLAYER_WARN("NULL image received");
+ delete msg;
+ msg = NULL;
+ pthread_testcancel();
+ continue;
+ }
+ if (((img->width) > 0) && ((img->height) > 0) && ((img->image_count) >
0) && (img->image))
+ {
+ this->Publish(this->p_camera_addr, PLAYER_MSGTYPE_DATA,
PLAYER_CAMERA_DATA_STATE, reinterpret_cast<void *>(img), 0,
&(msg->GetHeader()->timestamp), true); // copy = true
+ }
+ delete msg;
+ msg = NULL;
+ img = NULL;
+ last_time = t;
+ }
+ pthread_testcancel();
+ }
+}
+
+int Camerareq::ProcessMessage(QueuePointer & resp_queue, player_msghdr * hdr,
void * data)
+{
+ player_msghdr_t newhdr;
+ Message * msg;
+
+ assert(hdr);
+ if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
PLAYER_CAMERA_DATA_STATE, this->r_camera_addr))
+ {
+ assert(data);
+ this->Publish(this->p_camera_addr, PLAYER_MSGTYPE_DATA,
PLAYER_CAMERA_DATA_STATE, data, 0, &(hdr->timestamp), true); // copy = true
+ return 0;
+ } else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ, -1,
this->p_camera_addr))
+ {
+ hdr->addr = this->r_camera_addr;
+ msg = this->r_camera_dev->Request(this->InQueue, hdr->type, hdr->subtype,
data, 0, NULL, true); // threaded = true
+ if (!msg)
+ {
+ PLAYER_WARN("failed to forward request");
+ return -1;
+ }
+ newhdr = *(msg->GetHeader());
+ newhdr.addr = this->p_camera_addr;
+ this->Publish(resp_queue, &newhdr, msg->GetPayload(), true); // copy =
true, do not dispose published data as we're disposing whole source message in
the next line
+ delete msg;
+ return 0;
+ }
+ return -1;
+}
+
+void camerareq_Register(DriverTable *table)
+{
+ table->AddDriver("camerareq", Camerareq_Init);
+}
Modified: code/player/trunk/server/drivers/camera/compress/cameracompress.cc
===================================================================
--- code/player/trunk/server/drivers/camera/compress/cameracompress.cc
2010-07-23 17:12:01 UTC (rev 8830)
+++ code/player/trunk/server/drivers/camera/compress/cameracompress.cc
2010-07-25 20:00:24 UTC (rev 8831)
@@ -89,6 +89,7 @@
/** @} */
#include <string.h>
+#include <stdio.h>
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
@@ -104,6 +105,8 @@
{
// Constructor
public: CameraCompress( ConfigFile* cf, int section);
+ // Destructor
+ public: virtual ~CameraCompress();
// Setup/shutdown routines.
public: virtual int MainSetup();
@@ -129,7 +132,7 @@
bool camera_subscribed;
// Output (compressed) camera data
- private: player_camera_data_t data;
+ private: player_camera_data_t imgdata;
// Image quality for JPEG compression
private: double quality;
@@ -142,7 +145,6 @@
private: int request_only;
};
-
Driver *CameraCompress_Init(ConfigFile *cf, int section)
{
return ((Driver*) (new CameraCompress(cf, section)));
@@ -156,7 +158,8 @@
CameraCompress::CameraCompress( ConfigFile *cf, int section)
: ThreadedDriver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN,
PLAYER_CAMERA_CODE)
{
- this->data.image = NULL;
+ this->imgdata.image_count = 0;
+ this->imgdata.image = NULL;
this->frameno = 0;
this->camera = NULL;
@@ -177,6 +180,16 @@
return;
}
+CameraCompress::~CameraCompress()
+{
+ if (this->imgdata.image)
+ {
+ delete []this->imgdata.image;
+ this->imgdata.image = NULL;
+ this->imgdata.image_count = 0;
+ }
+}
+
int CameraCompress::MainSetup()
{
// Subscribe to the camera.
@@ -203,10 +216,11 @@
{
camera->Unsubscribe(InQueue);
- if (this->data.image)
+ if (this->imgdata.image)
{
- delete []this->data.image;
- this->data.image = NULL;
+ delete []this->imgdata.image;
+ this->imgdata.image = NULL;
+ this->imgdata.image_count = 0;
}
}
@@ -215,45 +229,33 @@
int CameraCompress::ProcessMessage(QueuePointer & resp_queue, player_msghdr *
hdr,
void * data)
{
- player_camera_data_t * imgData;
+ player_msghdr_t newhdr;
Message * msg;
assert(hdr);
if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
PLAYER_CAMERA_DATA_STATE, this->camera_id))
{
assert(data);
- imgData = reinterpret_cast<player_camera_data_t * >(data);
if (this->request_only) return 0;
if ((!(this->check_timestamps)) || (this->camera_time != hdr->timestamp))
{
this->camera_time = hdr->timestamp;
- if (!(this->ProcessImage(*imgData))) this->Publish(device_addr,
PLAYER_MSGTYPE_DATA, PLAYER_CAMERA_DATA_STATE, reinterpret_cast<void
*>(&(this->data)), 0, &this->camera_time);
- // don't delete anything here! this->data.image is required and is
deleted somewhere else
+ if (!(this->ProcessImage(*(reinterpret_cast<player_camera_data_t
*>(data))))) this->Publish(this->device_addr, PLAYER_MSGTYPE_DATA,
PLAYER_CAMERA_DATA_STATE, reinterpret_cast<void *>(&(this->imgdata)), 0,
&(this->camera_time));
+ // don't delete anything here! this->imgdata.image is required and is
deleted somewhere else
}
return 0;
- } else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
PLAYER_CAMERA_REQ_GET_IMAGE, this->device_addr))
+ } else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ, -1,
this->device_addr))
{
- msg = this->camera->Request(this->InQueue, PLAYER_MSGTYPE_REQ,
PLAYER_CAMERA_REQ_GET_IMAGE, NULL, 0, NULL);
- if (!msg) return -1;
- if ((msg->GetDataSize()) < (sizeof(player_camera_data_t)))
+ hdr->addr = this->camera_id;
+ msg = this->camera->Request(this->InQueue, hdr->type, hdr->subtype, data,
0, NULL, true); // threaded = true
+ if (!msg)
{
- delete msg;
+ PLAYER_WARN("failed to forward request");
return -1;
}
- imgData = reinterpret_cast<player_camera_data_t *>(msg->GetPayload());
- if (!imgData)
- {
- delete msg;
- return -1;
- }
- this->camera_time = hdr->timestamp;
- if (!(this->ProcessImage(*imgData))) this->Publish(this->device_addr,
- resp_queue,
- PLAYER_MSGTYPE_RESP_ACK,
-
PLAYER_CAMERA_REQ_GET_IMAGE,
- reinterpret_cast<void
*>(&(this->data)),
- 0, &this->camera_time);
- // don't delete anything here! this->data.image is required and is deleted
somewhere else
+ newhdr = *(msg->GetHeader());
+ newhdr.addr = this->device_addr;
+ this->Publish(resp_queue, &newhdr, msg->GetPayload(), true); // copy =
true, do not dispose published data as we're disposing whole source message in
the next line
delete msg;
return 0;
}
@@ -284,7 +286,7 @@
if ((rawdata.width <= 0) || (rawdata.height <= 0))
{
- if (!(this->data.image)) return -1;
+ if (!(this->imgdata.image)) return -1;
} else if (rawdata.compression == PLAYER_CAMERA_COMPRESS_RAW)
{
switch (rawdata.bpp)
@@ -293,7 +295,7 @@
l = (rawdata.width) * (rawdata.height);
ptr = buffer = new unsigned char[(rawdata.width) * (rawdata.height) * 3];
assert(buffer);
- ptr1 = (unsigned char *)(rawdata.image);
+ ptr1 = reinterpret_cast<unsigned char *>(rawdata.image);
for (i = 0; i < l; i++)
{
ptr[0] = *ptr1;
@@ -304,13 +306,13 @@
ptr = buffer;
break;
case 24:
- ptr = (unsigned char *)(rawdata.image);
+ ptr = reinterpret_cast<unsigned char *>(rawdata.image);
break;
case 32:
l = (rawdata.width) * (rawdata.height);
ptr = buffer = new unsigned char[(rawdata.width) * (rawdata.height) * 3];
assert(buffer);
- ptr1 = (unsigned char *)(rawdata.image);
+ ptr1 = reinterpret_cast<unsigned char *>(rawdata.image);
for (i = 0; i < l; i++)
{
ptr[0] = ptr1[0];
@@ -324,35 +326,35 @@
PLAYER_WARN("unsupported image depth (not good)");
return -1;
}
- if (this->data.image) delete []this->data.image;
- this->data.image = new unsigned char[(rawdata.width) * (rawdata.height) *
3];
- assert(this->data.image);
- this->data.image_count = jpeg_compress( (char *)(this->data.image),
- (char *)ptr,
- rawdata.width,
- rawdata.height,
- (rawdata.width) * (rawdata.height)
* 3,
- (int)(this->quality*100));
- this->data.width = (rawdata.width);
- this->data.height = (rawdata.height);
- this->data.bpp = 24;
- this->data.format = PLAYER_CAMERA_FORMAT_RGB888;
- this->data.fdiv = (rawdata.fdiv);
- this->data.compression = PLAYER_CAMERA_COMPRESS_JPEG;
- this->data.image_count = (this->data.image_count);
+ if (this->imgdata.image) delete []this->imgdata.image;
+ this->imgdata.image = new unsigned char[(rawdata.width) * (rawdata.height)
* 3];
+ assert(this->imgdata.image);
+ this->imgdata.image_count = jpeg_compress(reinterpret_cast<char
*>(this->imgdata.image),
+ reinterpret_cast<char *>(ptr),
+ rawdata.width,
+ rawdata.height,
+ (rawdata.width) *
(rawdata.height) * 3,
+ static_cast<int>(this->quality *
100));
+ this->imgdata.width = (rawdata.width);
+ this->imgdata.height = (rawdata.height);
+ this->imgdata.bpp = 24;
+ this->imgdata.format = PLAYER_CAMERA_FORMAT_RGB888;
+ this->imgdata.fdiv = (rawdata.fdiv);
+ this->imgdata.compression = PLAYER_CAMERA_COMPRESS_JPEG;
+ this->imgdata.image_count = (this->imgdata.image_count);
} else
{
- if (this->data.image) delete []this->data.image;
- this->data.image = new unsigned char[rawdata.image_count];
- assert(this->data.image);
- memcpy(this->data.image, rawdata.image, rawdata.image_count);
- this->data.width = (rawdata.width);
- this->data.height = (rawdata.height);
- this->data.bpp = (rawdata.bpp);
- this->data.format = (rawdata.format);
- this->data.fdiv = (rawdata.fdiv);
- this->data.compression = (rawdata.compression);
- this->data.image_count = (rawdata.image_count);
+ if (this->imgdata.image) delete []this->imgdata.image;
+ this->imgdata.image = new unsigned char[rawdata.image_count];
+ assert(this->imgdata.image);
+ memcpy(this->imgdata.image, rawdata.image, rawdata.image_count);
+ this->imgdata.width = (rawdata.width);
+ this->imgdata.height = (rawdata.height);
+ this->imgdata.bpp = (rawdata.bpp);
+ this->imgdata.format = (rawdata.format);
+ this->imgdata.fdiv = (rawdata.fdiv);
+ this->imgdata.compression = (rawdata.compression);
+ this->imgdata.image_count = (rawdata.image_count);
}
if (buffer) delete []buffer;
buffer = NULL;
@@ -367,7 +369,7 @@
fp = fopen(filename, "w+");
if (fp)
{
- ret = fwrite(this->data.image, 1, this->data.image_count, fp);
+ ret = fwrite(this->imgdata.image, 1, this->imgdata.image_count, fp);
if (ret < 0) PLAYER_ERROR("Failed to save frame");
fclose(fp);
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit