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/system.h>
25 #include <core/exceptions/software.h>
26 #include <fvcams/shmem.h>
27 #include <fvutils/writers/fvraw.h>
28 #include <fvutils/system/camargp.h>
29 
30 #include <cstring>
31 #include <cstdlib>
32 
33 using namespace fawkes;
34 
35 namespace firevision {
36 #if 0 /* just to make Emacs auto-indent happy */
37 }
38 #endif
39 
40 /** @class SharedMemoryCamera <fvcams/shmem.h>
41  * Shared memory camera.
42  * Camera to retrieve images from a shared memory segment.
43  *
44  * The camera can operate in a so-called deep-copy mode. In this mode a
45  * local internal buffer is created of the size of the image. On capture()
46  * the image is copied from the shared memory buffer to the local buffer
47  * with the shared memory segment locked for reading. This can be used if
48  * the image writing and the image reading processess run asynchronously.
49  * While locking would suffice the copying will account for only short
50  * locking times so that the interference between the two processes is
51  * minimal.
52  *
53  * @author Tim Niemueller
54  */
55 
56 /** Constructor.
57  * @param image_id image ID to open
58  * @param deep_copy true to operate in deep-copy mode, false otherwise
59  */
60 SharedMemoryCamera::SharedMemoryCamera(const char *image_id, bool deep_copy)
61 {
62  __image_id = strdup(image_id);
63  __deep_copy = deep_copy;
64 
65  try {
66  init();
67  } catch (Exception &e) {
68  free(__image_id);
69  __image_id = NULL;
70  throw;
71  }
72 }
73 
74 
75 /** Constructor.
76  * Take configuration data from camera argument parser. The following
77  * options are supported.
78  * - image_id=ID, where ID is the image ID
79  * @param cap camera argument parser
80  */
81 SharedMemoryCamera::SharedMemoryCamera(const CameraArgumentParser *cap)
82 {
83  __image_id = NULL;
84  __deep_copy = false;
85 
86  if ( cap->has("image_id") ) {
87  __image_id = strdup(cap->get("image_id").c_str());
88  }
89  else throw MissingParameterException("The parameter 'image_id' is required");
90 
91  if ( cap->has("deep_copy") ) {
92  __deep_copy = (strcasecmp(cap->get("deep_copy").c_str(), "true") == 0);
93  }
94 
95  try {
96  init();
97  } catch (Exception &e) {
98  free(__image_id);
99  __image_id = NULL;
100  throw;
101  }
102 }
103 
104 
105 /** Destructor. */
106 SharedMemoryCamera::~SharedMemoryCamera()
107 {
108  free(__image_id);
109  if ( __deep_buffer != NULL ) {
110  free( __deep_buffer );
111  }
112  delete __shm_buffer;
113  delete __capture_time;
114 }
115 
116 
117 void
118 SharedMemoryCamera::init()
119 {
120  __deep_buffer = NULL;
121  __capture_time = NULL;
122  try {
123  __shm_buffer = new SharedMemoryImageBuffer(__image_id);
124  if ( __deep_copy ) {
125  __deep_buffer = (unsigned char *)malloc(__shm_buffer->data_size());
126  if ( ! __deep_buffer ) {
127  throw OutOfMemoryException("SharedMemoryCamera: Cannot allocate deep buffer");
128  }
129  }
130  __opened = true;
131  } catch (Exception &e) {
132  e.append("Failed to open shared memory image");
133  throw;
134  }
135  __capture_time = new fawkes::Time(0, 0);
136 }
137 
138 void
139 SharedMemoryCamera::open()
140 {
141 }
142 
143 
144 void
145 SharedMemoryCamera::start()
146 {
147 }
148 
149 void
150 SharedMemoryCamera::stop()
151 {
152 }
153 
154 void
155 SharedMemoryCamera::print_info()
156 {
157 }
158 
159 void
160 SharedMemoryCamera::capture()
161 {
162  if ( __deep_copy ) {
163  __shm_buffer->lock_for_read();
164  memcpy(__deep_buffer, __shm_buffer->buffer(), __shm_buffer->data_size());
165  __capture_time->set_time(__shm_buffer->capture_time());
166  __shm_buffer->unlock();
167  }
168  else __capture_time->set_time(__shm_buffer->capture_time());
169 }
170 
171 unsigned char*
172 SharedMemoryCamera::buffer()
173 {
174  if ( __deep_copy ) {
175  return __deep_buffer;
176  } else {
177  return __shm_buffer->buffer();
178  }
179 }
180 
181 unsigned int
182 SharedMemoryCamera::buffer_size()
183 {
184  return colorspace_buffer_size(__shm_buffer->colorspace(),
185  __shm_buffer->width(),
186  __shm_buffer->height() );
187 }
188 
189 void
190 SharedMemoryCamera::close()
191 {
192 }
193 
194 void
195 SharedMemoryCamera::dispose_buffer()
196 {
197 }
198 
199 unsigned int
200 SharedMemoryCamera::pixel_width()
201 {
202  return __shm_buffer->width();
203 }
204 
205 unsigned int
206 SharedMemoryCamera::pixel_height()
207 {
208  return __shm_buffer->height();
209 }
210 
211 
212 colorspace_t
213 SharedMemoryCamera::colorspace()
214 {
215  return __shm_buffer->colorspace();
216 }
217 
218 
219 fawkes::Time *
220 SharedMemoryCamera::capture_time()
221 {
222  return __capture_time;
223 }
224 
225 
226 void
227 SharedMemoryCamera::flush()
228 {
229 }
230 
231 
232 /** Get the shared memory image buffer.
233  * @return shared memory image buffer used to access image
234  */
236 SharedMemoryCamera::shared_memory_image_buffer()
237 {
238  return __shm_buffer;
239 }
240 
241 
242 bool
243 SharedMemoryCamera::ready()
244 {
245  return __opened;
246 }
247 
248 
249 void
250 SharedMemoryCamera::set_image_number(unsigned int n)
251 {
252  // ignore for now
253 }
254 
255 
256 /** Lock image for reading.
257  * Aquire the lock to read images.
258  */
259 void
260 SharedMemoryCamera::lock_for_read()
261 {
262  __shm_buffer->lock_for_read();
263 }
264 
265 
266 /** Try to lock for reading.
267  * @return true if the lock has been aquired, false otherwise
268  */
269 bool
270 SharedMemoryCamera::try_lock_for_read()
271 {
272  return __shm_buffer->try_lock_for_read();
273 }
274 
275 
276 /** Lock image for writing.
277  * Aquire the lock to write images.
278  */
279 void
280 SharedMemoryCamera::lock_for_write()
281 {
282  __shm_buffer->lock_for_write();
283 }
284 
285 
286 /** Try to lock for reading.
287  * @return true if the lock has been aquired, false otherwise
288  */
289 bool
290 SharedMemoryCamera::try_lock_for_write()
291 {
292  return __shm_buffer->try_lock_for_write();
293 }
294 
295 
296 /** Unlock buffer. */
297 void
298 SharedMemoryCamera::unlock()
299 {
300  __shm_buffer->unlock();
301 }
302 
303 } // end namespace firevision
Fawkes library namespace.
A class for handling time.
Definition: time.h:91
Camera argument parser.
Definition: camargp.h:38
void lock_for_read()
Lock shared memory segment for reading.
Definition: shm.cpp:867
bool has(std::string s) const
Check if an parameter was given.
Definition: camargp.cpp:152
Base class for exceptions in Fawkes.
Definition: exception.h:36
Shared memory image buffer.
Definition: shm_image.h:181
std::string get(std::string s) const
Get the value of the given parameter.
Definition: camargp.cpp:164
Expected parameter is missing.
Definition: software.h:76
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341