otio: began early functionality to export to OTIO

This commit is contained in:
itsmattkc
2020-09-25 16:32:18 +10:00
parent 2ea7b91f5d
commit bb6d5505f5
14 changed files with 288 additions and 10 deletions
+5 -1
View File
@@ -69,7 +69,11 @@ find_package(FFMPEG 3.0 REQUIRED
swresample
)
find_package(OpenTimelineIO REQUIRED)
find_package(OpenTimelineIO)
if (NOT OpenTimelineIO_FOUND)
message(" OpenTimelineIO interchange will be disabled.")
endif()
find_package(GoogleCrashpad)
+17 -2
View File
@@ -123,7 +123,6 @@ target_include_directories(
${FFMPEG_INCLUDE_DIRS}
${OCIO_INCLUDE_DIRS}
${OIIO_INCLUDE_DIRS}
${OTIO_INCLUDE_DIRS}
${OPENEXR_INCLUDES}
# HACK: Brew on macOS separates OpenEXR and IlmBase into two folders even though they seem to
@@ -152,7 +151,6 @@ target_link_libraries(
FFMPEG::swresample
${OCIO_LIBRARIES}
${OIIO_LIBRARIES}
${OTIO_LIBRARIES}
${OPENEXR_LIBRARIES}
)
@@ -170,6 +168,23 @@ elseif (APPLE)
)
endif()
# Enable OTIO if found
if (OpenTimelineIO_FOUND)
set(OLIVE_DEFINITIONS ${OLIVE_DEFINITIONS} USE_OTIO)
target_include_directories(
${OLIVE_TARGET}
PRIVATE
${OTIO_INCLUDE_DIRS}
)
target_link_libraries(
${OLIVE_TARGET}
PRIVATE
${OTIO_LIBRARIES}
)
endif()
# Enable Crashpad if found
if (GoogleCrashpad_FOUND)
set(OLIVE_DEFINITIONS ${OLIVE_DEFINITIONS} USE_CRASHPAD)
+17
View File
@@ -170,4 +170,21 @@ bool FileFunctions::DirectoryIsValid(const QString &dir, bool try_to_create)
return false;
}
QString FileFunctions::EnsureFilenameExtension(QString fn, const QString &extension)
{
// No-op if either input is empty
if (!fn.isEmpty() && !extension.isEmpty()) {
QString extension_with_dot;
extension_with_dot.append('.');
extension_with_dot.append(extension);
if (!fn.endsWith(extension_with_dot, Qt::CaseInsensitive)) {
fn.append(extension_with_dot);
}
}
return fn;
}
OLIVE_NAMESPACE_EXIT
+11
View File
@@ -54,6 +54,17 @@ public:
static bool DirectoryIsValid(const QString& dir, bool try_to_create);
/**
* @brief Ensures a given filename has a certain extension
*
* Checks if the filename has the extension provided and appends it if not. The extension is
* checked case-insensitive. The extension should be provided with no dot (e.g. "ove" rather than
* ".ove").
* @return The filename provided either untouched or with the extension appended to it.
*/
static QString EnsureFilenameExtension(QString fn, const QString& extension);
};
+8
View File
@@ -102,6 +102,14 @@ AVRational rational::toAVRational() const
return r;
}
#ifdef USE_OTIO
opentime::RationalTime rational::toRationalTime() const
{
// Is this the best way of doing this?
return opentime::RationalTime::from_seconds(toDouble());
}
#endif
rational rational::flipped() const
{
return rational(denom_, numer_);
+8
View File
@@ -7,6 +7,10 @@
#define RATIONAL_H
#include <iostream>
#ifdef USE_OTIO
#include <opentime/rationalTime.h>
#endif
#include <QDebug>
#include <QMetaType>
@@ -96,6 +100,10 @@ public:
AVRational toAVRational() const;
#ifdef USE_OTIO
opentime::RationalTime toRationalTime() const;
#endif
// Produce "flipped" version
rational flipped() const;
+20 -4
View File
@@ -54,6 +54,7 @@
#include "task/project/import/importerrordialog.h"
#include "task/project/load/load.h"
#include "task/project/save/save.h"
#include "task/project/saveotio/projectsaveasotiotask.h"
#include "task/taskmanager.h"
#include "ui/style/style.h"
#include "undo/undostack.h"
@@ -265,6 +266,24 @@ void Core::CreateNewProject()
AddOpenProject(std::make_shared<Project>());
}
#ifdef USE_OTIO
void Core::ExportActiveSequenceAsOTIO()
{
QString fn = QFileDialog::getSaveFileName(main_window_,
tr("Export as OpenTimelineIO"),
QString(),
tr("OpenTimelineIO (*.otio)"));
if (!fn.isEmpty()) {
fn = FileFunctions::EnsureFilenameExtension(fn, QStringLiteral("otio"));
ProjectSaveAsOTIOTask* task = new ProjectSaveAsOTIOTask();
TaskDialog* dialog = new TaskDialog(task, tr("Export Sequence"), main_window_);
dialog->open();
}
}
#endif
const bool &Core::snapping() const
{
return snapping_;
@@ -858,10 +877,7 @@ bool Core::SaveProjectAs(ProjectPtr p)
GetProjectFilter());
if (!fn.isEmpty()) {
QString extension(QStringLiteral(".ove"));
if (!fn.endsWith(extension, Qt::CaseInsensitive)) {
fn.append(extension);
}
fn = FileFunctions::EnsureFilenameExtension(fn, QStringLiteral("ove"));
p->set_filename(fn);
+7
View File
@@ -378,6 +378,13 @@ public slots:
*/
void CreateNewProject();
#ifdef USE_OTIO
/**
* @brief Exports the active sequence to OpenTimelineIO
*/
void ExportActiveSequenceAsOTIO();
#endif
signals:
/**
* @brief Signal emitted when a project is opened
+1
View File
@@ -17,6 +17,7 @@
add_subdirectory(import)
add_subdirectory(load)
add_subdirectory(save)
add_subdirectory(saveotio)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
+22
View File
@@ -0,0 +1,22 @@
# Olive - Non-Linear Video Editor
# Copyright (C) 2019 Olive Team
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set(OLIVE_SOURCES
${OLIVE_SOURCES}
task/project/saveotio/projectsaveasotiotask.h
task/project/saveotio/projectsaveasotiotask.cpp
PARENT_SCOPE
)
@@ -0,0 +1,111 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "projectsaveasotiotask.h"
#include <opentimelineio/clip.h>
#include <opentimelineio/gap.h>
#include <opentimelineio/timeline.h>
#include <opentimelineio/transition.h>
#include "node/block/transition/transition.h"
OLIVE_NAMESPACE_ENTER
ProjectSaveAsOTIOTask::ProjectSaveAsOTIOTask(Sequence *sequence) :
sequence_(sequence)
{
SetTitle(tr("Saving '%1' as OpenTimelineIO").arg(sequence->name()));
}
bool ProjectSaveAsOTIOTask::Run()
{
auto otio_timeline = new opentimelineio::v1_0::Timeline();
ViewerOutput* viewer = sequence_->viewer_output();
opentimelineio::v1_0::ErrorStatus es;
foreach (TrackOutput* track, viewer->track_list(Timeline::kTrackTypeVideo)->GetTracks()) {
auto otio_track = new opentimelineio::v1_0::Track();
otio_track->set_kind("Video");
foreach (Block* block, track->Blocks()) {
opentimelineio::v1_0::Composable* otio_block = nullptr;
switch (block->type()) {
case Block::kClip:
{
auto otio_clip = new opentimelineio::v1_0::Clip();
otio_clip->set_source_range(opentimelineio::v1_0::TimeRange(block->in().toRationalTime(),
block->length().toRationalTime()));
otio_block = otio_clip;
break;
}
case Block::kGap:
{
auto otio_gap = new opentimelineio::v1_0::Gap();
otio_gap->set_source_range(opentimelineio::v1_0::TimeRange(block->in().toRationalTime(),
block->length().toRationalTime()));
otio_block = otio_gap;
break;
}
case Block::kTransition:
{
auto otio_transition = new opentimelineio::v1_0::Transition();
TransitionBlock* our_transition = static_cast<TransitionBlock*>(block);
otio_transition->set_in_offset(our_transition->in_offset().toRationalTime());
otio_transition->set_out_offset(our_transition->out_offset().toRationalTime());
otio_block = new opentimelineio::v1_0::Transition();
break;
}
}
if (!otio_block) {
// We shouldn't ever get here, but catch without crashing if we ever do
return false;
}
otio_track->append_child(otio_block, &es);
if (es != opentimelineio::v1_0::ErrorStatus::OK) {
return false;
}
}
otio_timeline->tracks()->append_child(otio_track, &es);
if (es != opentimelineio::v1_0::ErrorStatus::OK) {
return false;
}
}
return true;
}
OLIVE_NAMESPACE_EXIT
@@ -0,0 +1,45 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef PROJECTSAVEASOTIOTASK_H
#define PROJECTSAVEASOTIOTASK_H
#include "project/item/sequence/sequence.h"
#include "task/task.h"
OLIVE_NAMESPACE_ENTER
class ProjectSaveAsOTIOTask : public Task
{
Q_OBJECT
public:
ProjectSaveAsOTIOTask(Sequence* sequence);
protected:
virtual bool Run() override;
private:
Sequence* sequence_;
};
OLIVE_NAMESPACE_EXIT
#endif // PROJECTSAVEASOTIOTASK_H
+11 -2
View File
@@ -60,7 +60,12 @@ MainMenu::MainMenu(MainWindow *parent) :
file_menu_->addSeparator();
file_import_item_ = file_menu_->AddItem("import", Core::instance(), &Core::DialogImportShow, "Ctrl+I");
file_menu_->addSeparator();
file_export_item_ = file_menu_->AddItem("export", Core::instance(), &Core::DialogExportShow, "Ctrl+M");
file_export_menu_ = new Menu(file_menu_);
file_export_media_item_ = file_export_menu_->AddItem("export", Core::instance(), &Core::DialogExportShow, "Ctrl+M");
#ifdef USE_OTIO
file_export_menu_->addSeparator();
file_export_otio_item_ = file_export_menu_->AddItem("exportotio", Core::instance(), &Core::DialogExportShow);
#endif
file_menu_->addSeparator();
file_project_properties_item_ = file_menu_->AddItem("projectproperties", Core::instance(), &Core::DialogProjectPropertiesShow, "Shift+F10");
file_menu_->addSeparator();
@@ -642,7 +647,11 @@ void MainMenu::Retranslate()
file_open_recent_clear_item_->setText(tr("&Clear Recent List"));
file_save_all_item_->setText(tr("Sa&ve All Projects"));
file_import_item_->setText(tr("&Import..."));
file_export_item_->setText(tr("&Export..."));
file_export_menu_->setTitle(tr("&Export"));
file_export_media_item_->setText(tr("&Media..."));
#ifdef USE_OTIO
file_export_otio_item_->setText(tr("&OpenTimelineIO..."));
#endif
file_project_properties_item_->setText(tr("&Project Properties..."));
file_close_all_projects_item_->setText(tr("Close All Projects"));
file_exit_item_->setText(tr("E&xit"));
+5 -1
View File
@@ -198,7 +198,11 @@ private:
QAction* file_save_as_item_;
QAction* file_save_all_item_;
QAction* file_import_item_;
QAction* file_export_item_;
Menu* file_export_menu_;
QAction* file_export_media_item_;
#ifdef USE_OTIO
QAction* file_export_otio_item_;
#endif
QAction* file_project_properties_item_;
QAction* file_close_project_item_;
QAction* file_close_all_projects_item_;