Merge branch 'olive-editor:master' into av1
This commit is contained in:
+25
-13
@@ -824,7 +824,8 @@ void Core::SaveProjectInternal(Project* project, const QString& override_filenam
|
||||
return;
|
||||
#endif
|
||||
} else {
|
||||
psm = new ProjectSaveTask(project);
|
||||
bool use_compression = !project->filename().endsWith(QStringLiteral(".ovexml"), Qt::CaseInsensitive);
|
||||
psm = new ProjectSaveTask(project, use_compression);
|
||||
|
||||
if (!override_filename.isEmpty()) {
|
||||
// Set override filename if provided
|
||||
@@ -1170,24 +1171,35 @@ bool Core::CloseAllExceptActiveProject()
|
||||
|
||||
QString Core::GetProjectFilter(bool include_any_filter)
|
||||
{
|
||||
QString filters;
|
||||
static const QVector< QPair<QString, QString> > FILTERS = {
|
||||
// Standard compressed Olive project
|
||||
{tr("Olive Project"), QStringLiteral("ove")},
|
||||
|
||||
// Uncompressed XML Olive project
|
||||
{tr("Olive Project (Uncompressed XML)"), QStringLiteral("ovexml")},
|
||||
|
||||
// OpenTimelineIO project, if available
|
||||
#ifdef USE_OTIO
|
||||
{tr("OpenTimelineIO"), QStringLiteral("otio")}
|
||||
#endif
|
||||
};
|
||||
|
||||
QStringList filters;
|
||||
filters.reserve(FILTERS.size() + 1);
|
||||
|
||||
if (include_any_filter) {
|
||||
filters.append(QStringLiteral("All Supported Projects (*.ove *.otio);;"));
|
||||
QStringList combined;
|
||||
for (auto it=FILTERS.cbegin(); it!=FILTERS.cend(); it++) {
|
||||
combined.append(QStringLiteral("*.%1").arg(it->second));
|
||||
}
|
||||
filters.append(QStringLiteral("%1 (%2)").arg(tr("All Supported Projects"), combined.join(' ')));
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(include_any_filter)
|
||||
#endif
|
||||
|
||||
// Append standard filter
|
||||
filters.append(QStringLiteral("%1 (*.ove)").arg(tr("Olive Project")));
|
||||
for (auto it=FILTERS.cbegin(); it!=FILTERS.cend(); it++) {
|
||||
filters.append(QStringLiteral("%1 (*.%2)").arg(it->first, it->second));
|
||||
}
|
||||
|
||||
#ifdef USE_OTIO
|
||||
filters.append(QStringLiteral(";;%2 (*.otio)").arg(tr("OpenTimelineIO")));
|
||||
#endif
|
||||
|
||||
return filters;
|
||||
return filters.join(QStringLiteral(";;"));
|
||||
}
|
||||
|
||||
QString Core::GetRecentProjectsFilePath()
|
||||
|
||||
@@ -59,10 +59,21 @@ ProjectSerializer::Result ProjectSerializer::Load(Project *project, const QStrin
|
||||
{
|
||||
QFile project_file(filename);
|
||||
|
||||
if (project_file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QXmlStreamReader reader(&project_file);
|
||||
if (project_file.open(QFile::ReadOnly)) {
|
||||
// Some project files are compressed, marked with "OVEC" at the beginning of the file. Check for
|
||||
// that signature now.
|
||||
std::unique_ptr<QXmlStreamReader> reader;
|
||||
QByteArray b = project_file.read(4);
|
||||
if (!memcmp(b.data(), "OVEC", 4)) {
|
||||
// File is compressed, decompress into memory
|
||||
b = qUncompress(project_file.readAll());
|
||||
reader.reset(new QXmlStreamReader(b));
|
||||
} else {
|
||||
project_file.seek(0);
|
||||
reader.reset(new QXmlStreamReader(&project_file));
|
||||
}
|
||||
|
||||
Result inner_result = Load(project, &reader, type);
|
||||
Result inner_result = Load(project, reader.get(), type);
|
||||
|
||||
project_file.close();
|
||||
|
||||
@@ -70,9 +81,9 @@ ProjectSerializer::Result ProjectSerializer::Load(Project *project, const QStrin
|
||||
return inner_result;
|
||||
}
|
||||
|
||||
if (reader.hasError()) {
|
||||
if (reader->hasError()) {
|
||||
Result r(kXmlError);
|
||||
r.SetDetails(reader.errorString());
|
||||
r.SetDetails(reader->errorString());
|
||||
return r;
|
||||
} else {
|
||||
return kSuccess;
|
||||
@@ -148,14 +159,15 @@ ProjectSerializer::Result ProjectSerializer::Paste(const QString &type)
|
||||
return res;
|
||||
}
|
||||
|
||||
ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data, const QString &type)
|
||||
ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data, const QString &type, bool compress)
|
||||
{
|
||||
QString temp_save = FileFunctions::GetSafeTemporaryFilename(data.GetFilename());
|
||||
|
||||
QFile project_file(temp_save);
|
||||
|
||||
if (project_file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
QXmlStreamWriter writer(&project_file);
|
||||
if (project_file.open(QFile::WriteOnly)) {
|
||||
QByteArray b;
|
||||
QXmlStreamWriter writer(&b);
|
||||
|
||||
Result inner_result = Save(&writer, data, type);
|
||||
|
||||
@@ -164,6 +176,13 @@ ProjectSerializer::Result ProjectSerializer::Save(const SaveData &data, const QS
|
||||
return r;
|
||||
}
|
||||
|
||||
if (compress) {
|
||||
project_file.write("OVEC");
|
||||
project_file.write(qCompress(b));
|
||||
} else {
|
||||
project_file.write(b);
|
||||
}
|
||||
|
||||
project_file.close();
|
||||
|
||||
if (inner_result != kSuccess) {
|
||||
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
static Result Load(Project *project, QXmlStreamReader *read_device, const QString &type);
|
||||
static Result Paste(const QString &type);
|
||||
|
||||
static Result Save(const SaveData &data, const QString &type);
|
||||
static Result Save(const SaveData &data, const QString &type, bool compress);
|
||||
static Result Save(QXmlStreamWriter *write_device, const SaveData &data, const QString &type);
|
||||
static Result Copy(const SaveData &data, const QString &type);
|
||||
|
||||
|
||||
@@ -27,15 +27,17 @@ void main()
|
||||
// Convert 0.0-1.0 to -0.5-0.5
|
||||
yuv.gb -= (128.0/255.0);
|
||||
} else if (bits_per_pixel == 10) {
|
||||
// Scale from 10-bit to 16-bit
|
||||
yuv *= (65535.0/1023.0);
|
||||
|
||||
// Convert 0.0-1.0 to -0.5-0.5
|
||||
yuv.gb -= (512.0/1023.0);
|
||||
|
||||
yuv *= 64.0;
|
||||
} else if (bits_per_pixel == 12) {
|
||||
// Scale from 12-bit to 16-bit
|
||||
yuv *= (65535.0/4095.0);
|
||||
|
||||
// Convert 0.0-1.0 to -0.5-0.5
|
||||
yuv.gb -= (2048.0/4095.0);
|
||||
|
||||
yuv *= 16.0;
|
||||
}
|
||||
|
||||
// Convert YUV limited range from 16-235 to 0-255
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
ProjectSaveTask::ProjectSaveTask(Project *project) :
|
||||
project_(project)
|
||||
ProjectSaveTask::ProjectSaveTask(Project *project, bool use_compression) :
|
||||
project_(project),
|
||||
use_compression_(use_compression)
|
||||
{
|
||||
SetTitle(tr("Saving '%1'").arg(project->filename()));
|
||||
}
|
||||
@@ -42,7 +43,7 @@ bool ProjectSaveTask::Run()
|
||||
|
||||
ProjectSerializer::SaveData data(project_, using_filename);
|
||||
|
||||
ProjectSerializer::Result result = ProjectSerializer::Save(data, QStringLiteral("project"));
|
||||
ProjectSerializer::Result result = ProjectSerializer::Save(data, QStringLiteral("project"), use_compression_);
|
||||
|
||||
bool success = false;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class ProjectSaveTask : public Task
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProjectSaveTask(Project* project);
|
||||
ProjectSaveTask(Project* project, bool use_compression);
|
||||
|
||||
Project* GetProject() const
|
||||
{
|
||||
@@ -50,6 +50,8 @@ private:
|
||||
|
||||
QString override_filename_;
|
||||
|
||||
bool use_compression_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ void ManagedDisplayWidget::ColorConfigChanged()
|
||||
return;
|
||||
}
|
||||
|
||||
SetColorTransform(color_manager_->GetCompliantColorSpace(color_transform_, true));
|
||||
SetColorTransform(color_manager_->GetCompliantColorSpace(color_transform_, false));
|
||||
}
|
||||
|
||||
ColorProcessorPtr ManagedDisplayWidget::color_service()
|
||||
|
||||
@@ -475,45 +475,46 @@ void TimelineView::DrawBlock(QPainter *painter, bool foreground, Block *block, q
|
||||
|
||||
// Draw clip thumbnails
|
||||
if (clip->GetTrackType() == Track::kVideo
|
||||
&& OLIVE_CONFIG("TimelineThumbnailMode").toInt() != Timeline::kThumbnailOff
|
||||
&& preview_rect.height() > r.height()/3) {
|
||||
if (const FrameHashCache *thumbs = clip->thumbnails()) {
|
||||
// Start thumbnails underneath clip name
|
||||
preview_rect.adjust(0, text_total_height, 0, 0);
|
||||
&& OLIVE_CONFIG("TimelineThumbnailMode").toInt() != Timeline::kThumbnailOff) {
|
||||
// Start thumbnails underneath clip name
|
||||
preview_rect.adjust(0, text_total_height, 0, 0);
|
||||
|
||||
QRect thumb_rect;
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->setClipRect(preview_rect);
|
||||
if (preview_rect.height() > r.height()/3) {
|
||||
if (const FrameHashCache *thumbs = clip->thumbnails()) {
|
||||
QRect thumb_rect;
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->setClipRect(preview_rect);
|
||||
|
||||
if (OLIVE_CONFIG("TimelineThumbnailMode") == Timeline::kThumbnailOn) {
|
||||
if (OLIVE_CONFIG("TimelineThumbnailMode") == Timeline::kThumbnailOn) {
|
||||
|
||||
Sequence *s = clip->track()->sequence();
|
||||
int width = s->GetVideoParams().width();
|
||||
int height = s->GetVideoParams().height();
|
||||
int start;
|
||||
if (height > 0) { // Prevent divide by zero/invalid params
|
||||
double scale = double(preview_rect.height())/double(height);
|
||||
thumb_rect.setWidth(width * scale);
|
||||
start = (((preview_rect.left() - int(qFloor(block_in))) / thumb_rect.width()) * thumb_rect.width()) + qFloor(block_in);
|
||||
} else {
|
||||
start = preview_rect.left();
|
||||
}
|
||||
|
||||
for (int i=start; i<preview_rect.right(); i+=thumb_rect.width()+1) {
|
||||
rational time_here = SceneToTime(i - block_in, GetScale(), connected_track_list_->parent()->GetVideoParams().frame_rate_as_time_base()) + media_in;
|
||||
DrawThumbnail(painter, thumbs, time_here, i, preview_rect, &thumb_rect);
|
||||
}
|
||||
|
||||
Sequence *s = clip->track()->sequence();
|
||||
int width = s->GetVideoParams().width();
|
||||
int height = s->GetVideoParams().height();
|
||||
int start;
|
||||
if (height > 0) { // Prevent divide by zero/invalid params
|
||||
double scale = double(preview_rect.height())/double(height);
|
||||
thumb_rect.setWidth(width * scale);
|
||||
start = (((preview_rect.left() - int(qFloor(block_in))) / thumb_rect.width()) * thumb_rect.width()) + qFloor(block_in);
|
||||
} else {
|
||||
start = preview_rect.left();
|
||||
|
||||
rational time = clip->media_range().in();
|
||||
time = Timecode::snap_time_to_timebase(time, thumbs->GetTimebase(), Timecode::kFloor);
|
||||
DrawThumbnail(painter, thumbs, time, block_left, preview_rect, &thumb_rect);
|
||||
|
||||
}
|
||||
|
||||
for (int i=start; i<preview_rect.right(); i+=thumb_rect.width()+1) {
|
||||
rational time_here = SceneToTime(i - block_in, GetScale(), connected_track_list_->parent()->GetVideoParams().frame_rate_as_time_base()) + media_in;
|
||||
DrawThumbnail(painter, thumbs, time_here, i, preview_rect, &thumb_rect);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
rational time = clip->media_range().in();
|
||||
time = Timecode::snap_time_to_timebase(time, thumbs->GetTimebase(), Timecode::kFloor);
|
||||
DrawThumbnail(painter, thumbs, time, block_left, preview_rect, &thumb_rect);
|
||||
painter->setClipping(false);
|
||||
|
||||
}
|
||||
|
||||
painter->setClipping(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1350,6 +1350,11 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
if (context_menu_widget_) {
|
||||
// Color options
|
||||
if (context_menu_widget_->color_manager() && color_menu_enabled_) {
|
||||
{
|
||||
Menu* ocio_colorspace_menu = context_menu_widget_->GetColorSpaceMenu(&menu);
|
||||
menu.addMenu(ocio_colorspace_menu);
|
||||
}
|
||||
|
||||
{
|
||||
Menu* ocio_display_menu = context_menu_widget_->GetDisplayMenu(&menu);
|
||||
menu.addMenu(ocio_display_menu);
|
||||
|
||||
Reference in New Issue
Block a user