This commit is contained in:
itsmattkc
2018-11-01 16:12:17 +11:00
parent 229674f5e2
commit 9f0ff7f561
14 changed files with 136 additions and 53 deletions
+11 -2
View File
@@ -164,13 +164,22 @@ void load_vst_effects() {
}
void init_effects() {
dout << "Starting init effect (TODO: multithread this)";
EffectInit* init_thread = new EffectInit();
QObject::connect(init_thread, SIGNAL(finished()), init_thread, SLOT(deleteLater()));
init_thread->start();
}
EffectInit::EffectInit() {
effects_loaded.lock();
}
void EffectInit::run() {
dout << "[INFO] Initializing effects...";
load_internal_effects();
load_shader_effects();
load_vst_effects();
effects_loaded.unlock();
dout << "Completed init effect (TODO: multithread this)";
dout << "[INFO] Finished initializing effects";
}
double double_lerp(double a, double b, double t) {
+8
View File
@@ -10,6 +10,7 @@
#include <QOpenGLTexture>
#include <QJSEngine>
#include <QMutex>
#include <QThread>
class QLabel;
class QWidget;
class CollapsibleWidget;
@@ -262,4 +263,11 @@ private:
int get_index_in_clip();
};
class EffectInit : public QThread {
public:
EffectInit();
protected:
void run();
};
#endif // EFFECT_H
+2 -2
View File
@@ -66,11 +66,11 @@ void PreviewGenerator::parse_media() {
&& fmt_ctx->streams[i]->codecpar->width > 0
&& fmt_ctx->streams[i]->codecpar->height > 0) {
/*dout << "avg_frame_rate was:" << fmt_ctx->streams[i]->avg_frame_rate.num << "/" << fmt_ctx->streams[i]->avg_frame_rate.den;
dout << "avg_frame_rate was:" << fmt_ctx->streams[i]->avg_frame_rate.num << "/" << fmt_ctx->streams[i]->avg_frame_rate.den;
dout << "r_frame_rate was:" << fmt_ctx->streams[i]->r_frame_rate.num << "/" << fmt_ctx->streams[i]->r_frame_rate.den;
dout << "codec_frame_rate was:" << fmt_ctx->streams[i]->codec->framerate.num << "/" << fmt_ctx->streams[i]->codec->framerate.den;
dout << "nb_frames was:" << fmt_ctx->streams[i]->nb_frames;
dout << "duration was:" << fmt_ctx->streams[i]->duration << "OR fmt_ctx's duration is:" << fmt_ctx->duration;*/
dout << "duration was:" << fmt_ctx->streams[i]->duration << "OR fmt_ctx's duration is:" << fmt_ctx->duration;
if (fmt_ctx->streams[i]->avg_frame_rate.den == 0
&& fmt_ctx->streams[i]->duration == AV_NOPTS_VALUE) { // source is LIKELY a still image
+4 -2
View File
@@ -327,8 +327,10 @@ void MainWindow::editMenu_About_To_Be_Shown() {
}
void MainWindow::undo() {
undo_stack.undo();
update_ui(true);
if (!panel_timeline->importing) { // workaround to prevent crash (and also users should never need to do this)
undo_stack.undo();
update_ui(true);
}
}
void MainWindow::redo() {
+22 -2
View File
@@ -245,6 +245,18 @@ void Project::get_all_media_from_table(QList<QTreeWidgetItem*> items, QList<QTre
}
}
bool delete_clips_in_clipboard_with_media(ComboAction* ca, Media* m) {
int delete_count = 0;
for (int i=0;i<panel_timeline->clip_clipboard.size();i++) {
Clip* c = panel_timeline->clip_clipboard.at(i);
if (c->media == m) {
ca->append(new RemoveClipsFromClipboard(i-delete_count));
delete_count++;
}
}
return (delete_count > 0);
}
void Project::delete_selected_media() {
ComboAction* ca = new ComboAction();
QList<QTreeWidgetItem*> items = ui->treeWidget->selectedItems();
@@ -325,7 +337,11 @@ void Project::delete_selected_media() {
}
}
}
}
}
if (confirm_delete) {
delete_clips_in_clipboard_with_media(ca, media);
}
}
}
@@ -638,10 +654,10 @@ void Project::delete_clips_using_selected_media() {
} else {
ComboAction* ca = new ComboAction();
bool deleted = false;
QList<QTreeWidgetItem*> items = source_table->selectedItems();
for (int i=0;i<sequence->clips.size();i++) {
Clip* c = sequence->clips.at(i);
if (c != NULL) {
QList<QTreeWidgetItem*> items = source_table->selectedItems();
for (int j=0;j<items.size();j++) {
Media* m = get_footage_from_tree(items.at(j));
if (c->media == m) {
@@ -651,6 +667,10 @@ void Project::delete_clips_using_selected_media() {
}
}
}
for (int j=0;j<items.size();j++) {
Media* m = get_footage_from_tree(items.at(j));
if (delete_clips_in_clipboard_with_media(ca, m)) deleted = true;
}
if (deleted) {
undo_stack.push(ca);
update_ui(true);
+3 -1
View File
@@ -164,6 +164,9 @@ public:
bool creating;
int creating_object;
// clipboard
QVector<Clip*> clip_clipboard;
Ui::Timeline *ui;
public slots:
void repaint_timeline();
@@ -203,7 +206,6 @@ private:
void decheck_tool_buttons(QObject* sender);
void set_tool(int tool);
long last_frame;
QVector<Clip*> clip_clipboard;
int scroll;
int default_track_height;
+2
View File
@@ -132,6 +132,8 @@ void AudioSenderThread::run() {
// got all the bytes, write again
written_bytes += send_audio_to_output(0, audio_ibuffer_size);
}
dout << "read to" << audio_ibuffer_read;
}
}
lock.unlock();
+38 -41
View File
@@ -179,20 +179,25 @@ void cache_audio_worker(Clip* c, Clip* nest) {
rev_frame->nb_samples += frame->nb_samples;
// if (c->frame->pts == c->rev_target) {
if ((c->frame->pts >= c->reverse_target) || (ret == AVERROR_EOF)) {
/*dout << "time for the end of rev cache" << rev_frame->nb_samples << c->rev_target << c->frame->pts << c->frame->pkt_duration << c->frame->nb_samples;
/*
#ifdef AUDIOWARNINGS
dout << "time for the end of rev cache" << rev_frame->nb_samples << c->rev_target << c->frame->pts << c->frame->pkt_duration << c->frame->nb_samples;
dout << "diff:" << (c->frame->pkt_pts + c->frame->pkt_duration) - c->rev_target;
int cutoff = qRound64 ((((c->frame->pkt_pts + c->frame->pkt_duration) - c->rev_target) * timebase) * c->sequence->audio_frequency);
#endif
int cutoff = qRound64((((c->frame->pkt_pts + c->frame->pkt_duration) - c->reverse_target) * timebase) * c->sequence->audio_frequency);
if (cutoff > 0) {
#ifdef AUDIOWARNINGS
dout << "cut off" << cutoff << "samples (rate:" << c->sequence->audio_frequency << ")";
#endif
rev_frame->nb_samples -= cutoff;
}*/
}
*/
#ifdef AUDIOWARNINGS
dout << "pre cutoff deets::: rev_frame.pts:" << rev_frame->pts << "rev_frame.nb_samples" << rev_frame->nb_samples << "rev_target:" << c->reverse_target;
#endif
rev_frame->nb_samples = qRound64(static_cast<double>(c->reverse_target - rev_frame->pts) / c->stream->codecpar->sample_rate * c->sequence->audio_frequency);
rev_frame->nb_samples = qRound64(static_cast<double>(c->reverse_target - rev_frame->pts) / c->stream->codecpar->sample_rate * (c->sequence->audio_frequency / c->speed));
#ifdef AUDIOWARNINGS
dout << "post cutoff deets::" << rev_frame->nb_samples;
#endif
@@ -337,6 +342,7 @@ void cache_audio_worker(Clip* c, Clip* nest) {
#ifdef AUDIOWARNINGS
if (c->audio_buffer_write >= buffer_timeline_out) dout << "timeline out at fsi" << c->frame_sample_index << "of frame ts" << c->frame->pts;
#endif
audio_write_lock.unlock();
if (c->frame_sample_index == nb_bytes) {
@@ -360,25 +366,20 @@ void cache_video_worker(Clip* c, long playhead) {
int64_t target_pts = seconds_to_timestamp(c, playhead_to_clip_seconds(c, playhead));
int limit = c->max_queue_size;
if (c->reverse) limit *= 2;
/*if (c->reverse) {
bool found = false;
for (int i=0;i<c->queue.size();i++) {
if (target_pts > c->queue.at(i)->pts && target_pts <= c->queue.at(i)->pts + c->queue.at(i)->pkt_duration) {
found = true;
break;
}
}
if (!found) {
// we need like one more frame
limit = c->queue.size() + 1;
}
}*/
if (c->ignore_reverse) {
// waiting for one frame
limit = c->queue.size() + 1;
} else if (c->reverse) {
limit *= 2;
}
if (c->queue.size() < limit) {
bool reverse = (c->reverse && !c->ignore_reverse);
c->ignore_reverse = false;
int64_t eighth_second = av_q2d(av_inv_q(c->stream->time_base))*0.125;
int64_t smallest_pts = INT64_MAX;
if (c->reverse && c->queue.size() > 0) {
if (reverse && c->queue.size() > 0) {
int64_t quarter_sec = qRound64(av_q2d(av_inv_q(c->stream->time_base))) >> 2;
for (int i=0;i<c->queue.size();i++) {
smallest_pts = qMin(smallest_pts, c->queue.at(i)->pts);
@@ -401,7 +402,7 @@ void cache_video_worker(Clip* c, long playhead) {
if (read_ret >= 0) {
bool send_it = false;
if (c->reverse) {
if (reverse) {
send_it = true;
} else if (send_frame->pts > target_pts - eighth_second) {
send_it = true;
@@ -438,7 +439,7 @@ void cache_video_worker(Clip* c, long playhead) {
av_frame_free(&frame);
break;
} else {
if (c->reverse && ((smallest_pts == target_pts && frame->pts >= smallest_pts) || (smallest_pts != target_pts && frame->pts > smallest_pts))) {
if (reverse && ((smallest_pts == target_pts && frame->pts >= smallest_pts) || (smallest_pts != target_pts && frame->pts > smallest_pts))) {
av_frame_free(&frame);
break;
} else {
@@ -446,27 +447,23 @@ void cache_video_worker(Clip* c, long playhead) {
c->queue_lock.lock();
c->queue.append(frame);
if (!c->reverse && c->queue.size() == limit) {
// if (rendering) {
// see if we got the frame we needed (used for speed ups primarily)
bool found = false;
for (int i=0;i<c->queue.size();i++) {
// TODO/NOTE: this will not work on clips that are sped up AND reversed
if (c->queue.at(i)->pts >= target_pts) {
found = true;
break;
}
}
if (found) {
c->queue_lock.unlock();
if (!reverse && c->queue.size() == limit) {
// see if we got the frame we needed (used for speed ups primarily)
bool found = false;
for (int i=0;i<c->queue.size();i++) {
// TODO/NOTE: this will not work on clips that are sped up AND reversed
if (c->queue.at(i)->pts >= target_pts) {
found = true;
break;
} else {
// remove earliest frame and loop to store another
c->queue_remove_earliest();
}
// } else {
// break;
// }
}
if (found) {
c->queue_lock.unlock();
break;
} else {
// remove earliest frame and loop to store another
c->queue_remove_earliest();
}
}
c->queue_lock.unlock();
}
+2 -1
View File
@@ -197,7 +197,8 @@ void get_clip_frame(Clip* c, long playhead) {
#ifdef GCF_DEBUG
dout << "GCF ==> WAIT - target pts:" << target_pts << "closest frame:" << target_frame->pts;
#endif
//if (c->queue.size() >= c->max_queue_size) c->queue_remove_earliest();
if (c->queue.size() >= c->max_queue_size) c->queue_remove_earliest();
c->ignore_reverse = true;
target_frame = NULL;
}
}
+2 -1
View File
@@ -35,7 +35,8 @@ Clip::Clip(Sequence* s) :
autoscale(config.autoscale_by_default),
maintain_audio_pitch(false),
reverse(false),
use_existing_frame(false)
use_existing_frame(false),
ignore_reverse(false)
{
reset();
}
+1
View File
@@ -94,6 +94,7 @@ struct Clip
bool finished_opening;
bool replaced;
int skip_type;
bool ignore_reverse;
// caching functions
bool use_existing_frame;
+26
View File
@@ -1719,8 +1719,34 @@ MoveEffectCommand::MoveEffectCommand() :
void MoveEffectCommand::undo() {
clip->effects.move(to, from);
mainWindow->setWindowModified(old_project_changed);
}
void MoveEffectCommand::redo() {
clip->effects.move(from, to);
mainWindow->setWindowModified(true);
}
RemoveClipsFromClipboard::RemoveClipsFromClipboard(int index) :
pos(index),
old_project_changed(mainWindow->isWindowModified()),
done(false)
{}
RemoveClipsFromClipboard::~RemoveClipsFromClipboard() {
if (done) {
delete clip;
}
}
void RemoveClipsFromClipboard::undo() {
panel_timeline->clip_clipboard.insert(pos, clip);
done = false;
}
void RemoveClipsFromClipboard::redo() {
qDebug() << "removed" << pos << "from clipboard";
clip = panel_timeline->clip_clipboard.at(pos);
panel_timeline->clip_clipboard.removeAt(pos);
done = true;
}
+13
View File
@@ -557,4 +557,17 @@ private:
bool old_project_changed;
};
class RemoveClipsFromClipboard : public QUndoCommand {
public:
RemoveClipsFromClipboard(int index);
~RemoveClipsFromClipboard();
void undo();
void redo();
private:
int pos;
Clip* clip;
bool old_project_changed;
bool done;
};
#endif // UNDO_H
+2 -1
View File
@@ -235,7 +235,6 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
}
if (config.enable_drag_files_to_timeline && event->mimeData()->hasUrls()) {
dout << "TODO get data for:";
QList<QUrl> urls = event->mimeData()->urls();
if (!urls.isEmpty()) {
QStringList file_list;
@@ -247,6 +246,8 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
panel_project->process_file_list(false, file_list, NULL, false);
for (int i=0;i<panel_project->last_imported_media.size();i++) {
// waits for media to have a duration
// TODO would be much nicer if this was multithreaded
panel_project->last_imported_media.at(i)->ready_lock.lock();
panel_project->last_imported_media.at(i)->ready_lock.unlock();