better effects support with nested sequences
This commit is contained in:
@@ -89,7 +89,10 @@ private:
|
||||
int prev_x;
|
||||
int prev_y;
|
||||
int prev_rot;
|
||||
int perp_x;
|
||||
int perp_y;
|
||||
double t;
|
||||
bool inside;
|
||||
};
|
||||
|
||||
class TextEffect : public Effect {
|
||||
|
||||
+26
-4
@@ -12,7 +12,7 @@
|
||||
#include "project/sequence.h"
|
||||
#include "panels/timeline.h"
|
||||
|
||||
ShakeEffect::ShakeEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SHAKE_EFFECT) {
|
||||
ShakeEffect::ShakeEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SHAKE_EFFECT), inside(false) {
|
||||
ui_layout->addWidget(new QLabel("Intensity:"), 0, 0);
|
||||
intensity_val = new LabelSlider();
|
||||
intensity_val->set_minimum_value(0);
|
||||
@@ -88,6 +88,22 @@ void ShakeEffect::process_gl(int*, int*) {
|
||||
prev_y = next_y;
|
||||
next_x = (qrand() % (int) (intensity_val->value() * 2)) - intensity_val->value();
|
||||
next_y = (qrand() % (int) (intensity_val->value() * 2)) - intensity_val->value();
|
||||
|
||||
// find perpendicular slope that passes through (mid_x, mid_y)
|
||||
int mid_x = (prev_x + next_x) / 2;
|
||||
int mid_y = (prev_y + next_y) / 2;
|
||||
int slope_num = (next_y-prev_y);
|
||||
if (slope_num > 0) {
|
||||
int slope_den = (next_x-prev_x);
|
||||
int add = (next_x-prev_x)/4;
|
||||
if (inside) add = -add;
|
||||
inside = !inside;
|
||||
perp_x = mid_x + add;
|
||||
perp_y = (-(slope_den / slope_num)) * perp_x + mid_y;
|
||||
} else {
|
||||
perp_x = mid_x;
|
||||
perp_y = mid_y;
|
||||
}
|
||||
} else {
|
||||
prev_x = 0;
|
||||
prev_y = 0;
|
||||
@@ -106,10 +122,16 @@ void ShakeEffect::process_gl(int*, int*) {
|
||||
}
|
||||
shake_progress = 0;
|
||||
}
|
||||
t = 1 - qPow(((double) shake_progress / (double) shake_limit)-1, 2);
|
||||
offset_x = lerp(prev_x, next_x, t);
|
||||
offset_y = lerp(prev_y, next_y, t);
|
||||
|
||||
t = (double) shake_progress / (double) shake_limit;
|
||||
|
||||
double oneminust = 1 - t;
|
||||
|
||||
offset_x = (qPow(oneminust, 2)*prev_x) + (2*oneminust*t*perp_x) + (qPow(t, 2) * next_x);
|
||||
offset_y = (qPow(oneminust, 2)*prev_y) + (2*oneminust*t*perp_y) + (qPow(t, 2) * next_y);
|
||||
|
||||
offset_rot = lerp(prev_rot, next_rot, t);
|
||||
|
||||
glTranslatef(offset_x, offset_y, 0);
|
||||
glRotatef(offset_rot, 0, 0, 1);
|
||||
shake_progress++;
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ MainWindow::~MainWindow() {
|
||||
QString data_dir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||
if (!data_dir.isEmpty() && !autorecovery_filename.isEmpty()) {
|
||||
if (QFile::exists(autorecovery_filename)) {
|
||||
QFile::remove(autorecovery_filename);
|
||||
QFile::rename(autorecovery_filename, autorecovery_filename + "." + QDateTime::currentDateTimeUtc().toString("yyyyMMddHHmmss"));
|
||||
}
|
||||
}
|
||||
if (!config_dir.isEmpty()) {
|
||||
|
||||
+5
-1
@@ -46,7 +46,11 @@ void cache_audio_worker(Clip* c, Clip* nest) {
|
||||
// no more audio left in frame, get a new one
|
||||
if (!c->reached_end) {
|
||||
retrieve_next_frame_raw_data(c, frame);
|
||||
apply_audio_effects(c, frame, av_samples_get_buffer_size(NULL, frame->channels, frame->nb_samples, static_cast<AVSampleFormat>(frame->format), 1));
|
||||
int byte_count = av_samples_get_buffer_size(NULL, frame->channels, frame->nb_samples, static_cast<AVSampleFormat>(frame->format), 1);
|
||||
apply_audio_effects(c, frame, byte_count);
|
||||
if (nest != NULL) {
|
||||
apply_audio_effects(nest, frame, byte_count);
|
||||
}
|
||||
} else {
|
||||
// set by retrieve_next_frame_raw_data indicating no more frames in file,
|
||||
// but there still may be samples in swresample
|
||||
|
||||
@@ -131,6 +131,12 @@ void Clip::run_video_pre_effect_stack(long playhead, int* anchor_x, int* anchor_
|
||||
}
|
||||
}
|
||||
|
||||
void Clip::run_video_post_effect_stack() {
|
||||
for (int j=0;j<effects.size();j++) {
|
||||
if (effects.at(j)->is_enabled()) effects.at(j)->post_gl();
|
||||
}
|
||||
}
|
||||
|
||||
Clip::~Clip() {
|
||||
if (open) {
|
||||
close_clip(this);
|
||||
|
||||
@@ -43,6 +43,7 @@ struct Clip
|
||||
void reset();
|
||||
void refresh();
|
||||
void run_video_pre_effect_stack(long playhead, int *anchor_x, int *anchor_y);
|
||||
void run_video_post_effect_stack();
|
||||
|
||||
// timeline variables
|
||||
Sequence* sequence;
|
||||
|
||||
+2
-3
@@ -204,9 +204,7 @@ void ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
c->texture->release();
|
||||
|
||||
// perform all transform effects
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
if (c->effects.at(j)->is_enabled()) c->effects.at(j)->post_gl();
|
||||
}
|
||||
c->run_video_post_effect_stack();
|
||||
}
|
||||
} else if (render_audio &&
|
||||
c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
|
||||
@@ -218,6 +216,7 @@ void ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
compose_sequence(c, render_audio);
|
||||
c->run_video_post_effect_stack();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user