VERY buggy audio reversing implemented
This commit is contained in:
+6
-1
@@ -788,6 +788,10 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
stream_id = attr.value().toInt();
|
||||
} else if (attr.name() == "speed") {
|
||||
c->speed = attr.value().toDouble();
|
||||
} else if (attr.name() == "maintainpitch") {
|
||||
c->maintain_audio_pitch = (attr.value() == "1");
|
||||
} else if (attr.name() == "reverse") {
|
||||
c->reverse = (attr.value() == "1");
|
||||
} else if (attr.name() == "sequence") {
|
||||
c->media_type = MEDIA_TYPE_SEQUENCE;
|
||||
|
||||
@@ -1086,8 +1090,9 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
|
||||
stream.writeAttribute("b", QString::number(c->color_b));
|
||||
|
||||
stream.writeAttribute("autoscale", QString::number(c->autoscale));
|
||||
|
||||
stream.writeAttribute("speed", QString::number(c->speed, 'f', 10));
|
||||
stream.writeAttribute("maintainpitch", QString::number(c->maintain_audio_pitch));
|
||||
stream.writeAttribute("reverse", QString::number(c->reverse));
|
||||
|
||||
stream.writeAttribute("type", QString::number(c->media_type));
|
||||
switch (c->media_type) {
|
||||
|
||||
+49
-3
@@ -98,7 +98,48 @@ void cache_audio_worker(Clip* c, Clip* nest) {
|
||||
int ret;
|
||||
|
||||
while ((ret = av_buffersink_get_frame(c->buffersink_ctx, frame)) == AVERROR(EAGAIN)) {
|
||||
ret = retrieve_next_frame(c, c->frame);
|
||||
if (c->reverse) {
|
||||
/* TODO i have a feeling that here we're going to have to:
|
||||
* - seek to previous frame
|
||||
* - read it
|
||||
* - convert it to 16-bit PCM LE
|
||||
* - reverse it
|
||||
*
|
||||
* ...good luck :|
|
||||
*/
|
||||
|
||||
if (!c->audio_just_reset) {
|
||||
// get previous frame?
|
||||
avcodec_flush_buffers(c->codecCtx);
|
||||
qDebug() << "seeking to:" << (c->frame->pts - 1);
|
||||
if (av_seek_frame(c->formatCtx, c->stream->index, c->frame->pts - 1, AVSEEK_FLAG_BACKWARD) < 0) {
|
||||
qDebug() << "SEEK FAILED";
|
||||
}
|
||||
}
|
||||
|
||||
ret = retrieve_next_frame(c, c->frame);
|
||||
|
||||
// reverse it
|
||||
int frame_bytes = av_samples_get_buffer_size(NULL, c->frame->channels, c->frame->nb_samples, static_cast<AVSampleFormat>(c->frame->format), 1);
|
||||
qDebug() << "frame bytes:" << frame_bytes;
|
||||
int half_frame_bytes = frame_bytes >> 1;
|
||||
int sample_size = c->frame->channels*2;
|
||||
char* temp_chars = new char[sample_size];
|
||||
for (int i=0;i<half_frame_bytes;i+=sample_size) {
|
||||
for (int j=0;j<sample_size;j++) {
|
||||
temp_chars[j] = c->frame->data[0][i+j];
|
||||
}
|
||||
for (int j=0;j<sample_size;j++) {
|
||||
c->frame->data[0][i+j] = c->frame->data[0][frame_bytes-i-sample_size+j];
|
||||
}
|
||||
for (int j=0;j<sample_size;j++) {
|
||||
c->frame->data[0][frame_bytes-i-sample_size+j] = temp_chars[j];
|
||||
}
|
||||
}
|
||||
delete [] temp_chars;
|
||||
} else {
|
||||
ret = retrieve_next_frame(c, c->frame);
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
if ((ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, c->frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) {
|
||||
@@ -107,7 +148,8 @@ void cache_audio_worker(Clip* c, Clip* nest) {
|
||||
}
|
||||
} else {
|
||||
if (ret == AVERROR_EOF) {
|
||||
c->reached_end = true;
|
||||
// TODO likewise, I'm not sure if this if statement breaks anything (see equivalent section in cache_video_worker)
|
||||
if (c->reverse) c->reached_end = true;
|
||||
} else {
|
||||
qDebug() << "[WARNING] Raw audio frame data could not be retrieved." << ret;
|
||||
c->reached_end = true;
|
||||
@@ -321,7 +363,11 @@ void reset_cache(Clip* c, long target_frame) {
|
||||
av_frame_free(&temp);
|
||||
} else if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
// seek (target_frame represents timeline timecode in frames, not clip timecode)
|
||||
av_seek_frame(c->formatCtx, ms->file_index, playhead_to_seconds(c, target_frame) / timebase, AVSEEK_FLAG_BACKWARD);
|
||||
int64_t timestamp = qRound(playhead_to_seconds(c, target_frame) / timebase); // TODO qRound here might lead to clicking? or might fix it... who knows
|
||||
if (c->reverse) {
|
||||
timestamp = c->stream->duration - timestamp - 1;
|
||||
}
|
||||
av_seek_frame(c->formatCtx, ms->file_index, timestamp, AVSEEK_FLAG_BACKWARD);
|
||||
c->audio_target_frame = target_frame;
|
||||
c->frame_sample_index = -1;
|
||||
c->audio_just_reset = true;
|
||||
|
||||
@@ -1656,9 +1656,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cursor_contains_clip) {
|
||||
/*if (cursor_contains_clip) {
|
||||
QToolTip::showText(mapToGlobal(event->pos()), "HOVER OVER CLIP");
|
||||
}
|
||||
}*/
|
||||
if (found) {
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user