#include <iostream>#include <sys/time.h>#include <sys/types.h>#include <dirent.h>#include <pthread.h>#include "page_trim.h"#include "avi.h"#include "error.h"#include "message.h"#include "filehandler.h"#include "frame.h"#include "commands.h"#include "page_editor.h"#include "ieee1394io.h"#include "support.h"Include dependency graph for page_trim.cc:

Go to the source code of this file.
Defines | |
| #define | TRIM_ADJ_POS 0 |
| #define | TRIM_ADJ_IN 1 |
| #define | TRIM_ADJ_OUT 2 |
| #define | PLAYBACK_FRAMES 50 |
Functions | |
| static int | _getOneSecond (void) |
| static void | resetThreads () |
| static void * | readThread (void *info) |
| This function carries out the read ahead and is responsible for obtaining the each frame. | |
| static void * | videoThread (void *info) |
| static void * | audioThread (void *info) |
| gboolean | on_trim_value_changed_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) |
| void | on_spinbutton_trim_in_value_changed (GtkSpinButton *spinbutton, gpointer user_data) |
| void | on_spinbutton_trim_out_value_changed (GtkSpinButton *spinbutton, gpointer user_data) |
| void | on_button_trim_in_reset_clicked (GtkButton *button, gpointer user_data) |
| void | on_button_trim_out_reset_clicked (GtkButton *button, gpointer user_data) |
| void | on_button_trim_in_set_clicked (GtkButton *button, gpointer user_data) |
| void | on_button_trim_out_set_clicked (GtkButton *button, gpointer user_data) |
| void | on_togglebutton_trim_link_toggled (GtkToggleButton *togglebutton, gpointer user_data) |
| gboolean | on_spinbutton_trim_in_focus_in_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) |
| gboolean | on_spinbutton_trim_in_focus_out_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) |
| gboolean | on_spinbutton_trim_out_focus_in_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) |
| gboolean | on_spinbutton_trim_out_focus_out_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) |
| gboolean | on_trim_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) |
| gboolean | on_trim_button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) |
| gboolean | on_combo_trim_clip_entry_focus_in_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) |
| gboolean | on_combo_trim_clip_entry_focus_out_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) |
| void | on_combo_trim_clip_entry_changed (GtkEditable *editable, gpointer user_data) |
| void | on_button_trim_open_clicked (GtkButton *button, gpointer user_data) |
| void | on_button_trim_insert_before_clicked (GtkButton *button, gpointer user_data) |
| void | on_button_trim_insert_after_clicked (GtkButton *button, gpointer user_data) |
| void | on_menuitem_trim_update_activate (GtkMenuItem *menuitem, gpointer user_data) |
| void | on_menuitem_trim_insert_activate (GtkMenuItem *menuitem, gpointer user_data) |
| void | on_button_trim_apply_clicked (GtkButton *button, gpointer user_data) |
| void | on_entry_trim_in_activate (GtkEntry *entry, gpointer user_data) |
| gboolean | on_entry_trim_in_focus_out_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) |
| void | on_entry_trim_out_activate (GtkEntry *entry, gpointer user_data) |
| gboolean | on_entry_trim_out_focus_out_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) |
Variables | |
| KinoCommon * | common |
| navigate_control | g_nav_ctl |
| char | cmd [] |
| static char | lastcmd [256] = { 0 } |
| static pthread_t | readthreadTrim |
| static pthread_t | audiothreadTrim |
| static pthread_t | videothreadTrim |
| static pthread_mutex_t | threadlock = PTHREAD_MUTEX_INITIALIZER |
| static pthread_mutex_t | readlock = PTHREAD_MUTEX_INITIALIZER |
| static GtkAdjustment * | trim_adj [3] |
| static gboolean | skipPosUpdate = FALSE |
| static GtkSpinButton * | spin_in |
| static GtkSpinButton * | spin_out |
| static GtkToggleButton * | link_toggle |
| static GtkToggleButton * | loop_toggle |
| static gboolean | doScrub = false |
| static int | newFrame = 0 |
| static int | lastFrame = -1 |
| static Frame * | frameContent [PLAYBACK_FRAMES] |
| IEEE1394Writer * | writer1394 |
| GArray * | scenes = NULL |
| Constructor for the trimmer page object. | |
| static int | frameNumber [PLAYBACK_FRAMES] |
| static int | pending = 0 |
| static int | head = -1 |
| static int | tail = -1 |
| static bool | showing = false |
| static bool | playing = false |
|
|
Definition at line 78 of file page_trim.cc. |
|
|
Definition at line 46 of file page_trim.cc. Referenced by PageTrim::loadFile(), PageTrim::loadScene(), on_button_trim_in_set_clicked(), on_spinbutton_trim_in_value_changed(), on_trim_value_changed_event(), PageTrim::PageTrim(), PageTrim::processCommand(), PageTrim::resetInPoint(), and PageTrim::setMode(). |
|
|
Definition at line 47 of file page_trim.cc. Referenced by PageTrim::loadFile(), PageTrim::loadScene(), on_button_trim_out_set_clicked(), on_spinbutton_trim_out_value_changed(), on_trim_value_changed_event(), PageTrim::PageTrim(), PageTrim::processCommand(), PageTrim::resetOutPoint(), and PageTrim::setMode(). |
|
|
Definition at line 45 of file page_trim.cc. Referenced by PageTrim::loadFile(), PageTrim::loadScene(), PageTrim::PageTrim(), PageTrim::processCommand(), and PageTrim::showFrame(). |
|
|
Definition at line 2329 of file page_trim.cc. References common, KinoCommon::g_currentFrame, GetFramePool(), KinoCommon::getPlayList(), and Frame::IsPAL(). 02330 {
02331 Frame & frame = *( GetFramePool() ->GetFrame( ) );
02332 common->getPlayList() ->GetFrame( common->g_currentFrame, frame );
02333 int value = ( frame.IsPAL() ? 25 : 30 );
02334 GetFramePool( ) ->DoneWithFrame( &frame );
02335 return value;
02336 }
|
|
|
Definition at line 2164 of file page_trim.cc. References _getOneSecond(), navigate_control::active, Preferences::audioScrub, common, Preferences::dropFrame, Preferences::enableAudio, frameContent, Preferences::getInstance(), KinoCommon::getPageTrim(), lastFrame, PLAYBACK_FRAMES, navigate_control::rate, navigate_control::step, and threadlock. 02165 {
02166
02167 static Preferences & prefs = Preferences::getInstance();
02168 struct navigate_control *ctl = ( struct navigate_control * ) info;
02169 gint lastFrame = common->getPageTrim() ->getPosition() - 1;
02170 int time_per_frame = 1000000 / _getOneSecond( );
02171
02172 // cerr << ">>> Starting audio thread" << endl;
02173
02174 while ( ctl->active )
02175 {
02176
02177 // Only do this when drop frames is active (otherwise the audio thread takes care of it)
02178 if ( prefs.dropFrame && prefs.enableAudio )
02179 {
02180
02181 // Obtain the position of the last released frame
02182 pthread_mutex_lock( &threadlock );
02183 int new_tail = ( tail + 1 ) % PLAYBACK_FRAMES;
02184 //cerr << "playing pending = " << pending << " head = " << head << " new_tail = " << new_tail << endl;
02185 pthread_mutex_unlock( &threadlock );
02186
02187 // As long as its different to the previous one, then display it
02188 if ( pending > 0 && playing )
02189 {
02190
02191 // Move the main frame position to our newly derived location
02192 common->getPageTrim() ->setPosition( frameNumber[ tail ] );
02193
02194 // Play the audio
02195 if ( prefs.enableAudio && ( frameNumber[ tail ] != lastFrame || ctl->rate > 1 || ctl->rate < -1 ) )
02196 {
02197 common->getPageTrim() ->getFrameDisplayer() ->PutSound( *frameContent[ tail ] );
02198 if ( pending < 10 )
02199 {
02200 // Give the reader more time
02201 struct timespec t =
02202 {
02203 0, 0
02204 };
02205 nanosleep( &t, NULL );
02206 }
02207 }
02208 else if ( ctl->step == 0 && !prefs.audioScrub )
02209 {
02210 struct timespec t =
02211 {
02212 0, time_per_frame * 1000
02213 };
02214 nanosleep( &t, NULL );
02215 }
02216
02217 // Last encountered audio frame
02218 lastFrame = frameNumber[ tail ];
02219
02220 // Move the tail
02221 pthread_mutex_lock( &threadlock );
02222 pending --;
02223 tail = new_tail;
02224 pthread_mutex_unlock( &threadlock );
02225
02226 // Start showing frames from this point onwards
02227 showing = true;
02228
02229 }
02230 else
02231 {
02232 struct timespec t =
02233 {
02234 0, 0
02235 };
02236 nanosleep( &t, NULL );
02237 }
02238 }
02239 else
02240 {
02241 // It is safe to cancel the audio thread here since a change to prefs necessitates a restart.
02242 // cerr << ">>> Audio Thread not needed" << endl;
02243 return NULL;
02244 }
02245 }
02246
02247 // cerr << ">>> Ending video thread" << endl;
02248
02249 return NULL;
02250 }
|
|
||||||||||||
|
Definition at line 422 of file page_trim.cc. References lookup_widget(), and processCommand(). 00424 {
00425 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00426 processCommand( "Enter" );
00427 }
|
|
||||||||||||
|
Definition at line 197 of file page_trim.cc. References KinoCommon::getPageTrim(), and lookup_widget(). 00199 {
00200 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00201 common->getPageTrim() ->resetInPoint();
00202 }
|
|
||||||||||||
|
Definition at line 213 of file page_trim.cc. References KinoCommon::getPageTrim(), lookup_widget(), and TRIM_ADJ_IN. 00215 {
00216 int value = common->getPageTrim() ->getPosition();
00217 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00218 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], value );
00219 }
|
|
||||||||||||
|
Definition at line 398 of file page_trim.cc. References KinoCommon::getPageTrim(), lookup_widget(), and TRIM_INSERT_MODE_AFTER. 00400 {
00401 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00402 common->getPageTrim()->insertScene( TRIM_INSERT_MODE_AFTER );
00403 }
|
|
||||||||||||
|
Definition at line 390 of file page_trim.cc. References KinoCommon::getPageTrim(), lookup_widget(), and TRIM_INSERT_MODE_BEFORE. 00392 {
00393 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00394 common->getPageTrim()->insertScene( TRIM_INSERT_MODE_BEFORE );
00395 }
|
|
||||||||||||
|
Definition at line 378 of file page_trim.cc. References KinoCommon::getFileToOpen(), and lookup_widget(). 00380 {
00381 char *filename = common->getFileToOpen( _("Choose a DV file") );
00382 if ( filename && strcmp( filename, "" ) )
00383 {
00384 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( button ), "entry_trim_clip" ) ),
00385 filename );
00386 }
00387 }
|
|
||||||||||||
|
Definition at line 205 of file page_trim.cc. References KinoCommon::getPageTrim(), and lookup_widget(). 00207 {
00208 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00209 common->getPageTrim() ->resetOutPoint();
00210 }
|
|
||||||||||||
|
Definition at line 222 of file page_trim.cc. References KinoCommon::getPageTrim(), lookup_widget(), and TRIM_ADJ_OUT. 00224 {
00225 int value = common->getPageTrim() ->getPosition();
00226 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "eventbox_trim" ) );
00227 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], value );
00228 }
|
|
||||||||||||
|
Definition at line 337 of file page_trim.cc. References AVI, KinoCommon::checkFile(), navigate_control::escaped, KinoCommon::getPageTrim(), KinoCommon::importFile(), lookup_widget(), QT, and RAW_DV. 00339 {
00340 if ( g_nav_ctl.escaped == FALSE )
00341 {
00342 const gchar* filename = gtk_entry_get_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( editable ), "entry_trim_clip" ) ) );
00343 if ( strlen( filename ) )
00344 {
00345 switch ( common->checkFile( ( char* ) filename ) )
00346 {
00347 case AVI:
00348 case RAW_DV:
00349 case QT:
00350 if ( common->getPageTrim()->loadFile( filename ) )
00351 {
00352 common->getPageTrim()->movedToFrame( common->getPageTrim()->getInPoint() );
00353 break;
00354 }
00355 default:
00356 {
00357 const std::string& importedFile = common->importFile( filename );
00358 if ( common->getPageTrim()->loadFile( const_cast<char*>( importedFile.c_str() ) ) )
00359 {
00360 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( editable ), "entry_trim_clip" ) ), const_cast<char*>( importedFile.c_str() ) );
00361 common->getPageTrim()->movedToFrame( common->getPageTrim()->getInPoint() );
00362 }
00363 else
00364 {
00365 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( editable ), "entry_trim_clip" ) ), "" );
00366 }
00367 break;
00368 }
00369 // XXX: the following is making gtk abort
00370 //modal_message( _( "Invalid file specified." ) );
00371 // break;
00372 }
00373 }
00374 }
00375 }
|
|
||||||||||||||||
|
Definition at line 302 of file page_trim.cc. References navigate_control::escaped.
|
|
||||||||||||||||
|
Definition at line 311 of file page_trim.cc. References AVI, KinoCommon::checkFile(), navigate_control::escaped, KinoCommon::getPageTrim(), QT, and RAW_DV. 00314 {
00315 g_nav_ctl.escaped = FALSE;
00316 const gchar* filename = gtk_entry_get_text( GTK_ENTRY( widget ) );
00317 if ( strlen( filename ) )
00318 {
00319 switch ( common->checkFile( ( char* ) filename ) )
00320 {
00321 case AVI:
00322 case RAW_DV:
00323 case QT:
00324 if ( common->getPageTrim()->loadFile( filename ) )
00325 common->getPageTrim()->movedToFrame( common->getPageTrim()->getInPoint() );
00326 break;
00327 default:
00328 // XXX: the following is making gtk abort
00329 //modal_message( _( "Invalid file specified." ) );
00330 break;
00331 }
00332 }
00333 return FALSE;
00334 }
|
|
||||||||||||
|
Definition at line 430 of file page_trim.cc. References KinoCommon::getTime(), KinoCommon::getTimeFormat(), lookup_widget(), and on_spinbutton_trim_in_value_changed(). Referenced by on_entry_trim_in_focus_out_event(). 00432 {
00433 common->getTime().parseValueToString( gtk_entry_get_text( entry ), common->getTimeFormat() );
00434 GtkSpinButton *spinbutton = GTK_SPIN_BUTTON( lookup_widget( GTK_WIDGET( entry ), "spinbutton_trim_in" ) );
00435 gtk_spin_button_set_value( spinbutton, common->getTime().getFrames() );
00436 on_spinbutton_trim_in_value_changed( spinbutton, NULL );
00437 }
|
|
||||||||||||||||
|
Definition at line 440 of file page_trim.cc. References navigate_control::escaped, and on_entry_trim_in_activate(). 00443 {
00444 on_entry_trim_in_activate( GTK_ENTRY( widget ), NULL );
00445 g_nav_ctl.escaped = FALSE;
00446 return FALSE;
00447 }
|
|
||||||||||||
|
Definition at line 450 of file page_trim.cc. References KinoCommon::getTime(), KinoCommon::getTimeFormat(), lookup_widget(), and on_spinbutton_trim_out_value_changed(). Referenced by on_entry_trim_out_focus_out_event(). 00452 {
00453 common->getTime().parseValueToString( gtk_entry_get_text( entry ), common->getTimeFormat() );
00454 GtkSpinButton *spinbutton = GTK_SPIN_BUTTON( lookup_widget( GTK_WIDGET( entry ), "spinbutton_trim_out" ) );
00455 gtk_spin_button_set_value( spinbutton, common->getTime().getFrames() );
00456 on_spinbutton_trim_out_value_changed( spinbutton, NULL );
00457 }
|
|
||||||||||||||||
|
Definition at line 460 of file page_trim.cc. References navigate_control::escaped, and on_entry_trim_out_activate(). 00463 {
00464 on_entry_trim_out_activate( GTK_ENTRY( widget ), NULL );
00465 g_nav_ctl.escaped = FALSE;
00466 return FALSE;
00467 }
|
|
||||||||||||
|
Definition at line 414 of file page_trim.cc. References KinoCommon::getPageTrim(), lookup_widget(), and PAGE_TRIM_MODE_INSERT. 00416 {
00417 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( menuitem ), "eventbox_trim" ) );
00418 common->getPageTrim()->setMode( PAGE_TRIM_MODE_INSERT );
00419 }
|
|
||||||||||||
|
Definition at line 406 of file page_trim.cc. References KinoCommon::getPageTrim(), lookup_widget(), and PAGE_TRIM_MODE_UPDATE. 00408 {
00409 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( menuitem ), "eventbox_trim" ) );
00410 common->getPageTrim()->setMode( PAGE_TRIM_MODE_UPDATE );
00411 }
|
|
||||||||||||||||
|
Definition at line 243 of file page_trim.cc. References navigate_control::escaped.
|
|
||||||||||||||||
|
Definition at line 252 of file page_trim.cc. References navigate_control::escaped.
|
|
||||||||||||
|
Definition at line 169 of file page_trim.cc. References KinoCommon::getTime(), KinoCommon::getTimeFormat(), lookup_widget(), and TRIM_ADJ_IN. Referenced by on_entry_trim_in_activate(), and PageTrim::timeFormatChanged(). 00171 {
00172 if ( strcmp( gtk_entry_get_text( GTK_ENTRY( spin_in ) ), "" ) )
00173 {
00174 int value = atoi( gtk_entry_get_text( GTK_ENTRY( spin_in ) ) );
00175 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], value );
00176 }
00177 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( spinbutton ), "entry_trim_in" ) ),
00178 common->getTime().parseFramesToString( ( int )gtk_spin_button_get_value( spinbutton ),
00179 common->getTimeFormat() ).c_str() );
00180 }
|
|
||||||||||||||||
|
Definition at line 261 of file page_trim.cc. References navigate_control::escaped.
|
|
||||||||||||||||
|
Definition at line 271 of file page_trim.cc. References navigate_control::escaped.
|
|
||||||||||||
|
Definition at line 183 of file page_trim.cc. References KinoCommon::getTime(), KinoCommon::getTimeFormat(), lookup_widget(), and TRIM_ADJ_OUT. Referenced by on_entry_trim_out_activate(), and PageTrim::timeFormatChanged(). 00185 {
00186 if ( strcmp( gtk_entry_get_text( GTK_ENTRY( spin_out ) ), "" ) )
00187 {
00188 int value = atoi( gtk_entry_get_text( GTK_ENTRY( spin_out ) ) );
00189 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], value );
00190 }
00191 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( spinbutton ), "entry_trim_out" ) ),
00192 common->getTime().parseFramesToString( ( int )gtk_spin_button_get_value( spinbutton ),
00193 common->getTimeFormat() ).c_str() );
00194 }
|
|
||||||||||||
|
Definition at line 231 of file page_trim.cc. References lookup_widget(). 00233 {
00234 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( togglebutton ), "eventbox_trim" ) );
00235 GtkImage *image = GTK_IMAGE( lookup_widget( GTK_WIDGET( togglebutton ), "pixmap_trim_link" ) );
00236 if ( gtk_toggle_button_get_active( togglebutton ) )
00237 gtk_image_set_from_file( image, DATADIR "/kino/link.xpm" );
00238 else
00239 gtk_image_set_from_file( image, DATADIR "/kino/link_off.xpm" );
00240 }
|
|
||||||||||||||||
|
Definition at line 280 of file page_trim.cc. References videoPause(). Referenced by PageTrim::PageTrim(). 00283 {
00284 doScrub = TRUE;
00285 videoPause();
00286 return FALSE;
00287 }
|
|
||||||||||||||||
|
Definition at line 291 of file page_trim.cc. Referenced by PageTrim::PageTrim(). 00294 {
00295 doScrub = FALSE;
00296 return FALSE;
00297 }
|
|
||||||||||||||||
|
Definition at line 85 of file page_trim.cc. References KinoCommon::getPageTrim(), TRIM_ADJ_IN, and TRIM_ADJ_OUT. Referenced by PageTrim::PageTrim(). 00088 {
00089 int value = ( int ) GTK_ADJUSTMENT( widget ) ->value;
00090 if ( GTK_ADJUSTMENT( widget ) == trim_adj[ TRIM_ADJ_IN ] )
00091 {
00092 int diff = common->getPageTrim() ->getOutPoint() - common->getPageTrim() ->getInPoint() + value;
00093
00094 if ( gtk_toggle_button_get_active( link_toggle ) == TRUE && skipPosUpdate == FALSE )
00095 {
00096 if ( diff <= common->getPageTrim() ->getTotalFrames() )
00097 {
00098 if ( value >= common->getPageTrim() ->getOutPoint() )
00099 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], value );
00100 else
00101 common->getPageTrim() ->setInPoint( value );
00102
00103 skipPosUpdate = TRUE;
00104 gtk_spin_button_set_value( spin_out, ( gfloat ) diff );
00105 skipPosUpdate = TRUE;
00106 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], diff );
00107 }
00108 else
00109 {
00110 skipPosUpdate = TRUE;
00111 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], common->getPageTrim() ->getInPoint() );
00112 }
00113 }
00114 else
00115 {
00116 if ( value > common->getPageTrim() ->getOutPoint() )
00117 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], value );
00118 common->getPageTrim() ->setInPoint( value );
00119 }
00120 skipPosUpdate = TRUE;
00121 common->getPageTrim() ->movedToFrame( value );
00122 gtk_spin_button_set_value( spin_in, ( gfloat ) value );
00123
00124 }
00125 else if ( GTK_ADJUSTMENT( widget ) == trim_adj[ TRIM_ADJ_OUT ] )
00126 {
00127 int diff = common->getPageTrim() ->getInPoint() - common->getPageTrim() ->getOutPoint() + value;
00128
00129 if ( gtk_toggle_button_get_active( link_toggle ) == TRUE && skipPosUpdate == FALSE )
00130 {
00131 if ( diff >= 0 )
00132 {
00133 if ( value <= common->getPageTrim() ->getInPoint() )
00134 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], value - 1 );
00135 common->getPageTrim() ->setOutPoint( value );
00136
00137 skipPosUpdate = TRUE;
00138 gtk_spin_button_set_value( spin_in, ( gfloat ) diff );
00139 skipPosUpdate = TRUE;
00140 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], diff );
00141 }
00142 else
00143 {
00144 skipPosUpdate = TRUE;
00145 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_OUT ], common->getPageTrim() ->getOutPoint() );
00146 }
00147 }
00148 else
00149 {
00150 if ( value < common->getPageTrim() ->getInPoint() )
00151 gtk_adjustment_set_value( trim_adj[ TRIM_ADJ_IN ], value );
00152 common->getPageTrim() ->setOutPoint( value );
00153 }
00154 skipPosUpdate = TRUE;
00155 common->getPageTrim() ->movedToFrame( value );
00156 gtk_spin_button_set_value( spin_out, ( gfloat ) value );
00157
00158 }
00159 else if ( skipPosUpdate == FALSE )
00160 {
00161 skipPosUpdate = TRUE;
00162 common->getPageTrim() ->movedToFrame( value );
00163 }
00164 skipPosUpdate = FALSE;
00165 return FALSE;
00166 }
|
|
|
This function carries out the read ahead and is responsible for obtaining the each frame. audioThread monitors the queue (by checking mainly on pending) and plays the audio of each frame. videoThread picks up the last tail and displays it. Note that only half of the queue is filled here - this provides the video thread some time to safely use a frame without worrying about it being overwritten. Definition at line 2008 of file page_trim.cc. References _getOneSecond(), navigate_control::active, common, countFrames(), Preferences::dropFrame, Preferences::enableAudio, frameContent, Preferences::getInstance(), KinoCommon::getPageTrim(), lastFrame, loop_toggle, newFrame, PLAYBACK_FRAMES, navigate_control::rate, readlock, IEEE1394Writer::SendFrame(), navigate_control::step, navigate_control::subframe, threadlock, and writer1394. 02009 {
02010 struct navigate_control * ctl = ( struct navigate_control * ) info;
02011 newFrame = 0;
02012 lastFrame = common->getPageTrim() ->getPosition() - 1;
02013 gint totalFrames = common->getPageTrim() ->getTotalFrames();
02014 gint countFrames = 0;
02015 static Preferences &prefs = Preferences::getInstance();
02016 int time_per_frame = 1000000 / _getOneSecond( );
02017
02018 // cerr << ">>> Starting read thread " << endl;
02019
02020 // Get start of time
02021 struct timeval start;
02022 struct timeval end;
02023 gettimeofday( &start, NULL );
02024
02025 // Loop while active
02026 while ( ctl->active )
02027 {
02028
02029 // Calculate time for next frame
02030 start.tv_usec += time_per_frame;
02031 if ( start.tv_usec >= 1000000 )
02032 {
02033 start.tv_usec -= 1000000;
02034 start.tv_sec ++;
02035 }
02036
02037 pthread_mutex_lock( &readlock );
02038 // Determine the frame to render
02039 newFrame = lastFrame + ctl->step;
02040
02041 // determine new frame based upon jogshuttle rate
02042 if ( ctl->step == 0 )
02043 {
02044 ctl->subframe++;
02045 if ( ctl->rate < 0 )
02046 {
02047 if ( ctl->subframe >= -ctl->rate )
02048 {
02049 newFrame --;
02050 ctl->subframe = 0;
02051 }
02052 }
02053 else
02054 {
02055 if ( ctl->subframe >= ctl->rate )
02056 {
02057 newFrame ++;
02058 ctl->subframe = 0;
02059 }
02060 }
02061 }
02062 pthread_mutex_unlock( &readlock );
02063
02064 // Check the bounds and adjust as necessary
02065 if ( newFrame < 0 )
02066 newFrame = totalFrames - 1;
02067 else if ( newFrame > common->getPageTrim() ->getOutPoint() &&
02068 gtk_toggle_button_get_active( loop_toggle ) == TRUE )
02069 newFrame = common->getPageTrim() ->getInPoint();
02070 else if ( newFrame < common->getPageTrim() ->getInPoint() &&
02071 gtk_toggle_button_get_active( loop_toggle ) == TRUE )
02072 newFrame = common->getPageTrim() ->getOutPoint();
02073 else if ( newFrame >= totalFrames )
02074 newFrame = 0;
02075
02076 // Determine which locations in frameNumber and frameContent we need to use
02077 if ( pending >= PLAYBACK_FRAMES / 2 )
02078 {
02079 // Queue is full.. do nothing
02080 playing = true;
02081 struct timespec t =
02082 {
02083 0, 0
02084 };
02085 nanosleep( &t, NULL );
02086 }
02087 else if ( pending < PLAYBACK_FRAMES )
02088 {
02089 pthread_mutex_lock( &threadlock );
02090 int new_head = ( head + 1 ) % PLAYBACK_FRAMES;
02091 //cerr << "captured pending = " << pending << " new_head = " << new_head << " tail = " << tail << endl;
02092 pthread_mutex_unlock( &threadlock );
02093
02094 frameNumber[ new_head ] = newFrame;
02095 common->getPageTrim() ->getPlayList().GetFrame( frameNumber[ new_head ], *frameContent[ new_head ] );
02096
02097 pthread_mutex_lock( &threadlock );
02098 pending ++;
02099 head = new_head;
02100 pthread_mutex_unlock( &threadlock );
02101
02102 if ( writer1394 != NULL )
02103 writer1394->SendFrame( *frameContent[ new_head ], false );
02104
02105 // Inform the audio thread that it's got something to work with
02106 playing = true;
02107
02108 // Render all frames if requested
02109 if ( ( ! prefs.dropFrame || ! prefs.enableAudio ) && ctl->active )
02110 {
02111
02112 // Change the queue position
02113 tail = ( tail + 1 ) % PLAYBACK_FRAMES;
02114 pending --;
02115
02116 // Set the current position
02117 common->getPageTrim() ->setPosition( frameNumber[ tail ] );
02118
02119 // If audio is enabled and some other conditions
02120 if ( prefs.enableAudio && ( frameNumber[ tail ] != lastFrame || ctl->rate > 1 || ctl->rate < -1 ) )
02121 common->getPageTrim() ->getFrameDisplayer() ->PutSound( *frameContent[ tail ] );
02122
02123 // Show the corresponding image
02124 gdk_threads_enter();
02125 common->getPageTrim() ->showFrame( frameNumber[ tail ], *frameContent[ tail ] );
02126 gdk_flush();
02127 gdk_threads_leave();
02128
02129 // Determine how far from the next frame we really are
02130 gettimeofday( &end, NULL );
02131 int difference = ( ( start.tv_sec * 1000000 + start.tv_usec ) - ( end.tv_sec * 1000000 + end.tv_usec ) );
02132
02133 if ( difference > 2000 && difference < time_per_frame )
02134 {
02135 // Sleep for half the remaining time when audio is disabled
02136 if ( ! prefs.enableAudio )
02137 {
02138 struct timespec t =
02139 {
02140 0, difference * 500
02141 };
02142 nanosleep( &t, NULL );
02143 }
02144 }
02145 else if ( difference < 0 || difference >= time_per_frame )
02146 {
02147 gettimeofday( &start, NULL );
02148 }
02149 }
02150
02151 // update the lastFrame and lastPos variables
02152 lastFrame = newFrame;
02153
02154 // Incrment the frame count
02155 countFrames ++;
02156 }
02157 }
02158
02159 // cerr << ">>> Ending reading thread" << endl;
02160
02161 return NULL;
02162 }
|
|
|
Definition at line 1990 of file page_trim.cc. 01991 {
01992 showing = false;
01993 playing = false;
01994 pending = 0;
01995 head = 0;
01996 tail = 0;
01997 }
|
|
|
Definition at line 2252 of file page_trim.cc. References navigate_control::active, common, count, Preferences::dropFrame, Preferences::enableAudio, frameContent, Preferences::getInstance(), KinoCommon::getPageTrim(), lastFrame, navigate_control::rate, and navigate_control::step. 02253 {
02254
02255 static Preferences & prefs = Preferences::getInstance();
02256 struct navigate_control *ctl = ( struct navigate_control * ) info;
02257 int lastFrame = common->getPageTrim() ->getPosition() - 1;
02258
02259 #ifdef PLAY_WITH_STATS
02260 // Statistical analysis variables
02261 int dropped = 0;
02262 int count = 0;
02263 #endif
02264
02265 // cerr << ">>> Starting video thread" << endl;
02266
02267 while ( ctl->active )
02268 {
02269
02270 // Only do this when drop frames is active (otherwise the audio thread takes care of it)
02271 if ( prefs.dropFrame && prefs.enableAudio )
02272 {
02273
02274 if ( showing && pending > 0 )
02275 {
02276
02277 // Store the current tail
02278 int my_tail = tail;
02279
02280 // As long as its different to the previous one, then display it
02281 if ( frameNumber[ my_tail ] != lastFrame || ctl->rate > 1 )
02282 {
02283 #ifdef PLAY_WITH_STATS
02284 // Statistical analysis of frame playback (useful for limited kinds of tests)
02285 if ( ctl->step == 1 )
02286 {
02287 int skipped = frameNumber[ my_tail ] - lastFrame - 1;
02288 count += skipped + 1;
02289 if ( skipped != 0 && lastFrame != 0 && count != 0 )
02290 {
02291 dropped += skipped;
02292 cerr << ">>>> Dropped " << dropped << " in " << count << " frames - " << ( double ) ( ( ( double ) dropped / ( double ) count ) * 100.0 ) << "%" << endl;
02293 }
02294 lastFrame = frameNumber[ my_tail ];
02295 }
02296 #endif
02297
02298 // Show this frame
02299 if ( ctl->active )
02300 {
02301 gdk_threads_enter();
02302 common->getPageTrim() ->showFrame( frameNumber[ my_tail ], *frameContent[ my_tail ] );
02303 gdk_flush();
02304 gdk_threads_leave();
02305 }
02306 }
02307 }
02308 // Release thread
02309 struct timespec t = { 0, 0 };
02310 |