libeblearntools
/home/rex/ebltrunk/tools/libeblearntools/include/camera_shmem.hpp
00001 /***************************************************************************
00002  *   Copyright (C) 2010 by Pierre Sermanet   *
00003  *   pierre.sermanet@gmail.com   *
00004  *   All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Redistribution under a license not approved by the Open Source 
00014  *       Initiative (http://www.opensource.org) must display the 
00015  *       following acknowledgement in all advertising material:
00016  *        This product includes software developed at the Courant
00017  *        Institute of Mathematical Sciences (http://cims.nyu.edu).
00018  *     * The names of the authors may not be used to endorse or promote products
00019  *       derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00024  * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  ***************************************************************************/
00032 
00033 #ifndef CAMERA_SHMEM_HPP_
00034 #define CAMERA_SHMEM_HPP_
00035 
00036 namespace ebl {
00037 
00039   // constructors & initializations
00040 
00041   template <typename Tdata>
00042   camera_shmem<Tdata>::camera_shmem(const char *shmem_path,
00043                                     int height_, int width_)
00044     : camera<Tdata>(height_, width_), buffer(NULL) {
00045 #ifdef __WINDOWS__
00046     eblerror("missing shmem implementation for windows");
00047 #else
00048     cout << "Initializing shared buffer camera..." << endl;
00049     // connect to shared memory segment
00050    if ((shmem_key = ftok(shmem_path, 'A')) == -1) {
00051      cerr << "ftok couldnt get the shared mem descriptor from ";
00052      cerr << shmem_path << endl;
00053      eblerror("could not connect to shared memory");
00054    }
00055    // get segment
00056    if ((shmem_id = shmget(shmem_key, 16, 0644 | IPC_CREAT)) == -1) {
00057      eblerror("shmget couldnt sync the shared mem segment");
00058    }
00059    // link data to the segment
00060    buffer = (struct video_buffer *)shmat(shmem_id, (void *)0, 0);
00061    cout << "shared frame size: " << buffer->height << "x" << buffer->width;
00062    cout << "x" << buffer->bytes_per_pixel << endl;
00063    // get segment according to frame size
00064    if ((shmem_id = shmget(shmem_key, 16 + buffer->height * buffer->width *
00065                           buffer->bytes_per_pixel, 0644 | IPC_CREAT)) == -1) {
00066      eblerror("shmget couldnt sync the shared mem segment");
00067    }
00068    // link data to the segment
00069    buffer = (struct video_buffer *)shmat(shmem_id, (void *)0, 0);
00070 #endif /* __WINDOW__ */
00071   }
00072   
00073   template <typename Tdata>
00074   camera_shmem<Tdata>::~camera_shmem() {
00075 #ifndef __WINDOWS__
00076     // detach from shared memory
00077     if (buffer)
00078       shmdt((const void*)buffer);
00079 #endif /* __WINDOW__ */
00080   }
00081   
00083   // frame grabbing
00084 
00085   template <typename Tdata>
00086   idx<Tdata> camera_shmem<Tdata>::grab() {
00087 #ifndef __WINDOWS__
00088     // make a frame request
00089     buffer->dump_to_file = 0;
00090     buffer->request_frame = 1;
00091     while (buffer->request_frame) millisleep(1); // request received
00092     while (!buffer->frame_ready) millisleep(1); // wait for frame to be ready
00093     // check that shared segment is compatible
00094     if (buffer->bytes_per_pixel != 3)
00095       eblerror("shared segment doesnt contain an RGBA image\n");
00096     // allocate if necessary
00097     if (!grabbed) // first time, allocate frame
00098       frame = idx<Tdata>(buffer->height, buffer->width,
00099                          buffer->bytes_per_pixel);
00100     // cast and copy data
00101     ubyte *in = (ubyte*) &(buffer->data);
00102     Tdata *out = frame.idx_ptr();
00103     uint sz = frame.nelements();
00104     // cast and copy data
00105     for (uint i = 0; i < sz; ++i, ++out, ++in)
00106       *out = (Tdata) *in;
00107 #endif
00108     frame_id_++;
00109     return this->postprocess();
00110   }
00111   
00112 } // end namespace ebl
00113 
00114 #endif /* CAMERA_SHMEM_HPP_ */