transportque tweaks for shuttle, fixes videoscope/undo hangs
authorGood Guy <[email protected]>
Sun, 17 Feb 2019 00:29:27 +0000 (17:29 -0700)
committerGood Guy <[email protected]>
Sun, 17 Feb 2019 00:29:27 +0000 (17:29 -0700)
cinelerra-5.1/cinelerra/cwindowgui.C
cinelerra-5.1/cinelerra/playbackengine.C
cinelerra-5.1/cinelerra/playbackengine.h
cinelerra-5.1/cinelerra/playtransport.C
cinelerra-5.1/cinelerra/renderengine.C

index a8472145fd4463c749a683bac6b1e5a18253d3e1..8cf018446e68c13b330edcd77ff78b673522d561 100644 (file)
@@ -572,10 +572,7 @@ int CWindowGUI::keypress_event()
 
        if( !result && cwindow_operation < 0 && ctrl_down() && shift_down() ) {
                switch( get_keypress() ) {
-               case KEY_F1:
-               case KEY_F2:
-               case KEY_F3:
-               case KEY_F4:
+               case KEY_F1 ... KEY_F4: // mainmenu, load layout
                        resend_event(mwindow->gui);
                        result = 1;
                        break;
index 16f6bd7a73c65bda3ffd6065186063eefe206f58..364b8c9ed243d25427caca1e3f0710773eb992b1 100644 (file)
@@ -61,6 +61,7 @@ PlaybackEngine::PlaybackEngine(MWindow *mwindow, Canvas *output)
        stop_command->realtime = 1;
        sent_command = new TransportCommand();
        sent_command->command = -1;
+       send_active = 0;
        tracking_lock = new Mutex("PlaybackEngine::tracking_lock");
        renderengine_lock = new Mutex("PlaybackEngine::renderengine_lock");
        tracking_done = new Condition(1, "PlaybackEngine::tracking_done");
@@ -358,10 +359,14 @@ void PlaybackEngine::run()
 // Wait for current command to finish
                output_lock->lock("PlaybackEngine::run");
                if( done ) break;
-//printf("sent command=%d\n", sent_command->command);
 // Read the new command
+               input_lock->lock("PlaybackEngine::run");
                command->copy_from(sent_command);
+//printf("sent command=%d\n", sent_command->command);
+               int active = this->send_active;
+               this->send_active = 0;
                input_lock->unlock();
+               if( !active ) continue;
 
                interrupt_playback(0);
                wait_render_engine();
@@ -415,8 +420,10 @@ void PlaybackEngine::stop_playback(int wait_tracking)
 {
        transport_stop(wait_tracking);
        renderengine_lock->lock("PlaybackEngine::stop_playback");
-       if( render_engine )
+       if( render_engine ) {
+               render_engine->interrupt_playback();
                render_engine->wait_done();
+       }
        renderengine_lock->unlock();
 }
 
@@ -425,13 +432,14 @@ void PlaybackEngine::send_command(int command, EDL *edl, int wait_tracking, int
 {
 //printf("PlaybackEngine::send_command 1 %d\n", command);
 // Stop requires transferring the output buffer to a refresh buffer.
-       int do_stop = 0, do_resume = 0;
+       int do_stop = 0;
        int curr_command = this->command->command;
        int curr_single_frame = TransportCommand::single_frame(curr_command);
        int curr_audio = this->command->toggle_audio ?
                !curr_single_frame : curr_single_frame;
        int single_frame = TransportCommand::single_frame(command);
        int next_audio = next_command->toggle_audio ? !single_frame : single_frame;
+       float next_speed = next_command->speed;
 
 // Dispatch command
        switch( command ) {
@@ -445,17 +453,17 @@ void PlaybackEngine::send_command(int command, EDL *edl, int wait_tracking, int
        case FAST_FWD:
        case CURRENT_FRAME:
        case LAST_FRAME:
-               if( curr_command == command && !next_command->speed &&
-                   !curr_single_frame && curr_audio == next_audio ) {
+// run shuttle as no prev command
+               if( next_speed ) curr_command = COMMAND_NONE;
 // Same direction pressed twice, not shuttle, and no change in audio state,  Stop
-                       do_stop = 1;
-                       break;
-               }
+               if( curr_command == command && !curr_single_frame &&
+                   curr_audio == next_audio ) { do_stop = 1;  break; }
+
 // Resume or change direction
                switch( curr_command ) {
                default:
                        transport_stop(0);
-                       do_resume = 1;
+                       next_command->resume = 1;
 // fall through
                case STOP:
                case COMMAND_NONE:
@@ -464,7 +472,6 @@ void PlaybackEngine::send_command(int command, EDL *edl, int wait_tracking, int
                case CURRENT_FRAME:
                case LAST_FRAME:
                        next_command->realtime = 1;
-                       next_command->resume = do_resume;
 // Start from scratch
                        transport_command(command, CHANGE_NONE, edl, use_inout);
                        break;
@@ -486,15 +493,16 @@ void PlaybackEngine::send_command(int command, EDL *edl, int wait_tracking, int
 
 int PlaybackEngine::put_command(TransportCommand *command, int reset)
 {
-// commands can deadlock updating tracking,meters,clock...
-       int mlocked = mwindow->gui->break_lock();
        input_lock->lock("PlaybackEngine::put_command");
+       int prev_change_type = sent_command->change_type;
        sent_command->copy_from(command);
-       if( reset )
-               command->reset();
+// run only last command, sum change type
+       if( send_active )
+               sent_command->change_type |= prev_change_type;
+       send_active = 1;
+       if( reset ) command->reset();
        output_lock->unlock();
-       if( mlocked )
-               mwindow->gui->lock_window("PlaybackEngine::put_command");
+       input_lock->unlock();
        return 0;
 }
 
index 62616822b7ccf3c0012d649972419eb2acab8434..0a717f117f3bc0ba6e22a6ad09424d581da7b59f 100644 (file)
@@ -126,6 +126,7 @@ public:
 
        int done;
        int is_playing_back;
+       int send_active;
 
 // General purpose debugging register
        int debug;
index 4cb51aa75b7ce068848d30fa4cd5414cb2047aee..569fdbe2150b9d81502cb3bfdb7c25d8b4d509a8 100644 (file)
@@ -132,7 +132,7 @@ int PlayTransport::get_w()
 
 int PlayTransport::is_stopped()
 {
-       return engine->command->command == STOP ? 1 : 0;
+       return engine->is_playing_back ? 0 : 1;
 }
 
 int PlayTransport::flip_vertical(int vertical, int &x, int &y)
index 9b640d20e2ada9e5467960654c4fd1f9f267015b..faba961583a5ce347196f77099a9d006f9a6960e 100644 (file)
@@ -398,8 +398,10 @@ void RenderEngine::update_framerate(float framerate)
 
 void RenderEngine::wait_render_threads()
 {
+       interrupt_lock->unlock();
        if( do_audio ) arender->Thread::join();
        if( do_video ) vrender->Thread::join();
+       interrupt_lock->lock("RenderEngine::wait_render_threads");
 }
 
 void RenderEngine::interrupt_playback()
@@ -460,10 +462,8 @@ void RenderEngine::run()
 {
        render_active->lock("RenderEngine::run");
 
-       interrupt_lock->unlock();
        start_render_threads();
        wait_render_threads();
-       interrupt_lock->lock("RenderEngine::wait_render_threads");
 
        close_output();
 
@@ -473,8 +473,7 @@ void RenderEngine::run()
                        command->get_direction() == PLAY_FORWARD ?
                                command->end_position :
                                command->start_position;
-               playback_engine->command->command = STOP;
-               if( playback_engine->is_playing_back && command->displacement ) {
+               if( command->displacement ) {
                        position -= 1./command->get_edl()->session->frame_rate;
                        if( position < 0 ) position = 0;
                }