Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

commands.cc

Go to the documentation of this file.
00001 /*
00002 * Copyright (C) 2000 Arne Schirmacher <arne@schirmacher.de>
00003 * Copyright (C) 2001-2007 Dan Dennedy <dan@dennedy.org>
00004 *
00005 * This program is free software; you can redistribute it and/or modify
00006 * it under the terms of the GNU General Public License as published by
00007 * the Free Software Foundation; either version 2 of the License, or
00008 * (at your option) any later version.
00009 *
00010 * This program is distributed in the hope that it will be useful,
00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 * GNU General Public License for more details.
00014 *
00015 * You should have received a copy of the GNU General Public License
00016 * along with this program; if not, write to the Free Software Foundation,
00017 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023 
00024 #include <iostream>
00025 using std::cerr;
00026 using std::endl;
00027 
00028 // GUI Page Handling Code
00029 #include "kino_common.h"
00030 #include "page.h"
00031 #include "page_editor.h"
00032 #include "page_capture.h"
00033 #include "page_timeline.h"
00034 #include "page_export.h"
00035 #include "preferences.h"
00036 #include "avi.h"
00037 #include "filehandler.h"
00038 #include "ieee1394io.h"
00039 #include "message.h"
00040 #include "jogshuttle.h"
00041 
00042 extern "C"
00043 {
00044 
00045 #include <sys/stat.h>
00046 #include <sys/time.h>
00047 #include <gtk/gtk.h>
00048 #include <math.h>
00049 
00050 #include "callbacks.h"
00051 #include "support.h"
00052 #include "commands.h"
00053 #include "jogshuttle.h"
00054 #include "gtkenhancedscale.h"
00055 
00056     extern struct navigate_control g_nav_ctl;
00057 
00058     KinoCommon *common = NULL;
00059 
00060     static void getDroppedFiles( GtkWidget * w, GdkDragContext * context,
00061                                  gint x, gint y, GtkSelectionData * data, guint info,
00062                                  guint time, gpointer * extra )
00063     {
00064 
00065         if ( data->data )
00066         {
00067             gchar** urls = g_strsplit( ( gchar* ) data->data, "\n", 0 );
00068             gchar** tmp = urls;
00069             char *argv[ 2 ];
00070 
00071             /* For each URL we are passed */
00072             while ( tmp )
00073             {
00074                 if ( strcmp( *tmp, "" ) == 0 )
00075                     break;
00076                 if ( !strncmp( *tmp, "file:", 5 ) )
00077                 {
00078                     argv[ 1 ] = *tmp + 5;
00079                     argv[ 1 ][ strlen( argv[ 1 ] ) - 1 ] = '\0';
00080                     common->bulkLoad( 2, argv );
00081                 }
00082                 tmp++;
00083             };
00084             g_strfreev( urls );
00085             windowMoved();
00086             gtk_drag_finish( context, TRUE, FALSE, time );
00087         }
00088         gtk_drag_finish( context, FALSE, FALSE, time );
00089     }
00090 
00091     void kinoInitialise( GtkWidget * widget )
00092     {
00093         common = new KinoCommon( widget );
00094         common->setWindowTitle( );
00095         JogShuttle::getInstance();
00096         if ( ! Preferences::getInstance().enableV4L )
00097         {
00098             GtkWidget *widget2 = lookup_widget( widget, "menuitem_v4l" );
00099             gtk_container_remove( GTK_CONTAINER( widget2->parent ), widget2 );
00100             gtk_notebook_remove_page( GTK_NOTEBOOK( lookup_widget( widget, "main_notebook" ) ), PAGE_BTTV );
00101         }
00102 
00103         /* Allow drag from file manager */
00104         static GtkTargetEntry file_targets[] = {
00105                                                    {"text/uri-list", 0, 0}
00106                                                };
00107 
00108         g_signal_connect( G_OBJECT( widget ), "drag_data_received",
00109                           G_CALLBACK( getDroppedFiles ), NULL );
00110         gtk_drag_dest_set( GTK_WIDGET( widget ),
00111                            ( GtkDestDefaults ) ( GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT |
00112                                                  GTK_DEST_DEFAULT_DROP ), file_targets, 1,
00113                            ( GdkDragAction ) ( GDK_ACTION_COPY | GDK_ACTION_MOVE ) );
00114         g_signal_connect( G_OBJECT( lookup_widget( widget, "main_notebook" ) ), "drag_data_received",
00115                           G_CALLBACK( getDroppedFiles ), NULL );
00116         gtk_drag_dest_set( GTK_WIDGET( lookup_widget( widget, "main_notebook" ) ),
00117                            ( GtkDestDefaults ) ( GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT |
00118                                                  GTK_DEST_DEFAULT_DROP ), file_targets, 1,
00119                            ( GdkDragAction ) ( GDK_ACTION_COPY | GDK_ACTION_MOVE ) );
00120         gtk_window_set_default_size( GTK_WINDOW( widget ),
00121             Preferences::getInstance().windowWidth, Preferences::getInstance().windowHeight );
00122         gtk_paned_set_position( GTK_PANED( lookup_widget( widget , "hpaned1" ) ),
00123             Preferences::getInstance().storyboardPosition );
00124 
00125         if ( ! Preferences::getInstance().enablePublish )
00126         {
00127             GtkWidget *widget2 = lookup_widget( widget, "button_publish_project" );
00128             gtk_container_remove( GTK_CONTAINER( widget2->parent ), widget2 );
00129             widget2 = lookup_widget( widget, "button_publish_still" );
00130             gtk_container_remove( GTK_CONTAINER( widget2->parent ), widget2 );
00131             widget2 = lookup_widget( widget, "publish_project" );
00132             gtk_container_remove( GTK_CONTAINER( widget2->parent ), widget2 );
00133             widget2 = lookup_widget( widget, "publish_still" );
00134             gtk_container_remove( GTK_CONTAINER( widget2->parent ), widget2 );
00135         }
00136         common->updateRecentFiles();
00137     }
00138 
00139     void kinoPostInit()
00140     {
00141         common->setPreviewSize( float( Preferences::getInstance().previewSize ) / 10.0, true );
00142         notebookChangePage( PAGE_EDITOR );
00143     }
00144 
00145     gboolean kinoDeactivate()
00146     {
00147         if ( common->exitKino( ) )
00148         {
00149             cerr << "Exiting Kino\n";
00150             gtk_window_get_size( GTK_WINDOW( common->getWidget() ), &Preferences::getInstance().windowWidth,
00151                 &Preferences::getInstance().windowHeight );
00152             Preferences::getInstance().storyboardPosition = gtk_paned_get_position( GTK_PANED(
00153                 lookup_widget( common->getWidget() , "hpaned1" ) ) );
00154             Preferences::getInstance().Save();
00155             gtk_main_quit();
00156         }
00157         return TRUE;
00158     }
00159 
00160     void bulkLoad( int argc, char * argv[] )
00161     {
00162         if ( GetEditorBackup()->Restore( common->getPlayList() ) )
00163         {
00164             common->g_currentFrame = 0;
00165             common->hasListChanged = TRUE;
00166             common->setWindowTitle();
00167             modal_message( _( "Kino has recovered from a crash and restored your undo history!" ) );
00168         }
00169         else
00170         {
00171             common->newFile();
00172             common->bulkLoad( argc, argv );
00173         }
00174     }
00175 
00176     void newFile( )
00177     {
00178         common->newFile();
00179     }
00180 
00181     void openFile( )
00182     {
00183         common->loadFile();
00184     }
00185 
00186     void savePlayListAs( )
00187     {
00188         common->savePlayListAs();
00189     }
00190 
00191     void savePlayList( )
00192     {
00193         common->savePlayList();
00194     }
00195 
00196     void saveFrame( )
00197     {
00198         common->saveFrame();
00199     }
00200 
00201     void insertFile( )
00202     {
00203         common->moveToFrame( common->getPlayList() ->FindStartOfScene( common->g_currentFrame ) );
00204         common->insertFile();
00205     }
00206 
00207     void appendFile( )
00208     {
00209         common->moveToFrame( common->getPlayList() ->FindEndOfScene( common->g_currentFrame ) );
00210         common->appendFile();
00211     }
00212 
00213     void pageStart( int page )
00214     {
00215         common->setCurrentPage( page );
00216     }
00217 
00218     int moveToFrame( int frame )
00219     {
00220         return common->moveToFrame( frame );
00221     }
00222     
00223     int moveByFrames( int offs )
00224     {
00225         return common->moveByFrames( offs );
00226     }
00227 
00228     void videoStart( )
00229     {
00230         common->videoStartOfMovie();
00231     }
00232 
00233     void videoPreviousScene( )
00234     {
00235         common->videoPreviousScene();
00236     }
00237 
00238     void videoStartOfScene( )
00239     {
00240         common->videoStartOfScene();
00241     }
00242 
00243     void videoRewind( )
00244     {
00245         common->videoRewind();
00246     }
00247 
00248     void videoBack()
00249     {
00250         common->videoBack(-1);
00251     }
00252     void videoBackBy(int step)
00253     {
00254         common->videoBack(step);
00255     }
00256 
00257     void videoPlay( )
00258     {
00259         common->videoPlay();
00260     }
00261 
00262     void videoForward()
00263     {
00264         common->videoForward(1);
00265     }
00266     void videoForwardBy(int step)
00267     {
00268         common->videoForward(step);
00269     }
00270 
00271     void videoFastForward( )
00272     {
00273         common->videoFastForward();
00274     }
00275 
00276     void videoNextScene( )
00277     {
00278         common->videoNextScene();
00279     }
00280 
00281     void videoEndOfScene( )
00282     {
00283         common->videoEndOfScene();
00284     }
00285 
00286     void videoEndOfMovie( )
00287     {
00288         common->videoEndOfMovie();
00289     }
00290 
00291     void videoStop( )
00292     {
00293         common->videoStop();
00294     }
00295 
00296     void videoPause( )
00297     {
00298         common->videoPause();
00299     }
00300 
00301     void videoShuttle( int angle )
00302     {
00303         common->videoShuttle( angle );
00304     }
00305 
00306     void windowMoved()
00307     {
00308         if ( common )
00309             common->windowMoved();
00310     }
00311 
00312     void visibilityChanged( gboolean visible )
00313     {
00314         common->visibilityChanged( visible );
00315     }
00316 
00317     void notebookChangePage( int page )
00318     {
00319         common->changePageRequest( page );
00320     }
00321 
00322     gboolean processKeyboard( GdkEventKey * event )
00323     {
00324         // To avoid problems with repeat keys only process
00325         // top of the event queue key presses - issue is that
00326         // we don't know if any pending event is actually a
00327         // keypress... think all key press should move over to
00328         // a snoop, but even then.. dunno if that'll help
00329         if ( Preferences::getInstance().disableKeyRepeat && gdk_events_pending() )
00330             return TRUE;
00331 
00332         return common->processKeyboard( event );
00333     }
00334 
00335     void processCommand( char * command )
00336     {
00337         if ( strcmp( command, "Ctrl+W" ) == 0 )
00338             publishPlayList();
00339         else
00340             common->processCommand( command );
00341     }
00342 
00343     void selectScene( int i )
00344     {
00345         common->selectScene( i );
00346     }
00347 
00348     void startCapture( void )
00349     {
00350         common->getPageCapture() ->startCapture();
00351     }
00352 
00353     void stopCapture( void )
00354     {
00355         common->getPageCapture() ->stopCapture();
00356     }
00357 
00358     void setPreviewSize( float factor )
00359     {
00360         common->setPreviewSize( factor );
00361     }
00362 
00363     void previewExport( void )
00364     {
00365         common->getPageExport() ->previewExport();
00366     }
00367 
00368     void startExport( void )
00369     {
00370         common->getPageExport() ->startExport();
00371     }
00372     void stopExport( void )
00373     {
00374         common->getPageExport() ->stopExport();
00375     }
00376 
00377     void pauseExport( void )
00378     {
00379         common->getPageExport() ->pauseExport();
00380     }
00381 
00382     void setExportMode( int mode )
00383     {
00384         common->getPageExport() ->setCurrentMode( mode );
00385     }
00386 
00387     void RefreshBar( GtkWidget * drawingarea )
00388     {
00389         common->getPageEditor() ->DrawBar( common->g_currentFrame );
00390     }
00391 
00392     void setMoreInfo( int state )
00393     {
00394         common->setMoreInfo( state == 1 );
00395         Frame &frame = *( GetFramePool( ) ->GetFrame( ) );
00396         common->showFrameMoreInfo( frame, NULL );
00397         GetFramePool( ) ->DoneWithFrame( &frame );
00398         common->moveToFrame();
00399     }
00400 
00401     void setTimeFormat( int format )
00402     {
00403         common->setTimeFormat( static_cast< SMIL::Time::TimeFormat >( format ) );
00404     }
00405 
00406     void publishPlayList( void )
00407     {
00408         common->publishPlayList( );
00409     }
00410 
00411     void publishFrame( void )
00412     {
00413         common->publishFrame( );
00414     }
00415     
00416     void startJogShuttle( void )
00417     {
00418         JogShuttle::getInstance().start();
00419     }
00420     
00421     void showHelp( const char *page )
00422     {
00423         extern char* g_help_language;
00424         std::string cmd = "\"" DATADIR "/kino/scripts/help.sh\" \"file://" DATADIR "/kino/help/";
00425         if ( page == NULL || strcmp( page, "" ) == 0 )
00426             page = common->getCurrentPage()->getHelpPage().c_str();
00427         cmd += std::string( g_help_language ) + std::string( "\" \"" ) + std::string( page ) + "\" &";
00428         system( cmd.c_str() );
00429     }
00430     
00431     void handleMouseScroll( GdkEvent *event )
00432     {
00433         if ( Preferences::getInstance().enableJogShuttle )
00434             return;
00435         
00436         if ( event->scroll.state & GDK_SHIFT_MASK )
00437         {
00438             if ( event->scroll.direction == GDK_SCROLL_UP )
00439                 videoBack( );
00440             else if ( event->scroll.direction == GDK_SCROLL_DOWN )
00441                 videoForward( );
00442         }
00443         else if ( event->scroll.state & GDK_CONTROL_MASK )
00444         {
00445             int speedTable[] = {
00446                 0,
00447                 8,  10, 16, 20, 33, 50, 75,
00448                 100,
00449                 200, 300, 400, 500, 800, 1200,
00450                 3001 };
00451             int i = 0;
00452             int speed;
00453             int direction;
00454     
00455             if ( g_nav_ctl.active == FALSE )
00456             {
00457                 speed = 8;
00458                 direction = ( event->scroll.direction == GDK_SCROLL_UP ? -1 : 1 );
00459             }
00460             else if ( g_nav_ctl.step == 0 )
00461             {
00462                 speed = 100 / ( g_nav_ctl.rate < 0 ? -g_nav_ctl.rate : g_nav_ctl.rate );
00463                 speed = speed == 100 ? 75 : speed;
00464                 direction = g_nav_ctl.rate < 0 ? -1 : 1;
00465             }
00466             else
00467             {
00468                 speed = ( g_nav_ctl.step < 0 ? -g_nav_ctl.step : g_nav_ctl.step ) * 100;
00469                 direction = g_nav_ctl.step < 0 ? -1 : 1;
00470             }
00471             
00472             while ( i < 16 && speedTable[ i ] < speed )
00473                 ++i;
00474             
00475             i *= direction;
00476             //fprintf( stderr, "speed %d direction %d i %d\n", speed, direction, i );
00477             
00478             if ( event->scroll.direction == GDK_SCROLL_UP )
00479                 videoShuttle( -- i );
00480             else if ( event->scroll.direction == GDK_SCROLL_DOWN )
00481                 videoShuttle( ++ i );
00482         }
00483         else
00484         {
00485             if ( event->scroll.direction == GDK_SCROLL_UP )
00486                 videoBackBy( -10 );
00487             else if ( event->scroll.direction == GDK_SCROLL_DOWN )
00488                 videoForwardBy( 10 );
00489         }
00490     }
00491 
00492     int kino2raw( char* filename, char* option )
00493     {
00494         try
00495         {
00496             PlayList playlist;
00497             Frame frame;
00498             AudioInfo info;
00499     
00500             if ( playlist.LoadPlayList( filename ) )
00501             {
00502                 const double outputRate = 32000;
00503                 playlist.GetFrame( 0, frame );
00504 
00505                 if ( option )
00506                 {
00507                     if ( strcmp( option, "aspect" ) == 0 )
00508                     {
00509                         std::cout << ( frame.IsWide() ? "16:9" : "4:3" ) << std::endl;
00510                     }
00511                     else if ( strcmp( option, "normalisation" ) == 0 )
00512                     {
00513                         std::cout << ( frame.IsPAL() ? "pal" : "ntsc" ) << std::endl;
00514                     }
00515                     return 0;
00516                 }
00517 
00518                 frame.GetAudioInfo( info );
00519                 info.frequency = int( outputRate );
00520                 // Determine correct amount of audio for duration
00521                 double adjustedRate = 0.0;
00522                 {
00523                     double seconds = double( playlist.GetNumFrames() ) / frame.GetFrameRate();
00524                     int64_t idealSamples = int64_t( seconds * outputRate + 0.5 );
00525                     int64_t actualSamples = 0;
00526                     int n = -1, frameNum = 0, previousProgress = -1;
00527                     AsyncAudioResample<int16_ne_t,int16_le_t> resampler(
00528                         AUDIO_RESAMPLE_SRC_SINC_FASTEST, &playlist, outputRate, 0, playlist.GetNumFrames() - 1, 1 );
00529                         char buf[ 512 ];
00530 
00531                     // Determine the actual number of samples
00532                     while ( n != 0 )
00533                     {
00534                         n = resampler.Process( outputRate, frame.CalculateNumberSamples( int( outputRate ), frameNum++ ) );
00535                         actualSamples += n;
00536                         int progress = int( double( frameNum ) / playlist.GetNumFrames() * 100 );
00537                         if ( progress != previousProgress )
00538                         {
00539                             previousProgress = progress;
00540                             snprintf( buf, 512, "\r%s (%02d%%)", _("Locking audio"), progress );
00541                             std::cerr << buf;
00542                         }
00543                     }
00544                     adjustedRate = outputRate + ( idealSamples - actualSamples ) / seconds;
00545                     std::cerr << std::endl;
00546                 }
00547 
00548                 // Set up resampling
00549                 int16_le_t *audio_buffers[ 4 ];
00550                 for ( int c = 0; c < 4; c++ )
00551                     audio_buffers[ c ] = new int16_le_t[ 2 * DV_AUDIO_MAX_SAMPLES ];
00552         
00553                 // Create the resampler
00554                 AsyncAudioResample<int16_ne_t,int16_le_t> resampler(
00555                     AUDIO_RESAMPLE_SRC_SINC_BEST_QUALITY, &playlist, adjustedRate, 0, playlist.GetNumFrames() - 1, 1 );
00556                 if ( resampler.IsError() )
00557                 {
00558                     std::cerr << "Resampler error: " << resampler.GetError() << std::endl;
00559                     for ( int c = 0; c < 4; c++ )
00560                         delete[] audio_buffers[ c ];
00561                     return 4;
00562                 }
00563         
00564                 for ( int i = 0; i < playlist.GetNumFrames(); ++i )
00565                 {
00566                     // Resample
00567                     int requestedSamples = frame.CalculateNumberSamples( int( outputRate ), i );
00568 
00569                     playlist.GetFrame( i, frame );
00570                     info.samples = resampler.Process( adjustedRate, requestedSamples );
00571                     if ( info.samples )
00572                     {
00573                         // Deinterleave samples
00574                         int16_le_t *p = resampler.GetOutput();
00575                         for ( int s = 0; s < info.samples; s++ )
00576                             for ( int c = 0; c < info.channels; c++ )
00577                                 audio_buffers[ c ][ s ] = *p++;
00578 
00579                         frame.EncodeAudio( info, audio_buffers );
00580                     }
00581                     if ( !fwrite( frame.data, frame.GetFrameSize(), 1, stdout ) )
00582                     {
00583                         perror( "Failed to write raw DV" );
00584                         for ( int c = 0; c < 4; c++ )
00585                             delete[] audio_buffers[ c ];
00586                         return 2;
00587                     }
00588                 }
00589 
00590                 // Cleanup
00591                 for ( int c = 0; c < 4; c++ )
00592                     delete[] audio_buffers[ c ];
00593             }
00594         }
00595         catch (...)
00596         {
00597             std::cerr << "General Error" << std::endl;
00598             return 3;
00599         }
00600         return 0;
00601     }
00602 
00603 } // extern "C"

Generated on Sun Mar 11 22:11:45 2007 for Kino by  doxygen 1.4.2