00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00046
00047 void ReceiverCtrlThread::Create( const wxString destRTSPUrl, bool is_multi_stream )
00048 {
00049
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
00123 wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
00124 event.SetString( error );
00125
00126
00127 wxPostEvent( this->_main_frame_pointer, event );
00128 }
00129 }
00130
00131
00132
00133
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
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
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
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
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
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
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 {
00273 OmniConversion<OmniGCardConverter, double, IplImage, CvPoint> *conv;
00274 OmniGCardConverter *gcard_converter;
00275
00276 DEBUG_PRINT ("creating OmniGCardConverter\n");
00277
00278
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
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
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
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
00389 recv->notifyMainThread( image_received, stream_id );
00390 }
00391
00392 return true;
00393 }
00394
00395
00396
00397 #define DROP_PACKET_BOUND 200000
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 static int g_read_data_ptr;
00408 static int g_prebuff_ptr;
00409
00410
00411 static unsigned char *g_shared_buffer;
00412
00413
00414 static unsigned int g_shared_buffer_size;
00415
00416
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
00438 if ( g_available_bytes <= 0 ) {
00439
00440 *bytesread = 0;
00441
00442 DEBUG_PRINT("TODO SPECIAL CASE!!\n");
00443 return FMOD_ERR_FILE_EOF;
00444 }
00445 else if ( requested_bytes > g_available_bytes ) {
00446
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
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
00463 g_available_bytes = 0;
00464
00465
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
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
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
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
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
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
00577
00578 if ( g_available_bytes > DROP_PACKET_BOUND )
00579 return;
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 if ( g_prebuff_ptr < g_read_data_ptr ) {
00591
00592
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
00600
00601
00602
00603
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
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
00623
00624
00625
00626
00627
00628
00629
00630 else {
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
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