BufferedImageMultiVideoSource.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) Massimo Cora' 2006 <maxcvs@email.it>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 
00020 #include "BufferedImageMultiVideoSource.hh"
00021 
00022 using namespace std;
00023 
00024 BufferedImageMultiVideoSource::BufferedImageMultiVideoSource( unsigned int streams_num,
00025                                                                                                                          on_parsable_image_cb *f, 
00026                                                                                                                          void* parsable_image_callback_data,
00027                                                                                                                          BaseInputVideo *input_single_video ) : BaseInputVideo(),
00028                                                                                         _streams_num( streams_num ),
00029                                                                                         f_parsable_cb( f ),
00030                                                                                         _parsable_image_callback_data( parsable_image_callback_data ),
00031                                                                                         _input_single_video( input_single_video )
00032 {
00033         _initialized = false;
00034         _streams_vector = NULL;
00035 
00036         // initialize single video device
00037         if ( _input_single_video->init_device () == true ) {
00038                 DEBUG_PRINT("ERROR: _input_single_video->init_device () failed from BufferedImageMultiVideoSource ctor" );
00039         }
00040 }
00041 
00042 BufferedImageMultiVideoSource::~BufferedImageMultiVideoSource()
00043 {
00044         list<IplImage*>* tmp_list;
00045 
00046         while ( (tmp_list = _streams_vector->back()) != NULL ) {
00047 
00048                 // free the images stored in the list
00049                 if ( !tmp_list->empty() ) {
00050                         IplImage *tmp_image;
00051 
00052                         while ( (tmp_image = tmp_list->front ()) != NULL ) {
00053                                 cvReleaseImage( &tmp_image );
00054                                 tmp_list->pop_front ();
00055                         }
00056                 }
00057 
00058                 delete tmp_list;
00059                 _streams_vector->pop_back ();
00060         }
00061 
00062         delete _streams_vector;
00063 
00064         _initialized = false;
00065 }
00066 
00067 bool BufferedImageMultiVideoSource::init_device () 
00068 {
00069         if ( _initialized )
00070                 return true;
00071 
00072         _streams_vector = NULL;
00073 
00074         // initialize the streams accordingly to the streams_num
00075         if ( _streams_vector == NULL ) {
00076                 _streams_vector = new vector< list<IplImage*>* >;
00077                 for ( unsigned int i=0; i < _streams_num; i++ ) {
00078                         list<IplImage*> *tmp_stream = new list<IplImage*>;
00079                         _streams_vector->push_back( tmp_stream );
00080                 }
00081         }
00082 
00083         _initialized = true;
00084         return true;
00085 }
00086 
00087 void BufferedImageMultiVideoSource::add_image_by_stream_id( IplImage *image, 
00088                                                                                         int stream_id, char* __unused__, void* callback_data )
00089 {
00090         BufferedImageMultiVideoSource* klass;
00091         
00092         if ( callback_data != NULL )
00093                 klass = (BufferedImageMultiVideoSource*)callback_data;
00094         else
00095                 return;
00096         
00097         if ( !klass->_initialized ) {
00098                 if ( klass->init_device () == false ) {
00099                         return;
00100                 }
00101         }
00102                 
00103 //      DEBUG_PRINT("add_image_by_stream_id %d with size %d x %d\n", stream_id, image->width, image->height);
00104         klass->_streams_vector->at( stream_id )->push_back( image );
00105         return;
00106 }
00107 
00108 IplImage *BufferedImageMultiVideoSource::get_next_frame_by_stream_id ( int stream_id )
00109 {
00110         IplImage *tmp_image, *res_image;
00111 
00112         if ( !_initialized ) {
00113                 if ( init_device () == false ) {
00114                         DEBUG_PRINT ("device not initialized, returnning NULL from"
00115                                 "IplImage *BufferedImageMultiVideoSource::get_next_frame_by_stream_id\n");
00116                         return NULL;
00117                 }
00118         }
00119 
00120         // have we a available image? return it immediately!
00121         // check whether the list is empty
00122         if ( _streams_vector->at( stream_id )->empty () == false ) {
00123                 list<IplImage*> *tmp_stream;
00124 
00125                 tmp_stream = _streams_vector->at( stream_id );
00126                 // retrieve the image and remove it from the list
00127                 tmp_image = tmp_stream->front ();
00128 
00129                 tmp_stream->pop_front ();
00130                 return tmp_image;
00131         }
00132 
00133         // ok, that's not all. 
00134         // To avoid our queues to grow so much, we should check the number of their elements.
00135         // Say, if we found a list that has more than 5 elements, we should return NULL
00136         // here, so that others can be parsed, avoiding long-term memleaks.
00137         for ( int i = 0; i < (int)_streams_vector->size(); i++ ) {
00138                 if ( _streams_vector->at(i)->size() > 5 )
00139                         return NULL;
00140         }
00141 
00142         // ok: now there will be three steps left to accomplish this method.
00143         // #1: grab an image from our single video source
00144         res_image = _input_single_video->get_next_frame();
00145         
00146         if ( res_image == NULL ) {
00147                 DEBUG_PRINT ("ERROR: falied to retrieve frame from device.\n");
00148                 return NULL;
00149         }
00150 
00151         // #2: pass the frame to the callback function which will parse it.
00152         // the callback can be some face detecting library. e.g. OmniStuff :)
00153         f_parsable_cb( res_image, this, _parsable_image_callback_data );
00154 
00155         cvReleaseImage( &res_image );
00156 
00157         // #3 meanwhile the face detecting library can have added some images throught
00158         // add_image_by_stream_id (). We will check this and perform the required tasks.
00159         
00160         // check whether the list is empty
00161         if ( _streams_vector->at( stream_id )->empty () ) {
00162                 return NULL;
00163         }
00164 
00165         list<IplImage*> *tmp_stream;
00166         tmp_stream = _streams_vector->at( stream_id );
00167 
00168         // retrieve the image and remove it from the list
00169         tmp_image = tmp_stream->front ();
00170 
00171         tmp_stream->pop_front ();
00172         return tmp_image;
00173 }
00174 
00175 bool BufferedImageMultiVideoSource::is_multi_stream ()
00176 {
00177         return true;
00178 }
00179 
00180 IplImage * BufferedImageMultiVideoSource::get_next_frame ()
00181 {
00182         // well.. try to return something
00183         if ( _streams_num > 0 )
00184                 return get_next_frame_by_stream_id( 0 );
00185         else
00186                 return NULL;
00187 }
00188 
00189 

Generated on Tue Dec 26 10:32:38 2006 for Omnimeeting by  doxygen 1.4.7