various improvements

This commit is contained in:
itsmattkc
2018-10-05 00:17:09 +10:00
parent ceb744e589
commit 5f16c1c84f
17 changed files with 172 additions and 123 deletions
+38 -20
View File
@@ -13,6 +13,8 @@
#include "project/sequence.h"
#include "io/media.h"
#include "playback/playback.h"
#include "panels/panels.h"
#include "panels/timeline.h"
SpeedDialog::SpeedDialog(QWidget *parent) : QDialog(parent) {
QVBoxLayout* main_layout = new QVBoxLayout();
@@ -79,32 +81,38 @@ void SpeedDialog::run() {
// get "default" frame rate"
if (enable_frame_rate) {
// check if frame rate is equal to default
if (!qIsNaN(default_frame_rate) && media_frame_rate != default_frame_rate) {
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;
} else {
clip_percent = c->frame_rate;
if (i > 0) {
if (!qIsNaN(default_percent) && c->frame_rate != default_percent) {
default_percent = NAN;
}
} else {
default_percent = c->frame_rate;
}
}
// get default length
long clip_default_length = qRound(c->getLength() * clip_percent);
if (i == 0) {
current_length = c->getLength();
default_length = qRound(c->getLength() * clip_percent);
} else if (current_length != -1 && c->getLength() != current_length) {
current_length = -1;
default_length = clip_default_length;
current_percent = clip_percent;
} else {
if (current_length != -1 && c->getLength() != current_length) {
current_length = -1;
}
if (default_length != -1 && clip_default_length != default_length) {
default_length = -1;
}
if (!qIsNaN(current_percent) && !qFuzzyCompare(clip_percent, current_percent)) {
current_percent = NAN;
}
}
}
@@ -113,17 +121,18 @@ void SpeedDialog::run() {
frame_rate->set_value(current_frame_rate, false);
percent->set_value(current_percent, false);
duration->set_default_value(default_length);
duration->set_value(current_length, false);
exec();
}
void SpeedDialog::percent_update() {
frame_rate->set_value(default_frame_rate * percent->value(), false);
duration->set_value(clips.at(0)->getLength() / percent->value(), false);
duration->set_value(default_length / percent->value(), false);
}
void SpeedDialog::duration_update() {
double pc = clips.at(0)->getLength() / duration->value();
double pc = default_length / duration->value();
frame_rate->set_value(default_frame_rate * pc, false);
percent->set_value(pc, false);
}
@@ -132,18 +141,27 @@ void SpeedDialog::frame_rate_update() {
double fr = (frame_rate->value());
double pc = (fr / default_frame_rate);
percent->set_value(pc, false);
duration->set_value(clips.at(0)->getLength() / pc, false);
duration->set_value(default_length / pc, false);
}
void SpeedDialog::accept() {
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i);
if (c->track < 0) {
c->frame_rate = frame_rate->value();
} else {
c->frame_rate = percent->value();
}
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();
}
}
c->recalculateMaxLength();
}
panel_timeline->redraw_all_clips(true);
QDialog::accept();
}
-1
View File
@@ -737,7 +737,6 @@ void EffectField::uiElementChange() {
parent_row->set_keyframe_now(enableKeyframes);
} else if (enableKeyframes) {
// set undo
qDebug() << "h";
undo_stack.push(new EffectFieldUndo(this));
}
emit changed();
+6 -4
View File
@@ -73,7 +73,7 @@ TextEffect::TextEffect(Clip *c) :
shadow_softness->set_double_default_value(5);
shadow_distance->set_double_default_value(5);
shadow_opacity->set_double_default_value(80);
outline_width->set_double_default_value(2);
outline_width->set_double_default_value(20);
outline_enable(false);
shadow_enable(false);
@@ -245,12 +245,11 @@ void TextEffect::redraw(double timecode) {
}
path.addText(text_x, text_y, font, lines.at(i));
}
p.setPen(Qt::NoPen);
}
// draw shadow
if (shadow_bool->get_bool_value(timecode)) {
p.setPen(Qt::NoPen);
int shadow_offset = shadow_distance->get_double_value(timecode);
QPainterPath shadow_path(path);
@@ -271,9 +270,12 @@ void TextEffect::redraw(double timecode) {
QPen outline(outline_color->get_color_value(timecode));
outline.setWidth(outline_width_val);
p.setPen(outline);
p.setBrush(Qt::NoBrush);
p.drawPath(path);
}
// draw "master" text
p.setPen(Qt::NoPen);
p.setBrush(set_color_button->get_color_value(timecode));
p.drawPath(path);
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 131 KiB

+2 -2
View File
@@ -45,7 +45,7 @@ QMainWindow* mainWindow;
QTimer autorecovery_timer;
QString config_dir;
QString appName = "Olive (September 2018 | Alpha)";
QString appName = "Olive (October 2018 | Alpha)";
bool demoNoticeShown = false;
void MainWindow::setup_layout() {
@@ -383,7 +383,7 @@ bool MainWindow::can_close_project() {
void MainWindow::updateTitle(const QString& url) {
project_url = url;
setWindowTitle(appName + " - " + ((project_url.isEmpty()) ? "<untitled>" : project_url));
setWindowTitle(appName + " - " + ((project_url.isEmpty()) ? "<untitled>" : project_url) + "[*]");
}
void MainWindow::closeEvent(QCloseEvent *e) {
+3 -3
View File
@@ -1030,7 +1030,7 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
stream.writeAttribute("id", QString::number(ms->file_index));
stream.writeAttribute("width", QString::number(ms->video_width));
stream.writeAttribute("height", QString::number(ms->video_height));
stream.writeAttribute("framerate", QString::number(ms->video_frame_rate));
stream.writeAttribute("framerate", QString::number(ms->video_frame_rate, 'f', 10));
stream.writeAttribute("infinite", QString::number(ms->infinite_length));
stream.writeEndElement();
}
@@ -1057,7 +1057,7 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
stream.writeAttribute("name", s->name);
stream.writeAttribute("width", QString::number(s->width));
stream.writeAttribute("height", QString::number(s->height));
stream.writeAttribute("framerate", QString::number(s->frame_rate));
stream.writeAttribute("framerate", QString::number(s->frame_rate, 'f', 10));
stream.writeAttribute("afreq", QString::number(s->audio_frequency));
stream.writeAttribute("alayout", QString::number(s->audio_layout));
if (s == 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));
stream.writeAttribute("framerate", QString::number(c->frame_rate, 'f', 10));
stream.writeAttribute("type", QString::number(c->media_type));
switch (c->media_type) {
+15 -12
View File
@@ -25,6 +25,11 @@ Viewer::Viewer(QWidget *parent) :
viewer_widget = ui->openGLWidget;
update_sequence();
ui->currentTimecode->set_display_type(LABELSLIDER_FRAMENUMBER);
ui->currentTimecode->set_default_value(NAN);
ui->currentTimecode->set_value(0, false);
connect(ui->currentTimecode, SIGNAL(valueChanged()), this, SLOT(update_playhead()));
update_playhead_timecode(0);
update_end_timecode();
}
@@ -81,6 +86,8 @@ QString frame_to_timecode(long f, int view, double frame_rate) {
token = ";";
} else {
// non-drop timecode
int int_fps = qRound(frame_rate);
hours = f/ (3600 * int_fps);
mins = f / (60*int_fps) % 60;
@@ -99,7 +106,7 @@ bool frame_rate_is_droppable(float rate) {
}
void Viewer::update_playhead_timecode(long p) {
ui->currentTimecode->setText(frame_to_timecode(p, config.timecode_view, (sequence != NULL) ? sequence->frame_rate : 30));
ui->currentTimecode->set_value(p, false);
}
void Viewer::update_end_timecode() {
@@ -124,11 +131,7 @@ void Viewer::update_sequence() {
init_audio();
if (!null_sequence) {
if (frame_rate_is_droppable(sequence->frame_rate)) {
config.timecode_view = TIMECODE_DROP;
} else {
config.timecode_view = TIMECODE_NONDROP;
}
config.timecode_view = (frame_rate_is_droppable(sequence->frame_rate)) ? TIMECODE_DROP : TIMECODE_NONDROP;
update_playhead_timecode(sequence->playhead);
update_end_timecode();
@@ -167,13 +170,13 @@ void Viewer::on_pushButton_4_clicked()
void Viewer::on_pushButton_3_clicked()
{
panel_timeline->toggle_play();
panel_timeline->toggle_play();
}
void Viewer::update_playhead() {
panel_timeline->seek(ui->currentTimecode->value());
}
void Viewer::set_playpause_icon(bool play) {
if (play) {
ui->pushButton_3->setIcon(QIcon(":/icons/play.png"));
} else {
ui->pushButton_3->setIcon(QIcon(":/icons/pause.png"));
}
ui->pushButton_3->setIcon(QIcon((play) ? ":/icons/play.png" : ":/icons/pause.png"));
}
+2
View File
@@ -40,6 +40,8 @@ private slots:
void on_pushButton_4_clicked();
void on_pushButton_3_clicked();
void update_playhead();
};
#endif // VIEWER_H
+6 -1
View File
@@ -98,7 +98,7 @@
<number>0</number>
</property>
<item>
<widget class="QLabel" name="currentTimecode">
<widget class="LabelSlider" name="currentTimecode">
<property name="text">
<string>0</string>
</property>
@@ -228,6 +228,11 @@
<header>ui/viewercontainer.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LabelSlider</class>
<extends>QLabel</extends>
<header>ui/labelslider.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../icons/icons.qrc"/>
+12 -7
View File
@@ -206,7 +206,7 @@ void cache_video_worker(Clip* c, long playhead, ClipCache* cache) {
int i = 0;
double fr_ratio = qRound((c->sequence->frame_rate / c->frame_rate)*100)*0.01;
// double fr_ratio = c->sequence->frame_rate / c->frame_rate;
/* old swscale solution
if (!c->reached_end) {
@@ -231,17 +231,20 @@ void cache_video_worker(Clip* c, long playhead, ClipCache* cache) {
if (ret >= 0) {
// optimization: mathematically determine based on the sequence and clips' frame rates whether this frame will actually be shown
double timeline_frame = (i+cache->offset) * fr_ratio;
// note: is not actually much faster and currently leads to crashes, may remove in the future
// int proposed_frame = qFloor((i+cache->offset) * fr_ratio);
if (qFloor(timeline_frame) == timeline_frame) {
// if (proposed_frame != c->last_cached_frame) {
if ((ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, c->frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) {
qDebug() << "[ERROR] Could not feed filtergraph -" << ret;
error = true;
break;
// } else {
// c->last_cached_frame = proposed_frame;
}
} else {
i++;
}
// } else {
// i++;
// }
} else {
if (ret == AVERROR_EOF) {
c->reached_end = true;
@@ -306,6 +309,8 @@ void reset_cache(Clip* c, long target_frame) {
} while (retrieved_frame < target_frame);
av_frame_free(&temp);
c->last_cached_frame = -1;
} else if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
// seek (target_frame represents timeline timecode in frames, not clip timecode)
swr_drop_output(c->swr_ctx, swr_get_out_samples(c->swr_ctx, 0));
@@ -367,7 +372,7 @@ void open_clip_worker(Clip* clip) {
AVDictionary* opts = NULL;
// decoding optimization configuration
// optimized decoding settings
if (clip->stream->codecpar->codec_id != AV_CODEC_ID_PNG &&
clip->stream->codecpar->codec_id != AV_CODEC_ID_APNG &&
clip->stream->codecpar->codec_id != AV_CODEC_ID_TIFF &&
+6 -13
View File
@@ -36,12 +36,7 @@ void open_clip(Clip* clip, bool multithreaded) {
// maybe keep cacher instance in memory while clip exists for performance?
clip->cacher = new Cacher(clip);
QObject::connect(clip->cacher, SIGNAL(finished()), clip->cacher, SLOT(deleteLater()));
if (clip->track < 0) {
clip->cacher->start(QThread::LowPriority);
} else {
clip->cacher->start(QThread::TimeCriticalPriority);
}
clip->cacher->start((clip->track < 0) ? QThread::LowPriority : QThread::TimeCriticalPriority);
}
} else {
clip->finished_opening = false;
@@ -114,11 +109,6 @@ bool get_clip_frame(Clip* c, long playhead) {
// do we need to update the texture?
MediaStream* ms = static_cast<Media*>(c->media)->get_stream_from_file_index(c->track < 0, c->media_stream);
// backwards compatibilty code
if (c->frame_rate == 0) {
c->frame_rate = ms->video_frame_rate;
}
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);
@@ -286,7 +276,10 @@ void retrieve_next_frame_raw_data(Clip* c, AVFrame* output) {
// output->pts = c->frame->best_effort_timestamp;
} else if (c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
output->pts = c->frame->pts;
ret = swr_convert_frame(c->swr_ctx, output, c->frame);
ret = swr_convert_frame(c->swr_ctx, output, c->frame);
if (ret < 0) {
qDebug() << "[ERROR] Failed to resample audio." << ret;
}
@@ -303,7 +296,7 @@ bool is_clip_active(Clip* c, long playhead) {
return c->enabled
&& c->timeline_in < playhead + ceil(c->sequence->frame_rate)
&& c->timeline_out > playhead
&& playhead - c->timeline_in + c->clip_in < c->getMediaLength(c->sequence->frame_rate);
&& playhead - c->timeline_in + c->clip_in < c->getMaximumLength();
}
void set_sequence(Sequence* s) {
+32 -19
View File
@@ -124,7 +124,9 @@ void Clip::refresh() {
// reinitializes all effects... just in case
for (int i=0;i<effects.size();i++) {
effects.at(i)->refresh();
}
}
recalculateMaxLength();
}
Clip::~Clip() {
@@ -168,28 +170,39 @@ long Clip::getLength() {
return timeline_out - timeline_in;
}
long Clip::getMediaLength(double framerate) {
switch (media_type) {
case MEDIA_TYPE_FOOTAGE:
{
Media* m = static_cast<Media*>(media);
if (m->get_stream_from_file_index(track < 0, media_stream)->infinite_length) {
return LONG_MAX;
} else {
return m->get_length_in_frames(framerate);
}
}
break;
case MEDIA_TYPE_SEQUENCE:
{
Sequence* s = static_cast<Sequence*>(media);
return refactor_frame_number(s->getEndFrame(), s->frame_rate, framerate);
void Clip::recalculateMaxLength() {
double fr = this->sequence->frame_rate;
if (track < 0) {
fr *= (getMediaFrameRate()/frame_rate);
} else {
fr /= frame_rate;
}
switch (media_type) {
case MEDIA_TYPE_FOOTAGE:
{
Media* m = static_cast<Media*>(media);
if (m->get_stream_from_file_index(track < 0, media_stream)->infinite_length) {
calculated_length = LONG_MAX;
} else {
calculated_length = m->get_length_in_frames(fr);
}
}
break;
case MEDIA_TYPE_SEQUENCE:
{
Sequence* s = static_cast<Sequence*>(media);
calculated_length = refactor_frame_number(s->getEndFrame(), s->frame_rate, fr);
}
case MEDIA_TYPE_SOLID:
case MEDIA_TYPE_TONE:
return LONG_MAX;
calculated_length = LONG_MAX;
}
return 0;
}
long Clip::getMaximumLength() {
return calculated_length;
}
double Clip::getMediaFrameRate() {
+5 -2
View File
@@ -63,7 +63,8 @@ struct Clip
quint8 color_g;
quint8 color_b;
long getLength();
long getMediaLength(double framerate);
long getMaximumLength();
void recalculateMaxLength();
double getMediaFrameRate();
void* media; // attached media
int media_type;
@@ -71,6 +72,7 @@ struct Clip
int getWidth();
int getHeight();
double frame_rate;
long calculated_length;
// other variables (should be "duplicated" in copy())
QList<Effect*> effects;
@@ -101,6 +103,7 @@ struct Clip
ClipCache cache_B;
QMutex lock;
QMutex open_lock;
int last_cached_frame;
// converters/filters
AVFilterGraph* filter_graph;
@@ -115,7 +118,7 @@ struct Clip
bool autoscale;
// audio playback variables
SwrContext* swr_ctx;
// SwrContext* swr_ctx;
int frame_sample_index;
int audio_buffer_write;
bool audio_reset;
-1
View File
@@ -15,7 +15,6 @@ const QString& FontCombobox::getPreviousValue() {
}
void FontCombobox::updateInternals() {
qDebug() << "h";
previousValue = value;
value = currentText();
}
+14 -9
View File
@@ -10,6 +10,7 @@
#include <QApplication>
LabelSlider::LabelSlider(QWidget* parent) : QLabel(parent) {
decimal_places = 1;
drag_start = false;
drag_proc = false;
min_enabled = false;
@@ -21,7 +22,6 @@ LabelSlider::LabelSlider(QWidget* parent) : QLabel(parent) {
set_value(0, false);
set = false;
display_type = LABELSLIDER_NORMAL;
decimal_places = 1;
}
void LabelSlider::set_display_type(int type) {
@@ -57,7 +57,7 @@ QString LabelSlider::valueToString(double v) {
return "---";
} else {
switch (display_type) {
case LABELSLIDER_FRAMENUMBER: return frame_to_timecode(v, config.timecode_view, sequence->frame_rate);
case LABELSLIDER_FRAMENUMBER: return frame_to_timecode(v, config.timecode_view, (sequence != NULL) ? sequence->frame_rate : 30);
case LABELSLIDER_PERCENT: return QString::number((v*100), 'f', decimal_places) + "%";
}
return QString::number(v, 'f', decimal_places);
@@ -97,7 +97,7 @@ double LabelSlider::get_drag_start_value() {
void LabelSlider::mousePressEvent(QMouseEvent *ev) {
drag_start_value = internal_value;
if (ev->modifiers() & Qt::AltModifier) {
if (internal_value != default_value) {
if (internal_value != default_value && !qIsNaN(default_value)) {
previous_value = internal_value;
set_value(default_value, true);
}
@@ -115,11 +115,7 @@ void LabelSlider::mouseMoveEvent(QMouseEvent*) {
if (drag_start) {
drag_proc = true;
int diff = (cursor().pos().x()-drag_start_x) + (drag_start_y-cursor().pos().y());
if (display_type == LABELSLIDER_PERCENT) {
set_value(internal_value + (diff*0.01), true);
} else {
set_value(internal_value + diff, true);
}
set_value(internal_value + ((display_type == LABELSLIDER_PERCENT) ? (diff*0.01) : diff), true);
cursor().setPos(drag_start_x, drag_start_y);
}
}
@@ -133,7 +129,16 @@ void LabelSlider::mouseReleaseEvent(QMouseEvent*) {
previous_value = drag_start_value;
emit valueChanged();
} else {
double d = QInputDialog::getDouble(this, "Set Value", "New value:", internal_value);
double d = QInputDialog::getDouble(
this,
"Set Value",
"New value:",
(display_type == LABELSLIDER_PERCENT) ? internal_value * 100 : internal_value,
(min_enabled) ? min_value : INT_MIN,
(max_enabled) ? max_value : INT_MAX,
decimal_places
);
if (display_type == LABELSLIDER_PERCENT) d *= 0.01;
if (d != internal_value) {
previous_value = internal_value;
set_value(d, true);
+15 -26
View File
@@ -348,9 +348,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
c->color_g = 128;
c->color_b = 192;
}
if (c->track < 0) {
c->frame_rate = m->get_stream_from_file_index(true, c->media_stream)->video_frame_rate;
}
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?)
@@ -359,7 +357,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
c->color_b = 128;
Sequence* media = static_cast<Sequence*>(c->media);
c->frame_rate = media->frame_rate;
c->frame_rate = (c->track < 0) ? media->frame_rate : 1.0;
c->name = media->name;
}
@@ -621,13 +619,12 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
c->color_b = 64;
c->track = g.track;
if (c->track < 0) c->frame_rate = sequence->frame_rate;
c->frame_rate = (c->track < 0) ? sequence->frame_rate : 1.0;
QVector<Clip*> add;
add.append(c);
ca->append(new AddClipCommand(sequence, add));
// int clipIndex = sequence->clips.size();
if (c->track < 0) {
// default video effects (before custom effects)
c->effects.append(create_effect(VIDEO_TRANSFORM_EFFECT, c));
@@ -933,15 +930,7 @@ void TimelineWidget::init_ghosts() {
}
// used for trim ops
switch (c->media_type) {
case MEDIA_TYPE_FOOTAGE:
g.media_length = static_cast<Media*>(c->media)->get_length_in_frames(sequence->frame_rate);
break;
case MEDIA_TYPE_SEQUENCE:
Sequence* s = static_cast<Sequence*>(c->media);
g.media_length = refactor_frame_number(s->getEndFrame(), s->frame_rate, sequence->frame_rate);
break;
}
g.media_length = c->getMaximumLength();
}
for (int i=0;i<sequence->selections.size();i++) {
Selection& s = sequence->selections[i];
@@ -1710,18 +1699,10 @@ void TimelineWidget::redraw_clips() {
draw_checkerboard = true;
} else if (ms->preview_done) {
// draw thumbnail/waveform
long media_length = m->get_length_in_frames(clip->sequence->frame_rate);
int waveform_limit;
if (!ms->infinite_length) {
waveform_limit = qMin(clip_rect.width(), panel_timeline->getTimelineScreenPointFromFrame(media_length - clip->clip_in));
if (waveform_limit < clip_rect.width()) {
draw_checkerboard = true;
if (waveform_limit > 0) checkerboard_rect.setLeft(checkerboard_rect.left() + waveform_limit);
}
}
long media_length = clip->getMaximumLength();
if (clip->track < 0) {
// draw thumbnail
int space_for_thumb = clip_rect.width();
if (clip->opening_transition != NULL) {
int ot_width = panel_timeline->getTimelineScreenPointFromFrame(clip->opening_transition->length);
@@ -1739,13 +1720,21 @@ void TimelineWidget::redraw_clips() {
clip_painter.drawImage(thumb_rect, ms->video_preview);
}
} else if (clip_rect.height() > TRACK_MIN_HEIGHT) {
int waveform_limit = qMin(clip_rect.width(), panel_timeline->getTimelineScreenPointFromFrame(media_length - clip->clip_in));
if (waveform_limit < clip_rect.width()) {
draw_checkerboard = true;
if (waveform_limit > 0) checkerboard_rect.setLeft(checkerboard_rect.left() + waveform_limit);
}
// draw waveform
clip_painter.setPen(QColor(80, 80, 80));
int divider = ms->audio_channels*2;
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/panel_timeline->zoom))/media_length) * ms->audio_preview.size())/divider)*divider;
int waveform_index = qFloor((((clip->clip_in + ((double) (i*clip->frame_rate)/panel_timeline->zoom))/media_length) * ms->audio_preview.size())/divider)*divider;
int rectified_height = 0;
+16 -3
View File
@@ -176,19 +176,27 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
QVector<Clip*> current_clips;
for (int i=0;i<s->clips.size();i++) {
Clip* c = s->clips.at(i);
Clip* c = s->clips.at(i);
// 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;
}
switch (c->media_type) {
case MEDIA_TYPE_FOOTAGE:
{
Media* m = static_cast<Media*>(c->media);
if (m->ready) {
if (m->get_stream_from_file_index(c->track < 0, c->media_stream) != NULL
&& is_clip_active(c, playhead)) {
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) {
@@ -204,8 +212,13 @@ 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;