fixed more threading issues

This commit is contained in:
itsmattkc
2019-01-15 22:45:25 +11:00
parent e1ec2f6fbe
commit 08968706b0
12 changed files with 166 additions and 126 deletions
+9 -9
View File
@@ -34,7 +34,7 @@ EffectControls::EffectControls(QWidget *parent) :
QDockWidget(parent),
multiple(false),
zoom(1),
panel_name(tr("Effects: ")),
panel_name(tr("Effects: ")),
mode(TA_NO_TRANSITION)
{
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
@@ -94,7 +94,7 @@ void EffectControls::menu_select(QAction* q) {
update_ui(true);
} else {
reload_clips();
panel_sequence_viewer->viewer_widget->update();
panel_sequence_viewer->viewer_widget->frame_update();
}
}
@@ -303,7 +303,7 @@ void EffectControls::setup_ui() {
QPushButton* btnAddVideoEffect = new QPushButton(veHeader);
btnAddVideoEffect->setIcon(QIcon(":/icons/add-effect.png"));
btnAddVideoEffect->setToolTip(tr("Add Video Effect"));
btnAddVideoEffect->setToolTip(tr("Add Video Effect"));
veHeaderLayout->addWidget(btnAddVideoEffect);
connect(btnAddVideoEffect, SIGNAL(clicked(bool)), this, SLOT(video_effect_click()));
@@ -314,14 +314,14 @@ void EffectControls::setup_ui() {
font.setPointSize(9);
lblVideoEffects->setFont(font);
lblVideoEffects->setAlignment(Qt::AlignCenter);
lblVideoEffects->setText(tr("VIDEO EFFECTS"));
lblVideoEffects->setText(tr("VIDEO EFFECTS"));
veHeaderLayout->addWidget(lblVideoEffects);
veHeaderLayout->addStretch();
QPushButton* btnAddVideoTransition = new QPushButton(veHeader);
btnAddVideoTransition->setIcon(QIcon(":/icons/add-transition.png"));
btnAddVideoTransition->setToolTip(tr("Add Video Transition"));
btnAddVideoTransition->setToolTip(tr("Add Video Transition"));
connect(btnAddVideoTransition, SIGNAL(clicked(bool)), this, SLOT(video_transition_click()));
veHeaderLayout->addWidget(btnAddVideoTransition);
@@ -351,7 +351,7 @@ void EffectControls::setup_ui() {
QPushButton* btnAddAudioEffect = new QPushButton(aeHeader);
btnAddAudioEffect->setIcon(QIcon(":/icons/add-effect.png"));
btnAddAudioEffect->setToolTip(tr("Add Audio Effect"));
btnAddAudioEffect->setToolTip(tr("Add Audio Effect"));
connect(btnAddAudioEffect, SIGNAL(clicked(bool)), this, SLOT(audio_effect_click()));
aeHeaderLayout->addWidget(btnAddAudioEffect);
@@ -360,14 +360,14 @@ void EffectControls::setup_ui() {
QLabel* lblAudioEffects = new QLabel(aeHeader);
lblAudioEffects->setFont(font);
lblAudioEffects->setAlignment(Qt::AlignCenter);
lblAudioEffects->setText(tr("AUDIO EFFECTS"));
lblAudioEffects->setText(tr("AUDIO EFFECTS"));
aeHeaderLayout->addWidget(lblAudioEffects);
aeHeaderLayout->addStretch();
QPushButton* btnAddAudioTransition = new QPushButton(aeHeader);
btnAddAudioTransition->setIcon(QIcon(":/icons/add-transition.png"));
btnAddAudioTransition->setToolTip(tr("Add Audio Transition"));
btnAddAudioTransition->setToolTip(tr("Add Audio Transition"));
connect(btnAddAudioTransition, SIGNAL(clicked(bool)), this, SLOT(audio_transition_click()));
aeHeaderLayout->addWidget(btnAddAudioTransition);
@@ -384,7 +384,7 @@ void EffectControls::setup_ui() {
lblMultipleClipsSelected = new QLabel(effects_area);
lblMultipleClipsSelected->setAlignment(Qt::AlignCenter);
lblMultipleClipsSelected->setText(tr("(Multiple clips selected)"));
lblMultipleClipsSelected->setText(tr("(Multiple clips selected)"));
effects_area_layout->addWidget(lblMultipleClipsSelected);
effects_area_layout->addStretch();
+2 -3
View File
@@ -33,7 +33,6 @@ extern "C" {
//#define GCF_DEBUG
#endif
bool texture_failed = false;
bool rendering = false;
long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate) {
@@ -122,7 +121,7 @@ double get_timecode(Clip* c, long playhead) {
return ((double)(playhead-c->get_timeline_in_with_transition()+c->get_clip_in_with_transition())/(double)c->sequence->frame_rate);
}
void get_clip_frame(Clip* c, long playhead) {
void get_clip_frame(Clip* c, long playhead, bool& texture_failed) {
if (c->finished_opening) {
const FootageStream* ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream);
@@ -249,7 +248,7 @@ void get_clip_frame(Clip* c, long playhead) {
if (target_frame == nullptr || reset) {
// reset cache
texture_failed = true;
// qInfo() << "Frame queue couldn't keep up - either the user seeked or the system is overloaded (queue size:" << c->queue.size() << ")";
qInfo() << "Frame queue couldn't keep up - either the user seeked or the system is overloaded (queue size:" << c->queue.size() << ")";
}
if (target_frame != nullptr) {
+1 -2
View File
@@ -9,7 +9,6 @@ struct ClipCache;
struct Sequence;
struct AVFrame;
extern bool texture_failed;
extern bool rendering;
long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate);
@@ -21,7 +20,7 @@ void cache_audio_worker(Clip* c, bool write_A);
void cache_video_worker(Clip* c, long playhead);
void handle_media(Sequence* sequence, long playhead, bool multithreaded);
void reset_cache(Clip* c, long target_frame);
void get_clip_frame(Clip* c, long playhead);
void get_clip_frame(Clip* c, long playhead, bool &texture_failed);
double get_timecode(Clip* c, long playhead);
long playhead_to_clip_frame(Clip* c, long playhead);
+1 -1
View File
@@ -537,7 +537,7 @@ int Effect::gizmo_count(){
void Effect::refresh() {}
void Effect::field_changed() {
panel_sequence_viewer->viewer_widget->update();
panel_sequence_viewer->viewer_widget->frame_update();
panel_graph_editor->update_panel();
}
+9 -7
View File
@@ -83,6 +83,7 @@ void process_effect(QOpenGLContext* ctx,
GLTextureCoords& coords,
GLuint& composite_texture,
bool& fbo_switcher,
bool& texture_failed,
int data) {
if (e->is_enabled()) {
if (e->enable_coords) {
@@ -115,7 +116,8 @@ GLuint compose_sequence(Viewer* viewer,
QVector<Clip*>& nests,
bool video,
bool render_audio,
Effect** gizmos) {
Effect** gizmos,
bool& texture_failed) {
GLint current_fbo = 0;
if (video) {
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
@@ -235,7 +237,7 @@ GLuint compose_sequence(Viewer* viewer,
c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
c->texture->allocateStorage(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8);
}
get_clip_frame(c, playhead);
get_clip_frame(c, playhead, texture_failed);
textureID = c->texture->textureId();
break;
case MEDIA_TYPE_SEQUENCE:
@@ -281,7 +283,7 @@ GLuint compose_sequence(Viewer* viewer,
// for nested sequences
if (c->media->get_type()== MEDIA_TYPE_SEQUENCE) {
nests.append(c);
textureID = compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos);
textureID = compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed);
nests.removeLast();
fbo_switcher = true;
}
@@ -319,7 +321,7 @@ GLuint compose_sequence(Viewer* viewer,
for (int j=0;j<c->effects.size();j++) {
Effect* e = c->effects.at(j);
process_effect(ctx, c, e, timecode, coords, composite_texture, fbo_switcher, TA_NO_TRANSITION);
process_effect(ctx, c, e, timecode, coords, composite_texture, fbo_switcher, texture_failed, TA_NO_TRANSITION);
if (e->are_gizmos_enabled()) {
if (first_gizmo_effect == nullptr) first_gizmo_effect = e;
@@ -338,14 +340,14 @@ GLuint compose_sequence(Viewer* viewer,
if (c->get_opening_transition() != nullptr) {
int transition_progress = playhead - c->get_timeline_in_with_transition();
if (transition_progress < c->get_opening_transition()->get_length()) {
process_effect(ctx, c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_OPENING_TRANSITION);
process_effect(ctx, c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_OPENING_TRANSITION);
}
}
if (c->get_closing_transition() != nullptr) {
int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length());
if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) {
process_effect(ctx, c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_CLOSING_TRANSITION);
process_effect(ctx, c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_CLOSING_TRANSITION);
}
}
// EFFECT CODE END
@@ -452,7 +454,7 @@ GLuint compose_sequence(Viewer* viewer,
if (render_audio || (config.enable_audio_scrubbing && audio_scrub)) {
if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) {
nests.append(c);
compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos);
compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed);
nests.removeLast();
} else {
if (c->lock.tryLock()) {
+1 -1
View File
@@ -15,6 +15,6 @@ GLuint compose_sequence(Viewer* viewer,
QVector<Clip*>& nests,
bool video,
bool render_audio,
Effect **gizmos);
Effect **gizmos, bool &texture_failed);
#endif // RENDERFUNCTIONS_H
+72 -29
View File
@@ -10,13 +10,16 @@
#include "project/sequence.h"
RenderThread::RenderThread() :
share_ctx(nullptr),
ctx(nullptr),
frameBuffer(0),
texColorBuffer(0),
share_ctx(nullptr),
ctx(nullptr),
seq(nullptr),
tex_width(-1),
tex_height(-1),
queued(false)
queued(false),
texture_failed(false),
running(true)
{
surface.create();
}
@@ -28,26 +31,23 @@ RenderThread::~RenderThread() {
void RenderThread::run() {
mutex.lock();
bool running = true;
while (running) {
if (!queued) {
waitCond.wait(&mutex);
}
if (!running) {
break;
}
queued = false;
if (share_ctx != nullptr) {
if (ctx == nullptr) {
ctx = new QOpenGLContext();
ctx->setFormat(share_ctx->format());
ctx->setShareContext(share_ctx);
ctx->create();
ctx->makeCurrent(&surface);
}
if (share_ctx != nullptr) {
if (ctx != nullptr) {
ctx->makeCurrent(&surface);
// gen fbo
if (frameBuffer == 0) {
delete_fbo();
ctx->functions()->glGenFramebuffers(1, &frameBuffer);
}
@@ -55,13 +55,8 @@ void RenderThread::run() {
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer);
// gen texture
if (texColorBuffer == 0 || tex_width != seq->width || tex_height != seq->height) {\
if (texColorBuffer > 0) {
ctx->functions()->glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0
);
glDeleteTextures(1, &texColorBuffer);
}
if (texColorBuffer == 0 || tex_width != seq->width || tex_height != seq->height) {
delete_texture();
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
glTexImage2D(
@@ -91,12 +86,7 @@ void RenderThread::run() {
}
}
if (ctx != nullptr) {
if (texColorBuffer > 0) glDeleteTextures(1, &texColorBuffer);
if (frameBuffer > 0) ctx->functions()->glDeleteFramebuffers(1, &frameBuffer);
ctx->doneCurrent();
delete ctx;
}
delete_ctx();
mutex.unlock();
}
@@ -118,7 +108,7 @@ void RenderThread::paint() {
Effect* gizmos; // does nothing yet
QVector<Clip*> nests;
compose_sequence(nullptr, ctx, seq, nests, true, false, &gizmos);
compose_sequence(nullptr, ctx, seq, nests, true, false, &gizmos, texture_failed);
glDisable(GL_DEPTH);
glDisable(GL_BLEND);
@@ -126,8 +116,61 @@ void RenderThread::paint() {
}
void RenderThread::start_render(QOpenGLContext *share, Sequence *s, int idivider) {
share_ctx = share;
if (s != seq && seq != nullptr) {
closeActiveClips(seq);
}
seq = s;
queued = true;
if (share != nullptr && (ctx == nullptr || ctx->shareContext() != share_ctx)) {
share_ctx = share;
delete_ctx();
ctx = new QOpenGLContext();
ctx->setFormat(share_ctx->format());
ctx->setShareContext(share_ctx);
ctx->create();
ctx->moveToThread(this);
}
if (seq != nullptr) {
queued = true;
waitCond.wakeAll();
}
}
bool RenderThread::did_texture_fail() {
return texture_failed;
}
void RenderThread::cancel() {
running = false;
waitCond.wakeAll();
wait();
}
void RenderThread::delete_texture() {
if (texColorBuffer > 0) {
ctx->functions()->glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0
);
glDeleteTextures(1, &texColorBuffer);
}
texColorBuffer = 0;
}
void RenderThread::delete_fbo() {
if (frameBuffer > 0) {
ctx->functions()->glDeleteFramebuffers(1, &frameBuffer);
}
frameBuffer = 0;
}
void RenderThread::delete_ctx() {
if (ctx != nullptr) {
delete_texture();
delete_fbo();
ctx->doneCurrent();
delete ctx;
}
ctx = nullptr;
}
+9
View File
@@ -21,9 +21,16 @@ public:
GLuint texColorBuffer;
void paint();
void start_render(QOpenGLContext* share, Sequence* s, int idivider = 0);
bool did_texture_fail();
void cancel();
signals:
void ready();
private:
// cleanup functions
void delete_texture();
void delete_fbo();
void delete_ctx();
QWaitCondition waitCond;
QOffscreenSurface surface;
QOpenGLContext* share_ctx;
@@ -33,6 +40,8 @@ private:
int tex_width;
int tex_height;
bool queued;
bool texture_failed;
bool running;
};
#endif // RENDERTHREAD_H
+54 -54
View File
@@ -12,85 +12,85 @@
// enforces aspect ratio
ViewerContainer::ViewerContainer(QWidget *parent) :
QScrollArea(parent),
fit(true),
child(nullptr)
QScrollArea(parent),
fit(true),
child(nullptr)
{
setFrameShadow(QFrame::Plain);
setFrameShape(QFrame::NoFrame);
setFrameShadow(QFrame::Plain);
setFrameShape(QFrame::NoFrame);
area = new QWidget(this);
area->move(0, 0);
setWidget(area);
area = new QWidget(this);
area->move(0, 0);
setWidget(area);
child = new ViewerWidget(area);
child->container = this;
child = new ViewerWidget(area);
child->container = this;
}
ViewerContainer::~ViewerContainer() {
delete area;
delete area;
}
void ViewerContainer::dragScrollPress(const QPoint &p) {
drag_start_x = p.x();
drag_start_y = p.y();
horiz_start = horizontalScrollBar()->value();
vert_start = verticalScrollBar()->value();
drag_start_x = p.x();
drag_start_y = p.y();
horiz_start = horizontalScrollBar()->value();
vert_start = verticalScrollBar()->value();
}
void ViewerContainer::dragScrollMove(const QPoint &p) {
int true_x = p.x() + (horiz_start - horizontalScrollBar()->value());
int true_y = p.y() + (vert_start - verticalScrollBar()->value());
int true_x = p.x() + (horiz_start - horizontalScrollBar()->value());
int true_y = p.y() + (vert_start - verticalScrollBar()->value());
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + (drag_start_x - true_x));
verticalScrollBar()->setValue(verticalScrollBar()->value() + (drag_start_y - true_y));
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + (drag_start_x - true_x));
verticalScrollBar()->setValue(verticalScrollBar()->value() + (drag_start_y - true_y));
drag_start_x = true_x;
drag_start_y = true_y;
drag_start_x = true_x;
drag_start_y = true_y;
}
void ViewerContainer::adjust() {
if (viewer->seq != nullptr) {
if (child->waveform) {
child->move(0, 0);
child->resize(size());
} else if (fit) {
double aspect_ratio = double(viewer->seq->width)/double(viewer->seq->height);
if (viewer->seq != nullptr) {
if (child->waveform) {
child->move(0, 0);
child->resize(size());
} else if (fit) {
double aspect_ratio = double(viewer->seq->width)/double(viewer->seq->height);
int widget_x = 0;
int widget_y = 0;
int widget_width = width();
int widget_height = height();
float widget_ar = (float) widget_width /(float) widget_height;
int widget_x = 0;
int widget_y = 0;
int widget_width = width();
int widget_height = height();
double widget_ar = double(widget_width) / double(widget_height);
bool widget_is_wider_than_sequence = widget_ar > aspect_ratio;
bool widget_is_wider_than_sequence = widget_ar > aspect_ratio;
if (widget_is_wider_than_sequence) {
widget_width = widget_height * aspect_ratio;
widget_x = (width() / 2) - (widget_width / 2);
} else {
widget_height = widget_width / aspect_ratio;
widget_y = (height() / 2) - (widget_height / 2);
}
if (widget_is_wider_than_sequence) {
widget_width = widget_height * aspect_ratio;
widget_x = (width() / 2) - (widget_width / 2);
} else {
widget_height = widget_width / aspect_ratio;
widget_y = (height() / 2) - (widget_height / 2);
}
child->move(widget_x, widget_y);
child->resize(widget_width, widget_height);
child->move(widget_x, widget_y);
child->resize(widget_width, widget_height);
zoom = double(widget_width) / double(viewer->seq->width);
} else {
int zoomed_width = double(viewer->seq->width)*zoom;
int zoomed_height = double(viewer->seq->height)*zoom;
int zoomed_x = 0;
int zoomed_y = 0;
zoom = double(widget_width) / double(viewer->seq->width);
} else {
int zoomed_width = double(viewer->seq->width)*zoom;
int zoomed_height = double(viewer->seq->height)*zoom;
int zoomed_x = 0;
int zoomed_y = 0;
if (zoomed_width < width()) zoomed_x = (width()>>1)-(zoomed_width>>1);
if (zoomed_height < height()) zoomed_y = (height()>>1)-(zoomed_height>>1);
if (zoomed_width < width()) zoomed_x = (width()>>1)-(zoomed_width>>1);
if (zoomed_height < height()) zoomed_y = (height()>>1)-(zoomed_height>>1);
child->move(zoomed_x, zoomed_y);
child->resize(zoomed_width, zoomed_height);
}
child->move(zoomed_x, zoomed_y);
child->resize(zoomed_width, zoomed_height);
}
}
area->resize(qMax(width(), child->width()), qMax(height(), child->height()));
area->resize(qMax(width(), child->width()), qMax(height(), child->height()));
}
void ViewerContainer::resizeEvent(QResizeEvent *event) {
+6 -14
View File
@@ -57,7 +57,6 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
dragging(false),
gizmos(nullptr),
selected_gizmo(nullptr),
just_repaint(false),
window(nullptr)
{
setMouseTracking(true);
@@ -73,6 +72,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
renderer = new RenderThread();
renderer->start(QThread::HighPriority);
connect(renderer, SIGNAL(ready()), this, SLOT(queue_repaint()));
connect(renderer, SIGNAL(finished()), renderer, SLOT(deleteLater()));
}
ViewerWidget::~ViewerWidget() {
@@ -80,15 +80,11 @@ ViewerWidget::~ViewerWidget() {
window->close();
delete window;
}
renderer->cancel();
}
void ViewerWidget::delete_function() {
// destroy all textures as well
if (viewer->seq != nullptr) {
makeCurrent();
closeActiveClips(viewer->seq);
doneCurrent();
}
renderer->start_render(context(), nullptr);
}
void ViewerWidget::set_waveform_scroll(int s) {
@@ -173,7 +169,6 @@ void ViewerWidget::save_frame() {
}
void ViewerWidget::queue_repaint() {
just_repaint = true;
update();
}
@@ -222,14 +217,10 @@ void ViewerWidget::retry() {
void ViewerWidget::initializeGL() {
initializeOpenGLFunctions();
connect(context(), SIGNAL(aboutToBeDestroyed()), this, SLOT(delete_function()), Qt::DirectConnection);
if (window != nullptr) {
delete window;
}
window = new ViewerWindow(context());
// retry_timer.start();
}
void ViewerWidget::frame_update() {
@@ -246,7 +237,8 @@ void ViewerWidget::frame_update() {
// render the audio
QVector<Clip*> nests;
compose_sequence(viewer, context(), viewer->seq, nests, false, render_audio, &gizmos);
bool texture_failed;
compose_sequence(viewer, context(), viewer->seq, nests, false, render_audio, &gizmos, texture_failed);
}
}
@@ -482,7 +474,7 @@ void ViewerWidget::paintGL() {
renderer->mutex.unlock();
if (texture_failed) {
if (renderer->did_texture_fail()) {
doneCurrent();
renderer->start_render(context(), viewer->seq);
}
+2 -4
View File
@@ -28,6 +28,8 @@ public:
ViewerWidget(QWidget *parent = 0);
~ViewerWidget();
void delete_function();
void paintGL();
void initializeGL();
Viewer* viewer;
@@ -45,11 +47,8 @@ public:
void frame_update();
public slots:
void delete_function();
void set_waveform_scroll(int s);
protected:
// void paintEvent(QPaintEvent *e);
// void resizeGL(int w, int h);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
@@ -68,7 +67,6 @@ private:
void move_gizmos(QMouseEvent *event, bool done);
RenderThread* renderer;
ViewerWindow* window;
bool just_repaint;
private slots:
void retry();
void show_context_menu();
-2
View File
@@ -33,8 +33,6 @@ void ViewerWindow::paintGL() {
double widget_ar = double(width()) / double(height());
if (widget_ar > ar) {
/*widget_width = widget_height * aspect_ratio;
widget_x = (width() / 2) - (widget_width / 2);*/
double width = 1.0 * ar / widget_ar;
left = (1.0 - width)*0.5;
right = left + width;