mostly finished speed

This commit is contained in:
itsmattkc
2018-10-05 01:32:34 +10:00
parent 5f16c1c84f
commit a3cb0d6cb9
8 changed files with 79 additions and 83 deletions
+46 -28
View File
@@ -73,28 +73,38 @@ void SpeedDialog::run() {
double clip_percent; double clip_percent;
// get default frame rate/percentage // get default frame rate/percentage
clip_percent = c->speed;
if (c->track < 0) { if (c->track < 0) {
double media_frame_rate = c->getMediaFrameRate(); bool process_video = true;
if (c->media_type == MEDIA_TYPE_FOOTAGE) {
clip_percent = c->frame_rate / media_frame_rate; Media* m = static_cast<Media*>(c->media);
if (m != NULL) {
// get "default" frame rate" MediaStream* ms = m->get_stream_from_file_index(true, c->media_stream);
if (enable_frame_rate) { if (ms != NULL && ms->infinite_length) {
// check if frame rate is equal to default process_video = false;
if (!qIsNaN(default_frame_rate) && !qFuzzyCompare(media_frame_rate, default_frame_rate)) { }
default_frame_rate = NAN;
} }
if (!qIsNaN(current_frame_rate) && !qFuzzyCompare(c->frame_rate, current_frame_rate)) {
current_frame_rate = NAN;
}
} else {
default_frame_rate = media_frame_rate;
current_frame_rate = c->frame_rate;
} }
enable_frame_rate = true; if (process_video) {
} else { double media_frame_rate = c->getMediaFrameRate();
clip_percent = c->frame_rate;
// get "default" frame rate"
if (enable_frame_rate) {
// check if frame rate is equal to default
if (!qIsNaN(default_frame_rate) && !qFuzzyCompare(media_frame_rate, default_frame_rate)) {
default_frame_rate = NAN;
}
if (!qIsNaN(current_frame_rate) && !qFuzzyCompare(media_frame_rate*c->speed, current_frame_rate)) {
current_frame_rate = NAN;
}
} else {
default_frame_rate = media_frame_rate;
current_frame_rate = media_frame_rate*c->speed;
}
enable_frame_rate = true;
}
} }
// get default length // get default length
@@ -145,21 +155,29 @@ void SpeedDialog::frame_rate_update() {
} }
void SpeedDialog::accept() { void SpeedDialog::accept() {
// TODO make undoable lmao
for (int i=0;i<clips.size();i++) { for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i); Clip* c = clips.at(i);
close_clip(c); close_clip(c);
if (c->track < 0) { long proposed_out = c->timeline_out;
if (!qIsNaN(frame_rate->value())) { if (!qIsNaN(percent->value())) {
// TODO add validators double multiplier = (c->speed / percent->value());
c->timeline_out = c->timeline_in + (c->getLength() * (c->frame_rate / frame_rate->value())); proposed_out = c->timeline_in + (c->getLength() * multiplier);
c->frame_rate = frame_rate->value(); c->clip_in *= multiplier;
} c->speed = percent->value();
} else { }
if (!qIsNaN(percent->value())) { if (proposed_out > c->timeline_out) {
c->timeline_out = c->timeline_in + (c->getLength() * (c->frame_rate / percent->value())); for (int i=0;i<c->sequence->clips.size();i++) {
c->frame_rate = percent->value(); Clip* compare = c->sequence->clips.at(i);
if (compare != NULL
&& compare->track == c->track
&& compare->timeline_in >= c->timeline_out && compare->timeline_in < proposed_out) {
proposed_out = compare->timeline_in;
}
} }
} }
c->timeline_out = proposed_out;
c->recalculateMaxLength(); c->recalculateMaxLength();
} }
panel_timeline->redraw_all_clips(true); panel_timeline->redraw_all_clips(true);
+4 -4
View File
@@ -756,7 +756,7 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
// backwards compatibility code // backwards compatibility code
c->autoscale = false; c->autoscale = false;
c->frame_rate = 0; c->speed = 1.0;
c->media = NULL; c->media = NULL;
for (int j=0;j<stream.attributes().size();j++) { for (int j=0;j<stream.attributes().size();j++) {
@@ -788,8 +788,8 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
media_id = attr.value().toInt(); media_id = attr.value().toInt();
} else if (attr.name() == "stream") { } else if (attr.name() == "stream") {
stream_id = attr.value().toInt(); stream_id = attr.value().toInt();
} else if (attr.name() == "framerate") { } else if (attr.name() == "speed") {
c->frame_rate = attr.value().toDouble(); c->speed = attr.value().toDouble();
} else if (attr.name() == "sequence") { } else if (attr.name() == "sequence") {
c->media_type = MEDIA_TYPE_SEQUENCE; c->media_type = MEDIA_TYPE_SEQUENCE;
@@ -1089,7 +1089,7 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
stream.writeAttribute("autoscale", QString::number(c->autoscale)); stream.writeAttribute("autoscale", QString::number(c->autoscale));
stream.writeAttribute("framerate", QString::number(c->frame_rate, 'f', 10)); stream.writeAttribute("speed", QString::number(c->speed, 'f', 10));
stream.writeAttribute("type", QString::number(c->media_type)); stream.writeAttribute("type", QString::number(c->media_type));
switch (c->media_type) { switch (c->media_type) {
+5 -14
View File
@@ -110,19 +110,10 @@ void cache_audio_worker(Clip* c, Clip* nest) {
if (c->audio_just_reset) { if (c->audio_just_reset) {
// get precise sample offset for the elected clip_in from this audio frame // get precise sample offset for the elected clip_in from this audio frame
double target_sts = 0; double target_sts = playhead_to_seconds(c, c->audio_target_frame);
if (c->audio_target_frame < timeline_in) {
target_sts = ((double) c->clip_in / c->sequence->frame_rate);
} else {
target_sts = playhead_to_seconds(c, c->audio_target_frame);
}
double frame_sts = (frame->pts * av_q2d(c->stream->time_base)); double frame_sts = (frame->pts * av_q2d(c->stream->time_base));
int nb_samples = qRound((target_sts - frame_sts)*c->sequence->audio_frequency); int nb_samples = qRound((target_sts - frame_sts)*c->sequence->audio_frequency);
if (nb_samples == 0) { c->frame_sample_index = (nb_samples == 0) ? 0 : av_samples_get_buffer_size(NULL, av_get_channel_layout_nb_channels(c->sequence->audio_layout), nb_samples, AV_SAMPLE_FMT_S16, 1);
c->frame_sample_index = 0;
} else {
c->frame_sample_index = av_samples_get_buffer_size(NULL, av_get_channel_layout_nb_channels(c->sequence->audio_layout), nb_samples, AV_SAMPLE_FMT_S16, 1);
}
c->audio_just_reset = false; c->audio_just_reset = false;
} }
@@ -280,7 +271,7 @@ void cache_video_worker(Clip* c, long playhead, ClipCache* cache) {
} }
void reset_cache(Clip* c, long target_frame) { void reset_cache(Clip* c, long target_frame) {
// if we seek to a whole other place in the timeline, we'll need to reset the cache with new values // if we seek to a whole other place in the timeline, we'll need to reset the cache with new values
switch (c->media_type) { switch (c->media_type) {
case MEDIA_TYPE_FOOTAGE: case MEDIA_TYPE_FOOTAGE:
{ {
@@ -482,7 +473,7 @@ void open_clip_worker(Clip* clip) {
NULL, NULL,
sequence->audio_layout, sequence->audio_layout,
static_cast<AVSampleFormat>(sample_format), static_cast<AVSampleFormat>(sample_format),
sequence->audio_frequency, sequence->audio_frequency / clip->speed,
clip->codecCtx->channel_layout, clip->codecCtx->channel_layout,
static_cast<AVSampleFormat>(clip->stream->codecpar->format), static_cast<AVSampleFormat>(clip->stream->codecpar->format),
clip->stream->codecpar->sample_rate, clip->stream->codecpar->sample_rate,
@@ -497,7 +488,7 @@ void open_clip_worker(Clip* clip) {
clip->cache_A.frames[0]->format = sample_format; clip->cache_A.frames[0]->format = sample_format;
clip->cache_A.frames[0]->channel_layout = sequence->audio_layout; clip->cache_A.frames[0]->channel_layout = sequence->audio_layout;
clip->cache_A.frames[0]->channels = av_get_channel_layout_nb_channels(clip->cache_A.frames[0]->channel_layout); clip->cache_A.frames[0]->channels = av_get_channel_layout_nb_channels(clip->cache_A.frames[0]->channel_layout);
clip->cache_A.frames[0]->sample_rate = sequence->audio_frequency; clip->cache_A.frames[0]->sample_rate = sequence->audio_frequency / clip->speed;
av_frame_make_writable(clip->cache_A.frames[0]); av_frame_make_writable(clip->cache_A.frames[0]);
clip->audio_reset = true; clip->audio_reset = true;
+2 -2
View File
@@ -110,7 +110,7 @@ bool get_clip_frame(Clip* c, long playhead) {
MediaStream* ms = static_cast<Media*>(c->media)->get_stream_from_file_index(c->track < 0, c->media_stream); MediaStream* ms = static_cast<Media*>(c->media)->get_stream_from_file_index(c->track < 0, c->media_stream);
long sequence_clip_time = playhead - c->timeline_in + c->clip_in; long sequence_clip_time = playhead - c->timeline_in + c->clip_in;
long clip_time = refactor_frame_number(sequence_clip_time, c->sequence->frame_rate, c->frame_rate); long clip_time = refactor_frame_number(sequence_clip_time, c->sequence->frame_rate, c->getMediaFrameRate()*c->speed);
AVFrame* current_frame = NULL; AVFrame* current_frame = NULL;
bool no_frame = false; bool no_frame = false;
@@ -213,7 +213,7 @@ bool get_clip_frame(Clip* c, long playhead) {
double playhead_to_seconds(Clip* c, long playhead) { double playhead_to_seconds(Clip* c, long playhead) {
// returns time in seconds // returns time in seconds
return (qMax((long) 0, playhead - c->timeline_in) + c->clip_in)/c->sequence->frame_rate; return ((qMax(0L, playhead - c->timeline_in) + c->clip_in)/c->sequence->frame_rate)*c->speed;
} }
long seconds_to_clip_frame(Clip* c, double seconds) { long seconds_to_clip_frame(Clip* c, double seconds) {
+4 -6
View File
@@ -54,7 +54,7 @@ Clip* Clip::copy(Sequence* s) {
copy->media_type = media_type; copy->media_type = media_type;
copy->media_stream = media_stream; copy->media_stream = media_stream;
copy->autoscale = autoscale; copy->autoscale = autoscale;
copy->frame_rate = frame_rate; copy->speed = speed;
for (int i=0;i<effects.size();i++) { for (int i=0;i<effects.size();i++) {
copy->effects.append(effects.at(i)->copy(copy)); copy->effects.append(effects.at(i)->copy(copy));
@@ -63,6 +63,8 @@ Clip* Clip::copy(Sequence* s) {
if (opening_transition != NULL) copy->opening_transition = opening_transition->copy(); if (opening_transition != NULL) copy->opening_transition = opening_transition->copy();
if (closing_transition != NULL) copy->closing_transition = closing_transition->copy(); if (closing_transition != NULL) copy->closing_transition = closing_transition->copy();
copy->recalculateMaxLength();
return copy; return copy;
} }
@@ -173,11 +175,7 @@ long Clip::getLength() {
void Clip::recalculateMaxLength() { void Clip::recalculateMaxLength() {
double fr = this->sequence->frame_rate; double fr = this->sequence->frame_rate;
if (track < 0) { fr /= speed;
fr *= (getMediaFrameRate()/frame_rate);
} else {
fr /= frame_rate;
}
switch (media_type) { switch (media_type) {
case MEDIA_TYPE_FOOTAGE: case MEDIA_TYPE_FOOTAGE:
+3 -4
View File
@@ -71,7 +71,7 @@ struct Clip
int media_stream; int media_stream;
int getWidth(); int getWidth();
int getHeight(); int getHeight();
double frame_rate; double speed;
long calculated_length; long calculated_length;
// other variables (should be "duplicated" in copy()) // other variables (should be "duplicated" in copy())
@@ -110,15 +110,14 @@ struct Clip
AVFilterContext* buffersink_ctx; AVFilterContext* buffersink_ctx;
AVFilterContext* buffersrc_ctx; AVFilterContext* buffersrc_ctx;
// video playback variables // video playback variables
// SwsContext* sws_ctx;
QOpenGLFramebufferObject** fbo; QOpenGLFramebufferObject** fbo;
QOpenGLTexture* texture; QOpenGLTexture* texture;
long texture_frame; long texture_frame;
bool autoscale; bool autoscale;
// audio playback variables // audio playback variables
// SwrContext* swr_ctx; SwrContext* swr_ctx;
int frame_sample_index; int frame_sample_index;
int audio_buffer_write; int audio_buffer_write;
bool audio_reset; bool audio_reset;
+14 -11
View File
@@ -330,6 +330,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
c->timeline_out = g.out; c->timeline_out = g.out;
c->clip_in = g.clip_in; c->clip_in = g.clip_in;
c->track = g.track; c->track = g.track;
c->speed = 1.0;
if (c->media_type == MEDIA_TYPE_FOOTAGE) { if (c->media_type == MEDIA_TYPE_FOOTAGE) {
Media* m = static_cast<Media*>(c->media); Media* m = static_cast<Media*>(c->media);
if (m->video_tracks.size() == 0) { if (m->video_tracks.size() == 0) {
@@ -347,8 +348,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
c->color_r = 128; c->color_r = 128;
c->color_g = 128; c->color_g = 128;
c->color_b = 192; c->color_b = 192;
} }
c->frame_rate = (c->track < 0) ? m->get_stream_from_file_index(true, c->media_stream)->video_frame_rate : 1.0;
c->name = m->name; c->name = m->name;
} else if (c->media_type == MEDIA_TYPE_SEQUENCE) { } else if (c->media_type == MEDIA_TYPE_SEQUENCE) {
// sequence (red?ish?) // sequence (red?ish?)
@@ -357,10 +357,9 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
c->color_b = 128; c->color_b = 128;
Sequence* media = static_cast<Sequence*>(c->media); Sequence* media = static_cast<Sequence*>(c->media);
c->frame_rate = (c->track < 0) ? media->frame_rate : 1.0;
c->name = media->name; c->name = media->name;
} }
c->recalculateMaxLength();
added_clips.append(c); added_clips.append(c);
} }
@@ -619,7 +618,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
c->color_b = 64; c->color_b = 64;
c->track = g.track; c->track = g.track;
c->frame_rate = (c->track < 0) ? sequence->frame_rate : 1.0; c->speed = 1.0;
QVector<Clip*> add; QVector<Clip*> add;
add.append(c); add.append(c);
@@ -1734,7 +1733,7 @@ void TimelineWidget::redraw_clips() {
int channel_height = clip_rect.height()/ms->audio_channels; int channel_height = clip_rect.height()/ms->audio_channels;
for (int i=0;i<waveform_limit;i++) { for (int i=0;i<waveform_limit;i++) {
int waveform_index = qFloor((((clip->clip_in + ((double) (i*clip->frame_rate)/panel_timeline->zoom))/media_length) * ms->audio_preview.size())/divider)*divider; int waveform_index = qFloor((((clip->clip_in + ((double) i/panel_timeline->zoom))/media_length) * ms->audio_preview.size())/divider)*divider;
int rectified_height = 0; int rectified_height = 0;
@@ -1742,13 +1741,17 @@ void TimelineWidget::redraw_clips() {
int mid = clip_rect.top()+channel_height*j+(channel_height/2); int mid = clip_rect.top()+channel_height*j+(channel_height/2);
int offset = waveform_index+(j*2); int offset = waveform_index+(j*2);
qint8 min = (double)ms->audio_preview.at(offset) / 128.0 * (channel_height/2); if ((offset + 1) < ms->audio_preview.size()) {
qint8 max = (double)ms->audio_preview.at(offset+1) / 128.0 * (channel_height/2); qint8 min = (double)ms->audio_preview.at(offset) / 128.0 * (channel_height/2);
qint8 max = (double)ms->audio_preview.at(offset+1) / 128.0 * (channel_height/2);
if (config.rectified_waveforms) { if (config.rectified_waveforms) {
rectified_height += (max - min); rectified_height += (max - min);
} else {
clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max);
}
} else { } else {
clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max); qDebug() << "tried to reach" << offset + 1 << "limit:" << ms->audio_preview.size();
} }
} }
+1 -14
View File
@@ -180,12 +180,7 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
// if clip starts within one second and/or hasn't finished yet // if clip starts within one second and/or hasn't finished yet
if (c != NULL && !(nest != NULL && !same_sign(c->track, nest->track))) { if (c != NULL && !(nest != NULL && !same_sign(c->track, nest->track))) {
bool clip_is_active = false; bool clip_is_active = false;
// backwards compatibilty
if (c->frame_rate == 0 && c->track >= 0) {
c->frame_rate = 1.0;
}
switch (c->media_type) { switch (c->media_type) {
case MEDIA_TYPE_FOOTAGE: case MEDIA_TYPE_FOOTAGE:
@@ -194,9 +189,6 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
if (m->ready) { if (m->ready) {
MediaStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); MediaStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream);
if (ms != NULL && is_clip_active(c, playhead)) { if (ms != NULL && is_clip_active(c, playhead)) {
// backwards compatibility
if (c->frame_rate == 0 && c->track < 0) c->frame_rate = ms->video_frame_rate;
// if thread is already working, we don't want to touch this, // if thread is already working, we don't want to touch this,
// but we also don't want to hang the UI thread // but we also don't want to hang the UI thread
if (!c->open) { if (!c->open) {
@@ -212,13 +204,8 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
} }
break; break;
case MEDIA_TYPE_SEQUENCE: case MEDIA_TYPE_SEQUENCE:
// backwards compatibility
if (c->frame_rate == 0 == c->track < 0) c->frame_rate = static_cast<Sequence*>(c->media)->frame_rate;
case MEDIA_TYPE_SOLID: case MEDIA_TYPE_SOLID:
case MEDIA_TYPE_TONE: case MEDIA_TYPE_TONE:
// backwards compatibility
if (c->frame_rate == 0 && c->track < 0) c->frame_rate = s->frame_rate;
if (is_clip_active(c, playhead)) { if (is_clip_active(c, playhead)) {
if (!c->open) open_clip(c, !rendering); if (!c->open) open_clip(c, !rendering);
clip_is_active = true; clip_is_active = true;