potential fix for #240

This commit is contained in:
itsmattkc
2019-01-04 11:54:18 +11:00
parent dabed8ceec
commit 4157e4d432
11 changed files with 192 additions and 190 deletions
+44 -44
View File
@@ -57,7 +57,7 @@ enum ExportFormats {
ExportDialog::ExportDialog(QWidget *parent) :
QDialog(parent)
{
setWindowTitle("Export \"" + sequence->name + "\"");
setWindowTitle("Export \"" + sequence->name + "\"");
setup_ui();
rangeCombobox->setCurrentIndex(0);
@@ -479,7 +479,7 @@ void ExportDialog::export_action() {
connect(et, SIGNAL(finished()), this, SLOT(render_thread_finished()));
connect(et, SIGNAL(progress_changed(int, qint64)), this, SLOT(update_progress_bar(int, qint64)));
closeActiveClips(sequence, true);
closeActiveClips(sequence);
mainWindow->autorecover_interval();
@@ -603,40 +603,40 @@ void ExportDialog::setup_ui() {
videoGroupbox->setFlat(false);
videoGroupbox->setCheckable(true);
QGridLayout* videoGridLayout = new QGridLayout(videoGroupbox);
QGridLayout* videoGridLayout = new QGridLayout(videoGroupbox);
videoGridLayout->addWidget(new QLabel("Codec:"), 0, 0, 1, 1);
vcodecCombobox = new QComboBox(videoGroupbox);
videoGridLayout->addWidget(vcodecCombobox, 0, 1, 1, 1);
videoGridLayout->addWidget(new QLabel("Codec:"), 0, 0, 1, 1);
vcodecCombobox = new QComboBox(videoGroupbox);
videoGridLayout->addWidget(vcodecCombobox, 0, 1, 1, 1);
videoGridLayout->addWidget(new QLabel("Width:"), 1, 0, 1, 1);
widthSpinbox = new QSpinBox(videoGroupbox);
widthSpinbox->setMaximum(16777216);
videoGridLayout->addWidget(widthSpinbox, 1, 1, 1, 1);
videoGridLayout->addWidget(new QLabel("Width:"), 1, 0, 1, 1);
widthSpinbox = new QSpinBox(videoGroupbox);
widthSpinbox->setMaximum(16777216);
videoGridLayout->addWidget(widthSpinbox, 1, 1, 1, 1);
videoGridLayout->addWidget(new QLabel("Height:"), 2, 0, 1, 1);
heightSpinbox = new QSpinBox(videoGroupbox);
heightSpinbox->setMaximum(16777216);
videoGridLayout->addWidget(heightSpinbox, 2, 1, 1, 1);
videoGridLayout->addWidget(new QLabel("Height:"), 2, 0, 1, 1);
heightSpinbox = new QSpinBox(videoGroupbox);
heightSpinbox->setMaximum(16777216);
videoGridLayout->addWidget(heightSpinbox, 2, 1, 1, 1);
videoGridLayout->addWidget(new QLabel("Frame Rate:"), 3, 0, 1, 1);
framerateSpinbox = new QDoubleSpinBox(videoGroupbox);
framerateSpinbox->setMaximum(60);
framerateSpinbox->setValue(0);
videoGridLayout->addWidget(framerateSpinbox, 3, 1, 1, 1);
videoGridLayout->addWidget(new QLabel("Frame Rate:"), 3, 0, 1, 1);
framerateSpinbox = new QDoubleSpinBox(videoGroupbox);
framerateSpinbox->setMaximum(60);
framerateSpinbox->setValue(0);
videoGridLayout->addWidget(framerateSpinbox, 3, 1, 1, 1);
videoGridLayout->addWidget(new QLabel("Compression Type:"), 4, 0, 1, 1);
videoGridLayout->addWidget(new QLabel("Compression Type:"), 4, 0, 1, 1);
compressionTypeCombobox = new QComboBox(videoGroupbox);
compressionTypeCombobox->addItem("Quality-based (Constant Rate Factor)");
compressionTypeCombobox->addItem("File size-based (Two-Pass)");
videoGridLayout->addWidget(compressionTypeCombobox, 4, 1, 1, 1);
videoGridLayout->addWidget(compressionTypeCombobox, 4, 1, 1, 1);
videoBitrateLabel = new QLabel(videoGroupbox);
videoGridLayout->addWidget(videoBitrateLabel, 5, 0, 1, 1);
videobitrateSpinbox = new QDoubleSpinBox(videoGroupbox);
videobitrateSpinbox->setMaximum(100);
videobitrateSpinbox->setValue(2);
videoGridLayout->addWidget(videobitrateSpinbox, 5, 1, 1, 1);
videoBitrateLabel = new QLabel(videoGroupbox);
videoGridLayout->addWidget(videoBitrateLabel, 5, 0, 1, 1);
videobitrateSpinbox = new QDoubleSpinBox(videoGroupbox);
videobitrateSpinbox->setMaximum(100);
videobitrateSpinbox->setValue(2);
videoGridLayout->addWidget(videobitrateSpinbox, 5, 1, 1, 1);
verticalLayout->addWidget(videoGroupbox);
@@ -644,60 +644,60 @@ void ExportDialog::setup_ui() {
audioGroupbox->setTitle("Audio");
audioGroupbox->setCheckable(true);
QGridLayout* audioGridLayout = new QGridLayout(audioGroupbox);
QGridLayout* audioGridLayout = new QGridLayout(audioGroupbox);
audioGridLayout->addWidget(new QLabel("Codec:"), 0, 0, 1, 1);
audioGridLayout->addWidget(new QLabel("Codec:"), 0, 0, 1, 1);
acodecCombobox = new QComboBox(audioGroupbox);
audioGridLayout->addWidget(acodecCombobox, 0, 1, 1, 1);
audioGridLayout->addWidget(acodecCombobox, 0, 1, 1, 1);
audioGridLayout->addWidget(new QLabel("Sampling Rate:"), 1, 0, 1, 1);
audioGridLayout->addWidget(new QLabel("Sampling Rate:"), 1, 0, 1, 1);
samplingRateSpinbox = new QSpinBox(audioGroupbox);
samplingRateSpinbox->setMaximum(96000);
samplingRateSpinbox->setValue(0);
audioGridLayout->addWidget(samplingRateSpinbox, 1, 1, 1, 1);
audioGridLayout->addWidget(samplingRateSpinbox, 1, 1, 1, 1);
audioGridLayout->addWidget(new QLabel("Bitrate (Kbps/CBR):"), 3, 0, 1, 1);
audioGridLayout->addWidget(new QLabel("Bitrate (Kbps/CBR):"), 3, 0, 1, 1);
audiobitrateSpinbox = new QSpinBox(audioGroupbox);
audiobitrateSpinbox->setMaximum(320);
audiobitrateSpinbox->setValue(256);
audioGridLayout->addWidget(audiobitrateSpinbox, 3, 1, 1, 1);
audioGridLayout->addWidget(audiobitrateSpinbox, 3, 1, 1, 1);
verticalLayout->addWidget(audioGroupbox);
QHBoxLayout* progressLayout = new QHBoxLayout();
QHBoxLayout* progressLayout = new QHBoxLayout();
progressBar = new QProgressBar(this);
progressBar->setFormat("%p% (ETA: 0:00:00)");
progressBar->setEnabled(false);
progressBar->setValue(0);
progressLayout->addWidget(progressBar);
progressLayout->addWidget(progressBar);
renderCancel = new QPushButton(this);
renderCancel->setText("x");
renderCancel->setEnabled(false);
renderCancel->setMaximumSize(QSize(20, 16777215));
connect(renderCancel, SIGNAL(clicked(bool)), this, SLOT(cancel_render()));
progressLayout->addWidget(renderCancel);
progressLayout->addWidget(renderCancel);
verticalLayout->addLayout(progressLayout);
verticalLayout->addLayout(progressLayout);
QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->addStretch();
QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->addStretch();
export_button = new QPushButton(this);
export_button->setText("Export");
connect(export_button, SIGNAL(clicked(bool)), this, SLOT(export_action()));
buttonLayout->addWidget(export_button);
buttonLayout->addWidget(export_button);
cancel_button = new QPushButton(this);
cancel_button->setText("Cancel");
connect(cancel_button, SIGNAL(clicked(bool)), this, SLOT(reject()));
buttonLayout->addWidget(cancel_button);
buttonLayout->addWidget(cancel_button);
buttonLayout->addStretch();
buttonLayout->addStretch();
verticalLayout->addLayout(buttonLayout);
verticalLayout->addLayout(buttonLayout);
connect(formatCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(format_changed(int)));
connect(compressionTypeCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(comp_type_changed(int)));
+1 -1
View File
@@ -335,7 +335,7 @@ void SpeedDialog::accept() {
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i);
if (c->open) close_clip(c);
if (c->open) close_clip(c, true);
if (c->track >= 0
&& maintain_pitch->checkState() != Qt::PartiallyChecked
+25 -25
View File
@@ -80,13 +80,13 @@ void MainWindow::setup_layout(bool reset) {
#endif
// load panels from file
if (!reset) {
if (!reset) {
QFile panel_config(get_data_path() + "/layout");
if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) {
restoreState(panel_config.readAll(), 0);
panel_config.close();
}
}
}
layout()->update();
}
@@ -727,7 +727,7 @@ void MainWindow::setup_menus() {
tools_menu->addAction("Preferences", this, SLOT(preferences()), QKeySequence("Ctrl+."));
#ifdef QT_DEBUG
tools_menu->addAction("Clear Undo", this, SLOT(clear_undo_stack()));
tools_menu->addAction("Clear Undo", this, SLOT(clear_undo_stack()));
#endif
// INITIALIZE HELP MENU
@@ -762,11 +762,11 @@ void MainWindow::updateTitle(const QString& url) {
void MainWindow::closeEvent(QCloseEvent *e) {
if (can_close_project()) {
panel_effect_controls->clear_effects(true);
panel_sequence_viewer->viewer_widget->delete_function();
panel_footage_viewer->viewer_widget->delete_function();
set_sequence(NULL);
panel_footage_viewer->set_main_sequence();
QString data_dir = get_data_path();
if (!data_dir.isEmpty() && !autorecovery_filename.isEmpty()) {
if (QFile::exists(autorecovery_filename)) {
@@ -824,10 +824,10 @@ void MainWindow::reset_layout() {
}
void MainWindow::go_to_start() {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
panel_sequence_viewer->go_to_start();
} else if (panel_footage_viewer->is_focused()) {
panel_footage_viewer->go_to_start();
@@ -835,10 +835,10 @@ void MainWindow::go_to_start() {
}
void MainWindow::prev_frame() {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
panel_sequence_viewer->previous_frame();
} else if (panel_footage_viewer->is_focused()) {
panel_footage_viewer->previous_frame();
@@ -846,10 +846,10 @@ void MainWindow::prev_frame() {
}
void MainWindow::next_frame() {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
panel_sequence_viewer->next_frame();
} else if (panel_footage_viewer->is_focused()) {
panel_footage_viewer->next_frame();
@@ -857,10 +857,10 @@ void MainWindow::next_frame() {
}
void MainWindow::go_to_end() {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
panel_sequence_viewer->go_to_end();
} else if (panel_footage_viewer->is_focused()) {
panel_footage_viewer->go_to_end();
@@ -868,10 +868,10 @@ void MainWindow::go_to_end() {
}
void MainWindow::playpause() {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
if (panel_timeline->focused()
|| panel_sequence_viewer->is_focused()
|| panel_effect_controls->keyframe_focus()
|| panel_graph_editor->view_is_focused()) {
panel_sequence_viewer->toggle_play();
} else if (panel_footage_viewer->is_focused()) {
panel_footage_viewer->toggle_play();
+13 -9
View File
@@ -573,14 +573,14 @@ void Viewer::set_media(Media* m) {
seq->frame_rate = 30;
if (footage->video_tracks.size() > 0) {
const FootageStream& video_stream = footage->video_tracks.at(0);
seq->width = video_stream.video_width;
seq->height = video_stream.video_height;
if (video_stream.video_frame_rate > 0 && !video_stream.infinite_length) seq->frame_rate = video_stream.video_frame_rate;
const FootageStream& video_stream = footage->video_tracks.at(0);
seq->width = video_stream.video_width;
seq->height = video_stream.video_height;
if (video_stream.video_frame_rate > 0 && !video_stream.infinite_length) seq->frame_rate = video_stream.video_frame_rate;
Clip* c = new Clip(seq);
c->media = media;
c->media_stream = video_stream.file_index;
c->media_stream = video_stream.file_index;
c->timeline_in = 0;
c->timeline_out = footage->get_length_in_frames(seq->frame_rate);
if (c->timeline_out <= 0) c->timeline_out = 150;
@@ -594,12 +594,12 @@ void Viewer::set_media(Media* m) {
}
if (footage->audio_tracks.size() > 0) {
const FootageStream& audio_stream = footage->audio_tracks.at(0);
seq->audio_frequency = audio_stream.audio_frequency;
const FootageStream& audio_stream = footage->audio_tracks.at(0);
seq->audio_frequency = audio_stream.audio_frequency;
Clip* c = new Clip(seq);
c->media = media;
c->media_stream = audio_stream.file_index;
c->media_stream = audio_stream.file_index;
c->timeline_in = 0;
c->timeline_out = footage->get_length_in_frames(seq->frame_rate);
c->track = 0;
@@ -610,7 +610,7 @@ void Viewer::set_media(Media* m) {
if (footage->video_tracks.size() == 0) {
viewer_widget->waveform = true;
viewer_widget->waveform_clip = c;
viewer_widget->waveform_ms = &audio_stream;
viewer_widget->waveform_ms = &audio_stream;
viewer_widget->update();
}
} else {
@@ -698,6 +698,10 @@ void Viewer::clean_created_seq() {
void Viewer::set_sequence(bool main, Sequence *s) {
reset_all_audio();
if (seq != NULL) {
closeActiveClips(seq);
}
main_sequence = main;
seq = (main) ? sequence : s;
+85 -86
View File
@@ -37,39 +37,39 @@ bool texture_failed = false;
bool rendering = false;
bool clip_uses_cacher(Clip* clip) {
return (clip->media == NULL && clip->track >= 0) || (clip->media != NULL && clip->media->get_type() == MEDIA_TYPE_FOOTAGE);
return (clip->media == NULL && clip->track >= 0) || (clip->media != NULL && clip->media->get_type() == MEDIA_TYPE_FOOTAGE);
}
void open_clip(Clip* clip, bool multithreaded) {
if (clip_uses_cacher(clip)) {
clip->multithreaded = multithreaded;
if (multithreaded) {
if (clip->open_lock.tryLock()) {
// maybe keep cacher instance in memory while clip exists for performance?
clip->cacher = new Cacher(clip);
QObject::connect(clip->cacher, SIGNAL(finished()), clip->cacher, SLOT(deleteLater()));
clip->cacher->start((clip->track < 0) ? QThread::NormalPriority : QThread::TimeCriticalPriority);
}
} else {
clip->finished_opening = false;
clip->open = true;
if (clip_uses_cacher(clip)) {
clip->multithreaded = multithreaded;
if (multithreaded) {
if (clip->open_lock.tryLock()) {
// maybe keep cacher instance in memory while clip exists for performance?
clip->cacher = new Cacher(clip);
QObject::connect(clip->cacher, SIGNAL(finished()), clip->cacher, SLOT(deleteLater()));
clip->cacher->start((clip->track < 0) ? QThread::NormalPriority : QThread::TimeCriticalPriority);
}
} else {
clip->finished_opening = false;
clip->open = true;
open_clip_worker(clip);
}
} else {
clip->open = true;
}
open_clip_worker(clip);
}
} else {
clip->open = true;
}
}
void close_clip(Clip* clip) {
void close_clip(Clip* clip, bool wait) {
// destroy opengl texture in main thread
if (clip->texture != NULL) {
if (clip->texture != NULL) {
delete clip->texture;
clip->texture = NULL;
}
for (int i=0;i<clip->effects.size();i++) {
clip->effects.at(i)->close();
if (clip->effects.at(i)->is_open()) clip->effects.at(i)->close();
}
if (clip->fbo != NULL) {
@@ -79,29 +79,30 @@ void close_clip(Clip* clip) {
clip->fbo = NULL;
}
if (clip_uses_cacher(clip)) {
if (clip->multithreaded) {
clip->cacher->caching = false;
clip->can_cache.wakeAll();
} else {
close_clip_worker(clip);
}
} else {
if (clip->media != NULL && clip->media->get_type() == MEDIA_TYPE_SEQUENCE)
closeActiveClips(clip->media->to_sequence(), false);
if (clip_uses_cacher(clip)) {
if (clip->multithreaded) {
clip->cacher->caching = false;
clip->can_cache.wakeAll();
if (wait) clip->cacher->wait();
} else {
close_clip_worker(clip);
}
} else {
if (clip->media != NULL && clip->media->get_type() == MEDIA_TYPE_SEQUENCE)
closeActiveClips(clip->media->to_sequence());
clip->open = false;
}
}
}
void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVector<Clip*>& nests) {
if (clip_uses_cacher(clip)) {
if (clip_uses_cacher(clip)) {
if (clip->multithreaded) {
clip->cacher->playhead = playhead;
clip->cacher->reset = reset;
clip->cacher->nests = nests;
clip->cacher->scrubbing = scrubbing;
if (reset && clip->queue.size() > 0) clip->cacher->interrupt = true;
clip->cacher->scrubbing = scrubbing;
if (reset && clip->queue.size() > 0) clip->cacher->interrupt = true;
clip->can_cache.wakeAll();
} else {
@@ -111,16 +112,16 @@ void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVector<C
}
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);
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) {
if (c->finished_opening) {
const FootageStream* ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream);
const FootageStream* ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream);
int64_t target_pts = qMax(static_cast<int64_t>(0), playhead_to_timestamp(c, playhead));
int64_t second_pts = qRound64(av_q2d(av_inv_q(c->stream->time_base)));
if (ms->video_interlacing != VIDEO_PROGRESSIVE) {
int64_t target_pts = qMax(static_cast<int64_t>(0), playhead_to_timestamp(c, playhead));
int64_t second_pts = qRound64(av_q2d(av_inv_q(c->stream->time_base)));
if (ms->video_interlacing != VIDEO_PROGRESSIVE) {
target_pts *= 2;
second_pts *= 2;
}
@@ -132,7 +133,7 @@ void get_clip_frame(Clip* c, long playhead) {
c->queue_lock.lock();
if (c->queue.size() > 0) {
if (ms->infinite_length) {
if (ms->infinite_length) {
target_frame = c->queue.at(0);
#ifdef GCF_DEBUG
dout << "GCF ==> USE PRECISE (INFINITE)";
@@ -192,14 +193,14 @@ void get_clip_frame(Clip* c, long playhead) {
#endif
c->reached_end = false;
cache = false;
} else if (target_pts != c->last_invalid_ts && (target_pts < target_frame->pts || pts_diff > second_pts)) {
} else if (target_pts != c->last_invalid_ts && (target_pts < target_frame->pts || pts_diff > second_pts)) {
#ifdef GCF_DEBUG
dout << "GCF ==> RESET" << target_pts << "(" << target_frame->pts << "-" << target_frame->pts+target_frame->pkt_duration << ")";
#endif
if (!config.fast_seeking) target_frame = NULL;
if (!config.fast_seeking) target_frame = NULL;
reset = true;
c->last_invalid_ts = target_pts;
c->last_invalid_ts = target_pts;
} else {
#ifdef GCF_DEBUG
dout << "GCF ==> WAIT - target pts:" << target_pts << "closest frame:" << target_frame->pts;
@@ -225,26 +226,26 @@ void get_clip_frame(Clip* c, long playhead) {
int nb_components = av_pix_fmt_desc_get(static_cast<enum AVPixelFormat>(c->pix_fmt))->nb_components;
glPixelStorei(GL_UNPACK_ROW_LENGTH, target_frame->linesize[0]/nb_components);
bool copied = false;
uint8_t* data = target_frame->data[0];
int frame_size;
bool copied = false;
uint8_t* data = target_frame->data[0];
int frame_size;
for (int i=0;i<c->effects.size();i++) {
Effect* e = c->effects.at(i);
if (e->enable_image) {
if (!copied) {
frame_size = target_frame->linesize[0]*target_frame->height;
data = new uint8_t[frame_size];
memcpy(data, target_frame->data[0], frame_size);
copied = true;
}
e->process_image(get_timecode(c, playhead), data, frame_size);
}
}
for (int i=0;i<c->effects.size();i++) {
Effect* e = c->effects.at(i);
if (e->enable_image) {
if (!copied) {
frame_size = target_frame->linesize[0]*target_frame->height;
data = new uint8_t[frame_size];
memcpy(data, target_frame->data[0], frame_size);
copied = true;
}
e->process_image(get_timecode(c, playhead), data, frame_size);
}
}
c->texture->setData(0, get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8, data);
if (copied) delete [] data;
if (copied) delete [] data;
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
@@ -252,13 +253,13 @@ void get_clip_frame(Clip* c, long playhead) {
c->queue_lock.unlock();
// get more frames
QVector<Clip*> empty;
if (cache) cache_clip(c, playhead, reset, false, empty);
QVector<Clip*> empty;
if (cache) cache_clip(c, playhead, reset, false, empty);
}
}
long playhead_to_clip_frame(Clip* c, long playhead) {
return (qMax(0L, playhead - c->get_timeline_in_with_transition()) + c->get_clip_in_with_transition());
return (qMax(0L, playhead - c->get_timeline_in_with_transition()) + c->get_clip_in_with_transition());
}
double playhead_to_clip_seconds(Clip* c, long playhead) {
@@ -278,11 +279,11 @@ int64_t playhead_to_timestamp(Clip* c, long playhead) {
int retrieve_next_frame(Clip* c, AVFrame* f) {
int result = 0;
int receive_ret;
int receive_ret;
// do we need to retrieve a new packet for a new frame?
av_frame_unref(f);
while ((receive_ret = avcodec_receive_frame(c->codecCtx, f)) == AVERROR(EAGAIN)) {
while ((receive_ret = avcodec_receive_frame(c->codecCtx, f)) == AVERROR(EAGAIN)) {
int read_ret = 0;
do {
if (c->pkt_written) {
@@ -293,15 +294,15 @@ int retrieve_next_frame(Clip* c, AVFrame* f) {
if (read_ret >= 0) {
c->pkt_written = true;
}
} while (read_ret >= 0 && c->pkt->stream_index != c->media_stream);
} while (read_ret >= 0 && c->pkt->stream_index != c->media_stream);
if (read_ret >= 0) {
int send_ret = avcodec_send_packet(c->codecCtx, c->pkt);
if (send_ret < 0) {
dout << "[ERROR] Failed to send packet to decoder." << send_ret;
return send_ret;
return send_ret;
}
} else {
} else {
if (read_ret == AVERROR_EOF) {
int send_ret = avcodec_send_packet(c->codecCtx, NULL);
if (send_ret < 0) {
@@ -323,32 +324,30 @@ int retrieve_next_frame(Clip* c, AVFrame* f) {
}
bool is_clip_active(Clip* c, long playhead) {
return c->enabled
&& c->get_timeline_in_with_transition() < playhead + ceil(c->sequence->frame_rate*2)
&& c->get_timeline_out_with_transition() > playhead
&& playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition() < c->getMaximumLength();
return c->enabled
&& c->get_timeline_in_with_transition() < playhead + ceil(c->sequence->frame_rate*2)
&& c->get_timeline_out_with_transition() > playhead
&& playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition() < c->getMaximumLength();
}
void set_sequence(Sequence* s) {
closeActiveClips(sequence, true);
panel_effect_controls->clear_effects(true);
sequence = s;
sequence = s;
panel_sequence_viewer->set_main_sequence();
panel_timeline->update_sequence();
panel_timeline->setFocus();
panel_timeline->update_sequence();
panel_timeline->setFocus();
}
void closeActiveClips(Sequence *s, bool wait) {
void closeActiveClips(Sequence *s) {
if (s != NULL) {
for (int i=0;i<s->clips.size();i++) {
Clip* c = s->clips.at(i);
if (c != NULL) {
if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_SEQUENCE) {
closeActiveClips(c->media->to_sequence(), wait);
if (c->open) close_clip(c);
} else if (clip_uses_cacher(c) && c->open) {
close_clip(c);
if (c->multithreaded && wait) c->cacher->wait();
for (int i=0;i<s->clips.size();i++) {
Clip* c = s->clips.at(i);
if (c != NULL) {
if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_SEQUENCE) {
closeActiveClips(c->media->to_sequence());
if (c->open) close_clip(c, true);
} else if (c->open) {
close_clip(c, true);
}
}
}
+2 -2
View File
@@ -15,7 +15,7 @@ extern bool rendering;
bool clip_uses_cacher(Clip* clip);
void open_clip(Clip* clip, bool multithreaded);
void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVector<Clip *> &nests);
void close_clip(Clip* clip);
void close_clip(Clip* clip, bool wait);
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);
@@ -32,6 +32,6 @@ int retrieve_next_frame(Clip* c, AVFrame* f);
bool is_clip_active(Clip* c, long playhead);
void get_next_audio(Clip* c, bool mix);
void set_sequence(Sequence* s);
void closeActiveClips(Sequence* s, bool wait);
void closeActiveClips(Sequence* s);
#endif // PLAYBACK_H
+8 -12
View File
@@ -12,6 +12,7 @@
#include "project/media.h"
#include "io/clipboard.h"
#include "undo.h"
#include "debug.h"
extern "C" {
#include <libavformat/avformat.h>
@@ -113,9 +114,9 @@ void Clip::refresh() {
Footage* m = media->to_footage();
if (track < 0 && m->video_tracks.size() > 0) {
media_stream = m->video_tracks.at(0).file_index;
media_stream = m->video_tracks.at(0).file_index;
} else if (track >= 0 && m->audio_tracks.size() > 0) {
media_stream = m->audio_tracks.at(0).file_index;
media_stream = m->audio_tracks.at(0).file_index;
}
}
replaced = false;
@@ -171,12 +172,7 @@ Transition* Clip::get_closing_transition() {
Clip::~Clip() {
if (open) {
close_clip(this);
// make sure clip has closed before clip is destroyed
if (multithreaded && media != NULL && media->get_type() == MEDIA_TYPE_FOOTAGE) {
cacher->wait();
}
close_clip(this, true);
}
if (opening_transition != -1) this->sequence->hard_delete_transition(this, TA_OPENING_TRANSITION);
@@ -241,8 +237,8 @@ void Clip::recalculateMaxLength() {
case MEDIA_TYPE_FOOTAGE:
{
Footage* m = media->to_footage();
const FootageStream* ms = m->get_stream_from_file_index(track < 0, media_stream);
if (ms != NULL && ms->infinite_length) {
const FootageStream* ms = m->get_stream_from_file_index(track < 0, media_stream);
if (ms != NULL && ms->infinite_length) {
calculated_length = LONG_MAX;
} else {
calculated_length = m->get_length_in_frames(fr);
@@ -269,7 +265,7 @@ int Clip::getWidth() {
switch (media->get_type()) {
case MEDIA_TYPE_FOOTAGE:
{
const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream);
const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream);
if (ms != NULL) return ms->video_width;
if (sequence != NULL) return sequence->width;
}
@@ -287,7 +283,7 @@ int Clip::getHeight() {
switch (media->get_type()) {
case MEDIA_TYPE_FOOTAGE:
{
const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream);
const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream);
if (ms != NULL) return ms->video_height;
if (sequence != NULL) return sequence->height;
}
+4
View File
@@ -749,6 +749,10 @@ void Effect::save(QXmlStreamWriter& stream) {
}
}
bool Effect::is_open() {
return isOpen;
}
void Effect::validate_meta_path() {
if (!meta->path.isEmpty() || (vertPath.isEmpty() && fragPath.isEmpty())) return;
QList<QString> effects_paths = get_effects_paths();
+1
View File
@@ -140,6 +140,7 @@ public:
void save(QXmlStreamWriter& stream);
// glsl handling
bool is_open();
void open();
void close();
virtual void startEffect();
+5 -7
View File
@@ -150,7 +150,7 @@ void DeleteClipAction::redo() {
// remove ref to clip
ref = seq->clips.at(index);
if (ref->open) {
close_clip(ref);
close_clip(ref, true);
}
seq->clips[index] = NULL;
@@ -493,7 +493,7 @@ void AddClipCommand::undo() {
Clip* c = seq->clips.last();
panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track);
undone_clips.prepend(c);
if (c->open) close_clip(c);
if (c->open) close_clip(c, true);
seq->clips.removeLast();
}
mainWindow->setWindowModified(old_project_changed);
@@ -587,8 +587,7 @@ void ReplaceMediaCommand::replace(QString& filename) {
for (int j=0;j<s->clips.size();j++) {
Clip* c = s->clips.at(j);
if (c != NULL && c->media == item && c->open) {
close_clip(c);
if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) c->cacher->wait();
close_clip(c, true);
c->replaced = true;
}
}
@@ -628,8 +627,7 @@ void ReplaceClipMediaCommand::replace(bool undo) {
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i);
if (c->open) {
close_clip(c);
if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) c->cacher->wait();
close_clip(c, true);
}
if (undo) {
@@ -1102,7 +1100,7 @@ void CloseAllClipsCommand::undo() {
}
void CloseAllClipsCommand::redo() {
closeActiveClips(sequence, true);
closeActiveClips(sequence);
}
UpdateFootageTooltip::UpdateFootageTooltip(Media *i) :
+4 -4
View File
@@ -72,7 +72,7 @@ void ViewerWidget::delete_function() {
// destroy all textures as well
if (viewer->seq != NULL) {
makeCurrent();
closeActiveClips(viewer->seq, true);
closeActiveClips(viewer->seq);
doneCurrent();
}
}
@@ -485,7 +485,7 @@ GLuint ViewerWidget::compose_sequence(QVector<Clip*>& nests, bool render_audio)
Footage* m = c->media->to_footage();
if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) {
if (m->ready) {
const FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream);
const FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream);
if (ms != NULL && is_clip_active(c, playhead)) {
// if thread is already working, we don't want to touch this,
// but we also don't want to hang the UI thread
@@ -495,7 +495,7 @@ GLuint ViewerWidget::compose_sequence(QVector<Clip*>& nests, bool render_audio)
clip_is_active = true;
if (c->track >= 0) audio_track_count++;
} else if (c->open) {
close_clip(c);
close_clip(c, false);
}
} else {
//dout << "[WARNING] Media '" + m->name + "' was not ready, retrying...";
@@ -507,7 +507,7 @@ GLuint ViewerWidget::compose_sequence(QVector<Clip*>& nests, bool render_audio)
if (!c->open) open_clip(c, !rendering);
clip_is_active = true;
} else if (c->open) {
close_clip(c);
close_clip(c, false);
}
}
if (clip_is_active) {