00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025 #include <iostream>
00026 using std::cerr;
00027 using std::endl;
00028
00029 #include "page_editor.h"
00030 #include "frame.h"
00031 #include "commands.h"
00032 #include "sys/time.h"
00033 #include "pthread.h"
00034 #include "message.h"
00035 #include "filehandler.h"
00036 #include "ieee1394io.h"
00037 #include "gtkenhancedscale.h"
00038 #include "callbacks.h"
00039 #include "storyboard.h"
00040
00041 #undef PLAY_WITH_STATS
00042
00043 extern "C"
00044 {
00045 #include "support.h"
00046
00047 extern KinoCommon *common;
00048 extern struct navigate_control g_nav_ctl;
00049 char cmd[ 256 ] = { 0 };
00050 char lastcmd[ 256 ] = { 0 };
00051 static int _getOneSecond( void );
00052
00053 static void resetThreads( );
00054 static void *readThread( void * info );
00055 static void *audioThread( void * info );
00056 static void *videoThread( void * info );
00057 static pthread_t readthread = 0;
00058 static pthread_t audiothread = 0;
00059 static pthread_t videothread = 0;
00060 static pthread_mutex_t threadlock = PTHREAD_MUTEX_INITIALIZER;
00061 static pthread_mutex_t readlock = PTHREAD_MUTEX_INITIALIZER;
00062 static int newFrame = 0;
00063 static int lastFrame = -1;
00064
00065 #define PLAYBACK_FRAMES 50
00066
00067 static Frame *frameContent[ PLAYBACK_FRAMES ];
00068 IEEE1394Writer *writer1394 = NULL;
00069
00070 static gboolean doScrub = FALSE;
00071 gboolean
00072 on_scrub_bar_button_press_event ( GtkWidget * widget,
00073 GdkEventButton * event,
00074 gpointer user_data )
00075 {
00076 doScrub = TRUE;
00077 videoPause();
00078 return FALSE;
00079 }
00080
00081
00082 gboolean
00083 on_scrub_bar_button_release_event ( GtkWidget * widget,
00084 GdkEventButton * event,
00085 gpointer user_data )
00086 {
00087 doScrub = FALSE;
00088 return FALSE;
00089 }
00090
00091 gboolean
00092 on_scrub_bar_value_changed_event ( GtkWidget * widget,
00093 GdkEventButton * event,
00094 gpointer user_data )
00095 {
00096 if ( doScrub == TRUE )
00097 moveToFrame( ( int ) GTK_ADJUSTMENT( widget ) ->value );
00098 return FALSE;
00099 }
00100
00101 }
00102
00108 PageEditor::PageEditor( KinoCommon *common )
00109 {
00110 cerr << "> Creating page editor" << endl;
00111 this->common = common;
00112
00113 this->frameArea = GTK_DRAWING_AREA( lookup_widget( common->getWidget(), "drawingarea1" ) );
00114 gtk_widget_set_double_buffered( GTK_WIDGET( frameArea ), FALSE );
00115 this->positionLabelCurrent = GTK_LABEL( lookup_widget( common->getWidget(), "position_label_current" ) );
00116 this->positionLabelTotal = GTK_LABEL( lookup_widget( common->getWidget(), "position_label_total" ) );
00117 this->lastFrameShown = -1;
00118 this->g_copiedPlayList = new PlayList();
00119
00120 scrubAdjustment = GTK_ADJUSTMENT( gtk_adjustment_new( 0, 0, 0, 1, 10, 0 ) );
00121 g_signal_connect( G_OBJECT( scrubAdjustment ), "value_changed",
00122 G_CALLBACK( on_scrub_bar_value_changed_event ), NULL );
00123
00124 scrubBar = gtk_enhanced_scale_new( ( GtkObject** ) & scrubAdjustment, 1 );
00125 sceneIndex = g_array_new( FALSE, FALSE, sizeof( int ) );
00126 gtk_widget_set_name( scrubBar, "scrubBar" );
00127 gtk_widget_ref( scrubBar );
00128 gtk_object_set_data_full( GTK_OBJECT( common->getWidget() ), "scrubBar", scrubBar,
00129 ( GtkDestroyNotify ) gtk_widget_unref );
00130 GtkWidget *vbox_edit = lookup_widget( common->getWidget(), "vbox58" );
00131 gtk_widget_show( scrubBar );
00132 gtk_box_pack_start( GTK_BOX( vbox_edit ), scrubBar, FALSE, TRUE, 0 );
00133 g_signal_connect( G_OBJECT( scrubBar ), "button_press_event",
00134 G_CALLBACK( on_scrub_bar_button_press_event ), NULL );
00135 g_signal_connect( G_OBJECT( scrubBar ), "button_release_event",
00136 G_CALLBACK( on_scrub_bar_button_release_event ), NULL );
00137
00138 }
00139
00143 PageEditor::~PageEditor( )
00144 {
00145 cerr << "> Destroying page editor" << endl;
00146 delete this->g_copiedPlayList;
00147 if ( sceneIndex != NULL )
00148 g_array_free( sceneIndex, TRUE );
00149 }
00150
00154 void PageEditor::newFile()
00155 {
00156 this->stopNavigator();
00157 common->loadSplash( frameArea );
00158 this->ResetBar( );
00159 }
00160
00164 void PageEditor::start()
00165 {
00166 cerr << ">> Starting Editor" << endl;
00167
00168 for ( int i = 0; i < PLAYBACK_FRAMES; i ++ )
00169 frameContent[ i ] = GetFramePool( ) ->GetFrame( );
00170
00171 this->displayer = new FrameDisplayer();
00172 if ( Preferences::getInstance().dv1394Preview )
00173 {
00174 #ifdef HAVE_IEC61883
00175 AVC avc;
00176 Preferences::getInstance( ).phyID = avc.getNodeId( Preferences::getInstance( ).avcGUID );
00177 Preferences::getInstance( ).phyID = avc.isPhyIDValid( Preferences::getInstance( ).phyID );
00178 if ( !writer1394 )
00179 writer1394 = new iec61883Writer(
00180 ( avc.getPort() < 0 ) ? 0 : avc.getPort(),
00181 Preferences::getInstance().channel,
00182 2 );
00183 #else
00184 if ( Preferences::getInstance().dvExportDevice > 0 && !writer1394 )
00185 writer1394 = new dv1394Writer(
00186 Preferences::getInstance().dvExportDevice,
00187 Preferences::getInstance().channel,
00188 2,
00189 Preferences::getInstance().cip_n,
00190 Preferences::getInstance().cip_d,
00191 Preferences::getInstance().syt_offset );
00192 #endif
00193 }
00194
00195 this->lastFrameShown = common->g_currentFrame;
00196
00197 gtk_widget_grab_focus( GTK_WIDGET( frameArea ) );
00198 common->packIt( "packer_edit", "packer_edit_outer" );
00199
00200 gtk_notebook_set_page( GTK_NOTEBOOK( lookup_widget( common->getWidget(), "notebook_keyhelp" ) ), 0 );
00201 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( lookup_widget( common->getWidget(), "menuitem_editor" ) ), TRUE );
00202 }
00203
00207 gulong PageEditor::activate()
00208 {
00209 return EDIT_MENU |
00210 SCENE_LIST |
00211 VIDEO_START_OF_MOVIE |
00212 VIDEO_START_OF_SCENE |
00213 VIDEO_REWIND |
00214 VIDEO_BACK |
00215 VIDEO_PLAY |
00216 VIDEO_PAUSE |
00217 VIDEO_STOP |
00218 VIDEO_FORWARD |
00219 VIDEO_FAST_FORWARD |
00220 VIDEO_NEXT_SCENE |
00221 VIDEO_END_OF_MOVIE |
00222 VIDEO_SHUTTLE |
00223 INFO_FRAME;
00224 }
00225
00229 void PageEditor::clean()
00230 {
00231 cerr << ">> Leaving Editor" << endl;
00232 stopNavigator();
00233 delete displayer;
00234 displayer = 0;
00235 delete writer1394;
00236 writer1394 = NULL;
00237 for ( int i = 0; i < PLAYBACK_FRAMES; i ++ )
00238 GetFramePool( ) ->DoneWithFrame( frameContent[ i ] );
00239 gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( lookup_widget( common->getWidget(), "menuitem_editor" ) ), FALSE );
00240 cerr << ">> Left Editor" << endl;
00241 }
00242
00246 void PageEditor::startNavigator()
00247 {
00248 stopNavigator( );
00249 g_nav_ctl.active = TRUE;
00250 resetThreads( );
00251 pthread_create( &readthread, NULL, readThread, &g_nav_ctl );
00252 pthread_create( &audiothread, NULL, audioThread, &g_nav_ctl );
00253 pthread_create( &videothread, NULL, videoThread, &g_nav_ctl );
00254 }
00255
00259 void PageEditor::stopNavigator()
00260 {
00261 if ( g_nav_ctl.active )
00262 {
00263 g_nav_ctl.active = FALSE;
00264 gdk_threads_leave();
00265 pthread_join( readthread, NULL );
00266 pthread_join( audiothread, NULL );
00267 pthread_join( videothread, NULL );
00268 gdk_threads_enter();
00269 getFrameDisplayer()->CloseSound();
00270 }
00271 }
00272
00279 void PageEditor::movedToFrame( int frame )
00280 {
00281 if ( g_nav_ctl.active == FALSE )
00282 {
00283 showFrame( frame, ( frame == lastFrameShown ) || ( Preferences::getInstance().audioScrub == FALSE ) );
00284 }
00285 else
00286 {
00287 stopNavigator();
00288 common->g_currentFrame = frame;
00289 startNavigator();
00290 }
00291 }
00292
00299 void PageEditor::showFrame( int i, gboolean no_audio )
00300 {
00301 DrawBar( i );
00302 if ( common->getPlayList() ->GetNumFrames() == 0 )
00303 {
00304 common->loadSplash( frameArea );
00305 common->showFrameInfo( 0 );
00306 }
00307 else
00308 {
00309 Frame *frame = GetFramePool( ) ->GetFrame( );
00310 common->getPlayList() ->GetFrame( i, *frame );
00311 common->showFrameInfo( i );
00312 if ( writer1394 != NULL )
00313 writer1394->SendFrame( *frame, false ) ;
00314 getFrameDisplayer() ->Put( *frame, GTK_WIDGET( frameArea ), no_audio );
00315 lastFrameShown = i;
00316 GetFramePool( ) ->DoneWithFrame( frame );
00317 }
00318 }
00319
00323 void PageEditor::videoStartOfMovie()
00324 {
00325 common->moveToFrame( 0 );
00326 common->toggleComponents( VIDEO_START_OF_MOVIE, false );
00327 }
00328
00332 void PageEditor::videoPreviousScene()
00333 {
00334 int frame = common->getPlayList() ->FindStartOfScene( common->g_currentFrame );
00335
00336 if ( g_nav_ctl.active == FALSE && frame == common->g_currentFrame )
00337 frame = common->getPlayList() ->FindStartOfScene( frame - 1 );
00338 else if ( g_nav_ctl.active == TRUE && ( frame == common->g_currentFrame || ( common->g_currentFrame - frame ) <= 15 ) )
00339 frame = common->getPlayList() ->FindStartOfScene( frame - 1 );
00340
00341 common->moveToFrame( frame );
00342 common->toggleComponents( VIDEO_START_OF_SCENE, false );
00343 }
00344
00348 void PageEditor::videoStartOfScene()
00349 {
00350 int frame = common->getPlayList() ->FindStartOfScene( common->g_currentFrame );
00351 common->moveToFrame( frame );
00352 common->toggleComponents( VIDEO_START_OF_SCENE, false );
00353 }
00354
00358 void PageEditor::videoRewind()
00359 {
00360 common->toggleComponents( common->getComponentState(), false );
00361 stopNavigator();
00362
00363 if ( g_nav_ctl.step == -10 )
00364 {
00365 g_nav_ctl.step = 1;
00366 g_nav_ctl.rate = 1;
00367 common->toggleComponents( VIDEO_REWIND, false );
00368 common->toggleComponents( VIDEO_STOP, true );
00369 }
00370 else
00371 {
00372 common->toggleComponents( VIDEO_REWIND, true );
00373 g_nav_ctl.step = -10;
00374 g_nav_ctl.rate = 0;
00375 startNavigator();
00376 }
00377 }
00378
00383 void PageEditor::videoBack(int step)
00384 {
00385 common->toggleComponents( common->getComponentState(), false );
00386 if ( g_nav_ctl.active )
00387 {
00388 stopNavigator();
00389 if ( g_nav_ctl.step != -1 )
00390 {
00391 g_nav_ctl.step = -1;
00392 g_nav_ctl.rate = 1;
00393 common->toggleComponents( VIDEO_BACK, true );
00394 startNavigator();
00395 }
00396 else
00397 {
00398 g_nav_ctl.step = 1;
00399 g_nav_ctl.rate = 0;
00400 common->toggleComponents( VIDEO_BACK, false );
00401 common->toggleComponents( VIDEO_STOP, true );
00402 }
00403 }
00404 else
00405 {
00406 common->moveByFrames( step );
00407 common->toggleComponents( VIDEO_BACK, false );
00408 common->toggleComponents( VIDEO_STOP, true );
00409 }
00410 }
00411
00415 void PageEditor::videoPlay()
00416 {
00417 common->toggleComponents( common->getComponentState(), false );
00418 if ( g_nav_ctl.active == FALSE || g_nav_ctl.step != 1 )
00419 {
00420 common->toggleComponents( VIDEO_PLAY, true );
00421 stopNavigator();
00422 g_nav_ctl.step = 1;
00423 g_nav_ctl.rate = 1;
00424 startNavigator();
00425 }
00426 else
00427 {
00428 stopNavigator();
00429 common->toggleComponents( VIDEO_PLAY, false );
00430 common->toggleComponents( VIDEO_STOP, true );
00431 }
00432 }
00433
00437 void PageEditor::videoPause()
00438 {
00439 videoStop();
00440 }
00441
00445 void PageEditor::videoStop()
00446 {
00447 common->toggleComponents( common->getComponentState(), false );
00448 common->toggleComponents( VIDEO_STOP, true );
00449 stopNavigator();
00450 g_nav_ctl.step = 0;
00451 g_nav_ctl.rate = 0;
00452 }
00453
00458 void PageEditor::videoForward(int step)
00459 {
00460
00461 common->toggleComponents( common->getComponentState(), false );
00462 if ( g_nav_ctl.active && g_nav_ctl.step != 1 )
00463 {
00464 common->toggleComponents( VIDEO_FORWARD, true );
00465 stopNavigator();
00466 g_nav_ctl.step = 1;
00467 g_nav_ctl.rate = 1;
00468 startNavigator();
00469 }
00470 else
00471 {
00472 stopNavigator();
00473 common->moveByFrames( step );
00474 common->toggleComponents( VIDEO_FORWARD, false );
00475 common->toggleComponents( VIDEO_STOP, true );
00476 }
00477 }
00478
00482 void PageEditor::videoFastForward()
00483 {
00484 common->toggleComponents( common->getComponentState(), false );
00485 stopNavigator();
00486 if ( g_nav_ctl.step != 10 )
00487 {
00488 common->toggleComponents( VIDEO_FAST_FORWARD, true );
00489 g_nav_ctl.step = 10;
00490 g_nav_ctl.rate = 0;
00491 startNavigator();
00492 }
00493 else
00494 {
00495 g_nav_ctl.step = 1;
00496 g_nav_ctl.rate = 1;
00497 common->toggleComponents( VIDEO_FAST_FORWARD, false );
00498 common->toggleComponents( VIDEO_STOP, true );
00499 }
00500 }
00501
00509 void PageEditor::videoShuttle( int angle )
00510 {
00511 int frames_sec = _getOneSecond();
00512 int speedTable[] = {
00513 0,
00514 8, 10, 15, 20, 33, 50, 75,
00515 100,
00516 200, 300, 400, 500, 800, 1200,
00517 ( frames_sec * 100 ) };
00518 char s[ 64 ];
00519
00520 if ( angle < -15 )
00521 angle = -15;
00522 if ( angle > 15 )
00523 angle = 15;
00524
00525 int speed = speedTable[ ( angle < 0 ) ? -angle : angle ] * ( ( angle < 0 ) ? -1 : 1 );
00526 if ( speed == 0 || g_nav_ctl.step != speed / 100 || g_nav_ctl.rate != 100 / speed )
00527 {
00528 stopNavigator( );
00529 if ( speed == 0 )
00530 {
00531 common->keyboardFeedback( "", "" );
00532 common->toggleComponents( VIDEO_STOP, true );
00533 }
00534 else
00535 {
00536 g_nav_ctl.step = speed / 100;
00537 g_nav_ctl.rate = 100 / speed;
00538 g_nav_ctl.subframe = 0;
00539 startNavigator();
00540 snprintf( s, 63, _( "Shuttle %+.1f fps" ), ( float ) speed / 100.0 * frames_sec );
00541 common->keyboardFeedback( "", s );
00542 }
00543 }
00544 }
00545
00549 void PageEditor::videoNextScene()
00550 {
00551 int frame = common->getPlayList() ->FindEndOfScene( common->g_currentFrame );
00552 common->moveToFrame( frame + 1 );
00553 common->toggleComponents( VIDEO_NEXT_SCENE, false );
00554 }
00555
00559 void PageEditor::videoEndOfScene()
00560 {
00561 int frame = common->getPlayList() ->FindEndOfScene( common->g_currentFrame );
00562 common->moveToFrame( frame );
00563 common->toggleComponents( VIDEO_NEXT_SCENE, false );
00564 }
00565
00569 void PageEditor::videoEndOfMovie()
00570 {
00571 common->toggleComponents( common->getComponentState(), false );
00572 common->toggleComponents( VIDEO_END_OF_MOVIE, true );
00573 stopNavigator();
00574 common->moveToFrame( common->getPlayList() ->GetNumFrames() - 1 );
00575 common->toggleComponents( VIDEO_END_OF_MOVIE, false );
00576 common->toggleComponents( VIDEO_STOP, true );
00577 }
00578
00584 void PageEditor::selectScene( int i )
00585 {
00586 vector <int> scene = GetScene();
00587 int value = i == 0 ? 0 : scene[ i - 1 ];
00588 common->moveToFrame( value );
00589 }
00590
00596 gboolean PageEditor::processKeyboard( GdkEventKey *event )
00597 {
00598 gboolean ret = FALSE;
00599
00600
00601 if ( g_nav_ctl.escaped == FALSE )
00602 {
00603 if ( strcmp( lastcmd, "alt" ) == 0 )
00604 {
00605 strcpy( lastcmd, "" );
00606 return ret;
00607 }
00608
00609
00610 switch ( event->keyval )
00611 {
00612 case GDK_Home:
00613 strcat( cmd, "gg");
00614 ret = TRUE;
00615 break;
00616 case GDK_End:
00617 strcat( cmd, "G");
00618 ret = TRUE;
00619 break;
00620 case GDK_Page_Up:
00621 strcat( cmd, "5^" );
00622 ret = TRUE;
00623 break;
00624 case GDK_Page_Down:
00625 strcat( cmd, "5$" );
00626 ret = TRUE;
00627 break;
00628 case GDK_BackSpace:
00629 case GDK_Left:
00630 strcat( cmd, "h" );
00631 ret = TRUE;
00632 break;
00633 case GDK_Up:
00634 strcat( cmd, "k" );
00635 ret = TRUE;
00636 break;
00637 case GDK_Right:
00638 strcat( cmd, "l" );
00639 ret = TRUE;
00640 break;
00641 case GDK_Return:
00642 if ( cmd[ 0 ] != 0 )
00643 {
00644
00645 strcpy( lastcmd, cmd );
00646
00647
00648 cmd[ 0 ] = 0;
00649 common->setStatusBar( "" );
00650 }
00651 break;
00652 case GDK_Down:
00653 strcat( cmd, "j" );
00654 ret = TRUE;
00655 break;
00656 case GDK_Delete:
00657 strcat( cmd, "x" );
00658 ret = TRUE;
00659 break;
00660 case GDK_Escape:
00661 common->keyboardFeedback( cmd, _( "Stop" ) );
00662 common->videoStop( );
00663 cmd[ 0 ] = 0;
00664 return ret;
00665 case GDK_Alt_L:
00666 case GDK_Alt_R:
00667 strcpy( lastcmd, "alt" );
00668 return ret;
00669 default:
00670 if ( strcmp( event->string, "." ) )
00671 strcat( cmd, event->string );
00672 break;
00673 }
00674
00675 if ( !strcmp( event->string, "." ) )
00676 strcpy( cmd, lastcmd );
00677 else if ( cmd[ 0 ] == 0x06)
00678 strcpy( cmd, "5$" );
00679 else if ( cmd[ 0 ] == 0x02 )
00680 strcpy( cmd, "5^" );
00681 else if ( cmd[ 0 ] == 0x12 )
00682 strcpy( cmd, "Ctrl+R" );
00683
00684 #if 0
00685 printf( "send_event: %2.2x\n", event->send_event );
00686 printf( "time : %8.8x\n", event->time );
00687 printf( "state : %8.8x\n", event->state );
00688 printf( "keyval: %8.8x\n", event->keyval );
00689 printf( "length: %8.8x\n", event->length );
00690 printf( "string: %s\n", event->string );
00691 printf( "(hex) : %2.2x\n", event->string[ 0 ] );
00692 printf( "cmd : %s\n", cmd );
00693 printf( "(hex) : %8.8x\n", cmd[ 0 ] );
00694 fflush( stdout );
00695 #endif
00696
00697 processCommand( cmd );
00698 }
00699
00700 return ret;
00701 }
00702
00708 gboolean PageEditor::processCommand( char *command )
00709 {
00710 int start, end;
00711 int count = 1;
00712 char real[ 256 ] = "";
00713
00714 strcpy( cmd, command );
00715
00716 switch ( sscanf( cmd, "%d%s", &count, real ) )
00717 {
00718 case 1:
00719
00720 if ( strcmp( cmd, "0" ) )
00721 {
00722 common->keyboardFeedback( cmd, "" );
00723 return FALSE;
00724 }
00725 break;
00726 case 0:
00727 sscanf( cmd, "%s", real );
00728 count = 1;
00729 break;
00730 }
00731
00732 if ( strcmp( cmd, "." ) )
00733 strcpy( lastcmd, cmd );
00734
00735
00736
00737
00738
00739 if ( strcmp( cmd, " " ) == 0 )
00740 {
00741 if ( g_nav_ctl.active == FALSE )
00742 {
00743 common->keyboardFeedback( cmd, _( "Play" ) );
00744 common->videoPlay( );
00745 }
00746 else
00747 {
00748 common->keyboardFeedback( cmd, _( "Pause" ) );
00749 common->videoPause( );
00750 }
00751 cmd[ 0 ] = 0;
00752 }
00753
00754 else if ( strcmp( real, "Esc" ) == 0 )
00755 {
00756 common->keyboardFeedback( cmd, _( "Stop" ) );
00757 common->videoStop( );
00758 cmd[ 0 ] = 0;
00759 }
00760
00761
00762
00763 else if ( strcmp( real, "l" ) == 0 )
00764 {
00765 common->keyboardFeedback( cmd, _( "Move forward" ) );
00766 common->moveByFrames( count );
00767 cmd[ 0 ] = 0;
00768 }
00769
00770
00771
00772 else if ( strcmp( real, "h" ) == 0 )
00773 {
00774 common->keyboardFeedback( cmd, _( "Move backward" ) );
00775 common->moveByFrames( 0 - count );
00776 cmd[ 0 ] = 0;
00777 }
00778
00779
00780
00781 else if ( strcmp( real, "w" ) == 0 || strcmp( real, "W" ) == 0 ||
00782 strcmp( real, "e" ) == 0 || strcmp( real, "E" ) == 0 )
00783 {
00784 common->keyboardFeedback( cmd, _( "Move forward second" ) );
00785 common->moveByFrames( count * _getOneSecond() );
00786 cmd[ 0 ] = 0;
00787 }
00788
00789
00790
00791 else if ( ( strcmp( real, "b" ) == 0 ) || ( strcmp( real, "B" ) == 0 ) )
00792 {
00793 common->keyboardFeedback( cmd, _( "Move backwards one second" ) );
00794 common->moveByFrames( 0 - count * _getOneSecond() );
00795 cmd[ 0 ] = 0;
00796 }
00797
00798
00799
00800 else if ( ( strcmp( cmd, "0" ) == 0 ) || ( strcmp( real, "^" ) == 0 ) )
00801 {
00802 common->videoStartOfScene( );
00803 for ( ; count > 1 && common->g_currentFrame > 0; count -- )
00804 {
00805 common->g_currentFrame --;
00806 common->videoStartOfScene( );
00807 }
00808 common->keyboardFeedback( cmd, _( "Move to start of scene" ) );
00809 cmd[ 0 ] = 0;
00810 }
00811
00812
00813
00814 else if ( strcmp( real, "$" ) == 0 )
00815 {
00816 common->videoEndOfScene( );
00817 for ( ; count > 1 && common->g_currentFrame < common->getPlayList() ->GetNumFrames() - 1; count -- )
00818 {
00819 common->g_currentFrame ++;
00820 common->videoEndOfScene( );
00821 }
00822 common->keyboardFeedback( cmd, _( "Move to end of scene" ) );
00823 cmd[ 0 ] = 0;
00824 }
00825
00826
00827
00828 else if ( ( strcmp( real, "j" ) == 0 ) || strcmp( real, "+" ) == 0 )
00829 {
00830 for ( ; count >= 1 && common->g_currentFrame < common->getPlayList() ->GetNumFrames() - 1; count -- )
00831 common->videoNextScene( );
00832 common->keyboardFeedback( cmd, _( "Move to start of next scene" ) );
00833 cmd[ 0 ] = 0;
00834 }
00835
00836
00837
00838 else if ( ( strcmp( real, "k" ) == 0 ) || ( strcmp( real, "-" ) == 0 ) )
00839 {
00840 for ( ; count >= 1 && common->g_currentFrame > 0; count -- )
00841 common->videoPreviousScene( );
00842 common->keyboardFeedback( cmd, _( "Move to start of previous scene" ) );
00843 cmd[ 0 ] = 0;
00844 }
00845
00846
00847
00848 else if ( strcmp( cmd, "gg" ) == 0 )
00849 {
00850 common->videoStartOfMovie( );
00851 common->keyboardFeedback( cmd, _( "Move to first frame" ) );
00852 cmd[ 0 ] = 0;
00853 }
00854
00855
00856
00857 else if ( strcmp( cmd, "G" ) == 0 )
00858 {
00859 common->videoEndOfMovie( );
00860 common->keyboardFeedback( cmd, _( "Move to last frame" ) );
00861 cmd[ 0 ] = 0;
00862 }
00863
00864
00865
00866 else if ( ( strcmp( real, "x" ) == 0 ) || ( strcmp( cmd, "d " ) == 0 ) || ( strcmp( real, "dl" ) == 0 ) )
00867 {
00868 CopyFrames( common->g_currentFrame, common->g_currentFrame + count - 1 );
00869 DeleteFrames( common->g_currentFrame, common->g_currentFrame + count - 1 );
00870 common->moveToFrame( );
00871 common->keyboardFeedback( cmd, _( "Cut current frame" ) );
00872 DrawBar( common->g_currentFrame );
00873 cmd[ 0 ] = 0;
00874 }
00875
00876
00877
00878 else if ( strcmp( cmd, "dw" ) == 0 )
00879 {
00880 end = common->g_currentFrame + _getOneSecond() - 1;
00881 CopyFrames( common->g_currentFrame, end );
00882 DeleteFrames( common->g_currentFrame, end );
00883 common->moveToFrame( );
00884 common->keyboardFeedback( cmd, _( "Cut one second" ) );
00885 DrawBar( common->g_currentFrame );
00886 cmd[ 0 ] = 0;
00887 }
00888
00889
00890
00891 else if ( strcmp( real, "dd" ) == 0 )
00892 {
00893 start = common->getPlayList() ->FindStartOfScene( common->g_currentFrame );
00894 end = start;
00895 for ( ; count >= 1 && end <= common->getPlayList() ->GetNumFrames() - 1; count -- )
00896 {
00897 end = common->getPlayList() ->FindEndOfScene( end );
00898 end ++;
00899 }
00900 CopyFrames( start, end - 1 );
00901 DeleteFrames( start, end - 1 );
00902 common->moveToFrame( start );
00903 common->keyboardFeedback( cmd, _( "Cut current scene" ) );
00904 DrawBar( common->g_currentFrame );
00905 cmd[ 0 ] = 0;
00906 }
00907
00908
00909
00910 else if ( ( strcmp( cmd, "o" ) == 0 ) || strcmp( cmd, "d$" ) == 0 )
00911 {
00912 start = common->g_currentFrame;
00913 if ( strcmp( cmd, "o" ) == 0 )
00914 ++start;
00915 end = common->getPlayList() ->FindEndOfScene( common->g_currentFrame );
00916 CopyFrames( start, end );
00917 DeleteFrames( start, end );
00918 common->moveToFrame( );
00919 common->keyboardFeedback( cmd, _( "Cut to end of scene" ) );
00920 DrawBar( common->g_currentFrame );
00921 cmd[ 0 ] = 0;
00922 }
00923
00924
00925
00926 else if ( strcmp( cmd, "dG" ) == 0 )
00927 {
00928 end = common->getPlayList() ->GetNumFrames();
00929 CopyFrames( common->g_currentFrame, end );
00930 DeleteFrames( common->g_currentFrame, end );
00931 common->moveByFrames( -1 );
00932 common->keyboardFeedback( cmd, _( "Cut to end of movie" ) );
00933 DrawBar( common->g_currentFrame );
00934 cmd[ 0 ] = 0;
00935 }
00936
00937
00938
00939 else if ( ( strcmp( cmd, "i" ) == 0 ) || ( strcmp( cmd, "d0" ) == 0 ) || strcmp( cmd, "d^" ) == 0 )
00940 {
00941 start = common->getPlayList() ->FindStartOfScene( common->g_currentFrame );
00942 if ( start < common->g_currentFrame )
00943 {
00944 CopyFrames( start, common->g_currentFrame - 1 );
00945 DeleteFrames( start, common->g_currentFrame - 1 );
00946 common->moveToFrame( start );
00947 }
00948 common->keyboardFeedback( cmd, _( "Cut from start of scene" ) );
00949 DrawBar( common->g_currentFrame );
00950 cmd[ 0 ] = 0;
00951 }
00952
00953
00954
00955 else if ( strcmp( cmd, "dgg" ) == 0 )
00956 {
00957 CopyFrames( 0, common->g_currentFrame - 1 );
00958 DeleteFrames( 0, common->g_currentFrame - 1 );
00959 common->moveToFrame( 0 );
00960 common->keyboardFeedback( cmd, _( "Cut from start of movie" ) );
00961 DrawBar( common->g_currentFrame );
00962 cmd[ 0 ] = 0;
00963 }
00964
00965
00966
00967 else if ( ( strcmp( cmd, "y " ) == 0 ) || ( strcmp( real, "yl" ) == 0 ) )
00968 {
00969 CopyFrames( common->g_currentFrame, common->g_currentFrame + count - 1 );
00970 common->keyboardFeedback( cmd, _( "Copy current frame" ) );
00971 cmd[ 0 ] = 0;
00972 }
00973
00974
00975
00976 else if ( ( strcmp( real, "yy" ) == 0 ) || ( strcmp( real, "Y" ) == 0 ) )
00977 {
00978 start = common->getPlayList() ->FindStartOfScene( common->g_currentFrame );
00979 end = start;
00980 for ( ; count >= 1; count -- )
00981 {
00982 end = common->getPlayList() ->FindEndOfScene( end );
00983 end ++;
00984 }
00985 CopyFrames( start, end - 1 );
00986 common->keyboardFeedback( cmd, _( "Copy current scene" ) );
00987 cmd[ 0 ] = 0;
00988 }
00989
00990
00991
00992 else if ( strcmp( cmd, "y$" ) == 0 )
00993 {
00994 end = common->getPlayList() ->FindEndOfScene( common->g_currentFrame );
00995 CopyFrames( common->g_currentFrame, end );
00996 common->keyboardFeedback( cmd, _( "Copy to end of scene" ) );
00997 cmd[ 0 ] = 0;
00998 }
00999
01000
01001
01002 else if ( ( strcmp( cmd, "y0" ) == 0 ) || strcmp( cmd, "y^" ) == 0 )
01003 {
01004 start = common->getPlayList() ->FindStartOfScene( common->g_currentFrame );
01005 if ( start < common->g_currentFrame )
01006 {
01007 CopyFrames( start, common->g_currentFrame - 1 );
01008 common->moveToFrame( start );
01009 }
01010 common->keyboardFeedback( cmd, _( "Copy from start of scene" ) );
01011 cmd[ 0 ] = 0;
01012 }
01013
01014
01015
01016 else if ( strcmp( real, "p" ) == 0 )
01017 {
01018 start = common->g_currentFrame;
01019 for ( ; count >= 1; count -- )
01020 PasteFrames( common->g_currentFrame + 1 );
01021 common->moveToFrame( start + 1 );
01022 common->keyboardFeedback( cmd, _( "Paste after current frame" ) );
01023 DrawBar( common->g_currentFrame );
01024 cmd[ 0 ] = 0;
01025 }
01026
01027
01028
01029 else if ( strcmp( real, "P" ) == 0 )
01030 {
01031 for ( ; count >= 1; count -- )
01032 PasteFrames( common->g_currentFrame );
01033 end = common->getPlayList() ->FindEndOfScene( common->g_currentFrame + 1 );
01034 common->moveToFrame( );
01035 common->keyboardFeedback( cmd, _( "Paste before current frame" ) );
01036 DrawBar( common->g_currentFrame );
01037 cmd[ 0 ] = 0;
01038 }
01039
01040
01041
01042 else if ( strcmp( cmd, "a" ) == 0 )
01043 {
01044 common->keyboardFeedback( cmd, "Capture, insert after frame" );
01045 end = common->getPlayList() ->FindEndOfScene( common->g_currentFrame );
01046 common->moveToFrame( end );
01047 FileTracker::GetInstance().SetMode( CAPTURE_FRAME_APPEND );
01048 common->changePageRequest( PAGE_CAPTURE );
01049 cmd[ 0 ] = 0;
01050 }
01051
01052 else if ( strcmp( cmd, "A" ) == 0 )
01053 {
01054 common->keyboardFeedback( cmd, _( "Capture, append to movie" ) );
01055 end = common->getPlayList() ->GetNumFrames();
01056 common->moveToFrame( end );
01057 FileTracker::GetInstance().SetMode( CAPTURE_MOVIE_APPEND );
01058 common->changePageRequest( PAGE_CAPTURE );
01059 cmd[ 0 ] = 0;
01060 }
01061
01062 else if ( strcmp( cmd, "t" ) == 0 )
01063 {
01064 common->keyboardFeedback( cmd, _( "Trim" ) );
01065 common->changePageRequest( PAGE_TRIM );
01066 cmd[ 0 ] = 0;
01067 }
01068
01069 else if ( strcmp( cmd, "v" ) == 0 )
01070 {
01071 common->keyboardFeedback( cmd, _( "Timeline" ) );
01072 common->changePageRequest( PAGE_TIMELINE );
01073 cmd[ 0 ] = 0;
01074 }
01075
01076 else if ( strcmp( cmd, "C" ) == 0 )
01077 {
01078 common->keyboardFeedback( cmd, _( "FX" ) );
01079 common->changePageRequest( PAGE_MAGICK );
01080 cmd[ 0 ] = 0;
01081 }
01082
01083 else if ( strcmp( cmd, "u" ) == 0 )
01084 {
01085 GetEditorBackup() ->Undo( common->getPlayList() );
01086 common->keyboardFeedback( cmd, _( "Undo" ) );
01087 common->hasListChanged = TRUE;
01088 DrawBar( common->g_currentFrame );
01089 common->moveToFrame( );
01090 cmd[ 0 ] = 0;
01091 }
01092
01093 else if ( strcmp( cmd, "Ctrl+R" ) == 0 )
01094 {
01095 GetEditorBackup() ->Redo( common->getPlayList() );
01096 common->keyboardFeedback( cmd, _( "Redo" ) );
01097 common->hasListChanged = TRUE;
01098 DrawBar( common->g_currentFrame );
01099 common->moveToFrame( );
01100 cmd[ 0 ] = 0;
01101 }
01102
01103 else if ( strcmp( real, "J" ) == 0 )
01104 {
01105 common->keyboardFeedback( cmd, _( "Join scenes" ) );
01106 for ( ; count >= 1 && common->getPlayList() ->JoinScenesAt( common->g_currentFrame ); count -- )
01107 common->hasListChanged = TRUE;
01108 if ( common->hasListChanged == TRUE )
01109 {
01110 common->moveToFrame();
01111 DrawBar( common->g_currentFrame );
01112 GetEditorBackup() ->Store( common->getPlayList() );
01113 cmd[ 0 ] = 0;
01114 }
01115 }
01116
01117
01118
01119 else if ( strcmp( cmd, ":r" ) == 0 )
01120 {
01121 common->keyboardFeedback( cmd, _( "Insert file" ) );
01122 common->insertFile( );
01123 cmd[ 0 ] = 0;
01124 }
01125
01126 else if ( strcmp( cmd, ":a" ) == 0 )
01127 {
01128 common->keyboardFeedback( cmd, _( "Append file to scene" ) );
01129 int end = common->getPlayList() ->FindEndOfScene( common->g_currentFrame );
01130 common->moveToFrame( end );
01131 common->appendFile( );
01132 cmd[ 0 ] = 0;
01133 }
01134
01135 else if ( strcmp( cmd, ":A" ) == 0 )
01136 {
01137 common->keyboardFeedback( cmd, _( "Append file to movie" ) );
01138 int end = common->getPlayList() ->GetNumFrames();
01139 common->moveToFrame( end );
01140 common->appendFile( );
01141 cmd[ 0 ] = 0;
01142 }
01143
01144
01145
01146 else if ( strcmp( cmd, ":W" ) == 0 )
01147 {
01148 common->keyboardFeedback( cmd, _( "Export" ) );
01149 common->changePageRequest( PAGE_EXPORT );
01150 cmd[ 0 ] = 0;
01151 }
01152
01153
01154
01155 else if ( strcmp( cmd, ":w" ) == 0 )
01156 {
01157 common->keyboardFeedback( cmd, _( "Write playlist" ) );
01158 common->savePlayList( );
01159 cmd[ 0 ] = 0;
01160 }
01161
01162
01163
01164 else if ( strcmp( cmd, ":q" ) == 0 )
01165 {
01166 common->keyboardFeedback( cmd, _( "quit" ) );
01167 kinoDeactivate();
01168 cmd[ 0 ] = 0;
01169 }
01170
01171
01172
01173 else if ( strcmp( cmd, "Ctrl+J" ) == 0 )
01174 {
01175 common->keyboardFeedback( cmd, _( "Split scene before frame" ) );
01176 if ( common->getPlayList() ->SplitSceneBefore( common->g_currentFrame ) )
01177 {
01178 common->hasListChanged = TRUE;
01179 common->moveToFrame();
01180 DrawBar( common->g_currentFrame );
01181 GetEditorBackup() ->Store( common->getPlayList() );
01182 cmd[ 0 ] = 0;
01183 }
01184 }
01185
01186
01187 else if ( strncmp( cmd, ":", 1 ) == 0 )
01188 {
01189 int val = 0;
01190 char t[ 132 ] = "";
01191 if ( sscanf( cmd + 1, "%d", &val ) == 1 )
01192 {
01193 common->moveToFrame( val );
01194 sprintf( t, _( "Move to frame %d" ), val );
01195 common->keyboardFeedback( cmd, t );
01196 }
01197 else
01198 common->setStatusBar( cmd );
01199 }
01200
01201 else
01202 {
01203
01204 if ( strlen( real ) > 5 )
01205 cmd[ 0 ] = 0;
01206 else if ( strchr( "dgy ", real[ strlen( real ) - 1 ] ) == NULL )
01207 cmd[ 0 ] = 0;
01208
01209 common->keyboardFeedback( cmd, "" );
01210
01211 }
01212
01213 common->setWindowTitle( );
01214
01215 return FALSE;
01216 }
01217
01224 void PageEditor::CopyFrames( int first, int last )
01225 {
01226 PlayList * playList = new PlayList;
01227
01228
01229 delete g_copiedPlayList;
01230
01231 common->getPlayList() ->GetPlayList( first, last, *playList );
01232 g_copiedPlayList = playList;
01233 playList->SetDocName( "" );
01234 playList->SetDirty( true );
01235 }
01236
01237
01243 void PageEditor::PasteFrames( int before )
01244 {
01245 PlayList temp( *g_copiedPlayList );
01246
01247 if ( common->getPlayList() ->InsertPlayList( temp, before ) )
01248 {
01249 common->hasListChanged = TRUE;
01250 GetEditorBackup() ->Store( common->getPlayList() );
01251 }
01252 common->setWindowTitle( );
01253 }
01254
01261 void PageEditor::DeleteFrames( int first, int last )
01262 {
01263 int before, after;
01264
01265 before = common->getPlayList() ->GetNumFrames();
01266 if ( common->getPlayList() ->Delete( first, last ) )
01267 {
01268 after = common->getPlayList() ->GetNumFrames();
01269 common->hasListChanged = TRUE;
01270 GetEditorBackup() ->Store( common->getPlayList() );
01271 }
01272 common->setWindowTitle( );
01273 }
01274
01275 void PageEditor::showFrame( int position, Frame& frame )
01276 {
01277 gdk_threads_enter();
01278 if ( common->getPlayList() ->GetNumFrames() == 0 )
01279 {
01280 common->loadSplash( frameArea );
01281 }
01282 else
01283 {
01284 DrawBar( position );
01285 getFrameDisplayer() ->Put( frame, GTK_WIDGET( frameArea ), TRUE );
01286 showFrameInfo( position, frame );
01287 common->g_currentFrame = position;
01288 }
01289 gdk_flush();
01290 if ( position >= ( common->getPlayList()->GetNumFrames() - 1 ) ||
01291 ( position <= 0 && ( g_nav_ctl.step < 0 || g_nav_ctl.rate < 0 ) ) )
01292 {
01293 common->videoStop();
01294 }
01295 gdk_threads_leave();
01296 }
01297
01298
01299 void PageEditor::windowMoved()
01300 {
01301 if ( g_nav_ctl.active == FALSE )
01302 {
01303 if ( common->getPlayList() ->GetNumFrames() )
01304 {
01305 showFrame( common->g_currentFrame, TRUE );
01306 }
01307 else
01308 {
01309 common->loadSplash( frameArea );
01310 }
01311 }
01312 }
01313
01314
01315 void PageEditor::showFrameInfo( int i )
01316 {
01317 if ( common->g_currentFrame == -1 )
01318 {
01319 gtk_label_set_text( positionLabelCurrent, "" );
01320 gtk_label_set_text( positionLabelTotal, "" );
01321 return ;
01322 }
01323
01324 Frame *frame = GetFramePool() ->GetFrame();
01325 common->getPlayList() ->GetFrame( i, *frame );
01326 showFrameInfo( i, *frame );
01327 GetFramePool() ->DoneWithFrame( frame );
01328 }
01329
01330 void PageEditor::showFrameInfo( int i, Frame &frame )
01331 {
01332 FileHandler * media;
01333 int total = common->getPlayList() ->GetNumFrames();
01334
01335 common->getPlayList() ->GetMediaObject( i, &media );
01336 common->showFrameMoreInfo( frame, media );
01337
01338 common->getTime().setFramerate( frame.GetFrameRate() );
01339 string tc = "<span size=\"x-large\">" + common->getTime().parseFramesToString( i, common->getTimeFormat() ) + "</span>";
01340 gtk_label_set_markup( positionLabelCurrent, tc.c_str() );
01341 gtk_widget_set_redraw_on_allocate( GTK_WIDGET( positionLabelCurrent ), FALSE );
01342 tc = _("Duration: ") + common->getTime().parseFramesToString( total, common->getTimeFormat() );
01343 gtk_label_set_markup( positionLabelTotal, tc.c_str() );
01344 common->setCurrentScene( i );
01345 }
01346
01347 void PageEditor::DrawBar( int currentFrame )
01348 {
01349 if ( common->hasListChanged == TRUE )
01350 {
01351 ResetBar();
01352 common->hasListChanged = FALSE;
01353 }
01354 if ( currentFrame > -1 )
01355 gtk_adjustment_set_value( scrubAdjustment, ( gfloat ) currentFrame );
01356 }
01357
01358 void PageEditor::ResetBar()
01359 {
01360 int frameNum = 0, lastFrame = 0;
01361
01362 sceneStartList.erase( sceneStartList.begin(), sceneStartList.end() );
01363
01364 if ( sceneIndex != NULL )
01365 g_array_free( sceneIndex, TRUE );
01366 sceneIndex = g_array_new( FALSE, FALSE, sizeof( int ) );
01367 g_array_set_size( sceneIndex, 0 );
01368
01369 while ( frameNum < common->getPlayList() ->GetNumFrames() )
01370 {
01371 lastFrame = frameNum = common->getPlayList() ->FindEndOfScene( frameNum );
01372 frameNum++;
01373 g_array_append_val( sceneIndex, frameNum );
01374 sceneStartList.insert( sceneStartList.end(), frameNum );
01375 }
01376 GetStoryboard() ->reset();
01377 GetStoryboard() ->redraw();
01378 frameNum = common->getPlayList() ->GetNumFrames() - 1;
01379 if ( frameNum < 0 )
01380 frameNum = 0;
01381 scrubAdjustment->upper = frameNum;
01382 g_signal_emit_by_name( scrubAdjustment, "changed" );
01383 gtk_enhanced_scale_set_breaks( scrubBar, sceneIndex );
01384 }
01385
01386 vector <int> PageEditor::GetScene()
01387 {
01388 return sceneStartList;
01389 }
01390
01391 void PageEditor::snapshot()
01392 {
01393 GetEditorBackup() ->Store( common->getPlayList() );
01394 common->setWindowTitle( );
01395 }
01396
01397 extern "C"
01398 {
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408 static int frameNumber[ PLAYBACK_FRAMES ];
01409 static int pending = 0;
01410 static int head = -1;
01411 static int tail = -1;
01412 static bool playing = false;
01413 static bool showing = false;
01414
01415 static void resetThreads( )
01416 {
01417 playing = false;
01418 showing = false;
01419 pending = 0;
01420 head = 0;
01421 tail = 0;
01422 }
01423
01433 static void *readThread( void * info )
01434 {
01435 struct navigate_control * ctl = ( struct navigate_control * ) info;
01436 newFrame = 0;
01437 lastFrame = common->g_currentFrame - 1;
01438 gint totalFrames = common->getPlayList() ->GetNumFrames();
01439 gint countFrames = 0;
01440 static Preferences &prefs = Preferences::getInstance();
01441 int time_per_frame = 1000000 / _getOneSecond( );
01442
01443
01444
01445
01446 struct timeval start;
01447 struct timeval end;
01448 gettimeofday( &start, NULL );
01449
01450
01451 while ( ctl->active )
01452 {
01453
01454 start.tv_usec += time_per_frame;
01455 if ( start.tv_usec >= 1000000 )
01456 {
01457 start.tv_usec -= 1000000;
01458 start.tv_sec ++;
01459 }
01460
01461 pthread_mutex_lock( &readlock );
01462
01463 newFrame = lastFrame + ctl->step;
01464
01465
01466 if ( ctl->step == 0 )
01467 {
01468 ctl->subframe++;
01469 if ( ctl->rate < 0 )
01470 {
01471 if ( ctl->subframe >= -ctl->rate )
01472 {
01473 newFrame --;
01474 ctl->subframe = 0;
01475 }
01476 }
01477 else
01478 {
01479 if ( ctl->subframe >= ctl->rate )
01480 {
01481 newFrame ++;
01482 ctl->subframe = 0;
01483 }
01484 }
01485 }
01486 pthread_mutex_unlock( &readlock );
01487
01488
01489 if ( newFrame < 0 )
01490 newFrame = 0;
01491 else if ( newFrame >= totalFrames )
01492 newFrame = totalFrames - 1;
01493
01494
01495 if ( pending >= PLAYBACK_FRAMES - 10 )
01496 {
01497
01498 playing = true;
01499 struct timespec t = { 0, 0 };
01500 nanosleep( &t, NULL );
01501 }
01502 else
01503 {
01504 frameNumber[ head ] = newFrame;
01505 common->getPlayList() ->GetFrame( frameNumber[ head ], *frameContent[ head ] );
01506 if ( writer1394 != NULL )
01507 writer1394->SendFrame( *frameContent[ head ], false );
01508
01509 pthread_mutex_lock( &threadlock );
01510 ++pending;
01511 head = ( head + 1 ) % PLAYBACK_FRAMES;
01512 pthread_mutex_unlock( &threadlock );
01513
01514
01515 playing = true;
01516
01517
01518 if ( ( ! prefs.dropFrame || ! prefs.enableAudio ) && ctl->active )
01519 {
01520 if ( prefs.enableAudio && ( frameNumber[ tail ] != lastFrame || ctl->rate > 1 || ctl->rate < -1 ) )
01521 common->getPageEditor() ->getFrameDisplayer() ->PutSound( *frameContent[ tail ] );
01522 common->getPageEditor() ->showFrame( frameNumber[ tail ], *frameContent[ tail ] );
01523 tail = ( tail + 1 ) % PLAYBACK_FRAMES;
01524 --pending;
01525
01526
01527 gettimeofday( &end, NULL );
01528 int difference = ( ( start.tv_sec * 1000000 + start.tv_usec ) - ( end.tv_sec * 1000000 + end.tv_usec ) );
01529
01530 if ( difference > 2000 && difference < time_per_frame )
01531 {
01532
01533 if ( ! prefs.enableAudio )
01534 {
01535 struct timespec t =
01536 {
01537 0, difference * 500
01538 };
01539 nanosleep( &t, NULL );
01540 }
01541 }
01542 else if ( difference < 0 || difference >= time_per_frame )
01543 {
01544 gettimeofday( &start, NULL );
01545 }
01546 }
01547
01548
01549 lastFrame = newFrame;
01550
01551
01552 countFrames ++;
01553 }
01554 }
01555
01556
01557 return NULL;
01558 }
01559
01560 static void *audioThread( void * info )
01561 {
01562
01563 static Preferences & prefs = Preferences::getInstance();
01564 struct navigate_control *ctl = ( struct navigate_control * ) info;
01565 int lastFrame = common->g_currentFrame - 1;
01566 int time_per_frame = 1000000 / _getOneSecond( );
01567
01568
01569
01570 while ( ctl->active )
01571 {
01572
01573 if ( prefs.dropFrame && prefs.enableAudio )
01574 {
01575
01576 if ( playing && pending > 0 )
01577 {
01578
01579 if ( prefs.enableAudio && ( frameNumber[ tail ] != lastFrame || ctl->rate > 1 || ctl->rate < -1 ) )
01580 {
01581 common->getPageEditor() ->getFrameDisplayer() ->PutSound( *frameContent[ tail ] );
01582 if ( pending < 10 )
01583 {
01584 struct timespec t = { 0, 0 };
01585 nanosleep( &t, NULL );
01586 }
01587 }
01588 else if ( ctl->step == 0 && !prefs.audioScrub )
01589 {
01590 struct timespec t =
01591 {
01592 0, time_per_frame * 1000
01593 };
01594 nanosleep( &t, NULL );
01595 }
01596
01597
01598 lastFrame = frameNumber[ tail ];
01599
01600
01601 pthread_mutex_lock( &threadlock );
01602 --pending;
01603 tail = ( tail + 1 ) % PLAYBACK_FRAMES;;
01604 pthread_mutex_unlock( &threadlock );
01605
01606
01607 showing = true;
01608 }
01609 else
01610 {
01611 playing = false;
01612 struct timespec t = { 0, 0 };
01613 nanosleep( &t, NULL );
01614 }
01615 }
01616 else
01617 {
01618
01619
01620 return NULL;
01621 }
01622 }
01623
01624
01625 return NULL;
01626 }
01627
01628 static void *videoThread( void * info )
01629 {
01630
01631 static Preferences & prefs = Preferences::getInstance();
01632 struct navigate_control *ctl = ( struct navigate_control * ) info;
01633 int lastFrame = common->g_currentFrame - 1;
01634
01635 #ifdef PLAY_WITH_STATS
01636
01637 int dropped = 0;
01638 int count = 0;
01639 #endif
01640
01641
01642 while ( ctl->active )
01643 {
01644
01645 if ( prefs.dropFrame && prefs.enableAudio )
01646 {
01647 if ( showing && pending > 0 && ctl->active )
01648 {
01649
01650 int my_tail = tail;
01651
01652
01653 if ( frameNumber[ my_tail ] != lastFrame || ctl->rate > 1 )
01654 {
01655 #ifdef PLAY_WITH_STATS
01656
01657 if ( ctl->step == 1 )
01658 {
01659 int skipped = frameNumber[ my_tail ] - lastFrame - 1;
01660 count += skipped + 1;
01661 if ( skipped != 0 && lastFrame != 0 && count != 0 )
01662 {
01663 dropped += skipped;
01664 cerr << ">>>> Dropped " << dropped << " in " << count << " frames - " << ( double ) ( ( ( double ) dropped / ( double ) count ) * 100.0 ) << "%" << endl;
01665 }
01666 lastFrame = frameNumber[ my_tail ];
01667 }
01668 #endif
01669
01670 common->getPageEditor() ->showFrame( frameNumber[ my_tail ], *frameContent[ my_tail ] );
01671 }
01672 }
01673 struct timespec t = { 0, 0 };
01674 nanosleep( &t, NULL );
01675 }
01676 else
01677 {
01678
01679
01680 return NULL;
01681 }
01682 }
01683
01684 #ifdef PLAY_WITH_STATS
01685 cerr << ">>>> Video stopped: Dropped " << dropped << " in " << count << " frames - " << ( double ) ( ( ( double ) dropped / ( double ) count ) * 100.0 ) << "%" << endl;
01686 #endif
01687
01688
01689 return NULL;
01690 }
01691
01692 static int _getOneSecond( void )
01693 {
01694 Frame & frame = *( GetFramePool() ->GetFrame( ) );
01695 common->getPlayList() ->GetFrame( common->g_currentFrame, frame );
01696 int value = ( frame.IsPAL() ? 25 : 30 );
01697 GetFramePool( ) ->DoneWithFrame( &frame );
01698 return value;
01699 }
01700
01701 }