From 80bcd98759297354bcc9caeb6d9b83a245268f88 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 23 Jun 2018 00:48:45 -0700 Subject: [PATCH] fixed latent paste, mutex, and audio issues --- mainwindow.cpp | 4 +-- olive.pro.user | 2 +- panels/project.cpp | 2 +- panels/timeline.cpp | 41 +++++++++++---------- panels/timeline.h | 2 +- playback/cacher.cpp | 22 ++++++------ playback/playback.cpp | 2 +- project/clip.cpp | 1 + project/clip.h | 1 + ui/timelinewidget.cpp | 8 ++--- ui/viewerwidget.cpp | 84 +++++++++++++++++++++---------------------- 11 files changed, 87 insertions(+), 82 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 4d5b685c7..9f4de12a2 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -91,7 +91,7 @@ MainWindow::MainWindow(QWidget *parent) : if (dir.exists()) { autorecovery_filename = data_dir + "/autorecovery.ove"; if (QFile::exists(autorecovery_filename)) { - if (QMessageBox::question(this, "Auto-recovery", "Olive didn't close properly and an autorecovery file was detected. Would you like to open it?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { + if (QMessageBox::question(NULL, "Auto-recovery", "Olive didn't close properly and an autorecovery file was detected. Would you like to open it?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { project_url = autorecovery_filename; panel_project->load_project(); } @@ -173,7 +173,7 @@ void MainWindow::on_actionZoom_out_triggered() void MainWindow::on_actionTimeline_Track_Lines_toggled(bool e) { show_track_lines = e; - panel_timeline->redraw_all_clips(); + panel_timeline->redraw_all_clips(false); } void MainWindow::on_actionExport_triggered() diff --git a/olive.pro.user b/olive.pro.user index 148ad29d4..9dd1f6225 100644 --- a/olive.pro.user +++ b/olive.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/panels/project.cpp b/panels/project.cpp index dad10f437..e13982ba4 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -420,7 +420,7 @@ void Project::load_project() { qDebug() << "[ERROR] Error parsing XML." << stream.error(); } - panel_timeline->redraw_all_clips(); + panel_timeline->redraw_all_clips(false); project_changed = false; } diff --git a/panels/timeline.cpp b/panels/timeline.cpp index f14e2767f..475e151ba 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -161,7 +161,7 @@ void Timeline::update_sequence() { setWindowTitle("Timeline: "); } else { setWindowTitle("Timeline: " + sequence->name); - redraw_all_clips(); + redraw_all_clips(false); playback_updater.setInterval(qFloor(1000 / sequence->frame_rate)); } } @@ -180,8 +180,7 @@ void Timeline::undo() { // current_clips.clear(); // panel_effect_controls->set_clip(NULL); // sequence->undo(); -// ui->video_area->redraw_clips(); -// ui->audio_area->redraw_clips(); +// redraw_all_clips(false); // } } @@ -191,17 +190,22 @@ void Timeline::redo() { // current_clips.clear(); // panel_effect_controls->set_clip(NULL); // sequence->redo(); -// ui->video_area->redraw_clips(); -// ui->audio_area->redraw_clips(); +// redraw_all_clips(false); // } } QString frame_to_timecode(long f) { - int int_fps = qRound(sequence->frame_rate); - int hours = f/ (3600 * int_fps); - int mins = f / (60*int_fps) % 60; - int secs = f/int_fps % 60; - int frames = f%int_fps; + int hours = 0; + int mins = 0; + int secs = 0; + int frames = 0; + if (sequence != NULL) { + int int_fps = qRound(sequence->frame_rate); + hours = f/ (3600 * int_fps); + mins = f / (60*int_fps) % 60; + secs = f/int_fps % 60; + frames = f%int_fps; + } return QString(QString::number(hours).rightJustified(2, '0') + ":" + QString::number(mins).rightJustified(2, '0') + ":" + QString::number(secs).rightJustified(2, '0') + @@ -223,17 +227,18 @@ void Timeline::repaint_timeline() { panel_viewer->ui->currentTimecode->setText(frame_to_timecode(playhead)); } -void Timeline::redraw_all_clips() { +void Timeline::redraw_all_clips(bool changed) { if (sequence != NULL) { - project_changed = true; + if (changed) { + project_changed = true; + if (!playing) reset_all_audio(); + } ui->video_area->redraw_clips(); ui->audio_area->redraw_clips(); ui->headers->update(); panel_viewer->ui->endTimecode->setText(frame_to_timecode(sequence->getEndFrame())); - - reset_all_audio(); } } @@ -287,7 +292,7 @@ void Timeline::delete_selection(bool ripple_delete) { if (ripple_length > 0) ripple(ripple_point, -ripple_length); } - redraw_all_clips(); + redraw_all_clips(true); } } @@ -308,7 +313,7 @@ void Timeline::set_zoom(bool in) { 0.99f ) ); - redraw_all_clips(); + redraw_all_clips(false); } void Timeline::ripple(long ripple_point, long ripple_length) { @@ -561,7 +566,7 @@ void Timeline::paste() { cc->sequence = sequence; sequence->add_clip(cc); } - redraw_all_clips(); + redraw_all_clips(true); } } @@ -640,7 +645,7 @@ void Timeline::split_at_playhead() { } } - if (split_selected) redraw_all_clips(); + if (split_selected) redraw_all_clips(true); } bool Timeline::snap_to_point(long point, long* l) { diff --git a/panels/timeline.h b/panels/timeline.h index 7bb436ba4..6d6fada53 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -106,7 +106,7 @@ public: float zoom; long drag_frame_start; int drag_track_start; - void redraw_all_clips(); + void redraw_all_clips(bool changed); // snapping bool snapping; diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 87d103e9a..de9706e77 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -75,15 +75,14 @@ void cache_audio_worker(Clip* c) { if (offset > 0) { c->audio_buffer_write += offset; c->frame_sample_index += offset; - while (c->frame_sample_index > nb_bytes) { - // get new frame - retrieve_next_frame_raw_data(c, frame); - - nb_bytes = av_samples_get_buffer_size(NULL, frame->channels, frame->nb_samples, static_cast(frame->format), 1); - c->frame_sample_index -= nb_bytes; - } } - } + } + while (c->frame_sample_index > nb_bytes) { + // get new frame + retrieve_next_frame_raw_data(c, frame); + nb_bytes = av_samples_get_buffer_size(NULL, frame->channels, frame->nb_samples, static_cast(frame->format), 1); + c->frame_sample_index -= nb_bytes; + } while (c->frame_sample_index < nb_bytes) { if (c->audio_buffer_write >= audio_ibuffer_read+half_buffer || c->audio_buffer_write >= get_buffer_offset_from_frame(c->timeline_out)) { written = max_write; @@ -367,12 +366,15 @@ void close_clip_worker(Clip* clip) { void Cacher::run() { // open_lock is used to prevent the clip from being destroyed before the cacher has closed it properly + clip->lock.lock(); + clip->finished_opening = false; clip->open = true; caching = true; - clip->open_lock.lock(); open_clip_worker(clip); + clip->finished_opening = true; + while (caching) { clip->can_cache.wait(&clip->lock); if (!caching) { @@ -383,7 +385,7 @@ void Cacher::run() { } close_clip_worker(clip); - clip->lock.unlock(); + clip->lock.unlock(); clip->open_lock.unlock(); } diff --git a/playback/playback.cpp b/playback/playback.cpp index be4cbe922..5b924d4d8 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -36,7 +36,7 @@ void handle_media(Sequence* sequence, long playhead, bool multithreaded) { // if thread is already working, we don't want to touch this, // but we also don't want to hang the UI thread if (!c->open) { - if (c->lock.tryLock()) { + if (c->open_lock.tryLock()) { open_clip(c, multithreaded); // add to current_clips, (insertion) sorted by track so composite them in order diff --git a/project/clip.cpp b/project/clip.cpp index 3f92f0083..e954a48d9 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -56,6 +56,7 @@ void Clip::reset() { cache_A.offset = false; cache_B.offset = false; open = false; + finished_opening = false; pkt_written = false; cache_A.written = false; cache_B.written = false; diff --git a/project/clip.h b/project/clip.h index dbfa60b6c..07e3e85af 100644 --- a/project/clip.h +++ b/project/clip.h @@ -69,6 +69,7 @@ struct Clip bool pkt_written; bool reached_end; bool open; + bool finished_opening; // caching functions bool multithreaded; diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 5ae406411..65b2a6099 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -169,7 +169,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) { panel_timeline->importing = false; panel_timeline->snapped = false; - panel_timeline->redraw_all_clips(); + panel_timeline->redraw_all_clips(true); } } @@ -246,7 +246,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->split_clip_and_relink(sequence->get_clip(clip_index), panel_timeline->drag_frame_start, !(event->modifiers() & Qt::AltModifier)); } panel_timeline->splitting = true; - panel_timeline->redraw_all_clips(); + panel_timeline->redraw_all_clips(true); } break; } @@ -336,7 +336,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } } - panel_timeline->redraw_all_clips(); + panel_timeline->redraw_all_clips(true); } // destroy all ghosts @@ -745,7 +745,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } // redraw clips since we changed them - if (repaint) panel_timeline->redraw_all_clips(); + if (repaint) panel_timeline->redraw_all_clips(true); } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { track_resizing = false; diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 6ab86ac1a..14903dc8a 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -70,58 +70,54 @@ void ViewerWidget::paintGL() for (int i=0;iopen) { + if (!c->finished_opening) { qDebug() << "[WARNING] Tried to display clip" << i << "but it's closed"; texture_failed = true; } else if (is_clip_active(c, playhead)) { - if (c->lock.tryLock()) { - if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - // start preparing cache - get_clip_frame(c, playhead); + if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + // start preparing cache + get_clip_frame(c, playhead); - if (c->texture == NULL) { - qDebug() << "[WARNING] Texture hasn't been created yet"; - texture_failed = true; - } else if (playhead >= c->timeline_in) { - glLoadIdentity(); - int half_width = c->sequence->width/2; - int half_height = c->sequence->height/2; - glOrtho(-half_width, half_width, half_height,- half_height, -1, 1); - int anchor_x = c->media_stream->video_width/2; - int anchor_y = c->media_stream->video_height/2; + if (c->texture == NULL) { + qDebug() << "[WARNING] Texture hasn't been created yet"; + texture_failed = true; + } else if (playhead >= c->timeline_in) { + glLoadIdentity(); + int half_width = c->sequence->width/2; + int half_height = c->sequence->height/2; + glOrtho(-half_width, half_width, half_height,- half_height, -1, 1); + int anchor_x = c->media_stream->video_width/2; + int anchor_y = c->media_stream->video_height/2; - // perform all transform effects - for (int j=0;jeffects.size();j++) { - c->effects.at(j)->process_gl(&anchor_x, &anchor_y); - } - - int anchor_right = c->media_stream->video_width - anchor_x; - int anchor_bottom = c->media_stream->video_height - anchor_y; - - c->texture->bind(); - - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex2f(-anchor_x, -anchor_y); - glTexCoord2f(1.0, 0.0); - glVertex2f(anchor_right, -anchor_y); - glTexCoord2f(1.0, 1.0); - glVertex2f(anchor_right, anchor_bottom); - glTexCoord2f(0.0, 1.0); - glVertex2f(-anchor_x, anchor_bottom); - glEnd(); - - c->texture->release(); + // perform all transform effects + for (int j=0;jeffects.size();j++) { + c->effects.at(j)->process_gl(&anchor_x, &anchor_y); } - } else if (render_audio && - c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - // clip is not caching, start caching audio - cache_clip(c, playhead, false, false, c->reset_audio); + + int anchor_right = c->media_stream->video_width - anchor_x; + int anchor_bottom = c->media_stream->video_height - anchor_y; + + c->texture->bind(); + + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); + glVertex2f(-anchor_x, -anchor_y); + glTexCoord2f(1.0, 0.0); + glVertex2f(anchor_right, -anchor_y); + glTexCoord2f(1.0, 1.0); + glVertex2f(anchor_right, anchor_bottom); + glTexCoord2f(0.0, 1.0); + glVertex2f(-anchor_x, anchor_bottom); + glEnd(); + + c->texture->release(); } + } else if (render_audio && + c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && + c->lock.tryLock()) { + // clip is not caching, start caching audio + cache_clip(c, playhead, false, false, c->reset_audio); c->lock.unlock(); - } else { - qDebug() << "[WARNING] Clip was locked, must still be active"; - texture_failed = true; } } }