various improvements
This commit is contained in:
+38
-20
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 131 KiB |
+2
-2
@@ -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
@@ -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
@@ -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"));
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ private slots:
|
||||
void on_pushButton_4_clicked();
|
||||
|
||||
void on_pushButton_3_clicked();
|
||||
|
||||
void update_playhead();
|
||||
};
|
||||
|
||||
#endif // VIEWER_H
|
||||
|
||||
+6
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -15,7 +15,6 @@ const QString& FontCombobox::getPreviousValue() {
|
||||
}
|
||||
|
||||
void FontCombobox::updateInternals() {
|
||||
qDebug() << "h";
|
||||
previousValue = value;
|
||||
value = currentText();
|
||||
}
|
||||
|
||||
+14
-9
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user