giant rendering overhaul and many small fixes
This commit is contained in:
+587
-587
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "panels/panels.h"
|
||||
|
||||
#include "playback/playback.h"
|
||||
#include "ui/sourcetable.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
#include "project/undo.h"
|
||||
#include "project/clip.h"
|
||||
#include "panels/timeline.h"
|
||||
#include "playback/playback.h"
|
||||
#include "project/media.h"
|
||||
#include "playback/audio.h"
|
||||
#include "rendering/audio.h"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "oliveglobal.h"
|
||||
#include "io/config.h"
|
||||
#include "io/path.h"
|
||||
#include "playback/audio.h"
|
||||
#include "rendering/audio.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QMenuBar>
|
||||
|
||||
+116
-106
@@ -32,142 +32,152 @@
|
||||
#include "project/footage.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
ProxyDialog::ProxyDialog(QWidget *parent, const QVector<FootagePtr> &footage) :
|
||||
QDialog(parent),
|
||||
selected_footage(footage)
|
||||
ProxyDialog::ProxyDialog(QWidget *parent, const QVector<Media*> &media) :
|
||||
QDialog(parent),
|
||||
selected_media(media)
|
||||
{
|
||||
// set dialog title
|
||||
setWindowTitle(tr("Create Proxy"));
|
||||
// set dialog title
|
||||
setWindowTitle(tr("Create Proxy"));
|
||||
|
||||
// set proxy folder name to "Proxy", depending on the user's language
|
||||
proxy_folder_name = tr("Proxy");
|
||||
// set proxy folder name to "Proxy", depending on the user's language
|
||||
proxy_folder_name = tr("Proxy");
|
||||
|
||||
// set up dialog's layout
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
// set up dialog's layout
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
|
||||
// set the video dimensions of the proxy
|
||||
layout->addWidget(new QLabel(tr("Dimensions:"), this), 0, 0);
|
||||
// set the video dimensions of the proxy
|
||||
layout->addWidget(new QLabel(tr("Dimensions:"), this), 0, 0);
|
||||
|
||||
size_combobox = new QComboBox(this);
|
||||
size_combobox->addItem(tr("Same Size as Source"), 1.0);
|
||||
size_combobox->addItem(tr("Half Resolution (1/2)"), 0.5);
|
||||
size_combobox->addItem(tr("Quarter Resolution (1/4)"), 0.25);
|
||||
size_combobox->addItem(tr("Eighth Resolution (1/8)"), 0.125);
|
||||
size_combobox->addItem(tr("Sixteenth Resolution (1/16)"), 0.0625);
|
||||
layout->addWidget(size_combobox, 0, 1);
|
||||
size_combobox = new QComboBox(this);
|
||||
size_combobox->addItem(tr("Same Size as Source"), 1.0);
|
||||
size_combobox->addItem(tr("Half Resolution (1/2)"), 0.5);
|
||||
size_combobox->addItem(tr("Quarter Resolution (1/4)"), 0.25);
|
||||
size_combobox->addItem(tr("Eighth Resolution (1/8)"), 0.125);
|
||||
size_combobox->addItem(tr("Sixteenth Resolution (1/16)"), 0.0625);
|
||||
layout->addWidget(size_combobox, 0, 1);
|
||||
|
||||
// set the desired format of the proxy to create
|
||||
layout->addWidget(new QLabel(tr("Format:"), this), 1, 0);
|
||||
// set the desired format of the proxy to create
|
||||
layout->addWidget(new QLabel(tr("Format:"), this), 1, 0);
|
||||
|
||||
format_combobox = new QComboBox(this);
|
||||
format_combobox->addItem(tr("ProRes HQ"));
|
||||
// format_combobox->addItem(tr("ProRes SQ"));
|
||||
// format_combobox->addItem(tr("ProRes LT"));
|
||||
// format_combobox->addItem(tr("DNxHD"));
|
||||
// format_combobox->addItem(tr("H.264"));
|
||||
layout->addWidget(format_combobox, 1, 1);
|
||||
format_combobox = new QComboBox(this);
|
||||
format_combobox->addItem(tr("ProRes HQ"));
|
||||
// format_combobox->addItem(tr("ProRes SQ"));
|
||||
// format_combobox->addItem(tr("ProRes LT"));
|
||||
// format_combobox->addItem(tr("DNxHD"));
|
||||
// format_combobox->addItem(tr("H.264"));
|
||||
layout->addWidget(format_combobox, 1, 1);
|
||||
|
||||
// set the location to place the proxies
|
||||
layout->addWidget(new QLabel(tr("Location:"), this), 2, 0);
|
||||
// set the location to place the proxies
|
||||
layout->addWidget(new QLabel(tr("Location:"), this), 2, 0);
|
||||
|
||||
location_combobox = new QComboBox(this);
|
||||
location_combobox->addItem(tr("Same as Source (in \"%1\" folder)").arg(proxy_folder_name));
|
||||
location_combobox->addItem("");
|
||||
connect(location_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(location_changed(int)));
|
||||
layout->addWidget(location_combobox, 2, 1);
|
||||
location_combobox = new QComboBox(this);
|
||||
location_combobox->addItem(tr("Same as Source (in \"%1\" folder)").arg(proxy_folder_name));
|
||||
location_combobox->addItem("");
|
||||
connect(location_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(location_changed(int)));
|
||||
layout->addWidget(location_combobox, 2, 1);
|
||||
|
||||
// location_changed will set the default "location" items
|
||||
location_changed(0);
|
||||
// location_changed will set the default "location" items
|
||||
location_changed(0);
|
||||
|
||||
// set up dialog buttons
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
buttons->setCenterButtons(true);
|
||||
layout->addWidget(buttons, 3, 0, 1, 2);
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
// set up dialog buttons
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
buttons->setCenterButtons(true);
|
||||
layout->addWidget(buttons, 3, 0, 1, 2);
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
}
|
||||
|
||||
void ProxyDialog::accept() {
|
||||
QVector<ProxyInfo> info_list;
|
||||
QVector<ProxyInfo> info_list;
|
||||
|
||||
// set to TRUE if any existing proxies exist and the user chooses to overwrite all of them
|
||||
bool overwrite_all_existing = false;
|
||||
// set to TRUE if any existing proxies exist and the user chooses to overwrite all of them
|
||||
bool overwrite_all_existing = false;
|
||||
|
||||
for (int i=0;i<selected_footage.size();i++) {
|
||||
// loop through selected footage and send info to the proxy queue
|
||||
for (int i=0;i<selected_media.size();i++) {
|
||||
// loop through selected footage and send info to the proxy queue
|
||||
|
||||
ProxyInfo info;
|
||||
ProxyInfo info;
|
||||
|
||||
// fill info struct based on user input
|
||||
info.footage = selected_footage.at(i);
|
||||
info.codec_type = 0;
|
||||
info.size_multiplier = size_combobox->currentData().toDouble();
|
||||
// fill info struct based on user input
|
||||
info.media = selected_media.at(i);
|
||||
info.codec_type = 0;
|
||||
info.size_multiplier = size_combobox->currentData().toDouble();
|
||||
|
||||
QString base_footage_fn = QFileInfo(selected_footage.at(i)->url).baseName();
|
||||
FootagePtr footage = selected_media.at(i)->to_footage();
|
||||
|
||||
// TEMPORARILY hardcoded proxy format
|
||||
base_footage_fn.append(".mov");
|
||||
QString base_footage_fn = QFileInfo(footage->url).baseName();
|
||||
|
||||
// determine path from input
|
||||
if (custom_location.isEmpty()) {
|
||||
// use same as source (proxy subfolder)
|
||||
// TEMPORARILY hardcoded proxy format
|
||||
base_footage_fn.append(".mov");
|
||||
|
||||
// generate full path from footage path and proxy_folder_name's translated "Proxy"
|
||||
info.path = QDir(QFileInfo(selected_footage.at(i)->url).dir().filePath(proxy_folder_name)).filePath(base_footage_fn);
|
||||
} else {
|
||||
// use existing location
|
||||
info.path = QDir(custom_location).filePath(base_footage_fn);
|
||||
}
|
||||
// determine path from input
|
||||
if (custom_location.isEmpty()) {
|
||||
// use same as source (proxy subfolder)
|
||||
|
||||
// if the proposed proxy file already exists & user didn't select YesToAll box
|
||||
if (QFileInfo::exists(info.path) && !overwrite_all_existing){
|
||||
int rtn = QMessageBox::warning( this,
|
||||
tr("Proxy file exists"),
|
||||
tr("The file \"%1\" already exists. Do you wish to replace it?").arg(info.path),
|
||||
QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No);
|
||||
// generate full path from footage path and proxy_folder_name's translated "Proxy"
|
||||
info.path = QDir(QFileInfo(footage->url).dir().filePath(proxy_folder_name)).filePath(base_footage_fn);
|
||||
} else {
|
||||
// use existing location
|
||||
info.path = QDir(custom_location).filePath(base_footage_fn);
|
||||
}
|
||||
|
||||
switch (rtn){
|
||||
case QMessageBox::Yes:
|
||||
// continue as normal, proxy generator will automatically overwrite this file
|
||||
break;
|
||||
case QMessageBox::YesToAll:
|
||||
// continue as normal, also set variable so that above messagebox is not shown again
|
||||
overwrite_all_existing = true;
|
||||
break;
|
||||
case QMessageBox::No:
|
||||
// return to dialog without closing or starting any proxy generation
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if the proposed proxy file already exists & user didn't select YesToAll box
|
||||
if (QFileInfo::exists(info.path) && !overwrite_all_existing){
|
||||
int rtn = QMessageBox::warning( this,
|
||||
tr("Proxy file exists"),
|
||||
tr("The file \"%1\" already exists. Do you wish to replace it?").arg(info.path),
|
||||
QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
// send to proxy generator thread
|
||||
info_list.append(info);
|
||||
}
|
||||
switch (rtn){
|
||||
case QMessageBox::Yes:
|
||||
// continue as normal, proxy generator will automatically overwrite this file
|
||||
break;
|
||||
case QMessageBox::YesToAll:
|
||||
// continue as normal, also set variable so that above messagebox is not shown again
|
||||
overwrite_all_existing = true;
|
||||
break;
|
||||
case QMessageBox::No:
|
||||
// return to dialog without closing or starting any proxy generation
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// all proxy info checks out, queue it with the proxy generator
|
||||
for (int i=0;i<info_list.size();i++) {
|
||||
info_list.at(i).footage->proxy = true;
|
||||
info_list.at(i).footage->proxy_path.clear();
|
||||
// send to proxy generator thread
|
||||
info_list.append(info);
|
||||
}
|
||||
|
||||
proxy_generator.queue(info_list.at(i));
|
||||
}
|
||||
// all proxy info checks out, queue it with the proxy generator
|
||||
for (int i=0;i<info_list.size();i++) {
|
||||
FootagePtr footage = info_list.at(i).media->to_footage();
|
||||
footage->proxy = true;
|
||||
footage->proxy_path.clear();
|
||||
|
||||
olive::MainWindow->setWindowModified(true);
|
||||
olive::proxy_generator.queue(info_list.at(i));
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
olive::MainWindow->setWindowModified(true);
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void ProxyDialog::location_changed(int i) {
|
||||
custom_location.clear();
|
||||
if (i == 1) {
|
||||
QString s = QFileDialog::getExistingDirectory(this);
|
||||
if (s.isEmpty()) {
|
||||
location_combobox->setCurrentIndex(0);
|
||||
} else {
|
||||
location_combobox->setItemText(1, s);
|
||||
custom_location = s;
|
||||
}
|
||||
} else {
|
||||
location_combobox->setItemText(1, tr("Custom Location"));
|
||||
}
|
||||
// clear any custom location - either the user picked a new one or chose not a custom location
|
||||
custom_location.clear();
|
||||
|
||||
if (i == 1) {
|
||||
// if the user picked a custom location, ask which directory
|
||||
QString s = QFileDialog::getExistingDirectory(this);
|
||||
|
||||
if (s.isEmpty()) {
|
||||
// if the user didn't input anything, set the combobox back to default
|
||||
location_combobox->setCurrentIndex(0);
|
||||
} else {
|
||||
// if the user chose a custom location, set the combobox text to it and custom_location for future usage
|
||||
location_combobox->setItemText(1, s);
|
||||
custom_location = s;
|
||||
}
|
||||
} else {
|
||||
// if the user doesn't picks something other than custom location, set this string back to default for clearer UX
|
||||
location_combobox->setItemText(1, tr("Custom Location"));
|
||||
}
|
||||
}
|
||||
|
||||
+65
-19
@@ -25,36 +25,82 @@
|
||||
#include <QVector>
|
||||
#include <QComboBox>
|
||||
|
||||
#include "project/footage.h"
|
||||
#include "project/media.h"
|
||||
|
||||
/**
|
||||
* @brief The ProxyDialog class
|
||||
*
|
||||
* Dialog to set up proxy generation of footage
|
||||
*/
|
||||
class ProxyDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProxyDialog(QWidget* parent, const QVector<FootagePtr>& footage);
|
||||
/**
|
||||
* @brief ProxyDialog Constructor
|
||||
* @param parent
|
||||
*
|
||||
* Parent widget to become modal to.
|
||||
*
|
||||
* @param footage
|
||||
*
|
||||
* List of Footage items to process.
|
||||
*/
|
||||
ProxyDialog(QWidget* parent, const QVector<Media *> &media);
|
||||
public slots:
|
||||
// called if user clicks "OK" on the dialog
|
||||
virtual void accept() override;
|
||||
/**
|
||||
* @brief Accept changes
|
||||
*
|
||||
* Called when the user clicks OK on the dialog. Verifies all proxies, asking the user whether they want to overwrite
|
||||
* existing proxies if necessary, and if everything is valid, queues the footage with ProxyGenerator.
|
||||
*/
|
||||
virtual void accept() override;
|
||||
private:
|
||||
// user's desired dimensions
|
||||
QComboBox* size_combobox;
|
||||
/**
|
||||
* @brief User's desired dimensions
|
||||
*
|
||||
* Always a fraction of the original video size (e.g. 1/2, 1/4, 1/8, etc.)
|
||||
*/
|
||||
QComboBox* size_combobox;
|
||||
|
||||
// user's desired proxy format
|
||||
QComboBox* format_combobox;
|
||||
/**
|
||||
* @brief User's desired proxy format
|
||||
*
|
||||
* e.g. ProRes, DNxHD, etc.
|
||||
*/
|
||||
QComboBox* format_combobox;
|
||||
|
||||
// allows users to set the location to store proxies
|
||||
QComboBox* location_combobox;
|
||||
/**
|
||||
* @brief Allows users to set the directory to store proxies in
|
||||
*/
|
||||
QComboBox* location_combobox;
|
||||
|
||||
// stores the custom location to store proxies if the user sets a custom location
|
||||
QString custom_location;
|
||||
/**
|
||||
* @brief Stores the custom location to store proxies if the user sets a custom location
|
||||
*/
|
||||
QString custom_location;
|
||||
|
||||
// stores the subdirectory to be made next to the source (dependent on the user's language)
|
||||
QString proxy_folder_name;
|
||||
/**
|
||||
* @brief Stores the default subdirectory to be made next to the source (dependent on the user's language)
|
||||
*
|
||||
* "Proxy" in en-US.
|
||||
*/
|
||||
QString proxy_folder_name;
|
||||
|
||||
// list of footage to make proxies for
|
||||
QVector<FootagePtr> selected_footage;
|
||||
/**
|
||||
* @brief Stored list of footage to make proxies for
|
||||
*/
|
||||
QVector<Media*> selected_media;
|
||||
private slots:
|
||||
// triggered when the user changes the index in the location combobox
|
||||
void location_changed(int i);
|
||||
/**
|
||||
* @brief Slot when the user changes the location
|
||||
*
|
||||
* Triggered when the user changes the index in the location combobox.
|
||||
*
|
||||
* @param i
|
||||
*
|
||||
* location_combobox's new selected index
|
||||
*/
|
||||
void location_changed(int i);
|
||||
};
|
||||
|
||||
#endif // PROXYDIALOG_H
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
|
||||
#include "panels/panels.h"
|
||||
|
||||
#include "playback/playback.h"
|
||||
#include "playback/cacher.h"
|
||||
#include "rendering/cacher.h"
|
||||
#include "project/undo.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
@@ -112,7 +111,7 @@ void ReplaceClipMediaDialog::replace() {
|
||||
|
||||
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
|
||||
ClipPtr c = olive::ActiveSequence->clips.at(i);
|
||||
if (c != nullptr && c->media == media) {
|
||||
if (c != nullptr && c->media() == media) {
|
||||
rcmc->clips.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
+339
-318
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "project/sequence.h"
|
||||
#include "project/footage.h"
|
||||
#include "playback/playback.h"
|
||||
#include "rendering/renderfunctions.h"
|
||||
#include "panels/panels.h"
|
||||
#include "panels/timeline.h"
|
||||
#include "project/undo.h"
|
||||
@@ -36,394 +36,415 @@
|
||||
#include "project/media.h"
|
||||
|
||||
SpeedDialog::SpeedDialog(QWidget *parent) : QDialog(parent) {
|
||||
setWindowTitle(tr("Speed/Duration"));
|
||||
setWindowTitle(tr("Speed/Duration"));
|
||||
|
||||
QVBoxLayout* main_layout = new QVBoxLayout(this);
|
||||
QVBoxLayout* main_layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* grid = new QGridLayout();
|
||||
grid->setSpacing(6);
|
||||
QGridLayout* grid = new QGridLayout();
|
||||
grid->setSpacing(6);
|
||||
|
||||
grid->addWidget(new QLabel(tr("Speed:"), this), 0, 0);
|
||||
percent = new LabelSlider(this);
|
||||
percent->decimal_places = 2;
|
||||
percent->set_display_type(LABELSLIDER_PERCENT);
|
||||
percent->set_default_value(1);
|
||||
grid->addWidget(percent, 0, 1);
|
||||
grid->addWidget(new QLabel(tr("Speed:"), this), 0, 0);
|
||||
percent = new LabelSlider(this);
|
||||
percent->decimal_places = 2;
|
||||
percent->set_display_type(LABELSLIDER_PERCENT);
|
||||
percent->set_default_value(1);
|
||||
grid->addWidget(percent, 0, 1);
|
||||
|
||||
grid->addWidget(new QLabel(tr("Frame Rate:"), this), 1, 0);
|
||||
frame_rate = new LabelSlider(this);
|
||||
frame_rate->decimal_places = 3;
|
||||
grid->addWidget(frame_rate, 1, 1);
|
||||
grid->addWidget(new QLabel(tr("Frame Rate:"), this), 1, 0);
|
||||
frame_rate = new LabelSlider(this);
|
||||
frame_rate->decimal_places = 3;
|
||||
grid->addWidget(frame_rate, 1, 1);
|
||||
|
||||
grid->addWidget(new QLabel(tr("Duration:"), this), 2, 0);
|
||||
duration = new LabelSlider(this);
|
||||
duration->set_display_type(LABELSLIDER_FRAMENUMBER);
|
||||
duration->set_frame_rate(olive::ActiveSequence->frame_rate);
|
||||
grid->addWidget(duration, 2, 1);
|
||||
grid->addWidget(new QLabel(tr("Duration:"), this), 2, 0);
|
||||
duration = new LabelSlider(this);
|
||||
duration->set_display_type(LABELSLIDER_FRAMENUMBER);
|
||||
duration->set_frame_rate(olive::ActiveSequence->frame_rate);
|
||||
grid->addWidget(duration, 2, 1);
|
||||
|
||||
main_layout->addLayout(grid);
|
||||
main_layout->addLayout(grid);
|
||||
|
||||
reverse = new QCheckBox(tr("Reverse"), this);
|
||||
maintain_pitch = new QCheckBox(tr("Maintain Audio Pitch"), this);
|
||||
ripple = new QCheckBox(tr("Ripple Changes"), this);
|
||||
reverse = new QCheckBox(tr("Reverse"), this);
|
||||
maintain_pitch = new QCheckBox(tr("Maintain Audio Pitch"), this);
|
||||
ripple = new QCheckBox(tr("Ripple Changes"), this);
|
||||
|
||||
main_layout->addWidget(reverse);
|
||||
main_layout->addWidget(maintain_pitch);
|
||||
main_layout->addWidget(ripple);
|
||||
main_layout->addWidget(reverse);
|
||||
main_layout->addWidget(maintain_pitch);
|
||||
main_layout->addWidget(ripple);
|
||||
|
||||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
buttonBox->setCenterButtons(true);
|
||||
main_layout->addWidget(buttonBox);
|
||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
buttonBox->setCenterButtons(true);
|
||||
main_layout->addWidget(buttonBox);
|
||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
|
||||
connect(percent, SIGNAL(valueChanged()), this, SLOT(percent_update()));
|
||||
connect(frame_rate, SIGNAL(valueChanged()), this, SLOT(frame_rate_update()));
|
||||
connect(duration, SIGNAL(valueChanged()), this, SLOT(duration_update()));
|
||||
connect(percent, SIGNAL(valueChanged()), this, SLOT(percent_update()));
|
||||
connect(frame_rate, SIGNAL(valueChanged()), this, SLOT(frame_rate_update()));
|
||||
connect(duration, SIGNAL(valueChanged()), this, SLOT(duration_update()));
|
||||
}
|
||||
|
||||
void SpeedDialog::run() {
|
||||
bool enable_frame_rate = false;
|
||||
bool multiple_audio = false;
|
||||
maintain_pitch->setEnabled(false);
|
||||
bool enable_frame_rate = false;
|
||||
bool multiple_audio = false;
|
||||
maintain_pitch->setEnabled(false);
|
||||
|
||||
default_frame_rate = qSNaN();
|
||||
current_frame_rate = qSNaN();
|
||||
current_percent = qSNaN();
|
||||
default_length = -1;
|
||||
current_length = -1;
|
||||
default_frame_rate = qSNaN();
|
||||
current_frame_rate = qSNaN();
|
||||
current_percent = qSNaN();
|
||||
default_length = -1;
|
||||
current_length = -1;
|
||||
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
|
||||
double clip_percent;
|
||||
double clip_percent;
|
||||
|
||||
// get default frame rate/percentage
|
||||
clip_percent = c->speed;
|
||||
if (c->track < 0) {
|
||||
bool process_video = true;
|
||||
if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
FootagePtr m = c->media->to_footage();
|
||||
FootageStream* ms = m->get_stream_from_file_index(true, c->media_stream);
|
||||
if (ms != nullptr && ms->infinite_length) {
|
||||
process_video = false;
|
||||
}
|
||||
}
|
||||
// get default frame rate/percentage
|
||||
clip_percent = c->speed().value;
|
||||
if (c->track() < 0) {
|
||||
bool process_video = true;
|
||||
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
FootageStream* ms = c->media_stream();
|
||||
if (ms != nullptr && ms->infinite_length) {
|
||||
process_video = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (process_video) {
|
||||
double media_frame_rate = c->getMediaFrameRate();
|
||||
if (process_video) {
|
||||
double media_frame_rate = c->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 = qSNaN();
|
||||
}
|
||||
if (!qIsNaN(current_frame_rate) && !qFuzzyCompare(media_frame_rate*c->speed, current_frame_rate)) {
|
||||
current_frame_rate = qSNaN();
|
||||
}
|
||||
} else {
|
||||
default_frame_rate = media_frame_rate;
|
||||
current_frame_rate = media_frame_rate*c->speed;
|
||||
}
|
||||
// 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 = qSNaN();
|
||||
}
|
||||
if (!qIsNaN(current_frame_rate) && !qFuzzyCompare(media_frame_rate*c->speed().value, current_frame_rate)) {
|
||||
current_frame_rate = qSNaN();
|
||||
}
|
||||
} else {
|
||||
default_frame_rate = media_frame_rate;
|
||||
current_frame_rate = media_frame_rate*c->speed().value;
|
||||
}
|
||||
|
||||
enable_frame_rate = true;
|
||||
}
|
||||
} else {
|
||||
maintain_pitch->setEnabled(true);
|
||||
enable_frame_rate = true;
|
||||
}
|
||||
} else {
|
||||
maintain_pitch->setEnabled(true);
|
||||
|
||||
if (!multiple_audio) {
|
||||
maintain_pitch->setChecked(c->maintain_audio_pitch);
|
||||
multiple_audio = true;
|
||||
} else if (!maintain_pitch->isTristate() && maintain_pitch->isChecked() != c->maintain_audio_pitch) {
|
||||
maintain_pitch->setCheckState(Qt::PartiallyChecked);
|
||||
maintain_pitch->setTristate(true);
|
||||
}
|
||||
}
|
||||
if (!multiple_audio) {
|
||||
maintain_pitch->setChecked(c->speed().maintain_audio_pitch);
|
||||
multiple_audio = true;
|
||||
} else if (!maintain_pitch->isTristate() && maintain_pitch->isChecked() != c->speed().maintain_audio_pitch) {
|
||||
maintain_pitch->setCheckState(Qt::PartiallyChecked);
|
||||
maintain_pitch->setTristate(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
reverse->setChecked(c->reverse);
|
||||
} else if (c->reverse != reverse->isChecked()) {
|
||||
reverse->setTristate(true);
|
||||
reverse->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
if (i == 0) {
|
||||
reverse->setChecked(c->reversed());
|
||||
} else if (c->reversed() != reverse->isChecked()) {
|
||||
reverse->setTristate(true);
|
||||
reverse->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
|
||||
// get default length
|
||||
long clip_default_length = qRound(c->getLength() * clip_percent);
|
||||
if (i == 0) {
|
||||
current_length = c->getLength();
|
||||
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 = qSNaN();
|
||||
}
|
||||
}
|
||||
}
|
||||
// get default length
|
||||
long clip_default_length = qRound(c->length() * clip_percent);
|
||||
if (i == 0) {
|
||||
current_length = c->length();
|
||||
default_length = clip_default_length;
|
||||
current_percent = clip_percent;
|
||||
} else {
|
||||
if (current_length != -1 && c->length() != 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 = qSNaN();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frame_rate->set_minimum_value(1);
|
||||
percent->set_minimum_value(0.0001);
|
||||
duration->set_minimum_value(1);
|
||||
frame_rate->set_minimum_value(1);
|
||||
percent->set_minimum_value(0.0001);
|
||||
duration->set_minimum_value(1);
|
||||
|
||||
frame_rate->setEnabled(enable_frame_rate);
|
||||
frame_rate->set_default_value(default_frame_rate);
|
||||
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 == -1) ? qSNaN() : current_length, false);
|
||||
frame_rate->setEnabled(enable_frame_rate);
|
||||
frame_rate->set_default_value(default_frame_rate);
|
||||
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 == -1) ? qSNaN() : current_length, false);
|
||||
|
||||
exec();
|
||||
exec();
|
||||
}
|
||||
|
||||
void SpeedDialog::percent_update() {
|
||||
bool got_fr = false;
|
||||
double fr_val = qSNaN();
|
||||
long len_val = -1;
|
||||
bool got_fr = false;
|
||||
double fr_val = qSNaN();
|
||||
long len_val = -1;
|
||||
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
|
||||
// get frame rate
|
||||
if (frame_rate->isEnabled() && c->track < 0) {
|
||||
double clip_fr = c->getMediaFrameRate() * percent->value();
|
||||
if (got_fr) {
|
||||
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
|
||||
fr_val = qSNaN();
|
||||
}
|
||||
} else {
|
||||
fr_val = clip_fr;
|
||||
got_fr = true;
|
||||
}
|
||||
}
|
||||
// get frame rate
|
||||
if (frame_rate->isEnabled() && c->track() < 0) {
|
||||
double clip_fr = c->media_frame_rate() * percent->value();
|
||||
if (got_fr) {
|
||||
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
|
||||
fr_val = qSNaN();
|
||||
}
|
||||
} else {
|
||||
fr_val = clip_fr;
|
||||
got_fr = true;
|
||||
}
|
||||
}
|
||||
|
||||
// get duration
|
||||
long clip_default_length = qRound(c->getLength() * c->speed);
|
||||
long new_clip_length = qRound(clip_default_length / percent->value());
|
||||
if (i == 0) {
|
||||
len_val = new_clip_length;
|
||||
} else if (len_val > -1 && len_val != new_clip_length) {
|
||||
len_val = -1;
|
||||
}
|
||||
}
|
||||
// get duration
|
||||
long clip_default_length = qRound(c->length() * c->speed().value);
|
||||
long new_clip_length = qRound(clip_default_length / percent->value());
|
||||
if (i == 0) {
|
||||
len_val = new_clip_length;
|
||||
} else if (len_val > -1 && len_val != new_clip_length) {
|
||||
len_val = -1;
|
||||
}
|
||||
}
|
||||
|
||||
frame_rate->set_value(fr_val, false);
|
||||
duration->set_value((len_val == -1) ? qSNaN() : len_val, false);
|
||||
frame_rate->set_value(fr_val, false);
|
||||
duration->set_value((len_val == -1) ? qSNaN() : len_val, false);
|
||||
}
|
||||
|
||||
void SpeedDialog::duration_update() {
|
||||
double pc_val = qSNaN();
|
||||
bool got_fr = false;
|
||||
double fr_val = qSNaN();
|
||||
double pc_val = qSNaN();
|
||||
bool got_fr = false;
|
||||
double fr_val = qSNaN();
|
||||
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
|
||||
// get percent
|
||||
long clip_default_length = qRound(c->getLength() * c->speed);
|
||||
double clip_pc = clip_default_length / duration->value();
|
||||
if (i == 0) {
|
||||
pc_val = clip_pc;
|
||||
} else if (!qIsNaN(pc_val) && !qFuzzyCompare(clip_pc, pc_val)) {
|
||||
pc_val = qSNaN();
|
||||
}
|
||||
// get percent
|
||||
long clip_default_length = qRound(c->length() * c->speed().value);
|
||||
double clip_pc = clip_default_length / duration->value();
|
||||
if (i == 0) {
|
||||
pc_val = clip_pc;
|
||||
} else if (!qIsNaN(pc_val) && !qFuzzyCompare(clip_pc, pc_val)) {
|
||||
pc_val = qSNaN();
|
||||
}
|
||||
|
||||
// get frame rate
|
||||
if (frame_rate->isEnabled() && c->track < 0) {
|
||||
double clip_fr = c->getMediaFrameRate() * clip_pc;
|
||||
if (got_fr) {
|
||||
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
|
||||
fr_val = qSNaN();
|
||||
}
|
||||
} else {
|
||||
fr_val = clip_fr;
|
||||
got_fr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// get frame rate
|
||||
if (frame_rate->isEnabled() && c->track() < 0) {
|
||||
double clip_fr = c->media_frame_rate() * clip_pc;
|
||||
if (got_fr) {
|
||||
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
|
||||
fr_val = qSNaN();
|
||||
}
|
||||
} else {
|
||||
fr_val = clip_fr;
|
||||
got_fr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frame_rate->set_value(fr_val, false);
|
||||
percent->set_value(pc_val, false);
|
||||
frame_rate->set_value(fr_val, false);
|
||||
percent->set_value(pc_val, false);
|
||||
}
|
||||
|
||||
void SpeedDialog::frame_rate_update() {
|
||||
/*double fr = (frame_rate->value());
|
||||
double pc = (fr / default_frame_rate);
|
||||
percent->set_value(pc, false);
|
||||
duration->set_value(default_length / pc, false);*/
|
||||
/*double fr = (frame_rate->value());
|
||||
double pc = (fr / default_frame_rate);
|
||||
percent->set_value(pc, false);
|
||||
duration->set_value(default_length / pc, false);*/
|
||||
|
||||
double old_pc_val = qSNaN();
|
||||
bool got_pc_val = false;
|
||||
double pc_val = qSNaN();
|
||||
bool got_len_val = false;
|
||||
long len_val = -1;
|
||||
double old_pc_val = qSNaN();
|
||||
bool got_pc_val = false;
|
||||
double pc_val = qSNaN();
|
||||
bool got_len_val = false;
|
||||
long len_val = -1;
|
||||
|
||||
// analyze video clips
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
// analyze video clips
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
|
||||
// check if all selected clips are currently the same speed
|
||||
if (i == 0) {
|
||||
old_pc_val = c->speed;
|
||||
} else if (!qIsNaN(old_pc_val) && !qFuzzyCompare(c->speed, old_pc_val)) {
|
||||
old_pc_val = qSNaN();
|
||||
}
|
||||
// check if all selected clips are currently the same speed
|
||||
if (i == 0) {
|
||||
old_pc_val = c->speed().value;
|
||||
} else if (!qIsNaN(old_pc_val) && !qFuzzyCompare(c->speed().value, old_pc_val)) {
|
||||
old_pc_val = qSNaN();
|
||||
}
|
||||
|
||||
if (c->track < 0) {
|
||||
// what would the new speed be based on this frame rate
|
||||
double new_clip_speed = frame_rate->value() / c->getMediaFrameRate();
|
||||
if (!got_pc_val) {
|
||||
pc_val = new_clip_speed;
|
||||
got_pc_val = true;
|
||||
} else if (!qIsNaN(pc_val) && !qFuzzyCompare(pc_val, new_clip_speed)) {
|
||||
pc_val = qSNaN();
|
||||
}
|
||||
if (c->track() < 0) {
|
||||
// what would the new speed be based on this frame rate
|
||||
double new_clip_speed = frame_rate->value() / c->media_frame_rate();
|
||||
if (!got_pc_val) {
|
||||
pc_val = new_clip_speed;
|
||||
got_pc_val = true;
|
||||
} else if (!qIsNaN(pc_val) && !qFuzzyCompare(pc_val, new_clip_speed)) {
|
||||
pc_val = qSNaN();
|
||||
}
|
||||
|
||||
// what would be the new length based on this speed
|
||||
long new_clip_len = (c->getLength() * c->speed) / new_clip_speed;
|
||||
if (!got_len_val) {
|
||||
len_val = new_clip_len;
|
||||
got_len_val = true;
|
||||
} else if (len_val > -1 && new_clip_len != len_val) {
|
||||
len_val = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// what would be the new length based on this speed
|
||||
long new_clip_len = (c->length() * c->speed().value) / new_clip_speed;
|
||||
if (!got_len_val) {
|
||||
len_val = new_clip_len;
|
||||
got_len_val = true;
|
||||
} else if (len_val > -1 && new_clip_len != len_val) {
|
||||
len_val = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// analyze audio clips
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
// analyze audio clips
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
|
||||
if (c->track >= 0) {
|
||||
long new_clip_len = (qIsNaN(old_pc_val) || qIsNaN(pc_val)) ? c->getLength() : ((c->getLength() * c->speed) / pc_val);
|
||||
if (len_val > -1 && new_clip_len != len_val) {
|
||||
len_val = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c->track() >= 0) {
|
||||
long new_clip_len = (qIsNaN(old_pc_val) || qIsNaN(pc_val)) ? c->length() : ((c->length() * c->speed().value) / pc_val);
|
||||
if (len_val > -1 && new_clip_len != len_val) {
|
||||
len_val = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
percent->set_value(pc_val, false);
|
||||
duration->set_value((len_val == -1) ? qSNaN() : len_val, false);
|
||||
percent->set_value(pc_val, false);
|
||||
duration->set_value((len_val == -1) ? qSNaN() : len_val, false);
|
||||
}
|
||||
|
||||
void set_speed(ComboAction* ca, ClipPtr c, double speed, bool ripple, long& ep, long& lr) {
|
||||
panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track);
|
||||
panel_timeline->deselect_area(c->timeline_in(), c->timeline_out(), c->track());
|
||||
|
||||
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 (!ripple && proposed_out > c->timeline_out) {
|
||||
for (int i=0;i<c->sequence->clips.size();i++) {
|
||||
long proposed_out = c->timeline_out();
|
||||
double multiplier = (c->speed().value / speed);
|
||||
proposed_out = c->timeline_in() + (c->length() * multiplier);
|
||||
ca->append(new SetSpeedAction(c, speed));
|
||||
if (!ripple && proposed_out > c->timeline_out()) {
|
||||
for (int i=0;i<c->sequence->clips.size();i++) {
|
||||
ClipPtr compare = c->sequence->clips.at(i);
|
||||
if (compare != nullptr
|
||||
&& compare->track == c->track
|
||||
&& compare->timeline_in >= c->timeline_out && compare->timeline_in < proposed_out) {
|
||||
proposed_out = compare->timeline_in;
|
||||
}
|
||||
}
|
||||
}
|
||||
ep = qMin(ep, c->timeline_out);
|
||||
lr = qMax(lr, proposed_out - c->timeline_out);
|
||||
move_clip(ca, c, c->timeline_in, proposed_out, c->clip_in * multiplier, c->track);
|
||||
if (compare != nullptr
|
||||
&& compare->track() == c->track()
|
||||
&& compare->timeline_in() >= c->timeline_out() && compare->timeline_in() < proposed_out) {
|
||||
proposed_out = compare->timeline_in();
|
||||
}
|
||||
}
|
||||
}
|
||||
ep = qMin(ep, c->timeline_out());
|
||||
lr = qMax(lr, proposed_out - c->timeline_out());
|
||||
move_clip(ca, c, c->timeline_in(), proposed_out, qRound(c->clip_in() * multiplier), c->track());
|
||||
|
||||
c->refactor_frame_rate(ca, multiplier, false);
|
||||
c->refactor_frame_rate(ca, multiplier, false);
|
||||
|
||||
Selection sel;
|
||||
sel.in = c->timeline_in;
|
||||
sel.out = proposed_out;
|
||||
sel.track = c->track;
|
||||
olive::ActiveSequence->selections.append(sel);
|
||||
Selection sel;
|
||||
sel.in = c->timeline_in();
|
||||
sel.out = proposed_out;
|
||||
sel.track = c->track();
|
||||
olive::ActiveSequence->selections.append(sel);
|
||||
}
|
||||
|
||||
void SpeedDialog::accept() {
|
||||
ComboAction* ca = new ComboAction();
|
||||
ComboAction* ca = new ComboAction();
|
||||
|
||||
SetSelectionsCommand* sel_command = new SetSelectionsCommand(olive::ActiveSequence);
|
||||
sel_command->old_data = olive::ActiveSequence->selections;
|
||||
// undoable action for setting "maintain audio pitch"
|
||||
SetClipProperty* audio_pitch_action = new SetClipProperty(kSetClipPropertyMaintainAudioPitch);
|
||||
|
||||
long earliest_point = LONG_MAX;
|
||||
long longest_ripple = LONG_MIN;
|
||||
// undoable action for setting "reversed"
|
||||
SetClipProperty* reversed_action = new SetClipProperty(kSetClipPropertyReversed);
|
||||
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
if (c->open) close_clip(c, true);
|
||||
// undoable action for restoring clip selections
|
||||
SetSelectionsCommand* sel_command = new SetSelectionsCommand(olive::ActiveSequence);
|
||||
sel_command->old_data = olive::ActiveSequence->selections;
|
||||
|
||||
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()));
|
||||
}
|
||||
// variables used to calculate ripples
|
||||
long earliest_point = LONG_MAX;
|
||||
long longest_ripple = LONG_MIN;
|
||||
|
||||
if (reverse->checkState() != Qt::PartiallyChecked && c->reverse != reverse->isChecked()) {
|
||||
long new_clip_in = (c->getMaximumLength() - (c->getLength() + c->clip_in));
|
||||
move_clip(ca, 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()));
|
||||
}
|
||||
}
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
|
||||
if (!qIsNaN(percent->value())) {
|
||||
// simply set speed
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
set_speed(ca, c, percent->value(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
}
|
||||
} else if (!qIsNaN(frame_rate->value())) {
|
||||
bool can_change_all = true;
|
||||
double cached_speed;
|
||||
double cached_fr = qSNaN();
|
||||
// make sure the clip is closed while we're making changes
|
||||
if (c->IsOpen()) {
|
||||
c->Close(true);
|
||||
}
|
||||
|
||||
// see if we can use the frame rate to change all the speeds
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
if (i == 0) {
|
||||
cached_speed = c->speed;
|
||||
} else if (!qFuzzyCompare(cached_speed, c->speed)) {
|
||||
can_change_all = false;
|
||||
}
|
||||
if (c->track < 0) {
|
||||
if (qIsNaN(cached_fr)) {
|
||||
cached_fr = c->getMediaFrameRate();
|
||||
} else if (!qFuzzyCompare(cached_fr, c->getMediaFrameRate())) {
|
||||
can_change_all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// set maintain audio pitch if the user made a selection
|
||||
if (c->track() >= 0
|
||||
&& maintain_pitch->checkState() != Qt::PartiallyChecked
|
||||
&& c->speed().maintain_audio_pitch != maintain_pitch->isChecked()) {
|
||||
audio_pitch_action->AddSetting(c, maintain_pitch->isChecked());
|
||||
}
|
||||
|
||||
// make changes
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
if (c->track < 0) {
|
||||
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, ripple->isChecked(), earliest_point, longest_ripple);
|
||||
}
|
||||
}
|
||||
} else if (!qIsNaN(duration->value())) {
|
||||
// simply set duration
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
set_speed(ca, c, (c->getLength() * c->speed) / duration->value(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
}
|
||||
}
|
||||
// set reverse setting if the user made a selection
|
||||
if (reverse->checkState() != Qt::PartiallyChecked && c->reversed() != reverse->isChecked()) {
|
||||
long new_clip_in = (c->media_length() - (c->length() + c->clip_in()));
|
||||
move_clip(ca, c, c->timeline_in(), c->timeline_out(), new_clip_in, c->track());
|
||||
c->set_clip_in(new_clip_in);
|
||||
reversed_action->AddSetting(c, reverse->isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
if (ripple->isChecked()) {
|
||||
ripple_clips(ca, clips.at(0)->sequence, earliest_point, longest_ripple);
|
||||
}
|
||||
// setting the actual speed
|
||||
if (!qIsNaN(percent->value())) {
|
||||
|
||||
sel_command->new_data = olive::ActiveSequence->selections;
|
||||
ca->append(sel_command);
|
||||
// if we have a percentage value, use that on all the clips
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
set_speed(ca, c, percent->value(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
}
|
||||
|
||||
olive::UndoStack.push(ca);
|
||||
} else if (!qIsNaN(frame_rate->value())) {
|
||||
|
||||
update_ui(true);
|
||||
QDialog::accept();
|
||||
// if the user changed the speed by changing the frame rate,
|
||||
bool can_change_all = true;
|
||||
double cached_speed;
|
||||
double cached_fr = qSNaN();
|
||||
|
||||
// see if we can use the frame rate to change all the speeds
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
if (i == 0) {
|
||||
cached_speed = c->speed().value;
|
||||
} else if (!qFuzzyCompare(cached_speed, c->speed().value)) {
|
||||
can_change_all = false;
|
||||
}
|
||||
if (c->track() < 0) {
|
||||
if (qIsNaN(cached_fr)) {
|
||||
cached_fr = c->media_frame_rate();
|
||||
} else if (!qFuzzyCompare(cached_fr, c->media_frame_rate())) {
|
||||
can_change_all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make changes
|
||||
for (int i=0;i<clips.size();i++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
if (c->track() < 0) {
|
||||
set_speed(ca, c, frame_rate->value() / c->media_frame_rate(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
} else if (can_change_all) {
|
||||
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++) {
|
||||
ClipPtr c = clips.at(i);
|
||||
set_speed(ca, c, (c->length() * c->speed().value) / duration->value(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
}
|
||||
}
|
||||
|
||||
if (ripple->isChecked()) {
|
||||
ripple_clips(ca, clips.at(0)->sequence, earliest_point, longest_ripple);
|
||||
}
|
||||
|
||||
sel_command->new_data = olive::ActiveSequence->selections;
|
||||
ca->append(sel_command);
|
||||
|
||||
ca->append(reversed_action);
|
||||
ca->append(audio_pitch_action);
|
||||
|
||||
olive::UndoStack.push(ca);
|
||||
|
||||
update_ui(true);
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user