00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00047 #ifdef HAVE_CONFIG_H
00048 #include <config.h>
00049 #endif
00050
00051 #include <deque>
00052 #include <iostream>
00053
00054 using std::cerr;
00055 using std::endl;
00056
00057 #include <assert.h>
00058 #include <unistd.h>
00059 #include <fcntl.h>
00060 #include <pthread.h>
00061 #include <sys/ioctl.h>
00062 #include <sys/mman.h>
00063 #include <sys/poll.h>
00064 #include <errno.h>
00065 #include <time.h>
00066 #include <sys/time.h>
00067
00068 #include <libavc1394/avc1394.h>
00069 #include <libavc1394/avc1394_vcr.h>
00070 #include <libavc1394/rom1394.h>
00071
00072 #include "ieee1394io.h"
00073 #include "preferences.h"
00074 #include "kino_common.h"
00075 #include "page_capture.h"
00076 #include "frame.h"
00077 #include "error.h"
00078 #include "message.h"
00079 #include "commands.h"
00080
00081
00096 IEEE1394Reader::IEEE1394Reader( int c, int bufSize ) :
00097 droppedFrames( 0 ),
00098 currentFrame( NULL ),
00099 channel( c ),
00100 isRunning( false )
00101 {
00102 Frame * frame;
00103
00104
00105 for ( int i = 0; i < bufSize; ++i )
00106 {
00107 frame = GetFramePool( ) ->GetFrame( );
00108 inFrames.push_back( frame );
00109 }
00110
00111
00112 pthread_mutex_init( &mutex, NULL );
00113
00114
00115 pthread_mutex_init( &condition_mutex, NULL );
00116 pthread_cond_init( &condition, NULL );
00117 }
00118
00119
00129 IEEE1394Reader::~IEEE1394Reader()
00130 {
00131 Frame * frame;
00132
00133 for ( int i = inFrames.size(); i > 0; --i )
00134 {
00135 frame = inFrames[ 0 ];
00136 inFrames.pop_front();
00137 GetFramePool( ) ->DoneWithFrame( frame );
00138 }
00139 for ( int i = outFrames.size(); i > 0; --i )
00140 {
00141 frame = outFrames[ 0 ];
00142 outFrames.pop_front();
00143 GetFramePool( ) ->DoneWithFrame( frame );
00144 }
00145 if ( currentFrame != NULL )
00146 {
00147 GetFramePool( ) ->DoneWithFrame( currentFrame );
00148 currentFrame = NULL;
00149 }
00150 pthread_mutex_destroy( &condition_mutex );
00151 pthread_cond_destroy( &condition );
00152 }
00153
00154
00169 Frame* IEEE1394Reader::GetFrame()
00170 {
00171 Frame * frame = NULL;
00172
00173 pthread_mutex_lock( &mutex );
00174
00175 if ( outFrames.size() > 0 )
00176 {
00177 frame = outFrames[ 0 ];
00178 outFrames.pop_front();
00179 }
00180 pthread_mutex_unlock( &mutex );
00181 if ( frame != NULL )
00182 frame->ExtractHeader();
00183
00184 return frame;
00185 }
00186
00187
00191 void IEEE1394Reader::DoneWithFrame( Frame* frame )
00192 {
00193 pthread_mutex_lock( &mutex );
00194 inFrames.push_back( frame );
00195 pthread_mutex_unlock( &mutex );
00196 }
00197
00198
00202 int IEEE1394Reader::GetDroppedFrames( void )
00203 {
00204 pthread_mutex_lock( &mutex );
00205 int n = droppedFrames;
00206 droppedFrames = 0;
00207 pthread_mutex_unlock( &mutex );
00208 return n;
00209 }
00210
00211
00218 void IEEE1394Reader::Flush()
00219 {
00220 Frame * frame = NULL;
00221
00222 pthread_mutex_lock( &mutex );
00223 for ( int i = outFrames.size(); i > 0; --i )
00224 {
00225 frame = outFrames[ 0 ];
00226 outFrames.pop_front();
00227 inFrames.push_back( frame );
00228 }
00229 if ( currentFrame != NULL )
00230 {
00231 inFrames.push_back( currentFrame );
00232 currentFrame = NULL;
00233 }
00234 pthread_mutex_unlock( &mutex );
00235 }
00236
00237 bool IEEE1394Reader::WaitForAction( int seconds )
00238 {
00239 pthread_mutex_lock( &mutex );
00240 int size = outFrames.size( );
00241 pthread_mutex_unlock( &mutex );
00242
00243 if ( size == 0 )
00244 {
00245 pthread_mutex_lock( &condition_mutex );
00246 if ( seconds == 0 )
00247 {
00248 pthread_cond_wait( &condition, &condition_mutex );
00249 pthread_mutex_unlock( &condition_mutex );
00250 pthread_mutex_lock( &mutex );
00251 size = outFrames.size( );
00252 }
00253 else
00254 {
00255 struct timeval tp;
00256 struct timespec ts;
00257 int result;
00258
00259 gettimeofday( &tp, NULL );
00260 ts.tv_sec = tp.tv_sec + seconds;
00261 ts.tv_nsec = tp.tv_usec * 1000;
00262
00263 result = pthread_cond_timedwait( &condition, &condition_mutex, &ts );
00264 pthread_mutex_unlock( &condition_mutex );
00265 pthread_mutex_lock( &mutex );
00266
00267 if ( result == ETIMEDOUT )
00268 size = 0;
00269 else
00270 size = outFrames.size();
00271 }
00272 pthread_mutex_unlock( &mutex );
00273 }
00274
00275 return size != 0;
00276 }
00277
00278
00279 void IEEE1394Reader::TriggerAction( )
00280 {
00281 pthread_mutex_lock( &condition_mutex );
00282 pthread_cond_signal( &condition );
00283 pthread_mutex_unlock( &condition_mutex );
00284 }
00285
00286
00287 #ifdef HAVE_IEC61883
00288
00299 iec61883Reader::iec61883Reader( int c, int bufSize ) :
00300 IEEE1394Reader( c, bufSize )
00301 {
00302 m_handle = NULL;
00303 cerr << ">>> Using iec61883 capture" << endl;
00304 }
00305
00306
00307 iec61883Reader::~iec61883Reader()
00308 {
00309 StopThread();
00310 }
00311
00312
00321 bool iec61883Reader::StartThread( int port )
00322 {
00323 if ( isRunning )
00324 return true;
00325 if ( port < 0 )
00326 return false;
00327 cerr << ">>> iec61883Reader::StartThread on port " << port << endl;
00328
00329 pthread_mutex_lock( &mutex );
00330 currentFrame = NULL;
00331 if ( Open( port ) && StartReceive() )
00332 {
00333 isRunning = true;
00334 pthread_create( &thread, NULL, ThreadProxy, this );
00335 pthread_mutex_unlock( &mutex );
00336 return true;
00337 }
00338 else
00339 {
00340 Close();
00341 pthread_mutex_unlock( &mutex );
00342 return false;
00343 }
00344 }
00345
00346
00357 void iec61883Reader::StopThread()
00358 {
00359 if ( isRunning )
00360 {
00361 isRunning = false;
00362 pthread_join( thread, NULL );
00363 }
00364 Close();
00365 Flush();
00366 }
00367
00368
00369 void iec61883Reader::ResetHandler( void )
00370 {
00371 }
00372
00373 int iec61883Reader::ResetHandlerProxy( raw1394handle_t handle, unsigned int generation )
00374 {
00375 iec61883_dv_t dv = static_cast< iec61883_dv_t >( raw1394_get_userdata( handle ) );
00376 iec61883_dv_fb_t dvfb = static_cast< iec61883_dv_fb_t >( iec61883_dv_get_callback_data( dv ) );
00377 iec61883Reader *self = static_cast< iec61883Reader* >( iec61883_dv_fb_get_callback_data( dvfb ) );
00378 raw1394_update_generation( handle, generation );
00379 if ( self )
00380 self->ResetHandler();
00381 return 0;
00382 }
00383
00384
00390 bool iec61883Reader::Open( int port )
00391 {
00392 bool success;
00393
00394 assert( !m_handle );
00395
00396 try
00397 {
00398 m_handle = raw1394_new_handle_on_port( port );
00399 if ( !m_handle )
00400 return false;
00401 raw1394_set_bus_reset_handler( m_handle, this->ResetHandlerProxy );
00402
00403 m_iec61883dv = iec61883_dv_fb_init( m_handle, HandlerProxy, this );
00404 success = ( m_iec61883dv != NULL );
00405 }
00406 catch ( string exc )
00407 {
00408 Close();
00409 cerr << exc << endl;
00410 success = false;
00411 }
00412 return success;
00413 }
00414
00415
00420 void iec61883Reader::Close()
00421 {
00422 if ( m_handle )
00423 {
00424 StopReceive();
00425 raw1394_destroy_handle( m_handle );
00426 m_handle = NULL;
00427 }
00428 }
00429
00430 bool iec61883Reader::StartReceive()
00431 {
00432 bool success;
00433
00434
00435 try
00436 {
00437 fail_neg( iec61883_dv_fb_start( m_iec61883dv, channel ) );
00438 success = true;
00439 }
00440 catch ( string exc )
00441 {
00442 cerr << exc << endl;
00443 success = false;
00444 }
00445 return success;
00446 }
00447
00448
00449 void iec61883Reader::StopReceive()
00450 {
00451 if ( m_iec61883dv )
00452 {
00453 iec61883_dv_fb_close( m_iec61883dv );
00454 m_iec61883dv = NULL;
00455 }
00456 }
00457
00458 int iec61883Reader::HandlerProxy( unsigned char *data, int length, int complete,
00459 void *callback_data )
00460 {
00461 iec61883Reader *self = static_cast< iec61883Reader* >( callback_data );
00462 return self->Handler( length, complete, data );
00463 }
00464
00465 int iec61883Reader::Handler( int length, int complete, unsigned char *data )
00466 {
00467 pthread_mutex_lock( &mutex );
00468 if ( currentFrame )
00469 {
00470 outFrames.push_back( currentFrame );
00471 currentFrame = NULL;
00472
00473 TriggerAction( );
00474 }
00475 if ( inFrames.size() > 0 )
00476 {
00477 currentFrame = inFrames.front();
00478 currentFrame->bytesInFrame = 0;
00479 inFrames.pop_front();
00480 if ( outFrames.size( ) >= 25 )
00481 cerr << "reader < # inFrames: " << inFrames.size() << ", # outFrames: " << outFrames.size() << endl;
00482 }
00483 else
00484 {
00485 droppedFrames++;
00486 cerr << "reader < # dropped frames: " << droppedFrames << endl;
00487 }
00488 pthread_mutex_unlock( &mutex );
00489
00490 if ( currentFrame )
00491 {
00492 memcpy( currentFrame->data, data, length );
00493 currentFrame->bytesInFrame = length;
00494 }
00495
00496 return 0;
00497 }
00498
00499
00506 void* iec61883Reader::ThreadProxy( void* arg )
00507 {
00508 iec61883Reader* self = static_cast< iec61883Reader* >( arg );
00509 return self->Thread();
00510 }
00511
00512 void* iec61883Reader::Thread()
00513 {
00514 struct pollfd raw1394_poll;
00515 int result;
00516
00517 assert( m_handle );
00518 raw1394_poll.fd = raw1394_get_fd( m_handle );
00519 raw1394_poll.events = POLLIN | POLLERR | POLLHUP | POLLPRI;
00520
00521 while ( isRunning )
00522 {
00523 while ( ( result = poll( &raw1394_poll, 1, 200 ) ) < 0 )
00524 {
00525 if ( !( errno == EAGAIN || errno == EINTR ) )
00526 {
00527 perror( "error: raw1394 poll" );
00528 break;
00529 }
00530 }
00531 if ( result > 0 && ( ( raw1394_poll.revents & POLLIN )
00532 || ( raw1394_poll.revents & POLLPRI ) ) )
00533 result = raw1394_loop_iterate( m_handle );
00534 }
00535 return NULL;
00536 }
00537 #endif
00538
00539
00540 #ifdef HAVE_DV1394
00541
00548 dv1394Reader::dv1394Reader( int c, int bufSize ) :
00549 IEEE1394Reader( c, bufSize )
00550 {
00551 m_dv1394_map = NULL;
00552 m_dv1394_fd = -1;
00553 cerr << ">>> Using dv1394 capture" << endl;
00554 }
00555
00556
00557 dv1394Reader::~dv1394Reader()
00558 {}
00559
00560
00569 bool dv1394Reader::StartThread( int port )
00570 {
00571 if ( isRunning )
00572 return true;
00573 pthread_mutex_lock( &mutex );
00574 currentFrame = NULL;
00575 if ( Open( port ) && StartReceive() )
00576 {
00577 isRunning = true;
00578 pthread_create( &thread, NULL, ThreadProxy, this );
00579 pthread_mutex_unlock( &mutex );
00580 return true;
00581 }
00582 else
00583 {
00584 Close();
00585 pthread_mutex_unlock( &mutex );
00586 return false;
00587 }
00588 }
00589
00590
00600 void dv1394Reader::StopThread()
00601 {
00602 if ( isRunning )
00603 {
00604 isRunning = false;
00605 pthread_join( thread, NULL );
00606 StopReceive();
00607 Close();
00608 Flush();
00609 }
00610 TriggerAction( );
00611 }
00612
00613
00619 bool dv1394Reader::Open( int port )
00620 {
00621 int n_frames = DV1394_MAX_FRAMES / 4;
00622 struct dv1394_init init =
00623 {
00624 DV1394_API_VERSION, channel, n_frames, DV1394_PAL, 0, 0, 0
00625 };
00626
00627 m_dv1394_fd = open( Preferences::getInstance().dvCaptureDevice, O_RDWR );
00628 if ( m_dv1394_fd == -1 )
00629 return false;
00630
00631 if ( ioctl( m_dv1394_fd, DV1394_INIT, &init ) )
00632 {
00633 perror( "dv1394 INIT ioctl" );
00634 close( m_dv1394_fd );
00635 m_dv1394_fd = -1;
00636 return false;
00637 }
00638
00639 m_dv1394_map = ( unsigned char * ) mmap( NULL, DV1394_PAL_FRAME_SIZE * n_frames,
00640 PROT_READ | PROT_WRITE, MAP_SHARED, m_dv1394_fd, 0 );
00641 if ( m_dv1394_map == MAP_FAILED )
00642 {
00643 perror( "mmap frame buffers" );
00644 close( m_dv1394_fd );
00645 m_dv1394_fd = -1;
00646 m_dv1394_map = NULL;
00647 return false;
00648 }
00649
00650 return true;
00651 }
00652
00653
00657 void dv1394Reader::Close()
00658 {
00659 if ( m_dv1394_fd != -1 )
00660 {
00661 if ( m_dv1394_map != NULL )
00662 munmap( m_dv1394_map, DV1394_PAL_FRAME_SIZE * DV1394_MAX_FRAMES / 4 );
00663 close( m_dv1394_fd );
00664 m_dv1394_map = NULL;
00665 m_dv1394_fd = -1;
00666 }
00667 }
00668
00669
00670 bool dv1394Reader::StartReceive()
00671 {
00672
00673 if ( ioctl( m_dv1394_fd, DV1394_START_RECEIVE, NULL ) )
00674 {
00675 perror( "dv1394 START_RECEIVE ioctl" );
00676 return false;
00677 }
00678 return true;
00679 }
00680
00681
00682 void dv1394Reader::StopReceive()
00683 {}
00684
00685 bool dv1394Reader::Handler( int handle )
00686 {
00687 struct dv1394_status dvst;
00688 struct pollfd pol;
00689 int result;
00690
00691 pol.fd = m_dv1394_fd;
00692 pol.events = POLLIN | POLLERR | POLLHUP;
00693 while ( ( result = poll( &pol, 1, 200 ) ) < 0 )
00694 {
00695 if ( !( errno == EAGAIN || errno == EINTR ) )
00696 {
00697 perror( "error: dv1394 poll" );
00698 return false;
00699 }
00700 }
00701 if ( result == 0 )
00702 return true;
00703
00704 if ( ioctl( handle, DV1394_GET_STATUS, &dvst ) )
00705 {
00706 perror( "ioctl GET_STATUS" );
00707 return false;
00708 }
00709
00710 if ( dvst.dropped_frames > 0 )
00711 {
00712 std:cerr << "dv1394 reported " << dvst.dropped_frames << " dropped frames." << std::endl;
00713 droppedFrames += dvst.dropped_frames;
00714 }
00715
00716 for ( unsigned int i = 0; i < dvst.n_clear_frames; i++ )
00717 {
00718 pthread_mutex_lock( &mutex );
00719 if ( currentFrame != NULL )
00720 {
00721 outFrames.push_back( currentFrame );
00722 currentFrame = NULL;
00723 TriggerAction( );
00724
00725
00726 }
00727
00728
00729 if ( inFrames.size() > 0 )
00730 {
00731 currentFrame = inFrames.front();
00732 currentFrame->bytesInFrame = 0;
00733 inFrames.pop_front();
00734
00735
00736 }
00737 else
00738 {
00739 droppedFrames++;
00740 cerr << "reader < # dropped frames: " << droppedFrames << endl;
00741 }
00742
00743 pthread_mutex_unlock( &mutex );
00744
00745 if ( currentFrame != NULL )
00746 {
00747 memcpy( currentFrame->data,
00748 ( m_dv1394_map + ( dvst.first_clear_frame * DV1394_PAL_FRAME_SIZE ) ),
00749 DV1394_PAL_FRAME_SIZE );
00750 currentFrame->bytesInFrame = currentFrame->GetFrameSize( );
00751 }
00752
00753 if ( ioctl( handle, DV1394_RECEIVE_FRAMES, 1 ) )
00754 {
00755 perror( "error: ioctl RECEIVE_FRAMES" );
00756 return false;
00757 }
00758
00759 if ( ioctl( handle, DV1394_GET_STATUS, &dvst ) )
00760 {
00761 perror( "ioctl GET_STATUS" );
00762 return false;
00763 }
00764
00765 if ( dvst.dropped_frames > 0 )
00766 {
00767 std::cerr << "dv1394 reported " << dvst.dropped_frames << " dropped frames." << std::endl;
00768 droppedFrames += dvst.dropped_frames;
00769 }
00770
00771 }
00772 return true;
00773 }
00774
00775
00782 void* dv1394Reader::ThreadProxy( void* arg )
00783 {
00784 dv1394Reader* self = static_cast< dv1394Reader* >( arg );
00785 return self->Thread();
00786 }
00787
00788 void* dv1394Reader::Thread( )
00789 {
00790
00791 while ( isRunning )
00792 {
00793 if ( ! Handler( m_dv1394_fd ) )
00794 break;
00795 }
00796 return NULL;
00797 }
00798 #endif
00799
00800
00807 AVC::AVC( void ) : port( -1 ), totalPorts( 0 )
00808 {
00809 pthread_mutex_init( &avc_mutex, NULL );
00810 avc_handle = NULL;
00811 struct raw1394_portinfo pinf[ 16 ];
00812
00813 try
00814 {
00815 avc_handle = raw1394_new_handle();
00816 if ( avc_handle == 0 )
00817 return;
00818 fail_neg( totalPorts = raw1394_get_port_info( avc_handle, pinf, 16 ) );
00819 raw1394_destroy_handle( avc_handle );
00820 avc_handle = NULL;
00821 }
00822 catch ( string exc )
00823 {
00824 if ( avc_handle != NULL )
00825 raw1394_destroy_handle( avc_handle );
00826 avc_handle = NULL;
00827 cerr << exc << endl;
00828 }
00829 return;
00830 }
00831
00832
00837 AVC::~AVC()
00838 {
00839 if ( avc_handle != NULL )
00840 {
00841 pthread_mutex_lock( &avc_mutex );
00842 raw1394_destroy_handle( avc_handle );
00843 avc_handle = NULL;
00844 pthread_mutex_unlock( &avc_mutex );
00845 }
00846 }
00847
00848 extern "C" {
00849 extern KinoCommon *common;
00850 }
00851
00852 int AVC::ResetHandler( raw1394handle_t handle, unsigned int generation )
00853 {
00854 cerr << "Reset Handler received" << endl;
00855 raw1394_update_generation( handle, generation );
00856 common->getPageCapture()->driver_locked = true;
00857 return 0;
00858 }
00859
00860
00872 int AVC::isPhyIDValid( int phyID )
00873 {
00874 int value = -1;
00875 int currentNode, nodeCount;
00876 rom1394_directory rom1394_dir;
00877
00878 pthread_mutex_lock( &avc_mutex );
00879 if ( avc_handle != NULL )
00880 {
00881 nodeCount = raw1394_get_nodecount( avc_handle );
00882 if ( phyID >= 0 && phyID < nodeCount )
00883 {
00884 if ( rom1394_get_directory( avc_handle, phyID, &rom1394_dir ) >= 0 )
00885 {
00886 if ( rom1394_get_node_type( &rom1394_dir ) == ROM1394_NODE_TYPE_AVC )
00887 {
00888 if ( avc1394_check_subunit_type( avc_handle, phyID, AVC1394_SUBUNIT_TYPE_VCR ) )
00889 value = phyID;
00890 }
00891 rom1394_free_directory( &rom1394_dir );
00892 }
00893 }
00894
00895 if ( value == -1 )
00896 {
00897 raw1394_destroy_handle( avc_handle );
00898 avc_handle = NULL;
00899 port = -1;
00900 }
00901 }
00902 for ( int p = 0; value == -1 && p < totalPorts; p++ )
00903 {
00904 if ( ( avc_handle = raw1394_new_handle_on_port( p ) ) )
00905 {
00906 port = p;
00907 raw1394_set_bus_reset_handler( avc_handle, this->ResetHandler );
00908
00909
00910 nodeCount = raw1394_get_nodecount( avc_handle );
00911 for ( currentNode = 0; value == -1 && currentNode < nodeCount; currentNode++ )
00912 {
00913 if ( rom1394_get_directory( avc_handle, currentNode, &rom1394_dir ) >= 0 )
00914 {
00915 if ( rom1394_get_node_type( &rom1394_dir ) == ROM1394_NODE_TYPE_AVC )
00916 {
00917 if ( avc1394_check_subunit_type( avc_handle, currentNode, AVC1394_SUBUNIT_TYPE_VCR ) )
00918 {
00919
00920 octlet_t guid = rom1394_get_guid( avc_handle, currentNode );
00921 snprintf( Preferences::getInstance().avcGUID, 64, "%08x%08x",
00922 ( quadlet_t ) ( guid >> 32 ), ( quadlet_t ) ( guid & 0xffffffff ) );
00923 value = currentNode;
00924 }
00925 }
00926 rom1394_free_directory( &rom1394_dir );
00927 }
00928 }
00929 if ( value == -1 )
00930 {
00931 raw1394_destroy_handle( avc_handle );
00932 avc_handle = NULL;
00933 }
00934 }
00935 }
00936 if ( value == -1 )
00937 port = -1;
00938 pthread_mutex_unlock( &avc_mutex );
00939 return value;
00940 }
00941
00945 void AVC::Noop( void )
00946 {
00947 struct pollfd raw1394_poll;
00948 raw1394_poll.fd = raw1394_get_fd( avc_handle );
00949 raw1394_poll.events = POLLIN | POLLPRI;
00950 raw1394_poll.revents = 0;
00951 if ( poll( &raw1394_poll, 1, 100 ) > 0 )
00952 {
00953 if ( ( raw1394_poll.revents & POLLIN )
00954 || ( raw1394_poll.revents & POLLPRI ) )
00955 raw1394_loop_iterate( avc_handle );
00956 }
00957 }
00958
00959
00960 int AVC::Play( int phyID )
00961 {
00962 pthread_mutex_lock( &avc_mutex );
00963 if ( avc_handle != NULL )
00964 {
00965 if ( phyID >= 0 )
00966 {
00967 if ( !avc1394_vcr_is_recording( avc_handle, phyID ) &&
00968 avc1394_vcr_is_playing( avc_handle, phyID ) != AVC1394_VCR_OPERAND_PLAY_FORWARD )
00969 avc1394_vcr_play( avc_handle, phyID );
00970 }
00971 }
00972 pthread_mutex_unlock( &avc_mutex );
00973 return 0;
00974 }
00975
00976
00977 int AVC::Pause( int phyID )
00978 {
00979 pthread_mutex_lock( &avc_mutex );
00980 if ( avc_handle != NULL )
00981 {
00982 if ( phyID >= 0 )
00983 {
00984 if ( !avc1394_vcr_is_recording( avc_handle, phyID ) &&
00985 avc1394_vcr_is_playing( avc_handle, phyID ) != AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE )
00986 avc1394_vcr_pause( avc_handle, phyID );
00987 }
00988 }
00989 struct timespec t =
00990 {
00991 0, 250000000
00992 };
00993 nanosleep( &t, NULL );
00994 pthread_mutex_unlock( &avc_mutex );
00995 return 0;
00996 }
00997
00998
00999 int AVC::Stop( int phyID )
01000 {
01001 pthread_mutex_lock( &avc_mutex );
01002 if ( avc_handle != NULL )
01003 {
01004 if ( phyID >= 0 )
01005 avc1394_vcr_stop( avc_handle, phyID );
01006 }
01007 struct timespec t =
01008 {
01009 0, 250000000
01010 };
01011 nanosleep( &t, NULL );
01012 pthread_mutex_unlock( &avc_mutex );
01013 return 0;
01014 }
01015
01016
01017 int AVC::Rewind( int phyID )
01018 {
01019 pthread_mutex_lock( &avc_mutex );
01020 if ( avc_handle != NULL )
01021 {
01022 if ( phyID >= 0 )
01023 avc1394_vcr_rewind( avc_handle, phyID );
01024 }
01025 pthread_mutex_unlock( &avc_mutex );
01026 return 0;
01027 }
01028
01029
01030 int AVC::FastForward( int phyID )
01031 {
01032 pthread_mutex_lock( &avc_mutex );
01033 if ( avc_handle != NULL )
01034 {
01035 if ( phyID >= 0 )
01036 avc1394_vcr_forward( avc_handle, phyID );
01037 }
01038 pthread_mutex_unlock( &avc_mutex );
01039 return 0;
01040 }
01041
01042 int AVC::Forward( int phyID )
01043 {
01044 pthread_mutex_lock( &avc_mutex );
01045 if ( avc_handle != NULL )
01046 {
01047 if ( phyID >= 0 )
01048 avc1394_vcr_next( avc_handle, phyID );
01049 }
01050 pthread_mutex_unlock( &avc_mutex );
01051 return 0;
01052 }
01053
01054 int AVC::Back( int phyID )
01055 {
01056 pthread_mutex_lock( &avc_mutex );
01057 if ( avc_handle != NULL )
01058 {
01059 if ( phyID >= 0 )
01060 avc1394_vcr_previous( avc_handle, phyID );
01061 }
01062 pthread_mutex_unlock( &avc_mutex );
01063 return 0;
01064 }
01065
01066 int AVC::NextScene( int phyID )
01067 {
01068 pthread_mutex_lock( &avc_mutex );
01069 if ( avc_handle != NULL )
01070 {
01071 if ( phyID >= 0 )
01072 avc1394_vcr_next_index( avc_handle, phyID );
01073 }
01074 pthread_mutex_unlock( &avc_mutex );
01075 return 0;
01076 }
01077
01078 int AVC::PreviousScene( int phyID )
01079 {
01080 pthread_mutex_lock( &avc_mutex );
01081 if ( avc_handle != NULL )
01082 {
01083 if ( phyID >= 0 )
01084 avc1394_vcr_previous_index( avc_handle, phyID );
01085 }
01086 pthread_mutex_unlock( &avc_mutex );
01087 return 0;
01088 }
01089
01090 int AVC::Record( int phyID )
01091 {
01092 pthread_mutex_lock( &avc_mutex );
01093 if ( avc_handle != NULL )
01094 {
01095 if ( phyID >= 0 )
01096 avc1394_vcr_record( avc_handle, phyID );
01097 }
01098 pthread_mutex_unlock( &avc_mutex );
01099 return 0;
01100 }
01101
01102 int AVC::Shuttle( int phyID, int speed )
01103 {
01104 pthread_mutex_lock( &avc_mutex );
01105 if ( avc_handle != NULL )
01106 {
01107 if ( phyID >= 0 )
01108 avc1394_vcr_trick_play( avc_handle, phyID, speed );
01109 }
01110 pthread_mutex_unlock( &avc_mutex );
01111 return 0;
01112 }
01113
01114 unsigned int AVC::TransportStatus( int phyID )
01115 {
01116 quadlet_t val = 0;
01117 pthread_mutex_lock( &avc_mutex );
01118 if ( avc_handle != NULL )
01119 {
01120 if ( phyID >= 0 )
01121 val = avc1394_vcr_status( avc_handle, phyID );
01122 }
01123 pthread_mutex_unlock( &avc_mutex );
01124 return val;
01125 }
01126
01127 bool AVC::Timecode( int phyID, char* timecode )
01128 {
01129 pthread_mutex_lock( &avc_mutex );
01130 if ( avc_handle != NULL )
01131 {
01132 if ( phyID >= 0 )
01133 {
01134 quadlet_t request[ 2 ];
01135 quadlet_t *response;
01136
01137 request[ 0 ] = AVC1394_CTYPE_STATUS | AVC1394_SUBUNIT_TYPE_TAPE_RECORDER | AVC1394_SUBUNIT_ID_0 |
01138 AVC1394_VCR_COMMAND_TIME_CODE | AVC1394_VCR_OPERAND_TIME_CODE_STATUS;
01139 request[ 1 ] = 0xFFFFFFFF;
01140 response = avc1394_transaction_block( avc_handle, phyID, request, 2, 1 );
01141 if ( response == NULL )
01142 {
01143 pthread_mutex_unlock( &avc_mutex );
01144 return false;
01145 }
01146 if ( response[1] == 0xffffffff )
01147 strcpy( timecode, "--:--:--:--" );
01148 else
01149 sprintf( timecode, "%2.2x:%2.2x:%2.2x:%2.2x",
01150 response[ 1 ] & 0x000000ff,
01151 ( response[ 1 ] >> 8 ) & 0x000000ff,
01152 ( response[ 1 ] >> 16 ) & 0x000000ff,
01153 ( response[ 1 ] >> 24 ) & 0x000000ff );
01154 }
01155
01156 }
01157 pthread_mutex_unlock( &avc_mutex );
01158 return true;
01159 }
01160
01161 int AVC::getNodeId( const char *guid )
01162 {
01163 int value = -1;
01164 pthread_mutex_lock( &avc_mutex );
01165 if ( avc_handle != NULL )
01166 {
01167 raw1394_destroy_handle( avc_handle );
01168 avc_handle = NULL;
01169 }
01170 port = 0;
01171 for ( int p = 0; value == -1 && p < totalPorts; p++ )
01172 {
01173 rom1394_directory rom1394_dir;
01174
01175 if ( ( avc_handle = raw1394_new_handle_on_port( p ) ) )
01176 {
01177 int nodeCount = raw1394_get_nodecount( avc_handle );
01178
01179 port = p;
01180 raw1394_set_bus_reset_handler( avc_handle, this->ResetHandler );
01181
01182 for ( int currentNode = 0; value == -1 && currentNode < nodeCount; currentNode++ )
01183 {
01184 if ( rom1394_get_directory( avc_handle, currentNode, &rom1394_dir ) >= 0 )
01185 {
01186 octlet_t currentGUID = rom1394_get_guid( avc_handle, currentNode );
01187 char currentGUIDStr[ 65 ];
01188 snprintf( currentGUIDStr, 64, "%08x%08x", ( quadlet_t ) ( currentGUID >> 32 ),
01189 ( quadlet_t ) ( currentGUID & 0xffffffff ) );
01190 if ( strncmp( currentGUIDStr, guid, 64 ) == 0 )
01191 value = currentNode;
01192 rom1394_free_directory( &rom1394_dir );
01193 }
01194 }
01195 if ( value == -1 )
01196 {
01197 raw1394_destroy_handle( avc_handle );
01198 avc_handle = NULL;
01199 }
01200 }
01201 }
01202 if ( value == -1 )
01203 port = -1;
01204 pthread_mutex_unlock( &avc_mutex );
01205 return value;
01206 }
01207
01208
01209
01210 IEEE1394Writer::IEEE1394Writer() :
01211 m_isInitialised( false ), m_isRunning( false )
01212 {
01213 pthread_mutex_init( &m_dequeMutex, NULL );
01214 pthread_mutex_init( &m_conditionMutex, NULL );
01215 pthread_cond_init( &m_condition, NULL );
01216 }
01217
01218 IEEE1394Writer::~IEEE1394Writer()
01219 {
01220 for ( int i = m_deque.size(); i > 0; --i )
01221 {
01222 Frame* frame = m_deque[ 0 ];
01223 m_deque.pop_front();
01224 GetFramePool()->DoneWithFrame( frame );
01225 }
01226 pthread_mutex_destroy( &m_conditionMutex );
01227 pthread_cond_destroy( &m_condition );
01228 pthread_mutex_destroy( &m_dequeMutex );
01229 }
01230
01231 void IEEE1394Writer::StartThread()
01232 {
01233 if ( m_isRunning )
01234 return;
01235 pthread_create( &m_thread, NULL, ThreadProxy, this );
01236 }
01237
01238 void IEEE1394Writer::StopThread()
01239 {
01240 if ( m_isRunning )
01241 {
01242 m_isRunning = false;
01243 pthread_join( m_thread, NULL );
01244 }
01245 }
01246
01247 int IEEE1394Writer::WaitForAction( bool isBlocking, int seconds )
01248 {
01249 pthread_mutex_lock( &m_dequeMutex );
01250 int size = m_deque.size( );
01251 pthread_mutex_unlock( &m_dequeMutex );
01252
01253 if ( ( unsigned int )size >= m_nBuffers )
01254 {
01255 if ( isBlocking )
01256 {
01257 pthread_mutex_lock( &m_conditionMutex );
01258 if ( seconds == 0 )
01259 {
01260 pthread_cond_wait( &m_condition, &m_conditionMutex );
01261 pthread_mutex_unlock( &m_conditionMutex );
01262 pthread_mutex_lock( &m_dequeMutex );
01263 size = m_deque.size( );
01264 }
01265 else
01266 {
01267 struct timeval tp;
01268 struct timespec ts;
01269 int result;
01270
01271 gettimeofday( &tp, NULL );
01272 ts.tv_sec = tp.tv_sec + seconds;
01273 ts.tv_nsec = tp.tv_usec * 1000;
01274
01275 result = pthread_cond_timedwait( &m_condition, &m_conditionMutex, &ts );
01276 pthread_mutex_unlock( &m_conditionMutex );
01277 pthread_mutex_lock( &m_dequeMutex );
01278
01279 size = m_deque.size();
01280 if ( ( unsigned int )size >= m_nBuffers )
01281 size = -size;
01282 }
01283 pthread_mutex_unlock( &m_dequeMutex );
01284 }
01285 else
01286 {
01287 size = -size;
01288 }
01289 }
01290
01291 return size;
01292 }
01293
01294 void IEEE1394Writer::TriggerAction( )
01295 {
01296 pthread_mutex_lock( &m_conditionMutex );
01297 pthread_cond_signal( &m_condition );
01298 pthread_mutex_unlock( &m_conditionMutex );
01299 }
01300
01301 void* IEEE1394Writer::ThreadProxy( void *arg )
01302 {
01303 IEEE1394Writer* self = static_cast< IEEE1394Writer* >( arg );
01304 return self->Thread();
01305 }
01306
01307
01308 #ifdef HAVE_IEC61883
01309 iec61883Writer::iec61883Writer( int port, unsigned int channel, unsigned int buffers )
01310 : m_port( port ), m_handle( NULL ), m_iec61883dv( NULL ),
01311 m_data( 0 ), m_index( -1 ), m_isSilent( false ), m_isReset( false )
01312 {
01313 cerr << ">>> iec61883Writer::iec61883Writer port " << port << " channel " << channel << endl;
01314 m_channel = channel;
01315 m_nBuffers = buffers;
01316 }
01317
01318 iec61883Writer::~iec61883Writer()
01319 {
01320
01321 TriggerAction();
01322 m_isReset = true;
01323
01324 StopThread();
01325
01326 if ( m_iec61883dv )
01327 {
01328 iec61883_dv_close( m_iec61883dv );
01329 raw1394_destroy_handle( m_handle );
01330 }
01331 }
01332
01333
01334 int iec61883Writer::HandlerProxy( unsigned char *data, int n_dif_blocks,
01335 unsigned int dropped, void *callback_data)
01336 {
01337 if ( callback_data )
01338 {
01339 iec61883Writer* writer = static_cast< iec61883Writer* >( callback_data );
01340 return writer->Handler( data, n_dif_blocks, dropped );
01341 }
01342 else
01343 {
01344 return -1;
01345 }
01346 }
01347
01348
01349 int iec61883Writer::Handler( unsigned char *data, int n_dif_blocks, unsigned int dropped )
01350 {
01351
01352 if ( m_index <= 0 )
01353 {
01354
01355
01356
01357 if ( !m_isRunning || m_isReset )
01358 return -1;
01359
01360 pthread_mutex_lock( &m_dequeMutex );
01361 Frame* frame = m_deque[0];
01362 pthread_mutex_unlock( &m_dequeMutex );
01363
01364 m_data = frame->data;
01365 m_index = frame->GetFrameSize();
01366 }
01367
01368
01369 memcpy( data, m_data, n_dif_blocks * 480 );
01370
01371
01372 m_data += n_dif_blocks * 480;
01373 m_index -= n_dif_blocks * 480;
01374
01375
01376 if ( m_index == 0 )
01377 {
01378 pthread_mutex_lock( &m_dequeMutex );
01379 Frame* frame = m_deque[0];
01380 if ( m_deque.size() > 1 )
01381 {
01382
01383 m_deque.pop_front();
01384 GetFramePool()->DoneWithFrame( frame );
01385
01386
01387 TriggerAction();
01388
01389
01390 m_isSilent = false;
01391 }
01392 else if ( !m_isSilent )
01393 {
01394 AudioInfo info;
01395 int16_t* silence[4];
01396
01397
01398 for ( int i = 0; i < 4; i++ )
01399 silence[i] = (int16_t*) calloc( 2 * DV_AUDIO_MAX_SAMPLES, sizeof( int16_t ) );
01400 frame->GetAudioInfo( info );
01401 info.channels = 2;
01402 frame->EncodeAudio( info, silence );
01403 for ( int i = 0; i < 4; i++ )
01404 free( silence[i] );
01405
01406
01407 m_isSilent = true;
01408 }
01409 pthread_mutex_unlock( &m_dequeMutex );
01410 }
01411
01412 return 0;
01413 }
01414
01415 bool iec61883Writer::Open( bool isPAL )
01416 {
01417 assert( m_handle == 0 );
01418 m_isInitialised = false;
01419 m_handle = raw1394_new_handle_on_port( m_port );
01420 if ( m_handle != NULL )
01421 {
01422 raw1394_set_bus_reset_handler( m_handle, this->ResetHandlerProxy );
01423 m_iec61883dv = iec61883_dv_xmit_init( m_handle, isPAL, HandlerProxy, this );
01424 m_isInitialised = ( m_iec61883dv != NULL );
01425
01426 }
01427
01428 return m_isInitialised;
01429 }
01430
01431 bool iec61883Writer::SendFrame( Frame &frame, bool isBlocking )
01432 {
01433 bool result = false;
01434
01435 if ( m_isReset )
01436 {
01437 StopThread();
01438 if ( m_iec61883dv )
01439 {
01440
01441 free( m_iec61883dv );
01442 m_iec61883dv = NULL;
01443 }
01444 raw1394_destroy_handle( m_handle );
01445 m_handle = NULL;
01446 m_isInitialised = m_isReset = false;
01447 }
01448
01449
01450 if ( WaitForAction( isBlocking ) >= 0 )
01451 {
01452
01453 Frame *newFrame = GetFramePool()->GetFrame();
01454 *newFrame = frame;
01455
01456 pthread_mutex_lock( &m_dequeMutex );
01457 m_deque.push_back( newFrame );
01458 pthread_mutex_unlock( &m_dequeMutex );
01459
01460 if ( !m_isInitialised && Open( frame.IsPAL() ) )
01461 {
01462 m_isInitialised = ( iec61883_dv_xmit_start( m_iec61883dv, m_channel ) == 0 );
01463 StartThread();
01464 }
01465 result = true;
01466 }
01467 return result;
01468 }
01469
01470 void* iec61883Writer::Thread()
01471 {
01472
01473 struct pollfd pfd = {
01474 fd: raw1394_get_fd( m_handle ),
01475 events: POLLIN,
01476 revents: 0
01477 };
01478 int result = 0;
01479
01480 m_isRunning = true;
01481 while ( !m_isReset && result == 0 )
01482 {
01483 if ( poll( &pfd, 1, 100 ) > 0 && ( pfd.revents & POLLIN ) )
01484 result = raw1394_loop_iterate( m_handle );
01485 }
01486
01487 return NULL;
01488 }
01489
01490 void iec61883Writer::ResetHandler( void )
01491 {
01492 cerr << ">>> iec61883Writer::ResetHandler" << endl;
01493 if ( m_isInitialised )
01494 m_isReset = true;
01495 }
01496
01497 int iec61883Writer::ResetHandlerProxy( raw1394handle_t handle, unsigned int generation )
01498 {
01499 iec61883_dv_t dv = static_cast< iec61883_dv_t >( raw1394_get_userdata( handle ) );
01500 iec61883Writer *self = static_cast< iec61883Writer* >( iec61883_dv_get_callback_data( dv ) );
01501 raw1394_update_generation( handle, generation );
01502 if ( self )
01503 self->ResetHandler();
01504 return 0;
01505 }
01506 #endif
01507
01508
01509 #ifdef HAVE_DV1394
01510 dv1394Writer::dv1394Writer( string device, unsigned int channel, unsigned int nBuffers,
01511 unsigned int cip_n, unsigned int cip_d, unsigned int syt_offset )
01512 : m_channel( channel ), m_cip_n( cip_n ), m_cip_d( cip_d ), m_syt_offset( syt_offset ),
01513 m_isSilent( false )
01514 {
01515 m_nBuffers = ( nBuffers > DV1394_MAX_FRAMES ) ? DV1394_MAX_FRAMES : nBuffers;
01516 m_fd = open( device.c_str(), O_RDWR );
01517 cerr << ">>> dv1394Writer::dv1394Writer " << device << " channel " << m_channel << " fd " << m_fd << endl;
01518 }
01519
01520
01521 dv1394Writer::~dv1394Writer()
01522 {
01523 StopThread();
01524 if ( m_fd != -1 )
01525 {
01526 close( m_fd );
01527 m_fd = -1;
01528 }
01529 }
01530
01531
01532 bool dv1394Writer::SendFrame( Frame &frame, bool isBlocking )
01533 {
01534 bool result = false;
01535
01536 if ( m_fd < 0 )
01537 return result;
01538
01539 bool isPAL = frame.IsPAL();
01540
01541
01542 if ( WaitForAction( isBlocking ) >= 0 )
01543 {
01544
01545 Frame *newFrame = GetFramePool()->GetFrame();
01546 *newFrame = frame;
01547
01548 pthread_mutex_lock( &m_dequeMutex );
01549 m_deque.push_back( newFrame );
01550 pthread_mutex_unlock( &m_dequeMutex );
01551
01552 if ( !m_isInitialised )
01553 {
01554 m_isInitialised = true;
01555
01556 struct dv1394_init setup =
01557 {
01558 api_version: DV1394_API_VERSION,
01559 channel: m_channel,
01560 n_frames: m_nBuffers,
01561 format: ( isPAL ? DV1394_PAL : DV1394_NTSC ),
01562 cip_n : m_cip_n,
01563 cip_d : m_cip_d,
01564 syt_offset : m_syt_offset
01565 };
01566 ioctl( m_fd, DV1394_INIT, &setup );
01567 StartThread();
01568 }
01569 result = true;
01570 }
01571 return result;
01572 }
01573
01574 void* dv1394Writer::Thread()
01575 {
01576 m_isRunning = true;
01577 while ( m_isRunning )
01578 {
01579 Frame* frame = m_deque[0];
01580
01581 if ( frame )
01582 write( m_fd, frame->data, ( frame->IsPAL() ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE ) );
01583
01584 pthread_mutex_lock( &m_dequeMutex );
01585 if ( m_deque.size() > 1 )
01586 {
01587
01588 m_deque.pop_front();
01589 GetFramePool()->DoneWithFrame( frame );
01590
01591
01592 TriggerAction();
01593
01594
01595 m_isSilent = false;
01596 }
01597 else if ( !m_isSilent )
01598 {
01599 AudioInfo info;
01600 int16_t* silence[4];
01601
01602
01603 for ( int i = 0; i < 4; i++ )
01604 silence[i] = (int16_t*) calloc( 2 * DV_AUDIO_MAX_SAMPLES, sizeof( int16_t ) );
01605 frame->GetAudioInfo( info );
01606 info.channels = 2;
01607 frame->EncodeAudio( info, silence );
01608 for ( int i = 0; i < 4; i++ )
01609 free( silence[i] );
01610
01611
01612 m_isSilent = true;
01613 }
01614 pthread_mutex_unlock( &m_dequeMutex );
01615 }
01616
01617 return NULL;
01618 }
01619 #endif