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,
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.
: Thread(1, 0, 0)
{
this->mwindow = mwindow;
+ this->playback_engine = 0;
+ this->playback_cursor = 0;
+ this->gui = 0;
}
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();
}
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);
// 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");
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);
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;
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
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()
{
void create_objects(int want_gui,
int want_new,
char *config_path);
+ int uses_opengl();
void show_splash();
void hide_splash();
void start();
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;
}
+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;
{
// 5
WRITE_BUFFER = LAST_COMMAND,
+ FINISH_OUTPUT,
CLEAR_OUTPUT,
OVERLAY,
DO_FADE,
// 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);
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);
#include "bchash.h"
#include "bcsignals.h"
#include "cache.h"
+#include "canvas.h"
#include "condition.h"
#include "edl.h"
#include "edlsession.h"
// 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;
}
}
+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)
{
//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;
// 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);
}
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);
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;
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();
render_active->unlock();
}
-
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);
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();
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.
--- /dev/null
+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)