no /. in ffmpeg init_decode segv, build index fix audio wave, stop playback state...
authorGood Guy <good1.2guy@gmail.com>
Wed, 10 Apr 2019 22:31:32 +0000 (16:31 -0600)
committerGood Guy <good1.2guy@gmail.com>
Wed, 10 Apr 2019 22:31:32 +0000 (16:31 -0600)
18 files changed:
cinelerra-5.1/cinelerra/canvas.C
cinelerra-5.1/cinelerra/canvas.h
cinelerra-5.1/cinelerra/cwindow.C
cinelerra-5.1/cinelerra/cwindowgui.C
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/mainindexes.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/playback3d.C
cinelerra-5.1/cinelerra/playback3d.h
cinelerra-5.1/cinelerra/playbackengine.C
cinelerra-5.1/cinelerra/playbackengine.h
cinelerra-5.1/cinelerra/playtransport.C
cinelerra-5.1/cinelerra/renderengine.C
cinelerra-5.1/cinelerra/renderengine.h
cinelerra-5.1/cinelerra/vdevicex11.C
cinelerra-5.1/info/plugins.txt
cinelerra-5.1/thirdparty/src/ffmpeg-4.1.patch5 [new file with mode: 0644]

index 85316aa..a01d1b9 100644 (file)
@@ -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,
index 1b1adb1..2fd2a23 100644 (file)
@@ -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.
index 1511867..5285fd4 100644 (file)
@@ -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;
 }
 
 
index a93964c..7ebdd6e 100644 (file)
@@ -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(&center_x,
-                       &center_y, &center_z, position, PLAY_FORWARD);
+//     if( do_camera ) {
+//             track->automation->get_camera(&center_x,
+//                     &center_y, &center_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(&center_x,
                        &center_y, &center_z, position, PLAY_FORWARD);
 
index d13cf8b..0c351e5 100644 (file)
@@ -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;
index 0183c62..05812bb 100644 (file)
@@ -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
index 09e363c..66b37fa 100644 (file)
@@ -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()
 {
index 8a23118..3256ace 100644 (file)
@@ -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();
index 2ca2a4c..24f8cf7 100644 (file)
@@ -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;
index 4388624..1f3dd59 100644 (file)
@@ -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);
index 364b8c9..71126cf 100644 (file)
@@ -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);
        }
index 0a717f1..048dc7a 100644 (file)
@@ -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);
index 569fdbe..0690da0 100644 (file)
@@ -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;
index 6bc828a..ed99179 100644 (file)
@@ -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();
 }
 
-
index 4e9c968..d3853a1 100644 (file)
@@ -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);
index 362777f..c43f1c0 100644 (file)
@@ -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();
index 0955ba5..3016870 100644 (file)
@@ -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 (file)
index 0000000..9a53f7b
--- /dev/null
@@ -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)