Video4Linux1.cpp

Go to the documentation of this file.
00001 /** @file    Video4Linux1.cpp
00002  *  @author  Alessandro Polo
00003  *  @version $Id: Video4Linux1.cpp 3775 2011-01-01 16:38:17Z alex $
00004  *  @brief
00005  * File containing methods for the Video4Linux1 class.
00006  * The header for this class can be found in Video4Linux1.h, check that file
00007  * for class description.
00008  ****************************************************************************/
00009 /* Copyright (c) 2007-2011, WOSH - Wide Open Smart Home 
00010  * by Alessandro Polo - OpenSmartHome.com
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *     * Redistributions of source code must retain the above copyright
00016  *       notice, this list of conditions and the following disclaimer.
00017  *     * Redistributions in binary form must reproduce the above copyright
00018  *       notice, this list of conditions and the following disclaimer in the
00019  *       documentation and/or other materials provided with the distribution.
00020  *     * Neither the name of the OpenSmartHome.com WOSH nor the
00021  *       names of its contributors may be used to endorse or promote products
00022  *       derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
00025  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027  * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
00028  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  ****************************************************************************/
00035  
00036  #include "Video4Linux1.h"
00037  #include <core/FileSystem.h>
00038  #include <core/Utilities.h>
00039 
00040  #include <fcntl.h>
00041  #include <sys/ioctl.h>
00042 // #include <unistd.h>
00043 // #include <sys/types.h>
00044 // #include <sys/stat.h>
00045 // #include <stdio.h>
00046 // #include <stdlib.h>
00047 // #include <linux/types.h>
00048 
00049 
00050 using namespace std;
00051 using namespace wosh;
00052 
00053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00054 //////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
00055 
00056 Video4Linux1::Video4Linux1( BundleGeneric& bundle )
00057     : Video4LinuxImpl(bundle) {
00058     this->fd = -1;
00059     this->videoBuffer = NULL;
00060     this->videoBufferSize = 0;
00061 
00062     this->src_depth = 0;
00063 
00064     memset(&this->cap, 0, sizeof(this->cap));
00065     memset(&this->win, 0, sizeof(this->win));
00066     memset(&this->vpic, 0, sizeof(this->vpic));
00067 
00068 
00069  }
00070 
00071 Video4Linux1::~Video4Linux1() {
00072     Log(LOG_VERBOSE, ":~Video4Linux1(): Destroying.." );
00073     if ( isThreadRunning() )
00074         quitThread(20000);
00075 
00076     if ( this->videoBuffer != NULL )
00077         delete [] videoBuffer; this->videoBuffer = NULL;
00078  }
00079 
00080 //////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
00081 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00082 ////////////////////////////////////////////////////////////////////////////////////////////////// THREAD RUN
00083 
00084 bool Video4Linux1::initializingThread() {
00085     if ( this->fd < 0 ) return false;
00086     return true;
00087  }
00088 
00089 void Video4Linux1::runThread() {
00090     Log(LOG_VERBOSE, ":runThread(): Loop Starting.." );
00091 
00092     if ( this->videoListener != NULL )
00093         this->videoListener->video_device_connection( 1, this );
00094 
00095     while(this->running) {
00096         setThreadAlive();
00097         if ( !this->streaming ) {
00098             ThreadImpl::sleepForMSec( 500 );
00099          }
00100         if ( this->rate != 0 )
00101             Thread::sleepWhile( this,this->rate, 50, &this->running );
00102 
00103         switch(this->vpic.palette) {
00104             case VIDEO_PALETTE_RGB24:
00105                 if ( this->videoListener != NULL )
00106                     this->videoListener->video_frame_available( this );
00107                 break;
00108             case VIDEO_PALETTE_RGB565:
00109             case VIDEO_PALETTE_RGB555:
00110             default:
00111                 break;
00112          }
00113      }
00114 
00115     Log(LOG_VERBOSE, ":runThread(): Loop Stopped" );
00116  }
00117 
00118 void Video4Linux1::exitingThread() {
00119 
00120     if ( this->videoListener != NULL )
00121         this->videoListener->video_device_connection( 0, this );
00122 
00123     Log(LOG_INFO, ":disconnect() : Closing input device.." );
00124     close(this->fd);
00125     this->fd = -1;
00126 
00127  }
00128 
00129 ////////////////////////////////////////////////////////////////////////////////////////////////// THREAD RUN
00130 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00131 ///////////////////////////////////////////////////////////////////////////////////////////// GETTERS/SETTERS
00132 ///////////////////////////////////////////////////////////////////////////////////////////////////// SETTERS
00133 
00134 WRESULT Video4Linux1::connectDevice( const std::string& device, unsigned long timeout ) {
00135     if ( this->fd != -1 || isThreadRunning() ) {
00136         Log(LOG_CRITICAL, ":connect(%s) FAILED : device already opened!", device.c_str() );
00137         return WRET_ERR_ILLEGAL_USE;
00138      }
00139     // Open the video4link device for reading.
00140     this->fd = open( device.c_str(), O_RDONLY );
00141     if ( this->fd < 0 ) {
00142         Log(LOG_CRITICAL, ":connect(%s) FAILED opening device", device.c_str() );
00143         return WRET_ERR_INTERNAL;
00144      }
00145     //Make sure this is a video4linux device
00146     if ( ioctl(this->fd,VIDIOCGCAP, &this->cap) < 0 ) {
00147         Log(LOG_CRITICAL, ":connect(%s) FAILED opening device (not VIDEOGCAP device)", device.c_str() );
00148         close(this->fd);
00149         this->fd = -1;
00150         return WRET_ERR_INTERNAL;
00151      }
00152     //Get the video overlay window
00153     if ( ioctl(this->fd,VIDIOCGWIN, &this->win) < 0 ) {
00154         Log(LOG_CRITICAL, ":connect(%s) FAILED getting video overlay window (VIDIOCGWIN)", device.c_str() );
00155         close(this->fd);
00156         this->fd = -1;
00157         return WRET_ERR_INTERNAL;
00158      }
00159     WRESULT ret_res = setupResolution();
00160     if ( WFAILED(ret_res) ) {
00161         Log(LOG_CRITICAL, ":connect(%s) FAILED#%d setupResolution()", device.c_str(), ret_res );
00162         close(this->fd);
00163         this->fd = -1;
00164         return WRET_ERR_INTERNAL;
00165      }
00166     this->videoDevice = device;
00167     Log(LOG_VERBOSE, ":connect(%s,%d) : Starting Thread..", device.c_str(), timeout );
00168     WRESULT ret_thread = startThread(timeout);
00169     if ( WFAILED(ret_thread) )
00170         Log(LOG_CRITICAL, ":connect(%s) FAILED#%d starting thread()", device.c_str(), ret_thread );
00171     return ret_thread;
00172  }
00173 
00174 WRESULT Video4Linux1::disconnectDevice( unsigned long timeout ) {
00175     if ( this->fd == -1 || !isThreadRunning() ) {
00176         Log(LOG_CRITICAL, ":disconnect() FAILED : device not opened!" );
00177         return WRET_ERR_ILLEGAL_USE;
00178      }
00179     WRESULT ret = quitThread(timeout);
00180     if ( WFAILED(ret) ) {
00181         Log(LOG_CRITICAL, ":disconnect(%d) FAILED#%d [TimedOut]!", timeout, ret );
00182      }
00183     return ret;
00184  }
00185 
00186 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00188 
00189 WRESULT Video4Linux1::setupResolution() {
00190     if ( this->fd == -1 ) {
00191         Log(LOG_CRITICAL, ":setupResolution() FAILED : device not opened!" );
00192         return WRET_ERR_ILLEGAL_USE;
00193      }
00194     Log(LOG_VERBOSE, ":setupResolution() : Setting up resolution.." );
00195     // get the picture properties
00196     if ( ioctl(this->fd,VIDIOCGPICT, &this->vpic) < 0 ) {
00197         Log(LOG_CRITICAL, ":setupResolution() FAILED getting picture properties (VIDIOCGPICT)" );
00198         return WRET_ERR_INTERNAL;
00199      }
00200     // now set the color resolution on the camera
00201     if ( this->cap.type & VID_TYPE_MONOCHROME ) {
00202         this->vpic.depth = 8;
00203         this->vpic.palette = VIDEO_PALETTE_GREY;
00204         if( ioctl(this->fd,VIDIOCSPICT, &this->vpic) < 0 ) {
00205             Log(LOG_VERBOSE, ":setupResolution() GREY:8 not supported. Trying GREY:6 .." );
00206             this->vpic.depth = 6;
00207             if( ioctl(this->fd,VIDIOCSPICT, &this->vpic) < 0 ) {
00208                 Log(LOG_VERBOSE, ":setupResolution() GREY:6 not supported. Trying GREY:4 .." );
00209                 this->vpic.depth = 4;
00210                 if ( ioctl(this->fd,VIDIOCSPICT, &this->vpic) < 0 ) {
00211                     Log(LOG_CRITICAL, ":setupResolution() FAILED : Unable to find a supported Capture format" );
00212                     return WRET_ERR_INTERNAL;
00213                  }
00214              }
00215          }
00216         Log(LOG_INFO, ":setupResolution() : Resolution: GREY / %d bpp", this->vpic.depth );
00217      }
00218     else { // supports colors
00219         this->vpic.depth = 24;
00220         this->vpic.palette = VIDEO_PALETTE_RGB24;
00221         if ( ioctl(this->fd,VIDIOCSPICT, &this->vpic) < 0 ) {
00222             Log(LOG_VERBOSE, ":setupResolution() RGB24:24 not supported. Trying RGB565:16 .." );
00223             this->vpic.palette = VIDEO_PALETTE_RGB565;
00224             this->vpic.depth = 16;
00225             if( ioctl(this->fd,VIDIOCSPICT, &this->vpic) == -1 ) {
00226                 Log(LOG_VERBOSE, ":setupResolution() RGB565:16 not supported. Trying VIDEO_PALETTE_RGB555:15 .." );
00227                 this->vpic.palette = VIDEO_PALETTE_RGB555;
00228                 this->vpic.depth = 15;
00229                 if( ioctl(this->fd, VIDIOCSPICT, &this->vpic) == -1 ) {
00230                     Log(LOG_CRITICAL, ":setupResolution() FAILED : Unable to find a supported Capture format" );
00231                     return WRET_ERR_INTERNAL;
00232                  }
00233              }
00234          }
00235         Log(LOG_INFO, ":setupResolution() : Resolution: RGB / %d bpp", this->vpic.depth );
00236      }
00237     if ( this->win.width <= 0 || this->win.height <= 0 ) {
00238         Log(LOG_CRITICAL, ":setupResolution() FAILED : Invalid size [%d,%d]", this->win.width, this->win.height );
00239         return WRET_ERR_INTERNAL;
00240      }
00241     if ( this->videoBuffer != NULL )
00242         delete [] videoBuffer; this->videoBuffer = NULL;
00243 
00244     Log(LOG_DEBUG, ":setupResolution() Allocating buffer [%d,%d] * 3", this->win.width, this->win.height );
00245     this->videoBufferSize = this->win.width * this->win.height * 3;
00246     this->videoBuffer = new unsigned char[this->videoBufferSize];
00247     return WRET_OK;
00248  }
00249 
00250 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00251 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00252 
00253 WRESULT Video4Linux1::extractFrame( unsigned char* buffer, long size ) {
00254     if ( buffer == NULL ) return WRET_ERR_PARAM;
00255     if ( this->fd == -1 ) return WRET_ERR_ILLEGAL_USE;
00256     read( this->fd, buffer, size ); //BGR
00257     return WRET_OK;
00258  }
00259 /*
00260 WRESULT Video4Linux1::extract__() {
00261     read( this->fd, this->videoBuffer, this->videoBufferSize ); //BGR
00262     //vipUtility::conv_bgr_rgb((unsigned char*)img.data[0], videoBuffer, win.width, win.height);
00263     return WRET_OK;
00264  }
00265 */

Generated on Tue Feb 8 2011 09:33:09 for WOSH system 0.8.888 [wolf] by Alessandro Polo, using DoxyGen 1.7.2 hosted by WOSH Framework