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;
// get default frame rate/percentage
clip_percent = c->speed;
if (c->track < 0) {
double media_frame_rate = c->getMediaFrameRate();
clip_percent = c->frame_rate / media_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;
bool process_video = true;
if (c->media_type == MEDIA_TYPE_FOOTAGE) {
Media* m = static_cast<Media*>(c->media);
if (m != NULL) {
MediaStream* ms = m->get_stream_from_file_index(true, c->media_stream);
if (ms != NULL && ms->infinite_length) {
process_video = false;
}
}
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;
} else {
clip_percent = c->frame_rate;
if (process_video) {
double media_frame_rate = c->getMediaFrameRate();
// 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
@@ -145,21 +155,29 @@ void SpeedDialog::frame_rate_update() {
}
void SpeedDialog::accept() {
// TODO make undoable lmao
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i);
close_clip(c);
if (c->track < 0) {
if (!qIsNaN(frame_rate->value())) {
// TODO add validators
c->timeline_out = c->timeline_in + (c->getLength() * (c->frame_rate / frame_rate->value()));
c->frame_rate = frame_rate->value();
}
} else {
if (!qIsNaN(percent->value())) {
c->timeline_out = c->timeline_in + (c->getLength() * (c->frame_rate / percent->value()));
c->frame_rate = percent->value();
long proposed_out = c->timeline_out;
if (!qIsNaN(percent->value())) {
double multiplier = (c->speed / percent->value());
proposed_out = c->timeline_in + (c->getLength() * multiplier);
c->clip_in *= multiplier;
c->speed = percent->value();
}
if (proposed_out > c->timeline_out) {
for (int i=0;i<c->sequence->clips.size();i++) {
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();
}
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
c->autoscale = false;
c->frame_rate = 0;
c->speed = 1.0;
c->media = NULL;
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();
} else if (attr.name() == "stream") {
stream_id = attr.value().toInt();
} else if (attr.name() == "framerate") {
c->frame_rate = attr.value().toDouble();
} else if (attr.name() == "speed") {
c->speed = attr.value().toDouble();
} else if (attr.name() == "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("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));
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) {
// get precise sample offset for the elected clip_in from this audio frame
double target_sts = 0;
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 target_sts = playhead_to_seconds(c, c->audio_target_frame);
double frame_sts = (frame->pts * av_q2d(c->stream->time_base));
int nb_samples = qRound((target_sts - frame_sts)*c->sequence->audio_frequency);
if (nb_samples == 0) {
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->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->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) {
// 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) {
case MEDIA_TYPE_FOOTAGE:
{
@@ -482,7 +473,7 @@ void open_clip_worker(Clip* clip) {
NULL,
sequence->audio_layout,
static_cast<AVSampleFormat>(sample_format),
sequence->audio_frequency,
sequence->audio_frequency / clip->speed,
clip->codecCtx->channel_layout,
static_cast<AVSampleFormat>(clip->stream->codecpar->format),
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]->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]->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]);
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);
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;
bool no_frame = false;
@@ -213,7 +213,7 @@ bool get_clip_frame(Clip* c, long playhead) {
double playhead_to_seconds(Clip* c, long playhead) {
// 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) {
+4 -6
View File
@@ -54,7 +54,7 @@ Clip* Clip::copy(Sequence* s) {
copy->media_type = media_type;
copy->media_stream = media_stream;
copy->autoscale = autoscale;
copy->frame_rate = frame_rate;
copy->speed = speed;
for (int i=0;i<effects.size();i++) {
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 (closing_transition != NULL) copy->closing_transition = closing_transition->copy();
copy->recalculateMaxLength();
return copy;
}
@@ -173,11 +175,7 @@ long Clip::getLength() {
void Clip::recalculateMaxLength() {
double fr = this->sequence->frame_rate;
if (track < 0) {
fr *= (getMediaFrameRate()/frame_rate);
} else {
fr /= frame_rate;
}
fr /= speed;
switch (media_type) {
case MEDIA_TYPE_FOOTAGE:
+3 -4
View File
@@ -71,7 +71,7 @@ struct Clip
int media_stream;
int getWidth();
int getHeight();
double frame_rate;
double speed;
long calculated_length;
// other variables (should be "duplicated" in copy())
@@ -110,15 +110,14 @@ struct Clip
AVFilterContext* buffersink_ctx;
AVFilterContext* buffersrc_ctx;
// video playback variables
// SwsContext* sws_ctx;
// video playback variables
QOpenGLFramebufferObject** fbo;
QOpenGLTexture* texture;
long texture_frame;
bool autoscale;
// audio playback variables
// SwrContext* swr_ctx;
SwrContext* swr_ctx;
int frame_sample_index;
int audio_buffer_write;
bool audio_reset;
+14 -11
View File
@@ -330,6 +330,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
c->timeline_out = g.out;
c->clip_in = g.clip_in;
c->track = g.track;
c->speed = 1.0;
if (c->media_type == MEDIA_TYPE_FOOTAGE) {
Media* m = static_cast<Media*>(c->media);
if (m->video_tracks.size() == 0) {
@@ -347,8 +348,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
c->color_r = 128;
c->color_g = 128;
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;
} else if (c->media_type == MEDIA_TYPE_SEQUENCE) {
// sequence (red?ish?)
@@ -357,10 +357,9 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
c->color_b = 128;
Sequence* media = static_cast<Sequence*>(c->media);
c->frame_rate = (c->track < 0) ? media->frame_rate : 1.0;
c->name = media->name;
}
c->recalculateMaxLength();
added_clips.append(c);
}
@@ -619,7 +618,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
c->color_b = 64;
c->track = g.track;
c->frame_rate = (c->track < 0) ? sequence->frame_rate : 1.0;
c->speed = 1.0;
QVector<Clip*> add;
add.append(c);
@@ -1734,7 +1733,7 @@ void TimelineWidget::redraw_clips() {
int channel_height = clip_rect.height()/ms->audio_channels;
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;
@@ -1742,13 +1741,17 @@ void TimelineWidget::redraw_clips() {
int mid = clip_rect.top()+channel_height*j+(channel_height/2);
int offset = waveform_index+(j*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 ((offset + 1) < ms->audio_preview.size()) {
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) {
rectified_height += (max - min);
if (config.rectified_waveforms) {
rectified_height += (max - min);
} else {
clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max);
}
} 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 (c != NULL && !(nest != NULL && !same_sign(c->track, nest->track))) {
bool clip_is_active = false;
// backwards compatibilty
if (c->frame_rate == 0 && c->track >= 0) {
c->frame_rate = 1.0;
}
bool clip_is_active = false;
switch (c->media_type) {
case MEDIA_TYPE_FOOTAGE:
@@ -194,9 +189,6 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
if (m->ready) {
MediaStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream);
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,
// but we also don't want to hang the UI thread
if (!c->open) {
@@ -212,13 +204,8 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
}
break;
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_TONE:
// backwards compatibility
if (c->frame_rate == 0 && c->track < 0) c->frame_rate = s->frame_rate;
if (is_clip_active(c, playhead)) {
if (!c->open) open_clip(c, !rendering);
clip_is_active = true;