Fawkes API  Fawkes Development Version
shmem.cpp
1 /***************************************************************************
2  * shmem.cpp - Implementation to access images in shared memory
3  *
4  * Created: Thu Jan 12 19:43:05 2006
5  * Copyright 2005-2009 Tim Niemueller [www.niemueller.de]
6  *
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version. A runtime exception applies to
13  * this software (see LICENSE.GPL_WRE file mentioned below for details).
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
21  */
22 
23 #include <core/exception.h>
24 #include <core/exceptions/software.h>
25 #include <core/exceptions/system.h>
26 #include <fvcams/shmem.h>
27 #include <fvutils/system/camargp.h>
28 #include <fvutils/writers/fvraw.h>
29 
30 #include <cstdlib>
31 #include <cstring>
32 
33 using namespace fawkes;
34 
35 namespace firevision {
36 
37 /** @class SharedMemoryCamera <fvcams/shmem.h>
38  * Shared memory camera.
39  * Camera to retrieve images from a shared memory segment.
40  *
41  * The camera can operate in a so-called deep-copy mode. In this mode a
42  * local internal buffer is created of the size of the image. On capture()
43  * the image is copied from the shared memory buffer to the local buffer
44  * with the shared memory segment locked for reading. This can be used if
45  * the image writing and the image reading processess run asynchronously.
46  * While locking would suffice the copying will account for only short
47  * locking times so that the interference between the two processes is
48  * minimal.
49  *
50  * @author Tim Niemueller
51  */
52 
53 /** Constructor.
54  * @param image_id image ID to open
55  * @param deep_copy true to operate in deep-copy mode, false otherwise
56  */
57 SharedMemoryCamera::SharedMemoryCamera(const char *image_id, bool deep_copy)
58 {
59  image_id_ = strdup(image_id);
60  deep_copy_ = deep_copy;
61 
62  try {
63  init();
64  } catch (Exception &e) {
65  free(image_id_);
66  image_id_ = NULL;
67  throw;
68  }
69 }
70 
71 /** Constructor.
72  * Take configuration data from camera argument parser. The following
73  * options are supported.
74  * - image_id=ID, where ID is the image ID
75  * @param cap camera argument parser
76  */
77 SharedMemoryCamera::SharedMemoryCamera(const CameraArgumentParser *cap)
78 {
79  image_id_ = NULL;
80  deep_copy_ = false;
81 
82  if (cap->has("image_id")) {
83  image_id_ = strdup(cap->get("image_id").c_str());
84  } else
85  throw MissingParameterException("The parameter 'image_id' is required");
86 
87  if (cap->has("deep_copy")) {
88  deep_copy_ = (strcasecmp(cap->get("deep_copy").c_str(), "true") == 0);
89  }
90 
91  try {
92  init();
93  } catch (Exception &e) {
94  free(image_id_);
95  image_id_ = NULL;
96  throw;
97  }
98 }
99 
100 /** Destructor. */
101 SharedMemoryCamera::~SharedMemoryCamera()
102 {
103  free(image_id_);
104  if (deep_buffer_ != NULL) {
105  free(deep_buffer_);
106  }
107  delete shm_buffer_;
108  delete capture_time_;
109 }
110 
111 void
112 SharedMemoryCamera::init()
113 {
114  deep_buffer_ = NULL;
115  capture_time_ = NULL;
116  try {
117  shm_buffer_ = new SharedMemoryImageBuffer(image_id_);
118  if (deep_copy_) {
119  deep_buffer_ = (unsigned char *)malloc(shm_buffer_->data_size());
120  if (!deep_buffer_) {
121  throw OutOfMemoryException("SharedMemoryCamera: Cannot allocate deep buffer");
122  }
123  }
124  opened_ = true;
125  } catch (Exception &e) {
126  e.append("Failed to open shared memory image");
127  throw;
128  }
129  capture_time_ = new fawkes::Time(0, 0);
130 }
131 
132 void
133 SharedMemoryCamera::open()
134 {
135 }
136 
137 void
138 SharedMemoryCamera::start()
139 {
140 }
141 
142 void
143 SharedMemoryCamera::stop()
144 {
145 }
146 
147 void
148 SharedMemoryCamera::print_info()
149 {
150 }
151 
152 void
153 SharedMemoryCamera::capture()
154 {
155  if (deep_copy_) {
156  shm_buffer_->lock_for_read();
157  memcpy(deep_buffer_, shm_buffer_->buffer(), shm_buffer_->data_size());
158  capture_time_->set_time(shm_buffer_->capture_time());
159  shm_buffer_->unlock();
160  } else
161  capture_time_->set_time(shm_buffer_->capture_time());
162 }
163 
164 unsigned char *
165 SharedMemoryCamera::buffer()
166 {
167  if (deep_copy_) {
168  return deep_buffer_;
169  } else {
170  return shm_buffer_->buffer();
171  }
172 }
173 
174 unsigned int
175 SharedMemoryCamera::buffer_size()
176 {
177  return colorspace_buffer_size(shm_buffer_->colorspace(),
178  shm_buffer_->width(),
179  shm_buffer_->height());
180 }
181 
182 void
183 SharedMemoryCamera::close()
184 {
185 }
186 
187 void
188 SharedMemoryCamera::dispose_buffer()
189 {
190 }
191 
192 unsigned int
193 SharedMemoryCamera::pixel_width()
194 {
195  return shm_buffer_->width();
196 }
197 
198 unsigned int
199 SharedMemoryCamera::pixel_height()
200 {
201  return shm_buffer_->height();
202 }
203 
204 colorspace_t
205 SharedMemoryCamera::colorspace()
206 {
207  return shm_buffer_->colorspace();
208 }
209 
210 fawkes::Time *
211 SharedMemoryCamera::capture_time()
212 {
213  return capture_time_;
214 }
215 
216 void
217 SharedMemoryCamera::flush()
218 {
219 }
220 
221 /** Get the shared memory image buffer.
222  * @return shared memory image buffer used to access image
223  */
225 SharedMemoryCamera::shared_memory_image_buffer()
226 {
227  return shm_buffer_;
228 }
229 
230 bool
231 SharedMemoryCamera::ready()
232 {
233  return opened_;
234 }
235 
236 void
237 SharedMemoryCamera::set_image_number(unsigned int n)
238 {
239  // ignore for now
240 }
241 
242 /** Lock image for reading.
243  * Aquire the lock to read images.
244  */
245 void
246 SharedMemoryCamera::lock_for_read()
247 {
248  shm_buffer_->lock_for_read();
249 }
250 
251 /** Try to lock for reading.
252  * @return true if the lock has been aquired, false otherwise
253  */
254 bool
255 SharedMemoryCamera::try_lock_for_read()
256 {
257  return shm_buffer_->try_lock_for_read();
258 }
259 
260 /** Lock image for writing.
261  * Aquire the lock to write images.
262  */
263 void
264 SharedMemoryCamera::lock_for_write()
265 {
266  shm_buffer_->lock_for_write();
267 }
268 
269 /** Try to lock for reading.
270  * @return true if the lock has been aquired, false otherwise
271  */
272 bool
273 SharedMemoryCamera::try_lock_for_write()
274 {
275  return shm_buffer_->try_lock_for_write();
276 }
277 
278 /** Unlock buffer. */
279 void
280 SharedMemoryCamera::unlock()
281 {
282  shm_buffer_->unlock();
283 }
284 
285 } // end namespace firevision
firevision::SharedMemoryImageBuffer
Definition: shm_image.h:183
fawkes::Exception::append
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:333
fawkes
firevision::CameraArgumentParser::has
bool has(std::string s) const
Check if an parameter was given.
Definition: camargp.cpp:145
fawkes::MissingParameterException
Definition: software.h:79
firevision::CameraArgumentParser
Definition: camargp.h:41
fawkes::Time
Definition: time.h:98
firevision::CameraArgumentParser::get
std::string get(std::string s) const
Get the value of the given parameter.
Definition: camargp.cpp:156
fawkes::OutOfMemoryException
Definition: system.h:37
fawkes::SharedMemory::lock_for_read
void lock_for_read()
Lock shared memory segment for reading.
Definition: shm.cpp:915
fawkes::Exception
Definition: exception.h:41