Skip to content

Commit

Permalink
Merge pull request #27 from darbyjohnston/refactor5
Browse files Browse the repository at this point in the history
Refactoring
  • Loading branch information
darbyjohnston authored Nov 27, 2024
2 parents e646ca8 + c636b07 commit f565123
Show file tree
Hide file tree
Showing 27 changed files with 871 additions and 189 deletions.
2 changes: 1 addition & 1 deletion cmake/SuperBuild/Builddtk-deps.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include(ExternalProject)

set(dtk_GIT_REPOSITORY "https://github.com/darbyjohnston/dtk.git")
set(dtk_GIT_TAG "11e0c38016c8c7b860a7bc03dbc0adec7a1f0d91")
set(dtk_GIT_TAG "957d7bb8e6f7e12fc291e8c31a4180ee4a9dfd8f")

set(dtk-deps_ARGS
${toucan_EXTERNAL_PROJECT_ARGS}
Expand Down
2 changes: 1 addition & 1 deletion cmake/SuperBuild/Builddtk.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include(ExternalProject)

set(dtk_GIT_REPOSITORY "https://github.com/darbyjohnston/dtk.git")
set(dtk_GIT_TAG "11e0c38016c8c7b860a7bc03dbc0adec7a1f0d91")
set(dtk_GIT_TAG "957d7bb8e6f7e12fc291e8c31a4180ee4a9dfd8f")

set(dtk_DEPS dtk-deps)
set(dtk_ARGS
Expand Down
2 changes: 2 additions & 0 deletions lib/toucan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(HEADERS
PropertySet.h
Read.h
TimeWarp.h
TimelineAlgo.h
TimelineWrapper.h
Util.h)
set(HEADERS_PRIVATE
Expand All @@ -30,6 +31,7 @@ set(SOURCE
PropertySet.cpp
Read.cpp
TimeWarp.cpp
TimelineAlgo.cpp
TimelineWrapper.cpp
Util.cpp)
if(WIN32)
Expand Down
115 changes: 70 additions & 45 deletions lib/toucan/ImageGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "ImageEffectHost.h"
#include "Read.h"
#include "TimeWarp.h"
#include "TimelineAlgo.h"
#include "Util.h"

#include <opentimelineio/clip.h>
Expand All @@ -21,6 +22,19 @@ namespace toucan
namespace
{
const std::string logPrefix = "toucan::ImageGraph";

std::string toImageDataType(const OIIO::TypeDesc& value)
{
std::string out = "Unknown";
switch (value.basetype)
{
case OIIO::TypeDesc::UINT8: out = "u8"; break;
case OIIO::TypeDesc::UINT16: out = "u16"; break;
case OIIO::TypeDesc::HALF: out = "half"; break;
case OIIO::TypeDesc::FLOAT: out = "float"; break;
}
return out;
}
}

ImageGraph::ImageGraph(
Expand All @@ -34,54 +48,55 @@ namespace toucan
{
_loadCache.setMax(10);

// Get the image size from the first video clip.
for (auto track : _timelineWrapper->getTimeline()->find_children<OTIO_NS::Track>())
// Get the image information from the first video clip.
for (auto clip : getVideoClips(_timelineWrapper->getTimeline()))
{
if (OTIO_NS::Track::Kind::video == track->kind())
if (auto externalRef = dynamic_cast<OTIO_NS::ExternalReference*>(clip->media_reference()))
{
for (auto clip : track->find_clips())
auto read = std::make_shared<ReadNode>(
_timelineWrapper->getMediaPath(externalRef->target_url()),
_timelineWrapper->getMemoryReference(externalRef->target_url()));
const auto& spec = read->getSpec();
if (spec.width > 0)
{
if (auto externalRef = dynamic_cast<OTIO_NS::ExternalReference*>(clip->media_reference()))
{
auto read = std::make_shared<ReadNode>(
_timelineWrapper->getMediaPath(externalRef->target_url()),
_timelineWrapper->getMemoryReference(externalRef->target_url()));
const auto& spec = read->getSpec();
if (spec.width > 0)
{
_imageSize.x = spec.width;
_imageSize.y = spec.height;
break;
}
}
else if (auto sequenceRef = dynamic_cast<OTIO_NS::ImageSequenceReference*>(clip->media_reference()))
{
auto read = std::make_shared<SequenceReadNode>(
_timelineWrapper->getMediaPath(sequenceRef->target_url_base()),
sequenceRef->name_prefix(),
sequenceRef->name_suffix(),
sequenceRef->start_frame(),
sequenceRef->frame_step(),
sequenceRef->rate(),
sequenceRef->frame_zero_padding(),
_timelineWrapper->getMemoryReferences());
const auto& spec = read->getSpec();
if (spec.width > 0)
{
_imageSize.x = spec.width;
_imageSize.y = spec.height;
break;
}
}
else if (auto generatorRef = dynamic_cast<OTIO_NS::GeneratorReference*>(clip->media_reference()))
{
auto parameters = generatorRef->parameters();
auto i = parameters.find("size");
if (i != parameters.end() && i->second.has_value())
{
anyToVec(std::any_cast<OTIO_NS::AnyVector>(i->second), _imageSize);
}
}
_imageSize.x = spec.width;
_imageSize.y = spec.height;
_imageChannels = spec.nchannels;
_imageDataType = toImageDataType(spec.format);
break;
}
}
else if (auto sequenceRef = dynamic_cast<OTIO_NS::ImageSequenceReference*>(clip->media_reference()))
{
auto read = std::make_shared<SequenceReadNode>(
_timelineWrapper->getMediaPath(sequenceRef->target_url_base()),
sequenceRef->name_prefix(),
sequenceRef->name_suffix(),
sequenceRef->start_frame(),
sequenceRef->frame_step(),
sequenceRef->rate(),
sequenceRef->frame_zero_padding(),
_timelineWrapper->getMemoryReferences());
const auto& spec = read->getSpec();
if (spec.width > 0)
{
_imageSize.x = spec.width;
_imageSize.y = spec.height;
_imageChannels = spec.nchannels;
_imageDataType = toImageDataType(spec.format);
break;
}
}
else if (auto generatorRef = dynamic_cast<OTIO_NS::GeneratorReference*>(clip->media_reference()))
{
auto parameters = generatorRef->parameters();
auto i = parameters.find("size");
if (i != parameters.end() && i->second.has_value())
{
anyToVec(std::any_cast<OTIO_NS::AnyVector>(i->second), _imageSize);
//! \bug Hard coded:
_imageChannels = 4;
_imageDataType = toImageDataType(OIIO::TypeDesc::UINT8);
}
}
}
Expand All @@ -95,6 +110,16 @@ namespace toucan
return _imageSize;
}

int ImageGraph::getImageChannels() const
{
return _imageChannels;
}

const std::string& ImageGraph::getImageDataType() const
{
return _imageDataType;
}

std::shared_ptr<IImageNode> ImageGraph::exec(
const std::shared_ptr<ImageEffectHost>& host,
const OTIO_NS::RationalTime& time)
Expand Down
8 changes: 8 additions & 0 deletions lib/toucan/ImageGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ namespace toucan
//! Get the timeline image size.
const IMATH_NAMESPACE::V2i& getImageSize() const;

//! Get the timeline image channels.
int getImageChannels() const;

//! Get the timeline image data type.
const std::string& getImageDataType() const;

//! Get an image graph for the given time.
std::shared_ptr<IImageNode> exec(
const std::shared_ptr<ImageEffectHost>&,
Expand Down Expand Up @@ -66,6 +72,8 @@ namespace toucan
OTIO_NS::TimeRange _timeRange;
ImageGraphOptions _options;
IMATH_NAMESPACE::V2i _imageSize = IMATH_NAMESPACE::V2i(0, 0);
int _imageChannels = 0;
std::string _imageDataType;
LRUCache<OTIO_NS::MediaReference*, std::shared_ptr<ReadNode> > _loadCache;
};
}
67 changes: 67 additions & 0 deletions lib/toucan/TimelineAlgo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Contributors to the toucan project.

#include "TimelineAlgo.h"

#include <opentimelineio/clip.h>

namespace toucan
{
std::vector<OTIO_NS::SerializableObject::Retainer<OTIO_NS::Clip> >
getVideoClips(const OTIO_NS::SerializableObject::Retainer<OTIO_NS::Timeline>& timeline)
{
std::vector<OTIO_NS::SerializableObject::Retainer<OTIO_NS::Clip> > out;
for (const auto& child : timeline->tracks()->children())
{
if (auto track = OTIO_NS::dynamic_retainer_cast<OTIO_NS::Track>(child))
{
if (OTIO_NS::Track::Kind::video == track->kind())
{
const auto clips = track->find_clips(nullptr, std::nullopt, true);
out.insert(out.end(), clips.begin(), clips.end());
}
}
}
return out;
}

std::optional<OTIO_NS::TimeRange> getTimeRange(
const std::vector<OTIO_NS::SerializableObject::Retainer<OTIO_NS::Item> >& items,
const OTIO_NS::RationalTime& startTime,
double rate)
{
std::optional<OTIO_NS::TimeRange> out;
for (const auto& item : items)
{
//! \bug Shouldn't trimmed_range_in_parent() check whether the parent
//! is null?
if (item->parent())
{
const auto timeRangeOpt = item->trimmed_range_in_parent();
if (timeRangeOpt.has_value())
{
const OTIO_NS::TimeRange timeRange(
timeRangeOpt.value().start_time() + startTime,
timeRangeOpt.value().duration());
if (out.has_value())
{
out = OTIO_NS::TimeRange::range_from_start_end_time_inclusive(
std::min(
out.value().start_time(),
timeRange.start_time().rescaled_to(rate).round()),
std::max(
out.value().end_time_inclusive(),
timeRange.end_time_inclusive().rescaled_to(rate).round()));
}
else
{
out = OTIO_NS::TimeRange(
timeRange.start_time().rescaled_to(rate).round(),
timeRange.duration().rescaled_to(rate).round());
}
}
}
}
return out;
}
}
19 changes: 19 additions & 0 deletions lib/toucan/TimelineAlgo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Contributors to the toucan project.

#pragma once

#include <opentimelineio/timeline.h>

namespace toucan
{
//! Get the video clips in a timeline.
std::vector<OTIO_NS::SerializableObject::Retainer<OTIO_NS::Clip> >
getVideoClips(const OTIO_NS::SerializableObject::Retainer<OTIO_NS::Timeline>&);

//! Get the range of multiple items.
std::optional<OTIO_NS::TimeRange> getTimeRange(
const std::vector<OTIO_NS::SerializableObject::Retainer<OTIO_NS::Item> >&,
const OTIO_NS::RationalTime& startTime,
double rate);
}
2 changes: 2 additions & 0 deletions lib/toucan/Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "Util.h"

#include <opentimelineio/clip.h>

#include <OpenFX/ofxImageEffect.h>

#include <algorithm>
Expand Down
10 changes: 10 additions & 0 deletions lib/toucanView/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ namespace toucan
return _graph->getImageSize();
}

int Document::getImageChannels() const
{
return _graph->getImageChannels();
}

const std::string& Document::getImageDataType() const
{
return _graph->getImageDataType();
}

std::shared_ptr<dtk::IObservableValue<std::shared_ptr<dtk::Image> > > Document::observeCurrentImage() const
{
return _currentImage;
Expand Down
2 changes: 2 additions & 0 deletions lib/toucanView/Document.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ namespace toucan
const std::shared_ptr<ThumbnailGenerator>& getThumbnailGenerator() const;

const IMATH_NAMESPACE::V2i& getImageSize() const;
int getImageChannels() const;
const std::string& getImageDataType() const;

std::shared_ptr<dtk::IObservableValue<std::shared_ptr<dtk::Image> > > observeCurrentImage() const;

Expand Down
12 changes: 8 additions & 4 deletions lib/toucanView/InfoBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,22 @@ namespace toucan
const IMATH_NAMESPACE::V2i& imageSize = document->getImageSize();
const size_t trackCount = document->getTimeline()->find_children<OTIO_NS::Track>().size();

text = dtk::Format("{0}: {1}x{2}, {3} tracks").
text = dtk::Format("{0}: {1}x{2}, {3} channels, {4} data, {5} tracks").
arg(dtk::elide(document->getPath().filename().string())).
arg(imageSize.x).
arg(imageSize.y).
arg(document->getImageChannels()).
arg(document->getImageDataType()).
arg(trackCount);
tooltip = dtk::Format(
"path: {0}\n"
"resolution: {1}x{2}\n"
"tracks: {3}").
"Path: {0}\n"
"Render: {1}x{2}, {3} channels, {4} data\n"
"Tracks: {5}").
arg(document->getPath().string()).
arg(imageSize.x).
arg(imageSize.y).
arg(document->getImageChannels()).
arg(document->getImageDataType()).
arg(trackCount);
}
_label->setText(text);
Expand Down
Loading

0 comments on commit f565123

Please sign in to comment.