receiver_ctrl.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) Massimo Cora' 2005 <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 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 #include "receiver_ctrl.h"
00020 
00021 //--------------------------------------------------------------------------
00022 //
00023 
00024 ReceiverCtrlThread::ReceiverCtrlThread( MainFrame * main_frame_instance ) :
00025                                 _fmod_initialized( false ),
00026                                 _main_frame_pointer( main_frame_instance ),
00027                                 _receiving_status( false ),
00028                                 _shutting_down( false ),
00029                                 _gcard_use( false ),
00030                                 _ctrl_initialized( false ),
00031                                 _receiver( NULL )
00032 {
00033 }
00034 
00035 //--------------------------------------------------------------------------
00036 //
00037 
00038 ReceiverCtrlThread::~ReceiverCtrlThread() 
00039 {
00040         if ( _receiver )
00041                 delete _receiver;
00042 }
00043 
00044 //--------------------------------------------------------------------------
00045 // create the thread and initialize some useful data
00046 
00047 void ReceiverCtrlThread::Create( const wxString destRTSPUrl, bool is_multi_stream /* = false */ ) 
00048 {
00049         // let's create the thread
00050         wxThread::Create();
00051 
00052         _is_multi_stream = is_multi_stream;
00053 
00054         _receiver = new OStreamReceiver( (const char*)wxConvCurrent->cWX2MB(destRTSPUrl),
00055                 ReceiverCtrlThread::onImageReceivedFromNet, this,
00056                 ReceiverCtrlThread::onAudioFrameReceivedFromNet, this );
00057 
00058         _gcard_use = _main_frame_pointer->GetGCardUseStatus();
00059 }
00060 
00061 
00062 //--------------------------------------------------------------------------
00063 //
00064 
00065 bool ReceiverCtrlThread::isReceiving() 
00066 {
00067         return _receiving_status;
00068 }
00069 
00070 //--------------------------------------------------------------------------
00071 //
00072 
00073 bool ReceiverCtrlThread::isShuttingDown() 
00074 {
00075         return _shutting_down;
00076 }
00077 
00078 //--------------------------------------------------------------------------
00079 //
00080 
00081 void ReceiverCtrlThread::StopReceiving() 
00082 {
00083         _shutting_down = true;
00084         _receiver->stopReceiving();
00085 }
00086 
00087 
00088 //--------------------------------------------------------------------------
00089 //
00090 
00091 void ReceiverCtrlThread::parseErrorStatus( int err_status ) 
00092 {
00093         if ( err_status != ERROR_NORMAL_STATUS ) {
00094 
00095                 wxString error;
00096 
00097                 switch (err_status){
00098 
00099                         case ERROR_FAILED_SDP_DESCRIPTION:
00100                                 error = wxT( "Error getting SDP description from URL." );
00101                                 break;
00102                         case ERROR_FAILED_FILE_SINK_CREATION:
00103                                 error = wxT( "Failed to create Filesink for this URL." );
00104                                 break;
00105                         case ERROR_FAILED_TO_CREATE_RECEIVER:
00106                                 error = wxT( "Unable to create receiver for this stream." );
00107                                 break;  
00108                         case ERROR_FAILED_CREATE_RTSP_CLIENT:
00109                                 error = wxT( "Error creating the stream client." );
00110                                 break;
00111                         case ERROR_FAILED_CREATE_MEDIASESSION:
00112                                 error = wxT( "Error creating MediaSession." );
00113                                 break;
00114                         case ERROR_FAILED_SETUP_STREAMS:
00115                                 error = wxT( "Failed to setup this media stream." );
00116                                 break;
00117                         case ERROR_UNKOWN_ERROR:
00118                                 error = wxT( "An error occurred preparing the stream to receive. STREAM CLOSED!!!" );
00119                                 break;
00120                 }
00121 
00122         // create any type of command event here
00123         wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
00124         event.SetString( error );
00125 
00126         // send in a thread-safe way
00127         wxPostEvent( this->_main_frame_pointer, event );
00128         }
00129 }
00130 
00131 
00132 //--------------------------------------------------------------------------
00133 // Thread entry: will be called after a Run() on this object
00134 
00135 void *ReceiverCtrlThread::Entry() 
00136 {
00137         int err_status;
00138         _receiving_status = true;
00139 
00140         if ( ( err_status = _receiver->isReadyToStream() ) == ERROR_NORMAL_STATUS ) {
00141                 printf("gonna start receiving....\n");
00142                 err_status = _receiver->startReceiving();
00143         }
00144         else {
00145                 printf("some error occurred checking for ready to stream\n");
00146         }
00147 
00148         _receiving_status = false;
00149         _shutting_down = false;
00150 
00151         parseErrorStatus( err_status );
00152 
00153         // let's notify main_frame class that we are exiting.
00154         _main_frame_pointer->OnReceiverCtrlThreadEnd();
00155 
00156         return 0;
00157 }
00158 
00159 
00160 void ReceiverCtrlThread::notifyMainThread( IplImage* image_received, int stream_id )
00161 {
00162 
00163         image_received_data_t *img_data = new image_received_data_t;
00164 
00165         // create any type of command event here
00166     wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, IMAGE_RECEIVED_EVENT );
00167 
00168         img_data->image = image_received;
00169         img_data->stream_id = stream_id;
00170 
00171     event.SetClientData( img_data );
00172 
00173     // send in a thread-safe way
00174     wxPostEvent( _main_frame_pointer, event );
00175 
00176 }
00177 
00178 
00179 void ReceiverCtrlThread::fake_destroy_image_context( char*, void* ) 
00180 {
00181 }
00182 
00183 void ReceiverCtrlThread::fake_create_image_context( char*, void* )
00184 {
00185 }
00186 
00187 void ReceiverCtrlThread::ready_to_send_image( IplImage *image, int stream_id, char* __unused__, 
00188                                                                                 void* callback_data )
00189 {
00190         ReceiverCtrlThread *recv;
00191         
00192         recv = (ReceiverCtrlThread*)callback_data;
00193 
00194         recv->notifyMainThread( image, stream_id );
00195 }
00196 
00197 
00198 void ReceiverCtrlThread::initializeOmniStuff( IplImage *image_to_parse ) 
00199 {
00200         if ( _gcard_use == false ) {
00201                 OmniConversion<OmniFastLookupTable, int, IplImage, CvPoint> *conv;
00202                 OmniFastLookupTable *fast_lookup;
00203                                         
00204                 DEBUG_PRINT ("creating OmniFastLookupTable from receiver thread\n");
00205 
00206                 // create the fastlookup table
00207                 if ( !_main_frame_pointer->is_face_detect_options_set () ) {
00208                         DEBUG_PRINT("WARNING! !_main_frame_pointer->is_face_detect_options_set () \n");
00209                         return;
00210                 }
00211 
00212                 fast_lookup = new OmniFastLookupTable( _main_frame_pointer->GetMinRadius (),
00213                                                                                            _main_frame_pointer->GetMaxRadius (),
00214                                                                                            _main_frame_pointer->GetCenterX (),
00215                                                                                            _main_frame_pointer->GetCenterY (),
00216                                                                                            0,
00217                                                                                            _main_frame_pointer->GetFlippedModeStatus() );
00218 
00219                 // conversion
00220                 conv = new OmniConversion<OmniFastLookupTable, int, IplImage, CvPoint>( fast_lookup );
00221                 if ( !conv->is_initialized () ) {
00222                         wxMessageDialog dlg1( NULL, 
00223                         wxT("Error initializing OmniFastLookupTable.") , wxT( "Error" ), wxOK );
00224                         dlg1.ShowModal();
00225                         return;
00226                 }
00227 
00228                 if ( _main_frame_pointer->GetAlgoSimpleStatus() ) {
00229                         const char **c_array;
00230                         wxArrayString *wx_array = _main_frame_pointer->GetCascadeArray ();
00231                         int c_size = _main_frame_pointer->GetCascadeSize ();
00232 
00233                         if ( c_size <= 0 ) {
00234                                 wxMessageDialog dlg1( NULL, 
00235                                 wxT("No cascade selected. You need at least one") , wxT( "Error" ), wxOK );
00236                                 dlg1.ShowModal();
00237                                 return;
00238                         }
00239                         c_array = (const char**)calloc(c_size, sizeof(char*));
00240 
00241                         for ( int i = 0; i < c_size; i++ ) {
00242                                 c_array[i] = strdup( wxConvCurrent->cWX2MB( wx_array->Item(i) ) );
00243                         }
00244 
00245 
00246                         // instantiate the algorithm
00247                         _ctrl_lookup = new OmniAlgoSimpleDetection<OmniFastLookupTable, int, IplImage, CvPoint>( conv, 
00248                                                                                                 image_to_parse, 
00249                                                                                                 (const char**)c_array,
00250                                                                                                 c_size,
00251                                                                                                 _main_frame_pointer->GetFreezeFrameBound (),
00252                                                                                                 _main_frame_pointer->GetTrackWindowHitrate ()
00253                                                                                                 );
00254 
00255                         _ctrl_lookup->register_all_image_callbacks( ReceiverCtrlThread::fake_create_image_context, 
00256                                                                                                                 ReceiverCtrlThread::ready_to_send_image,
00257                                                                                                                 ReceiverCtrlThread::fake_destroy_image_context,
00258                                                                                                                 this );
00259                 }
00260                 else {
00261                         _ctrl_vr_lookup = new OmniAlgoVRFilterDetection
00262                                                                 <OmniFastLookupTable, int, IplImage, CvPoint> ( conv, image_to_parse );
00263 
00264                         _ctrl_vr_lookup->register_all_image_callbacks(  ReceiverCtrlThread::fake_create_image_context, 
00265                                                                                                                         ReceiverCtrlThread::ready_to_send_image,
00266                                                                                                                         ReceiverCtrlThread::fake_destroy_image_context,
00267                                                                                                                         this );
00268                 }
00269 
00270                 _ctrl_initialized = true;
00271         }
00272         else {          // we have a compatible graphic card and we want to use it
00273                 OmniConversion<OmniGCardConverter, double, IplImage, CvPoint> *conv;
00274                 OmniGCardConverter *gcard_converter;
00275                 
00276                 DEBUG_PRINT ("creating OmniGCardConverter\n");
00277                 
00278                 // create the gcard_converter class
00279                 gcard_converter = new OmniGCardConverter( _main_frame_pointer->GetMinRadius(), 
00280                                                                                           _main_frame_pointer->GetMaxRadius(), 
00281                                                                                           _main_frame_pointer->GetCenterX(), 
00282                                                                                           _main_frame_pointer->GetCenterY(), 
00283                                                                                           image_to_parse->width,
00284                                                                                           image_to_parse->height,
00285                                                                                           "omnigcard",
00286                                                                                           "omnistuff/data/shaders/vertex_shader.cg",
00287                                                                                           "vertex_shader_main",
00288                                                                                           "omnistuff/data/shaders/pixel_shader.cg",
00289                                                                                           "pixel_shader_main",
00290                                                                                           _main_frame_pointer->GetFlippedModeStatus());
00291 
00292                 // conversion
00293                 conv = new OmniConversion<OmniGCardConverter, double, IplImage, CvPoint>( gcard_converter );
00294                 if ( !conv->is_initialized () ) {
00295                         DEBUG_PRINT("Error initializing OmniGCardConverter");
00296                         delete conv;
00297                         gcard_converter = NULL;
00298                         return;
00299                 }
00300 
00301                 if ( _main_frame_pointer->GetAlgoSimpleStatus() ) {
00302                         const char **c_array;
00303                         wxArrayString *wx_array = _main_frame_pointer->GetCascadeArray ();
00304                         int c_size = _main_frame_pointer->GetCascadeSize ();
00305 
00306                         if ( c_size <= 0 ) {
00307                                 DEBUG_PRINT("ERROR: bad number of cascaded selected");
00308                                 return;
00309                         }
00310                         c_array = (const char**)calloc(c_size, sizeof(char*));
00311 
00312                         for ( int i = 0; i < c_size; i++ ) 
00313                                 c_array[i] = strdup( wxConvCurrent->cWX2MB( wx_array->Item(i) ) );
00314 
00315                         // instantiate the algorithm
00316                         _ctrl_gcard = new OmniAlgoSimpleDetection<OmniGCardConverter, double, IplImage, CvPoint>( conv, 
00317                                                                                                         image_to_parse, 
00318                                                                                                         (const char**)c_array,
00319                                                                                                         c_size,
00320                                                                                                         _main_frame_pointer->GetFreezeFrameBound(),
00321                                                                                                         _main_frame_pointer->GetTrackWindowHitrate());
00322 
00323                         _ctrl_gcard->register_all_image_callbacks(  ReceiverCtrlThread::fake_create_image_context, 
00324                                                                                                                 ReceiverCtrlThread::ready_to_send_image,
00325                                                                                                                 ReceiverCtrlThread::fake_destroy_image_context,
00326                                                                                                                 this );
00327                 }
00328                 else {
00329                         _ctrl_vr_gcard = new OmniAlgoVRFilterDetection
00330                                 <OmniGCardConverter, double, IplImage, CvPoint>( conv, image_to_parse );
00331 
00332                         _ctrl_vr_gcard->register_all_image_callbacks(  ReceiverCtrlThread::fake_create_image_context, 
00333                                                                                                                 ReceiverCtrlThread::ready_to_send_image,
00334                                                                                                                 ReceiverCtrlThread::fake_destroy_image_context,
00335                                                                                                                 this );
00336                 }
00337                 _ctrl_initialized = true;
00338         }
00339 }
00340 
00341 void ReceiverCtrlThread::doOmniStuffParsing( IplImage* image_to_parse, int stream_id ) 
00342 {
00343         if ( image_to_parse == NULL ) {
00344                 DEBUG_PRINT ("image_to_parse from void StreamerCtrlThread::onParsableImage is NULL\n");
00345                 return;
00346         }
00347         
00348         if ( _ctrl_initialized == false ) {
00349                 initializeOmniStuff( image_to_parse );
00350         }
00351         
00352         if ( _gcard_use == true ) {
00353                 if ( _main_frame_pointer->GetAlgoSimpleStatus() ) {
00354             _ctrl_gcard->loop_next_frame( image_to_parse );
00355                 }
00356                 else {
00357                         _ctrl_vr_gcard->loop_next_frame( image_to_parse );
00358                 }
00359         }
00360         else {
00361                 if ( _main_frame_pointer->GetAlgoSimpleStatus() ) {
00362                         _ctrl_lookup->loop_next_frame( image_to_parse );
00363                 }
00364                 else {
00365                         _ctrl_vr_lookup->loop_next_frame( image_to_parse );
00366                 }
00367         }
00368 }
00369 
00370 //--------------------------------------------------------------------------
00371 //
00372 
00373 bool ReceiverCtrlThread::onImageReceivedFromNet( IplImage* image_received, 
00374                                                                                                 int stream_id, const void *client_data ) 
00375 {
00376         ReceiverCtrlThread *recv;
00377         
00378         recv = (ReceiverCtrlThread*)client_data;
00379 
00380         // image_received is an omnidirectional frame?
00381         if ( recv->_main_frame_pointer->is_face_detect_options_set()
00382                 && recv->_is_multi_stream == false ) {
00383                 recv->doOmniStuffParsing( image_received, stream_id );
00384 
00385                 cvReleaseImage( &image_received );
00386         }
00387         else {
00388                 // other kind of stream: multi or direct.
00389                 recv->notifyMainThread( image_received, stream_id );
00390         }
00391 
00392         return true;
00393 }
00394 
00395 
00396 
00397 #define DROP_PACKET_BOUND               200000
00398 
00399 //           +----- _read_data_prt;
00400 //           |
00401 //           v
00402 //  [________#######################___]
00403 //                                 ^-------g_prebuff_ptr
00404 //                                  
00405 //
00406 
00407 static  int g_read_data_ptr;
00408 static  int g_prebuff_ptr;
00409                 
00410 // the circular buffer
00411 static  unsigned char *g_shared_buffer;
00412         
00413 // size of circular buffer
00414 static  unsigned int g_shared_buffer_size;
00415                 
00416 // it's (g_prebuff_ptr - _read_data_prt) in a circular fashion.
00417 static  unsigned int g_available_bytes;
00418 
00419 static  wxMutex *g_mutex_sound;
00420 
00421 void ReceiverCtrlThread::ERRCHECK(FMOD_RESULT result)
00422 {
00423         char buf[0xffff];
00424     if (result != FMOD_OK)
00425     {
00426         sprintf(buf, "FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
00427     }
00428 }
00429 
00430 FMOD_RESULT F_CALLBACK ReceiverCtrlThread::fmod_read_cb(void *handle, void *buffer, 
00431                                                                                    unsigned int requested_bytes, 
00432                                                                                    unsigned int *bytesread, void *userdata)
00433 {
00434         DEBUG_PRINT("myread...");       
00435         wxMutexLocker lock(*g_mutex_sound);
00436 
00437         // this should never happen.
00438         if ( g_available_bytes <= 0 ) {
00439                                 
00440                 *bytesread = 0;
00441                 // has the sound end?
00442                 DEBUG_PRINT("TODO SPECIAL CASE!!\n");
00443                 return FMOD_ERR_FILE_EOF;
00444         } 
00445         else if ( requested_bytes > g_available_bytes ) {               // better to return the available bytes 
00446                                                                                                                         // and then sleep a bit
00447                 DEBUG_PRINT ("sizebytes > g_available_bytes\n");
00448                 
00449                 if ( (g_prebuff_ptr < g_read_data_ptr) && 
00450                         (g_available_bytes > g_shared_buffer_size - g_read_data_ptr)) {
00451 
00452                         int tmp_written = g_shared_buffer_size - g_read_data_ptr;
00453                         memcpy( buffer, &g_shared_buffer[g_read_data_ptr], tmp_written );
00454                         
00455                         // just to clarify the if(s)  :-)
00456                         g_read_data_ptr = 0;
00457                         
00458                         memcpy( buffer, &g_shared_buffer[0], g_available_bytes - tmp_written );
00459                                                 
00460                         *bytesread = g_available_bytes;
00461                         
00462                         // we use all of them
00463                         g_available_bytes = 0;
00464                         
00465                         // update the _read_data_prt. We cyclic here.
00466                         g_read_data_ptr += g_available_bytes - tmp_written;
00467                         
00468                 }
00469                 else {
00470                         memcpy( buffer, &g_shared_buffer[g_read_data_ptr], g_available_bytes );
00471                         *bytesread = g_available_bytes;
00472                         g_read_data_ptr += g_available_bytes;
00473                         
00474                         g_available_bytes = 0;
00475                 }               
00476         }
00477         else {          
00478                 // the normal case
00479                 DEBUG_PRINT (" requested sizebytes %d\n", requested_bytes );
00480                 
00481                 if ( (g_prebuff_ptr < g_read_data_ptr) && (requested_bytes > g_shared_buffer_size - g_read_data_ptr)) {
00482                         
00483                         int tmp_written = g_shared_buffer_size - g_read_data_ptr;
00484                         
00485                         memcpy( buffer, &g_shared_buffer[g_read_data_ptr], tmp_written );
00486                         
00487                         // just to clarify the if(s)  :-)
00488                         g_read_data_ptr = 0;
00489                         
00490                         memcpy( &((unsigned char*)buffer)[tmp_written], &g_shared_buffer[0], requested_bytes - tmp_written );
00491 
00492                         *bytesread = requested_bytes;
00493                         g_available_bytes -= requested_bytes;
00494                         
00495                         // update the _read_data_prt. We cyclic here.
00496                         g_read_data_ptr += requested_bytes - tmp_written;
00497                 }
00498                 else {
00499                         memcpy( buffer, &g_shared_buffer[g_read_data_ptr], requested_bytes );
00500                         *bytesread = requested_bytes;
00501                         g_available_bytes -= requested_bytes;
00502                         
00503                         g_read_data_ptr += requested_bytes;
00504                 }               
00505         }
00506 
00507         
00508     return FMOD_OK;
00509 }
00510 
00511 
00512 FMOD_RESULT F_CALLBACK ReceiverCtrlThread::fmod_open_cb(const char *name, int unicode, 
00513                                                                                            unsigned int *filesize, void **handle, 
00514                                                                                            void **userdata)
00515 {
00516         DEBUG_PRINT("myopen\n");
00517         
00518         *filesize = 10000000;
00519     return FMOD_OK;
00520 }
00521 
00522 FMOD_RESULT F_CALLBACK ReceiverCtrlThread::fmod_close_cb(void *handle, void *userdata)
00523 {
00524         DEBUG_PRINT("myclose\n");       
00525 
00526         return FMOD_OK;
00527 }
00528 
00529 FMOD_RESULT F_CALLBACK ReceiverCtrlThread::fmod_seek_cb( void * handle, unsigned int pos, void * userdata )
00530 {
00531         DEBUG_PRINT("myseek to pos %d\n", pos);
00532         return FMOD_OK;
00533 }
00534 
00535 void ReceiverCtrlThread::fmod_init ()
00536 {
00537         _channel = 0;
00538     /*
00539         Create a System object and initialize.
00540     */
00541     _result = FMOD::System_Create(&_system);
00542     ERRCHECK( _result );
00543 
00544     _result = _system->getVersion(&_version);
00545     ERRCHECK( _result );
00546 
00547     if (_version < FMOD_VERSION)
00548     {
00549         DEBUG_PRINT("Error!  You are using an old version of FMOD %08x.  This program requires %08x\n", 
00550                            _version, FMOD_VERSION);
00551         return;
00552     }
00553         
00554                 
00555     _result = _system->init( 32, FMOD_INIT_NORMAL, 0 );
00556     ERRCHECK( _result );
00557 
00558     _result = _system->setFileSystem( ReceiverCtrlThread::fmod_open_cb, 
00559                                                                           ReceiverCtrlThread::fmod_close_cb, 
00560                                                                           ReceiverCtrlThread::fmod_read_cb, 
00561                                                                           ReceiverCtrlThread::fmod_seek_cb,
00562                                                                           80000 );
00563         ERRCHECK( _result );
00564 
00565         g_mutex_sound = new wxMutex();
00566 
00567     
00568 }
00569 
00570 
00571 // will manage all the circular buffer stuff
00572 void ReceiverCtrlThread::add_available_bytes( unsigned char* bytes_to_add_buff, unsigned int bytes_to_add_size )
00573 {
00574         wxMutexLocker lock(*g_mutex_sound);
00575 
00576         // it can happen that the available_bytes collected are too much.
00577         // In that case we will drop them.
00578         if ( g_available_bytes > DROP_PACKET_BOUND )
00579                 return;
00580 
00581 
00582         //           +----- g_prebuff_ptr
00583         //           |
00584         //           v
00585         //  [#########___________________########]
00586         //                              ^------- _read_data_prt
00587         //                                  
00588         //
00589         
00590         if ( g_prebuff_ptr < g_read_data_ptr ) {
00591                 // we should not warning about the override ot the remaining g_read_data_ptr    
00592                 // if we take a big g_shared_buffer. I.e. 1MB or more.
00593                 memcpy( &g_shared_buffer[g_prebuff_ptr], bytes_to_add_buff, bytes_to_add_size );
00594                 
00595                 g_prebuff_ptr += bytes_to_add_size;
00596                 g_available_bytes += bytes_to_add_size;
00597         }
00598         
00599         //           +----- _read_data_prt
00600         //           |                  __________  bytes_to_add_size > g_shared_buffer_size - g_prebuff_ptr
00601         //           v                  vvv 
00602         //  [________###################___]
00603         //                             ^------- g_prebuff_ptr
00604         //                                  
00605         //
00606         
00607         else if ( (g_prebuff_ptr > g_read_data_ptr) && 
00608                          (bytes_to_add_size > g_shared_buffer_size - g_prebuff_ptr) ) {
00609                                 
00610                 int tmp_written = g_shared_buffer_size - g_prebuff_ptr;
00611                 memcpy( &g_shared_buffer[g_prebuff_ptr], bytes_to_add_buff, tmp_written );
00612                                  
00613                 // cyclic here
00614                 g_prebuff_ptr = 0;
00615                                  
00616                 memcpy( &g_shared_buffer[g_prebuff_ptr], &bytes_to_add_buff[tmp_written], bytes_to_add_size - tmp_written );
00617                                  
00618                 g_prebuff_ptr = bytes_to_add_size - tmp_written;
00619                 g_available_bytes += bytes_to_add_size;
00620         }
00621 
00622         //           +----- _read_data_prt
00623         //           |      
00624         //           v      
00625         //  [________#############_________]
00626         //                       ^------- g_prebuff_ptr
00627         //                                  
00628         //
00629         
00630         else {          // the normal case
00631         
00632                 memcpy( &g_shared_buffer[g_prebuff_ptr], bytes_to_add_buff, bytes_to_add_size );
00633                 
00634                 g_prebuff_ptr += bytes_to_add_size;     
00635                 g_available_bytes += bytes_to_add_size;
00636         }
00637         
00638         DEBUG_PRINT ("g_read_data_ptr %d - g_prebuff_ptr %d [+bytes %d] - difference %d\n", 
00639                                  g_read_data_ptr, g_prebuff_ptr, bytes_to_add_size, g_available_bytes );
00640 }
00641 
00642 
00643 void ReceiverCtrlThread::doAudioParsing( unsigned char* audio_received_buf, int audio_received_size, 
00644                                                                                 int stream_id ) 
00645 {
00646         DEBUG_PRINT ("doAudioParsing\n");
00647         // we should use fmod here.
00648         if ( _fmod_initialized == false ) {
00649                 fmod_init ();
00650 
00651                 g_shared_buffer_size = 1000000;
00652 
00653                 g_shared_buffer = new unsigned char[g_shared_buffer_size];
00654                                 
00655                 g_read_data_ptr = 0;
00656                 g_prebuff_ptr = 0;                              
00657                                 
00658                 _channel = 0;
00659                 _sound = 0;
00660                 _fmod_initialized = true;
00661         }
00662                 
00663         add_available_bytes( audio_received_buf, audio_received_size );
00664         if ( g_available_bytes >= 131070 ) {
00665                 if ( _sound == NULL ) {
00666 
00667                         DEBUG_PRINT ("created new sound.....\n");
00668                     _result = _system->createSound( "dummy_file", FMOD_SOFTWARE | 
00669                                                                                  FMOD_CREATESTREAM, 0, &_sound );
00670                         ERRCHECK(_result);
00671                         _result = _sound->setMode( FMOD_LOOP_OFF );
00672                         ERRCHECK( _result );
00673                                         
00674                         DEBUG_PRINT ("playing it....\n");
00675                         _result = _system->playSound(FMOD_CHANNEL_FREE, _sound, false, &_channel);
00676                 }
00677         }
00678 }
00679 
00680 
00681 //--------------------------------------------------------------------------
00682 //
00683 
00684 bool ReceiverCtrlThread::onAudioFrameReceivedFromNet( unsigned char* audio_buf, int audio_buf_size, 
00685                                                                                         int stream_id, const void *client_data ) 
00686 {
00687         ReceiverCtrlThread *recv;
00688         
00689         recv = (ReceiverCtrlThread*)client_data;
00690 
00691         recv->doAudioParsing( audio_buf, audio_buf_size, stream_id );
00692         return true;    
00693 }
00694 
00695 

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