implemented reversing #120
This commit is contained in:
+23
-11
@@ -296,12 +296,12 @@ void SpeedDialog::frame_rate_update() {
|
||||
duration->set_value((len_val == -1) ? qSNaN() : len_val, false);
|
||||
}
|
||||
|
||||
void set_speed(ComboAction* ca, Clip* c, double speed) {
|
||||
void set_speed(ComboAction* ca, Clip* c, double speed, bool ripple, long& ep, long& lr) {
|
||||
long proposed_out = c->timeline_out;
|
||||
double multiplier = (c->speed / speed);
|
||||
proposed_out = c->timeline_in + (c->getLength() * multiplier);
|
||||
ca->append(new SetSpeedAction(c, speed));
|
||||
if (proposed_out > c->timeline_out) {
|
||||
if (!ripple && 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
|
||||
@@ -311,23 +311,31 @@ void set_speed(ComboAction* ca, Clip* c, double speed) {
|
||||
}
|
||||
}
|
||||
}
|
||||
ep = qMin(ep, c->timeline_out);
|
||||
lr = qMax(lr, proposed_out - c->timeline_out);
|
||||
ca->append(new MoveClipAction(c, c->timeline_in, proposed_out, c->clip_in * multiplier, c->track));
|
||||
}
|
||||
|
||||
void SpeedDialog::accept() {
|
||||
ComboAction* ca = new ComboAction();
|
||||
|
||||
long earliest_point = LONG_MAX;
|
||||
long longest_ripple = LONG_MIN;
|
||||
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
Clip* c = clips.at(i);
|
||||
if (c->open) close_clip(c);
|
||||
|
||||
if (c->track >= 0) {
|
||||
if (maintain_pitch->checkState() != Qt::PartiallyChecked) {
|
||||
ca->append(new SetBool(&c->maintain_audio_pitch, maintain_pitch->isChecked()));
|
||||
}
|
||||
if (c->track >= 0
|
||||
&& maintain_pitch->checkState() != Qt::PartiallyChecked
|
||||
&& c->maintain_audio_pitch != maintain_pitch->isChecked()) {
|
||||
ca->append(new SetBool(&c->maintain_audio_pitch, maintain_pitch->isChecked()));
|
||||
}
|
||||
|
||||
if (reverse->checkState() != Qt::PartiallyChecked) {
|
||||
if (reverse->checkState() != Qt::PartiallyChecked && c->reverse != reverse->isChecked()) {
|
||||
long new_clip_in = (c->getMaximumLength() - (c->getLength() + c->clip_in));
|
||||
ca->append(new MoveClipAction(c, c->timeline_in, c->timeline_out, new_clip_in, c->track));
|
||||
c->clip_in = new_clip_in;
|
||||
ca->append(new SetBool(&c->reverse, reverse->isChecked()));
|
||||
}
|
||||
}
|
||||
@@ -336,7 +344,7 @@ void SpeedDialog::accept() {
|
||||
// simply set speed
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
Clip* c = clips.at(i);
|
||||
set_speed(ca, c, percent->value());
|
||||
set_speed(ca, c, percent->value(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
}
|
||||
} else if (!qIsNaN(frame_rate->value())) {
|
||||
bool can_change_all = true;
|
||||
@@ -365,19 +373,23 @@ void SpeedDialog::accept() {
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
Clip* c = clips.at(i);
|
||||
if (c->track < 0) {
|
||||
set_speed(ca, c, frame_rate->value() / c->getMediaFrameRate());
|
||||
set_speed(ca, c, frame_rate->value() / c->getMediaFrameRate(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
} else if (can_change_all) {
|
||||
set_speed(ca, c, frame_rate->value() / cached_fr);
|
||||
set_speed(ca, c, frame_rate->value() / cached_fr, ripple->isChecked(), earliest_point, longest_ripple);
|
||||
}
|
||||
}
|
||||
} else if (!qIsNaN(duration->value())) {
|
||||
// simply set duration
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
Clip* c = clips.at(i);
|
||||
set_speed(ca, c, (c->getLength() * c->speed) / duration->value());
|
||||
set_speed(ca, c, (c->getLength() * c->speed) / duration->value(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
}
|
||||
}
|
||||
|
||||
if (ripple->isChecked()) {
|
||||
ca->append(new RippleCommand(clips.at(0)->sequence, earliest_point, longest_ripple));
|
||||
}
|
||||
|
||||
undo_stack.push(ca);
|
||||
|
||||
panel_timeline->redraw_all_clips(true);
|
||||
|
||||
+4
-1
@@ -257,7 +257,8 @@ void cache_video_worker(Clip* c, long playhead, ClipCache* cache) {
|
||||
}
|
||||
} else {
|
||||
if (ret == AVERROR_EOF) {
|
||||
c->reached_end = true;
|
||||
// TODO sorta hacky? not even sure if "reached_end" serves a proper purpose anymore
|
||||
if (!c->reverse) c->reached_end = true;
|
||||
} else {
|
||||
qDebug() << "[WARNING] Raw frame data could not be retrieved." << ret;
|
||||
error = true;
|
||||
@@ -559,6 +560,8 @@ void cache_clip_worker(Clip* clip, long playhead, bool write_A, bool write_B, bo
|
||||
}
|
||||
|
||||
void close_clip_worker(Clip* clip) {
|
||||
clip->finished_opening = false;
|
||||
|
||||
if (clip->media_type == MEDIA_TYPE_FOOTAGE) {
|
||||
// closes ffmpeg file handle and frees any memory used for caching
|
||||
MediaStream* ms = static_cast<Media*>(clip->media)->get_stream_from_file_index(clip->track < 0, clip->media_stream);
|
||||
|
||||
@@ -111,7 +111,9 @@ bool get_clip_frame(Clip* c, long playhead) {
|
||||
|
||||
long sequence_clip_time = playhead - c->timeline_in + c->clip_in;
|
||||
|
||||
if (c->reverse && !ms->infinite_length) sequence_clip_time = c->getMaximumLength() - sequence_clip_time - 1;
|
||||
if (c->reverse && !ms->infinite_length) {
|
||||
sequence_clip_time = c->getMaximumLength() - sequence_clip_time - 1;
|
||||
}
|
||||
|
||||
long clip_time = refactor_frame_number(sequence_clip_time, c->sequence->frame_rate, c->getMediaFrameRate()*c->speed);
|
||||
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ void Clip::reset_audio() {
|
||||
audio_buffer_write = 0;
|
||||
reached_end = false;
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
{
|
||||
Sequence* nested_sequence = static_cast<Sequence*>(media);
|
||||
for (int i=0;i<nested_sequence->clips.size();i++) {
|
||||
|
||||
+4
-5
@@ -49,6 +49,10 @@ void ComboAction::append(QUndoCommand* u) {
|
||||
|
||||
MoveClipAction::MoveClipAction(Clip *c, long iin, long iout, long iclip_in, int itrack) :
|
||||
clip(c),
|
||||
old_in(c->timeline_in),
|
||||
old_out(c->timeline_out),
|
||||
old_clip_in(c->clip_in),
|
||||
old_track(c->track),
|
||||
new_in(iin),
|
||||
new_out(iout),
|
||||
new_clip_in(iclip_in),
|
||||
@@ -66,11 +70,6 @@ void MoveClipAction::undo() {
|
||||
}
|
||||
|
||||
void MoveClipAction::redo() {
|
||||
old_in = clip->timeline_in;
|
||||
old_out = clip->timeline_out;
|
||||
old_clip_in = clip->clip_in;
|
||||
old_track = clip->track;
|
||||
|
||||
clip->timeline_in = new_in;
|
||||
clip->timeline_out = new_out;
|
||||
clip->clip_in = new_clip_in;
|
||||
|
||||
@@ -1732,6 +1732,10 @@ void TimelineWidget::redraw_clips() {
|
||||
for (int i=0;i<waveform_limit;i++) {
|
||||
int waveform_index = qFloor((((clip->clip_in + ((double) i/panel_timeline->zoom))/media_length) * ms->audio_preview.size())/divider)*divider;
|
||||
|
||||
if (clip->reverse) {
|
||||
waveform_index = ms->audio_preview.size() - waveform_index;
|
||||
}
|
||||
|
||||
int rectified_height = 0;
|
||||
|
||||
for (int j=0;j<ms->audio_channels;j++) {
|
||||
@@ -1748,7 +1752,7 @@ void TimelineWidget::redraw_clips() {
|
||||
clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "tried to reach" << offset + 1 << "limit:" << ms->audio_preview.size();
|
||||
qDebug() << "[WARNING] Tried to reach" << offset + 1 << ", limit:" << ms->audio_preview.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user