From 8ca6d1b8ee0a3e687c57f76e793d1b1688a426f2 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Sun, 21 Jun 2015 15:19:03 -0600 Subject: [PATCH] several bug fixes and minor feature changes: vwindow close while playback active format tools segv in preferences 1 frame video files are stretchable opengl deadlocks reworked added kernel version to dmp file better dialog thread cleanup --- cinelerra-5.0/cinelerra/file.C | 17 +-- cinelerra-5.0/cinelerra/formattools.C | 36 +++++- cinelerra-5.0/cinelerra/main.C | 1 + cinelerra-5.0/cinelerra/mwindow.C | 6 +- cinelerra-5.0/cinelerra/vwindowgui.C | 10 +- cinelerra-5.0/guicast/bcdialog.C | 1 + cinelerra-5.0/guicast/bcsignals.C | 1 + cinelerra-5.0/guicast/bcsynchronous.C | 162 ++++++-------------------- cinelerra-5.0/guicast/bcsynchronous.h | 27 +---- cinelerra-5.0/guicast/mutex.C | 5 + 10 files changed, 91 insertions(+), 175 deletions(-) diff --git a/cinelerra-5.0/cinelerra/file.C b/cinelerra-5.0/cinelerra/file.C index 5e870d42..294c6c6c 100644 --- a/cinelerra-5.0/cinelerra/file.C +++ b/cinelerra-5.0/cinelerra/file.C @@ -795,28 +795,31 @@ int File::open_file(Preferences *preferences, // Reopen file with correct parser and get header. if(file->open_file(rd, wr)) { delete file; - file = 0; + return FILE_NOT_FOUND; } // Set extra writing parameters to mandatory settings. - if(file && wr) { + if( wr ) { if(this->asset->dither) file->set_dither(); } - + if( rd ) { +// one frame image file, no specific length + if( !this->asset->audio_data && this->asset->video_data && + this->asset->video_length == 1 ) + this->asset->video_length = -1; + } // Synchronize header parameters - if(file) { - asset->copy_from(this->asset, 1); + asset->copy_from(this->asset, 1); //asset->dump(); - } if(debug) printf("File::open_file %d file=%p\n", __LINE__, file); // sleep(1); - return file ? FILE_OK : FILE_NOT_FOUND; + return FILE_OK; } void File::delete_temp_samples_buffer() diff --git a/cinelerra-5.0/cinelerra/formattools.C b/cinelerra-5.0/cinelerra/formattools.C index b27409f9..0cf493fa 100644 --- a/cinelerra-5.0/cinelerra/formattools.C +++ b/cinelerra-5.0/cinelerra/formattools.C @@ -52,10 +52,34 @@ FormatTools::FormatTools(MWindow *mwindow, aparams_thread = 0; vparams_thread = 0; channels_tumbler = 0; + audio_switch = 0; + video_switch = 0; path_textbox = 0; path_button = 0; - w = window->get_w(); + format_title = 0; + format_button = 0; + format_text = 0; + audio_title = 0; + audio_switch = 0; + video_title = 0; + video_switch = 0; + channels_title = 0; + channels_button = 0; + multiple_files = 0; file_entries = 0; + w = window->get_w(); + + recording = 0; + use_brender = 0; + do_audio = 0; + do_video = 0; + prompt_audio = 0; + prompt_audio_channels = 0; + prompt_video = 0; + prompt_video_compression = 0; + strategy = 0; + locked_compressor = 0; + video_driver = 0; } FormatTools::~FormatTools() @@ -334,7 +358,7 @@ void FormatTools::update_driver(int driver) void FormatTools::update_format() { - if( do_audio && audio_switch ) { + if( do_audio && prompt_audio && audio_switch ) { asset->audio_data = File::supports_audio(asset->format); audio_switch->update(asset->audio_data); if( !asset->audio_data ) @@ -342,7 +366,7 @@ void FormatTools::update_format() else audio_switch->enable(); } - if( do_video && video_switch ) { + if( do_video && prompt_video && video_switch ) { asset->video_data = File::supports_video(asset->format); video_switch->update(asset->video_data); if( !asset->video_data ) @@ -445,8 +469,10 @@ void FormatTools::update(Asset *asset, int *strategy) if(path_textbox) path_textbox->update(asset->path); format_text->update(File::formattostr(plugindb, asset->format)); - if(do_audio && audio_switch) audio_switch->update(asset->audio_data); - if(do_video && video_switch) video_switch->update(asset->video_data); + if(do_audio && prompt_audio && audio_switch) + audio_switch->update(asset->audio_data); + if(do_video && prompt_video && video_switch) + video_switch->update(asset->video_data); if(strategy) { multiple_files->update(strategy); diff --git a/cinelerra-5.0/cinelerra/main.C b/cinelerra-5.0/cinelerra/main.C index de0743ef..9f9149d8 100644 --- a/cinelerra-5.0/cinelerra/main.C +++ b/cinelerra-5.0/cinelerra/main.C @@ -404,6 +404,7 @@ COPYRIGHT_DATE); // run the program //PRINT_TRACE mwindow.start(); + mwindow.run(); //PRINT_TRACE if( mwindow.reload() ) start_remote_control = diff --git a/cinelerra-5.0/cinelerra/mwindow.C b/cinelerra-5.0/cinelerra/mwindow.C index 40a8b471..1a1d4dba 100644 --- a/cinelerra-5.0/cinelerra/mwindow.C +++ b/cinelerra-5.0/cinelerra/mwindow.C @@ -235,7 +235,6 @@ MWindow::~MWindow() hide_keyframe_guis(); clean_indexes(); save_defaults(); - // Give up and go to a movie // cant run valgrind if this is used // if( !reload_status ) exit(0); @@ -330,8 +329,7 @@ void MWindow::quit(int unlock) interrupt_indexes(); clean_indexes(); save_defaults(); -// This is the last thread to exit - playback_3d->quit(); + gui->set_done(0); if(unlock) gui->lock_window("MWindow::quit"); } @@ -1807,7 +1805,7 @@ ENABLE_BUFFER //PRINT_TRACE gwindow->start(); //PRINT_TRACE - Thread::start(); +// Thread::start(); //PRINT_TRACE playback_3d->start(); //PRINT_TRACE diff --git a/cinelerra-5.0/cinelerra/vwindowgui.C b/cinelerra-5.0/cinelerra/vwindowgui.C index 8fe9f99b..10ad8c87 100644 --- a/cinelerra-5.0/cinelerra/vwindowgui.C +++ b/cinelerra-5.0/cinelerra/vwindowgui.C @@ -79,6 +79,7 @@ VWindowGUI::VWindowGUI(MWindow *mwindow, VWindow *vwindow) VWindowGUI::~VWindowGUI() { + vwindow->playback_engine->interrupt_playback(1); sources.remove_all_objects(); labels.remove_all_objects(); delete canvas; @@ -405,13 +406,8 @@ void VWindowGUI::drag_motion() cursor_y < canvas->y + canvas->h); -printf("VWindowGUI::drag_motion 1 %d %d %d %d %d\n", -__LINE__, -mwindow->session->vcanvas_highlighted, -get_cursor_over_window(), -cursor_x, -cursor_y); - +//printf("VWindowGUI::drag_motion 1 %d %d %d %d %d\n", __LINE__, +// mwindow->session->vcanvas_highlighted, get_cursor_over_window(), cursor_x, cursor_y); if(old_status != mwindow->session->vcanvas_highlighted) canvas->draw_refresh(); diff --git a/cinelerra-5.0/guicast/bcdialog.C b/cinelerra-5.0/guicast/bcdialog.C index 9528abbb..b3501477 100644 --- a/cinelerra-5.0/guicast/bcdialog.C +++ b/cinelerra-5.0/guicast/bcdialog.C @@ -46,6 +46,7 @@ BC_DialogThread::~BC_DialogThread() gui->unlock_window(); } startup_lock->unlock(); + cancel(); join(); delete startup_lock; diff --git a/cinelerra-5.0/guicast/bcsignals.C b/cinelerra-5.0/guicast/bcsignals.C index 2610b2c4..e2a8b149 100644 --- a/cinelerra-5.0/guicast/bcsignals.C +++ b/cinelerra-5.0/guicast/bcsignals.C @@ -863,6 +863,7 @@ static void handle_dump(int n, siginfo_t * info, void *sc) fprintf(fp,"\nMAIN HOOK:\n"); BC_Signals::trap_hook(fp, BC_Signals::trap_data); } + fprintf(fp,"\nVERSION:\n"); bc_copy_textfile(fp,"/proc/version"); fprintf(fp,"\nMEMINFO:\n"); bc_copy_textfile(fp,"/proc/meminfo"); fprintf(fp,"\nMAPS:\n"); bc_copy_textfile(fp,"/proc/%d/maps",pid); fprintf(fp,"\n\n"); diff --git a/cinelerra-5.0/guicast/bcsynchronous.C b/cinelerra-5.0/guicast/bcsynchronous.C index 4ea90a52..671ec0df 100644 --- a/cinelerra-5.0/guicast/bcsynchronous.C +++ b/cinelerra-5.0/guicast/bcsynchronous.C @@ -72,97 +72,6 @@ PBufferID::PBufferID(int window_id, GLXPbuffer glx_pbuffer, GLXContext glx_conte -BC_SynchGarbage::BC_SynchGarbage(BC_Synchronous *synchronous) - : Thread(1, 0, 0) -{ - this->synchronous = synchronous; - more_garbage = new Condition(0, "BC_SynchGarbage::more_garbage", 0); - garbage_lock = new Mutex("BC_SyncGarbage::garbage_lock"); - done = -1; -} - -BC_SynchGarbage::~BC_SynchGarbage() -{ - if( running() ) { - quit(); - join(); - } - garbage.remove_all_objects(); - delete more_garbage; - delete garbage_lock; -} - -void BC_SynchGarbage::send_garbage(BC_SynchronousCommand *command) -{ - garbage_lock->lock("BC_SynchGarbage::send_garbage"); - garbage.append(command); - garbage_lock->unlock(); - more_garbage->unlock(); -} - -void BC_SynchGarbage::handle_garbage() -{ - garbage_lock->lock("BC_SynchGarbage::handle_garbage 0"); - while( !done && garbage.total ) { - BC_SynchronousCommand *command = garbage.get(0); - garbage.remove_number(0); - garbage_lock->unlock(); - - switch(command->command) { - case BC_SynchronousCommand::QUIT: - done = 1; - break; - - case BC_SynchronousCommand::DELETE_WINDOW: - synchronous->delete_window_sync(command); - break; - - case BC_SynchronousCommand::DELETE_PIXMAP: - synchronous->delete_pixmap_sync(command); - break; - - case BC_SynchronousCommand::DELETE_DISPLAY: - synchronous->delete_display_sync(command); - break; - } - - delete command; - garbage_lock->lock("BC_SynchGarbage::handle_garbage 1"); - } - garbage_lock->unlock(); -} - - -void BC_SynchGarbage::start() -{ - done = 0; - Thread::start(); -} - -void BC_SynchGarbage::stop() -{ - if( running() ) { - quit(); - join(); - } -} - -void BC_SynchGarbage::quit() -{ - BC_SynchronousCommand *command = new BC_SynchronousCommand(); - command->command = BC_SynchronousCommand::QUIT; - send_garbage(command); -} - -void BC_SynchGarbage::run() -{ - while( !done ) { - more_garbage->lock("BC_SynchGarbage::run"); - handle_garbage(); - } -} - - BC_SynchronousCommand::BC_SynchronousCommand() { command = BC_SynchronousCommand::NONE; @@ -197,12 +106,11 @@ BC_Synchronous::BC_Synchronous() : Thread(1, 0, 0) { lock_sync = new Mutex("BC_Synchronous::lock_sync"); - sync_garbage = new BC_SynchGarbage(this); - next_command = new Condition(0, "BC_Synchronous::next_command", 0); + next_command = new Condition(0, "BC_Synchronous::next_command", 1); command_lock = new Mutex("BC_Synchronous::command_lock"); table_lock = new Mutex("BC_Synchronous::table_lock"); done = 0; - is_running = 0; + is_started = 0; current_window = 0; BC_WindowBase::get_resources()->set_synchronous(this); } @@ -214,7 +122,6 @@ BC_Synchronous::~BC_Synchronous() join(); } commands.remove_all_objects(); - delete sync_garbage; delete lock_sync; delete next_command; delete command_lock; @@ -226,23 +133,11 @@ void BC_Synchronous::sync_lock(const char *cp) lock_sync->lock(cp); } -void BC_Synchronous::sync_lock(Display *display, const char *cp) -{ - // get both display lock and sync_lock - XLockDisplay(display); - while( lock_sync->trylock(cp) ) { - XUnlockDisplay(display); - usleep(100000); - XLockDisplay(display); - } -} - void BC_Synchronous::sync_unlock() { lock_sync->unlock(); } -void sync_unlock(); BC_SynchronousCommand* BC_Synchronous::new_command() { return new BC_SynchronousCommand(); @@ -254,18 +149,22 @@ void BC_Synchronous::create_objects() void BC_Synchronous::start() { - sync_garbage->start(); - run(); + is_started = 1; + //run(); + Thread::start(); } void BC_Synchronous::quit() { + if( !is_started ) return; + is_started = 0; BC_SynchronousCommand *command = new_command(); command->command = BC_SynchronousCommand::QUIT; command_lock->lock("BC_Synchronous::quit"); commands.append(command); command_lock->unlock(); next_command->unlock(); + command->command_done->lock("BC_Synchronous::quit"); } long BC_Synchronous::send_command(BC_SynchronousCommand *command) @@ -287,9 +186,8 @@ long BC_Synchronous::send_command(BC_SynchronousCommand *command) void BC_Synchronous::run() { - is_running = 1; + sync_lock("BC_Synchronous::run 0"); while(!done) { - next_command->lock("BC_Synchronous::run"); command_lock->lock("BC_Synchronous::run"); BC_SynchronousCommand *command = 0; if(commands.total) { @@ -297,28 +195,43 @@ void BC_Synchronous::run() commands.remove_number(0); } command_lock->unlock(); - if( !command ) continue; - + if( !command ) { + sync_unlock(); + next_command->lock("BC_Synchronous::run"); + sync_lock("BC_Synchronous::run 1"); + continue; + } //printf("BC_Synchronous::run %d\n", command->command); handle_command_base(command); } - is_running = 0; + sync_unlock(); } void BC_Synchronous::handle_command_base(BC_SynchronousCommand *command) { - sync_lock("BC_Synchronous::handle_command_base"); switch(command->command) { case BC_SynchronousCommand::QUIT: done = 1; break; + case BC_SynchronousCommand::DELETE_WINDOW: + delete_window_sync(command); + break; + + case BC_SynchronousCommand::DELETE_PIXMAP: + delete_pixmap_sync(command); + break; + + case BC_SynchronousCommand::DELETE_DISPLAY: + delete_display_sync(command); + break; + default: handle_command(command); break; } + command->command_done->unlock(); - sync_unlock(); } void BC_Synchronous::handle_command(BC_SynchronousCommand *command) @@ -449,9 +362,6 @@ void BC_Synchronous::dump_shader(unsigned int handle) if(!got_it) printf("BC_Synchronous::dump_shader couldn't find %d\n", handle); } -// has to run in sync_garbage thread, because mwindow playback_3d -// thread ends before all windows are deleted. runs as synchronous -// command since resources must be freed immediately void BC_Synchronous::delete_window(BC_WindowBase *window) { #ifdef HAVE_GL @@ -476,7 +386,7 @@ void BC_Synchronous::delete_window_sync(BC_SynchronousCommand *command) Window win = command->win; GLXWindow glx_win = command->glx_win; GLXContext glx_context = command->glx_context; - sync_lock(display, "BC_Synchronous::delete_window_sync"); + XLockDisplay(display); //int debug = 0; // texture ID's are unique to different contexts @@ -529,7 +439,6 @@ void BC_Synchronous::delete_window_sync(BC_SynchronousCommand *command) glXDestroyContext(display, glx_context); command->command_done->unlock(); XUnlockDisplay(display); - sync_unlock(); #endif } @@ -548,10 +457,9 @@ void BC_Synchronous::delete_display_sync(BC_SynchronousCommand *command) { #ifdef HAVE_GL Display *display = command->display; - sync_lock(display, "BC_Synchronous::delete_display_sync"); + XLockDisplay(display); XUnlockDisplay(display); XCloseDisplay(display); - sync_unlock(); #endif } @@ -633,12 +541,11 @@ void BC_Synchronous::delete_pixmap_sync(BC_SynchronousCommand *command) #ifdef HAVE_GL Display *display = command->display; GLXWindow glx_win = command->glx_win; - sync_lock(display, "BC_Synchronous::delete_pixmap_sync"); + XLockDisplay(display); glXMakeContextCurrent(display, glx_win, glx_win, command->glx_context); glXDestroyContext(display, command->glx_context); glXDestroyGLXPixmap(display, command->glx_pixmap); XUnlockDisplay(display); - sync_unlock(); #endif } @@ -646,7 +553,10 @@ void BC_Synchronous::delete_pixmap_sync(BC_SynchronousCommand *command) void BC_Synchronous::send_garbage(BC_SynchronousCommand *command) { - sync_garbage->send_garbage(command); + command_lock->lock("BC_Synchronous::send_garbage"); + commands.append(command); + command_lock->unlock(); + next_command->unlock(); } BC_WindowBase* BC_Synchronous::get_window() diff --git a/cinelerra-5.0/guicast/bcsynchronous.h b/cinelerra-5.0/guicast/bcsynchronous.h index 0afb610e..ba347b78 100644 --- a/cinelerra-5.0/guicast/bcsynchronous.h +++ b/cinelerra-5.0/guicast/bcsynchronous.h @@ -146,31 +146,8 @@ public: #endif }; -class BC_Synchronous; - -class BC_SynchGarbage : public Thread -{ -public: - BC_SynchGarbage(BC_Synchronous*sync); - ~BC_SynchGarbage(); - - void send_garbage(BC_SynchronousCommand *command); - void handle_garbage(); - void start(); - void run(); - void quit(); - void stop(); - - BC_Synchronous *synchronous; - Condition *more_garbage; - Mutex *garbage_lock; - ArrayList garbage; - int done; -}; - class BC_Synchronous : public Thread { - BC_SynchGarbage *sync_garbage; public: BC_Synchronous(); virtual ~BC_Synchronous(); @@ -180,7 +157,6 @@ public: friend class BC_PBuffer; friend class BC_Pixmap; friend class BC_Texture; - friend class BC_SynchGarbage; void quit(); // Must be called after constructor to create inherited objects. @@ -266,7 +242,6 @@ private: Mutex *lock_sync; void sync_lock(const char *cp=0); - void sync_lock(Display *display, const char *cp); void sync_unlock(); void get_display_sync(Display *display, const char *cp); @@ -282,7 +257,7 @@ private: int done; // Command stack ArrayList commands; - int is_running; + int is_started; // The window the opengl context is currently bound to. // Set by BC_WindowBase::enable_opengl. BC_WindowBase *current_window; diff --git a/cinelerra-5.0/guicast/mutex.C b/cinelerra-5.0/guicast/mutex.C index 9b993fe8..a4a6e21f 100644 --- a/cinelerra-5.0/guicast/mutex.C +++ b/cinelerra-5.0/guicast/mutex.C @@ -19,11 +19,15 @@ * */ +#include +#include + #ifndef NO_GUICAST #include "bcsignals.h" #endif #include "mutex.h" + Mutex::Mutex(const char *title, int recursive) { this->title = title; @@ -122,6 +126,7 @@ int Mutex::unlock() int Mutex::trylock(const char *location) { + if( count ) return EBUSY; int ret = pthread_mutex_trylock(&mutex); if( ret ) return ret; -- 2.26.2