From aa9374b902768107ebda0cffe739325ffed372f6 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Wed, 10 Apr 2019 16:31:32 -0600 Subject: [PATCH] no /. in ffmpeg init_decode segv, build index fix audio wave, stop playback state bug, camera/projector jitter fixes, ffmpeg pal100bars segv --- cinelerra-5.1/cinelerra/canvas.C | 16 ++-- cinelerra-5.1/cinelerra/canvas.h | 2 +- cinelerra-5.1/cinelerra/cwindow.C | 3 + cinelerra-5.1/cinelerra/cwindowgui.C | 76 ++++++------------- cinelerra-5.1/cinelerra/ffmpeg.C | 6 +- cinelerra-5.1/cinelerra/mainindexes.C | 1 - cinelerra-5.1/cinelerra/mwindow.C | 6 ++ cinelerra-5.1/cinelerra/mwindow.h | 1 + cinelerra-5.1/cinelerra/playback3d.C | 17 +++++ cinelerra-5.1/cinelerra/playback3d.h | 5 ++ cinelerra-5.1/cinelerra/playbackengine.C | 22 +++--- cinelerra-5.1/cinelerra/playbackengine.h | 1 + cinelerra-5.1/cinelerra/playtransport.C | 2 +- cinelerra-5.1/cinelerra/renderengine.C | 2 - cinelerra-5.1/cinelerra/renderengine.h | 2 - cinelerra-5.1/cinelerra/vdevicex11.C | 2 - cinelerra-5.1/info/plugins.txt | 4 +- .../thirdparty/src/ffmpeg-4.1.patch5 | 29 +++++++ 18 files changed, 114 insertions(+), 83 deletions(-) create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-4.1.patch5 diff --git a/cinelerra-5.1/cinelerra/canvas.C b/cinelerra-5.1/cinelerra/canvas.C index 85316aaa..a01d1b9e 100644 --- a/cinelerra-5.1/cinelerra/canvas.C +++ b/cinelerra-5.1/cinelerra/canvas.C @@ -900,20 +900,16 @@ void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame) refresh_frame->transfer_from(output_frame, -1); } - -void Canvas::clear(int flush) +void Canvas::clear(int flash) { - if( refresh_frame ) - refresh_frame->clear_frame(); - BC_WindowBase *wdw = get_canvas(); - if( !wdw ) return; - wdw->set_bg_color(BLACK); - wdw->clear_box(0,0, wdw->get_w(), wdw->get_h()); - wdw->flash(flush); + BC_WindowBase *cwdw = get_canvas(); + if( !cwdw ) return; + cwdw->set_bg_color(BLACK); + cwdw->clear_box(0,0, cwdw->get_w(), cwdw->get_h()); + if( flash ) cwdw->flash(); } - CanvasOutput::CanvasOutput(Canvas *canvas, int x, int y, diff --git a/cinelerra-5.1/cinelerra/canvas.h b/cinelerra-5.1/cinelerra/canvas.h index 1b1adb1d..2fd2a23e 100644 --- a/cinelerra-5.1/cinelerra/canvas.h +++ b/cinelerra-5.1/cinelerra/canvas.h @@ -134,7 +134,7 @@ public: void update_refresh(VideoDevice *device, VFrame *output_frame); // Redraws the refresh_frame virtual void draw_refresh(int flush = 1) {}; - virtual void clear(int flush=1); + virtual void clear(int flash=1); // Get top left offset of canvas relative to output. // Normally negative. Can be positive if output is smaller than canvas. diff --git a/cinelerra-5.1/cinelerra/cwindow.C b/cinelerra-5.1/cinelerra/cwindow.C index 1511867b..5285fd4e 100644 --- a/cinelerra-5.1/cinelerra/cwindow.C +++ b/cinelerra-5.1/cinelerra/cwindow.C @@ -59,6 +59,9 @@ CWindow::CWindow(MWindow *mwindow) : Thread(1, 0, 0) { this->mwindow = mwindow; + this->playback_engine = 0; + this->playback_cursor = 0; + this->gui = 0; } diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index a93964c4..7ebdd6e4 100644 --- a/cinelerra-5.1/cinelerra/cwindowgui.C +++ b/cinelerra-5.1/cinelerra/cwindowgui.C @@ -681,7 +681,7 @@ void CWindowGUI::sync_parameters(int change_type, int redraw, int overlay) mwindow->sync_parameters(change_type); } if( overlay ) { - mwindow->gui->lock_window("CWindow::camera_keyframe"); + mwindow->gui->lock_window("CWindowGUI::sync_parameters"); mwindow->gui->draw_overlays(1); mwindow->gui->unlock_window(); } @@ -1125,43 +1125,29 @@ float CWindowCanvas::get_zoom() void CWindowCanvas::draw_refresh(int flush) { - if(get_canvas() && !get_canvas()->get_video_on()) - { - - if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0) - { + if( get_canvas() && !get_canvas()->get_video_on() ) { + clear(0); + if( mwindow->uses_opengl() ) { + get_canvas()->unlock_window(); + mwindow->playback_3d->finish_output(); + get_canvas()->lock_window("CWindowCanvas::draw_refresh"); + get_canvas()->flush(); + get_canvas()->sync_display(); + } + if( refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0 ) { float in_x1, in_y1, in_x2, in_y2; float out_x1, out_y1, out_x2, out_y2; get_transfers(mwindow->edl, - in_x1, - in_y1, - in_x2, - in_y2, - out_x1, - out_y1, - out_x2, - out_y2); - - if(!EQUIV(out_x1, 0) || - !EQUIV(out_y1, 0) || - !EQUIV(out_x2, get_canvas()->get_w()) || - !EQUIV(out_y2, get_canvas()->get_h())) - { - get_canvas()->clear_box(0, - 0, - get_canvas()->get_w(), - get_canvas()->get_h()); - } + in_x1, in_y1, in_x2, in_y2, + out_x1, out_y1, out_x2, out_y2); + //printf("CWindowCanvas::draw_refresh %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", //in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2); - if(out_x2 > out_x1 && - out_y2 > out_y1 && - in_x2 > in_x1 && - in_y2 > in_y1) - { + if( out_x2 > out_x1 && out_y2 > out_y1 && + in_x2 > in_x1 && in_y2 > in_y1 ) { // input scaled from session to refresh frame coordinates int ow = get_output_w(mwindow->edl); int oh = get_output_h(mwindow->edl); @@ -1174,29 +1160,17 @@ void CWindowCanvas::draw_refresh(int flush) // Can't use OpenGL here because it is called asynchronously of the // playback operation. get_canvas()->draw_vframe(refresh_frame, - (int)out_x1, - (int)out_y1, + (int)out_x1, (int)out_y1, (int)(out_x2 - out_x1), (int)(out_y2 - out_y1), - (int)in_x1, - (int)in_y1, + (int)in_x1, (int)in_y1, (int)(in_x2 - in_x1), (int)(in_y2 - in_y1), 0); } } - else - { - get_canvas()->clear_box(0, - 0, - get_canvas()->get_w(), - get_canvas()->get_h()); - } - +//usleep(10000); draw_overlays(); -// allow last opengl write to complete before redraw -// tried sync_display, glFlush, glxMake*Current(0..) -usleep(20000); get_canvas()->flash(flush); } //printf("CWindowCanvas::draw_refresh 10\n"); @@ -2891,13 +2865,13 @@ void CWindowCanvas::draw_bezier(int do_camera) int64_t position = track->to_units( mwindow->edl->local_session->get_selectionstart(1), 0); - if( do_camera ) { - track->automation->get_camera(¢er_x, - ¢er_y, ¢er_z, position, PLAY_FORWARD); +// if( do_camera ) { +// track->automation->get_camera(¢er_x, +// ¢er_y, ¢er_z, position, PLAY_FORWARD); // follow image, not camera - center_x = -center_x * center_z; center_y = -center_y * center_z; - } - else +// center_x = -center_x * center_z; center_y = -center_y * center_z; +// } +// else track->automation->get_projector(¢er_x, ¢er_y, ¢er_z, position, PLAY_FORWARD); diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index d13cf8b3..0c351e5a 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -1948,8 +1948,10 @@ int FFMPEG::init_decoder(const char *filename) ff_lock("FFMPEG::init_decoder"); av_register_all(); char file_opts[BCTEXTLEN]; - char *bp = strrchr(strcpy(file_opts, filename), '/'); - char *sp = strrchr(!bp ? file_opts : bp, '.'); + strcpy(file_opts, filename); + char *bp = strrchr(file_opts, '/'); + if( !bp ) bp = file_opts; + char *sp = strrchr(bp, '.'); if( !sp ) sp = bp + strlen(bp); FILE *fp = 0; AVInputFormat *ifmt = 0; diff --git a/cinelerra-5.1/cinelerra/mainindexes.C b/cinelerra-5.1/cinelerra/mainindexes.C index 0183c62a..05812bb7 100644 --- a/cinelerra-5.1/cinelerra/mainindexes.C +++ b/cinelerra-5.1/cinelerra/mainindexes.C @@ -109,7 +109,6 @@ void MainIndexes::stop_loop() void MainIndexes::start_build() { - if( !current_indexables.size() ) return; //printf("MainIndexes::start_build 1\n"); interrupt_flag = 0; // Locked up when indexes were already being built and an indexable was diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 09e363cd..66b37fa9 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -2730,6 +2730,12 @@ void MWindow::create_objects(int want_gui, BC_WindowBase::get_resources()->vframe_shm = 1; } +int MWindow::uses_opengl() +{ + if( !playback_3d || !playback_3d->running() ) return 0; + PlaybackConfig *playback_config = edl->session->playback_config; + return playback_config->vconfig->driver == PLAYBACK_X11_GL ? 1 : 0; +} void MWindow::show_splash() { diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index 8a23118a..3256ace6 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -115,6 +115,7 @@ public: void create_objects(int want_gui, int want_new, char *config_path); + int uses_opengl(); void show_splash(); void hide_splash(); void start(); diff --git a/cinelerra-5.1/cinelerra/playback3d.C b/cinelerra-5.1/cinelerra/playback3d.C index 2ca2a4c6..24f8cf70 100644 --- a/cinelerra-5.1/cinelerra/playback3d.C +++ b/cinelerra-5.1/cinelerra/playback3d.C @@ -402,6 +402,10 @@ void Playback3D::handle_command(BC_SynchronousCommand *command) write_buffer_sync((Playback3DCommand*)command); break; + case Playback3DCommand::FINISH_OUTPUT: + finish_output_sync((Playback3DCommand*)command); + break; + case Playback3DCommand::CLEAR_OUTPUT: clear_output_sync((Playback3DCommand*)command); break; @@ -765,6 +769,19 @@ void Playback3D::init_frame(Playback3DCommand *command, int is_yuv) } +void Playback3D::finish_output() +{ + Playback3DCommand command; + command.command = Playback3DCommand::FINISH_OUTPUT; + send_command(&command); +} + +void Playback3D::finish_output_sync(Playback3DCommand *command) +{ + glFinish(); +} + + void Playback3D::clear_output(Canvas *canvas, VFrame *output) { Playback3DCommand command; diff --git a/cinelerra-5.1/cinelerra/playback3d.h b/cinelerra-5.1/cinelerra/playback3d.h index 4388624a..1f3dd59a 100644 --- a/cinelerra-5.1/cinelerra/playback3d.h +++ b/cinelerra-5.1/cinelerra/playback3d.h @@ -205,6 +205,7 @@ public: { // 5 WRITE_BUFFER = LAST_COMMAND, + FINISH_OUTPUT, CLEAR_OUTPUT, OVERLAY, DO_FADE, @@ -278,6 +279,9 @@ public: // output - passed when rendering refresh frame. If 0, the canvas is cleared. void clear_output(Canvas *canvas, VFrame *output); +// Finish all active opengl requests + void finish_output(); + void do_fade(Canvas *canvas, VFrame *frame, float fade); void convert_cmodel(Canvas *canvas, VFrame *output, int dst_cmodel); @@ -328,6 +332,7 @@ private: void init_frame(Playback3DCommand *command, int is_yuv=0); void write_buffer_sync(Playback3DCommand *command); void draw_output(Playback3DCommand *command, int flip_y); + void finish_output_sync(Playback3DCommand *command); void clear_output_sync(Playback3DCommand *command); void clear_input_sync(Playback3DCommand *command); void overlay_sync(Playback3DCommand *command); diff --git a/cinelerra-5.1/cinelerra/playbackengine.C b/cinelerra-5.1/cinelerra/playbackengine.C index 364b8c9e..71126cf8 100644 --- a/cinelerra-5.1/cinelerra/playbackengine.C +++ b/cinelerra-5.1/cinelerra/playbackengine.C @@ -22,6 +22,7 @@ #include "bchash.h" #include "bcsignals.h" #include "cache.h" +#include "canvas.h" #include "condition.h" #include "edl.h" #include "edlsession.h" @@ -406,7 +407,7 @@ void PlaybackEngine::run() // Start tracking after arming so the tracking position doesn't change. // The tracking for a single frame command occurs during PAUSE init_tracking(); - + clear_output(); // Dispatch the command start_render_engine(); break; @@ -415,6 +416,14 @@ void PlaybackEngine::run() } } +void PlaybackEngine::clear_output() +{ + BC_WindowBase *cwdw = output->get_canvas(); + if( !cwdw ) return; + cwdw->lock_window("PlaybackEngine::clear_output"); + output->clear(); + cwdw->unlock_window(); +} void PlaybackEngine::stop_playback(int wait_tracking) { @@ -433,7 +442,7 @@ 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; - int curr_command = this->command->command; + int curr_command = is_playing_back ? this->command->command : STOP; int curr_single_frame = TransportCommand::single_frame(curr_command); int curr_audio = this->command->toggle_audio ? !curr_single_frame : curr_single_frame; @@ -525,15 +534,10 @@ int PlaybackEngine::transport_command(int command, int change_type, EDL *new_edl // Just change the EDL if the change requires it because renderengine // structures won't point to the new EDL otherwise and because copying the // EDL for every cursor movement is slow. - switch( change_type ) { - case CHANGE_EDL: - case CHANGE_ALL: + if( change_type & CHANGE_EDL ) next_command->get_edl()->copy_all(new_edl); - break; - case CHANGE_PARAMS: + else if( change_type & CHANGE_PARAMS ) next_command->get_edl()->synchronize_params(new_edl); - break; - } next_command->set_playback_range(new_edl, use_inout, preferences->forward_render_displacement); } diff --git a/cinelerra-5.1/cinelerra/playbackengine.h b/cinelerra-5.1/cinelerra/playbackengine.h index 0a717f11..048dc7a2 100644 --- a/cinelerra-5.1/cinelerra/playbackengine.h +++ b/cinelerra-5.1/cinelerra/playbackengine.h @@ -55,6 +55,7 @@ public: void create_cache(); void perform_change(); void sync_parameters(EDL *edl); + void clear_output(); // Set wait_tracking for events that change the cursor location but // be sure to unlock the windows void interrupt_playback(int wait_tracking = 0); diff --git a/cinelerra-5.1/cinelerra/playtransport.C b/cinelerra-5.1/cinelerra/playtransport.C index 569fdbe2..0690da07 100644 --- a/cinelerra-5.1/cinelerra/playtransport.C +++ b/cinelerra-5.1/cinelerra/playtransport.C @@ -210,7 +210,7 @@ int PlayTransport::do_keypress(int key) int loop_play = shft_key & ctrl_key; float speed = 0; int command = -1; - int curr_command = engine->command->command; + int curr_command = engine->is_playing_back ? engine->command->command : STOP; subwindow->unlock_window(); result = 0; diff --git a/cinelerra-5.1/cinelerra/renderengine.C b/cinelerra-5.1/cinelerra/renderengine.C index 6bc828a3..ed991791 100644 --- a/cinelerra-5.1/cinelerra/renderengine.C +++ b/cinelerra-5.1/cinelerra/renderengine.C @@ -477,7 +477,6 @@ void RenderEngine::run() position -= 1./command->get_edl()->session->frame_rate; if( position < 0 ) position = 0; } - playback_engine->command->command = STOP; playback_engine->is_playing_back = 0; playback_engine->tracking_position = position; playback_engine->stop_tracking(); @@ -494,4 +493,3 @@ void RenderEngine::wait_done() render_active->unlock(); } - diff --git a/cinelerra-5.1/cinelerra/renderengine.h b/cinelerra-5.1/cinelerra/renderengine.h index 4e9c9689..d3853a1d 100644 --- a/cinelerra-5.1/cinelerra/renderengine.h +++ b/cinelerra-5.1/cinelerra/renderengine.h @@ -84,8 +84,6 @@ public: int64_t sync_position(); // Called by VRender to reset the timers once the first frame is done. void reset_sync_position(); -// return samples since start of playback - int64_t session_position(); // Update preferences window void update_framerate(float framerate); diff --git a/cinelerra-5.1/cinelerra/vdevicex11.C b/cinelerra-5.1/cinelerra/vdevicex11.C index 362777ff..c43f1c04 100644 --- a/cinelerra-5.1/cinelerra/vdevicex11.C +++ b/cinelerra-5.1/cinelerra/vdevicex11.C @@ -549,8 +549,6 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) 0); //printf("VDeviceX11::write_buffer %d bitmap=%p\n", __LINE__, bitmap); } - if( !output->get_canvas()->get_video_on() ) - output->get_canvas()->flash(0); } output->get_canvas()->unlock_window(); diff --git a/cinelerra-5.1/info/plugins.txt b/cinelerra-5.1/info/plugins.txt index 0955ba52..30168703 100644 --- a/cinelerra-5.1/info/plugins.txt +++ b/cinelerra-5.1/info/plugins.txt @@ -340,8 +340,8 @@ F_oscilloscope: 2D video oscilloscope. Useful to measure spatial impulse, F_owndenoise: Denoises using wavelets. F_pad: Add paddings to the input image, and place the original input at the provided x, y coordinates. -F_pal100bars: Generate PAL 100% color bars. -F_pal75bars: Generate PAL 75% color bars. +F_pal100bars: Generate PAL 100% color bars. This only works with RGB 8-bit. +F_pal75bars: Generate PAL 75% color bars. This only works with RGB 8-bit. F_perms: Set permissions for the output video frame. F_perspective: Corrects the perspective of video. F_phase: Phases shift fields. diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.1.patch5 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.1.patch5 new file mode 100644 index 00000000..9a53f7b4 --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.1.patch5 @@ -0,0 +1,29 @@ +diff -u a/libavfilter/formats.c b/libavfilter/formats.c +--- a/libavfilter/formats.c 2018-11-02 18:17:29.000000000 -0600 ++++ b/libavfilter/formats.c 2019-04-09 14:12:01.659501027 -0600 +@@ -107,11 +107,13 @@ + possibly causing a lossy conversion elsewhere in the graph. + To avoid that, pretend that there are no common formats to force the + insertion of a conversion filter. */ +- if (type == AVMEDIA_TYPE_VIDEO) +- for (i = 0; i < a->nb_formats; i++) ++ if (type == AVMEDIA_TYPE_VIDEO) { ++ for (i = 0; i < a->nb_formats; i++) { ++ const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]); ++ if( !adesc ) continue; + for (j = 0; j < b->nb_formats; j++) { +- const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]); + const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]); ++ if( !bdesc ) continue; + alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA; + chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1; + if (a->formats[i] == b->formats[j]) { +@@ -119,6 +121,8 @@ + chroma1|= adesc->nb_components > 1; + } + } ++ } ++ } + + // If chroma or alpha can be lost through merging then do not merge + if (alpha2 > alpha1 || chroma2 > chroma1) -- 2.26.2