start moving core frameworks to external libraries

This commit is contained in:
itsmattkc
2023-01-19 09:51:47 -08:00
parent e7982239b8
commit dd9c52ab59
158 changed files with 478 additions and 2484 deletions
+8
View File
@@ -94,6 +94,14 @@ find_package(OpenEXR REQUIRED)
list(APPEND OLIVE_LIBRARIES ${OPENEXR_LIBRARIES})
list(APPEND OLIVE_INCLUDE_DIRS ${OPENEXR_INCLUDES})
# Link Olive
find_package(Olive REQUIRED
COMPONENTS
Core
)
list(APPEND OLIVE_LIBRARIES ${LIBOLIVE_LIBRARIES})
list(APPEND OLIVE_INCLUDE_DIRS ${LIBOLIVE_INCLUDE_DIRS})
# Link Qt
set(QT_LIBRARIES
Core
+2
View File
@@ -25,6 +25,8 @@ extern "C" {
#include <libavfilter/buffersink.h>
}
#include <QDebug>
#include "common/ffmpegutils.h"
namespace olive {
+1
View File
@@ -27,6 +27,7 @@ extern "C" {
#include <libavfilter/avfilter.h>
}
#include "common/define.h"
#include "render/audioparams.h"
namespace olive {
+2 -2
View File
@@ -22,13 +22,13 @@
#include <QCoreApplication>
#include <QDebug>
#include <QHash>
#include "codec/ffmpeg/ffmpegdecoder.h"
#include "codec/planarfiledevice.h"
#include "codec/oiio/oiiodecoder.h"
#include "common/ffmpegutils.h"
#include "common/filefunctions.h"
#include "common/timecodefunctions.h"
#include "conformmanager.h"
#include "node/project/project.h"
#include "task/taskmanager.h"
@@ -338,7 +338,7 @@ void Decoder::UpdateLastAccessed()
uint qHash(Decoder::CodecStream stream, uint seed)
{
return qHash(stream.filename(), seed) ^ qHash(stream.stream(), seed) ^ qHash(stream.block(), seed);
return qHash(stream.filename(), seed) ^ ::qHash(stream.stream(), seed) ^ qHash(stream.block(), seed);
}
}
+2 -2
View File
@@ -32,10 +32,10 @@ extern "C" {
#include <stdint.h>
#include "codec/samplebuffer.h"
#include "common/rational.h"
#include "node/block/block.h"
#include "node/project/footage/footagedescription.h"
#include "render/cancelatom.h"
#include "render/rendermodes.h"
namespace olive {
@@ -160,7 +160,7 @@ public:
Renderer *renderer = nullptr;
rational time;
int divider = 1;
VideoParams::Format maximum_format = VideoParams::kFormatInvalid;
PixelFormat maximum_format = PixelFormat::INVALID;
CancelAtom *cancelled = nullptr;
VideoParams::ColorRange force_range = VideoParams::kColorRangeDefault;
VideoParams::Interlacing src_interlacing = VideoParams::kInterlaceNone;
+9 -10
View File
@@ -22,7 +22,6 @@
#include <QFile>
#include "common/timecodefunctions.h"
#include "common/xmlutils.h"
#include "ffmpeg/ffmpegencoder.h"
#include "oiio/oiioencoder.h"
@@ -202,8 +201,8 @@ void EncodingParams::Save(QXmlStreamWriter *writer) const
writer->writeTextElement(QStringLiteral("format"), QString::number(format_));
writer->writeTextElement(QStringLiteral("range"), QString::number(has_custom_range_));
writer->writeTextElement(QStringLiteral("customrangein"), custom_range_.in().toString());
writer->writeTextElement(QStringLiteral("customrangeout"), custom_range_.out().toString());
writer->writeTextElement(QStringLiteral("customrangein"), QString::fromStdString(custom_range_.in().toString()));
writer->writeTextElement(QStringLiteral("customrangeout"), QString::fromStdString(custom_range_.out().toString()));
writer->writeStartElement(QStringLiteral("video"));
@@ -214,8 +213,8 @@ void EncodingParams::Save(QXmlStreamWriter *writer) const
writer->writeTextElement(QStringLiteral("width"), QString::number(video_params_.width()));
writer->writeTextElement(QStringLiteral("height"), QString::number(video_params_.height()));
writer->writeTextElement(QStringLiteral("format"), QString::number(video_params_.format()));
writer->writeTextElement(QStringLiteral("pixelaspect"), video_params_.pixel_aspect_ratio().toString());
writer->writeTextElement(QStringLiteral("timebase"), video_params_.time_base().toString());
writer->writeTextElement(QStringLiteral("pixelaspect"), QString::fromStdString(video_params_.pixel_aspect_ratio().toString()));
writer->writeTextElement(QStringLiteral("timebase"), QString::fromStdString(video_params_.time_base().toString()));
writer->writeTextElement(QStringLiteral("divider"), QString::number(video_params_.divider()));
writer->writeTextElement(QStringLiteral("bitrate"), QString::number(video_bit_rate_));
writer->writeTextElement(QStringLiteral("minbitrate"), QString::number(video_min_bit_rate_));
@@ -381,9 +380,9 @@ bool EncodingParams::LoadV1(QXmlStreamReader *reader)
} else if (reader->name() == QStringLiteral("range")) {
has_custom_range_ = reader->readElementText().toInt();
} else if (reader->name() == QStringLiteral("customrangein")) {
custom_range_in = rational::fromString(reader->readElementText());
custom_range_in = rational::fromString(reader->readElementText().toStdString());
} else if (reader->name() == QStringLiteral("customrangeout")) {
custom_range_out = rational::fromString(reader->readElementText());
custom_range_out = rational::fromString(reader->readElementText().toStdString());
} else if (reader->name() == QStringLiteral("video")) {
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("enabled")) {
@@ -399,11 +398,11 @@ bool EncodingParams::LoadV1(QXmlStreamReader *reader)
} else if (reader->name() == QStringLiteral("height")) {
video_params_.set_height(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("format")) {
video_params_.set_format(static_cast<VideoParams::Format>(reader->readElementText().toInt()));
video_params_.set_format(static_cast<PixelFormat::Format>(reader->readElementText().toInt()));
} else if (reader->name() == QStringLiteral("pixelaspect")) {
video_params_.set_pixel_aspect_ratio(rational::fromString(reader->readElementText()));
video_params_.set_pixel_aspect_ratio(rational::fromString(reader->readElementText().toStdString()));
} else if (reader->name() == QStringLiteral("timebase")) {
video_params_.set_time_base(rational::fromString(reader->readElementText()));
video_params_.set_time_base(rational::fromString(reader->readElementText().toStdString()));
} else if (reader->name() == QStringLiteral("divider")) {
video_params_.set_divider(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("bitrate")) {
+3 -4
View File
@@ -30,7 +30,6 @@
#include "codec/exportformat.h"
#include "codec/frame.h"
#include "codec/samplebuffer.h"
#include "common/timerange.h"
#include "node/block/subtitle/subtitle.h"
#include "render/audioparams.h"
#include "render/colortransform.h"
@@ -209,9 +208,9 @@ public:
const EncodingParams& params() const;
virtual VideoParams::Format GetDesiredPixelFormat() const
virtual PixelFormat GetDesiredPixelFormat() const
{
return VideoParams::kFormatInvalid;
return PixelFormat::INVALID;
}
const QString& GetError() const
@@ -232,7 +231,7 @@ public:
public slots:
virtual bool Open() = 0;
virtual bool WriteFrame(olive::FramePtr frame, olive::rational time) = 0;
virtual bool WriteFrame(olive::FramePtr frame, olive::core::rational time) = 0;
virtual bool WriteAudio(const olive::SampleBuffer &audio) = 0;
virtual bool WriteSubtitle(const SubtitleBlock *sub_block) = 0;
+5 -6
View File
@@ -42,7 +42,6 @@ extern "C" {
#include "codec/planarfiledevice.h"
#include "common/ffmpegutils.h"
#include "common/filefunctions.h"
#include "common/timecodefunctions.h"
#include "render/renderer.h"
#include "render/subtitleparams.h"
@@ -78,7 +77,7 @@ TexturePtr FFmpegDecoder::ProcessFrameIntoTexture(AVFramePtr f, const RetrieveVi
{
// Determine native format
AVPixelFormat ideal_fmt = FFmpegUtils::GetCompatiblePixelFormat(static_cast<AVPixelFormat>(f->format));
VideoParams::Format native_fmt = GetNativePixelFormat(ideal_fmt);
PixelFormat native_fmt = GetNativePixelFormat(ideal_fmt);
int native_channels = GetNativeChannelCount(ideal_fmt);
// Set up video params
@@ -642,17 +641,17 @@ bool FFmpegDecoder::ConformAudioInternal(const QVector<QString> &filenames, cons
return success;
}
VideoParams::Format FFmpegDecoder::GetNativePixelFormat(AVPixelFormat pix_fmt)
PixelFormat FFmpegDecoder::GetNativePixelFormat(AVPixelFormat pix_fmt)
{
switch (pix_fmt) {
case AV_PIX_FMT_RGB24:
case AV_PIX_FMT_RGBA:
return VideoParams::kFormatUnsigned8;
return PixelFormat::U8;
case AV_PIX_FMT_RGB48:
case AV_PIX_FMT_RGBA64:
return VideoParams::kFormatUnsigned16;
return PixelFormat::U16;
default:
return VideoParams::kFormatInvalid;
return PixelFormat::INVALID;
}
}
+1 -1
View File
@@ -136,7 +136,7 @@ private:
void FreeScaler();
static VideoParams::Format GetNativePixelFormat(AVPixelFormat pix_fmt);
static PixelFormat GetNativePixelFormat(AVPixelFormat pix_fmt);
static int GetNativeChannelCount(AVPixelFormat pix_fmt);
static uint64_t ValidateChannelLayout(AVStream *stream);
+1 -2
View File
@@ -29,7 +29,6 @@ extern "C" {
#include <QFile>
#include "common/ffmpegutils.h"
#include "common/timecodefunctions.h"
namespace olive {
@@ -130,7 +129,7 @@ bool FFmpegEncoder::Open()
}
// This is the format we will expect frames received in Write() to be in
VideoParams::Format native_pixel_fmt = params().video_params().format();
PixelFormat native_pixel_fmt = params().video_params().format();
// This is the format we will need to convert the frame to for swscale to understand it
video_conversion_fmt_ = FFmpegUtils::GetCompatiblePixelFormat(native_pixel_fmt);
+3 -3
View File
@@ -45,7 +45,7 @@ public:
virtual bool Open() override;
virtual bool WriteFrame(olive::FramePtr frame, olive::rational time) override;
virtual bool WriteFrame(olive::FramePtr frame, olive::core::rational time) override;
virtual bool WriteAudio(const olive::SampleBuffer &audio) override;
@@ -55,7 +55,7 @@ public:
virtual void Close() override;
virtual VideoParams::Format GetDesiredPixelFormat() const override
virtual PixelFormat GetDesiredPixelFormat() const override
{
return video_conversion_fmt_;
}
@@ -91,7 +91,7 @@ private:
AVFilterGraph *video_scale_ctx_;
AVFilterContext *video_buffersrc_ctx_;
AVFilterContext *video_buffersink_ctx_;
VideoParams::Format video_conversion_fmt_;
PixelFormat video_conversion_fmt_;
AVStream* audio_stream_;
AVCodecContext* audio_codec_ctx_;
+2 -2
View File
@@ -84,7 +84,7 @@ FramePtr Frame::Interlace(FramePtr top, FramePtr bottom)
return interlaced;
}
int Frame::generate_linesize_bytes(int width, VideoParams::Format format, int channel_count)
int Frame::generate_linesize_bytes(int width, PixelFormat format, int channel_count)
{
// Align to 32 bytes (not sure if this is necessary?)
return VideoParams::GetBytesPerPixel(format, channel_count) * ((width + 31) & ~31);
@@ -146,7 +146,7 @@ void Frame::destroy()
}
}
FramePtr Frame::convert(VideoParams::Format format) const
FramePtr Frame::convert(PixelFormat format) const
{
// Create new params with destination format
VideoParams params = params_;
+4 -5
View File
@@ -22,11 +22,10 @@
#define FRAME_H
#include <memory>
#include <olive/core/core.h>
#include <QVector>
#include "common/define.h"
#include "common/rational.h"
#include "render/color.h"
#include "render/videoparams.h"
namespace olive {
@@ -53,7 +52,7 @@ public:
static FramePtr Interlace(FramePtr top, FramePtr bottom);
static int generate_linesize_bytes(int width, VideoParams::Format format, int channel_count);
static int generate_linesize_bytes(int width, PixelFormat format, int channel_count);
int linesize_pixels() const
{
@@ -75,7 +74,7 @@ public:
return params_.effective_height();
}
VideoParams::Format format() const
PixelFormat format() const
{
return params_.format();
}
@@ -152,7 +151,7 @@ public:
return data_size_;
}
FramePtr convert(VideoParams::Format format) const;
FramePtr convert(PixelFormat format) const;
private:
VideoParams params_;
+1 -1
View File
@@ -205,7 +205,7 @@ bool OIIODecoder::OpenImageHandler(const QString &fn, int subimage)
// We use RGBA frames because that tends to be the native format of GPUs
pix_fmt_ = OIIOUtils::GetFormatFromOIIOBasetype(static_cast<OIIO::TypeDesc::BASETYPE>(spec.format.basetype));
if (pix_fmt_ == VideoParams::kFormatInvalid) {
if (pix_fmt_ == PixelFormat::INVALID) {
qWarning() << "Failed to convert OIIO::ImageDesc to native pixel format";
return false;
}
+1 -1
View File
@@ -58,7 +58,7 @@ private:
static VideoParams GetVideoParamsFromImageSpec(const OIIO::ImageSpec &spec);
VideoParams::Format pix_fmt_;
PixelFormat pix_fmt_;
OIIO::TypeDesc::BASETYPE oiio_pix_fmt_;
Frame buffer_;
+1 -1
View File
@@ -34,7 +34,7 @@ public:
public slots:
virtual bool Open() override;
virtual bool WriteFrame(olive::FramePtr frame, olive::rational time) override;
virtual bool WriteFrame(olive::FramePtr frame, olive::core::rational time) override;
virtual bool WriteAudio(const SampleBuffer &audio) override;
virtual bool WriteSubtitle(const SubtitleBlock *sub_block) override;
+2
View File
@@ -20,6 +20,8 @@
#include "samplebuffer.h"
#include <QDebug>
#include "common/cpuoptimize.h"
namespace olive {
-6
View File
@@ -50,13 +50,7 @@ set(OLIVE_SOURCES
common/range.h
common/ratiodialog.cpp
common/ratiodialog.h
common/rational.cpp
common/rational.h
common/threadsafemap.h
common/timecodefunctions.cpp
common/timecodefunctions.h
common/timerange.cpp
common/timerange.h
common/tohex.h
common/util.h
common/xmlutils.cpp
+25 -25
View File
@@ -22,13 +22,13 @@
namespace olive {
AVPixelFormat FFmpegUtils::GetCompatiblePixelFormat(const AVPixelFormat &pix_fmt, VideoParams::Format maximum)
AVPixelFormat FFmpegUtils::GetCompatiblePixelFormat(const AVPixelFormat &pix_fmt, PixelFormat maximum)
{
AVPixelFormat possible_pix_fmts[3];
possible_pix_fmts[0] = AV_PIX_FMT_RGBA;
if (maximum == VideoParams::kFormatUnsigned8) {
if (maximum == PixelFormat::U8) {
possible_pix_fmts[1] = AV_PIX_FMT_NONE;
} else {
possible_pix_fmts[1] = AV_PIX_FMT_RGBA64;
@@ -148,30 +148,30 @@ AVPixelFormat FFmpegUtils::ConvertJPEGSpaceToRegularSpace(AVPixelFormat f)
return f;
}
AVPixelFormat FFmpegUtils::GetFFmpegPixelFormat(const VideoParams::Format &pix_fmt, int channel_layout)
AVPixelFormat FFmpegUtils::GetFFmpegPixelFormat(const PixelFormat &pix_fmt, int channel_layout)
{
if (channel_layout == VideoParams::kRGBChannelCount) {
switch (pix_fmt) {
case VideoParams::kFormatUnsigned8:
case PixelFormat::U8:
return AV_PIX_FMT_RGB24;
case VideoParams::kFormatUnsigned16:
case PixelFormat::U16:
return AV_PIX_FMT_RGB48;
case VideoParams::kFormatFloat16:
case VideoParams::kFormatFloat32:
case VideoParams::kFormatInvalid:
case VideoParams::kFormatCount:
case PixelFormat::F16:
case PixelFormat::F32:
case PixelFormat::INVALID:
case PixelFormat::FORMAT_COUNT:
break;
}
} else if (channel_layout == VideoParams::kRGBAChannelCount) {
switch (pix_fmt) {
case VideoParams::kFormatUnsigned8:
case PixelFormat::U8:
return AV_PIX_FMT_RGBA;
case VideoParams::kFormatUnsigned16:
case PixelFormat::U16:
return AV_PIX_FMT_RGBA64;
case VideoParams::kFormatFloat16:
case VideoParams::kFormatFloat32:
case VideoParams::kFormatInvalid:
case VideoParams::kFormatCount:
case PixelFormat::F16:
case PixelFormat::F32:
case PixelFormat::INVALID:
case PixelFormat::FORMAT_COUNT:
break;
}
}
@@ -179,21 +179,21 @@ AVPixelFormat FFmpegUtils::GetFFmpegPixelFormat(const VideoParams::Format &pix_f
return AV_PIX_FMT_NONE;
}
VideoParams::Format FFmpegUtils::GetCompatiblePixelFormat(const VideoParams::Format &pix_fmt)
PixelFormat FFmpegUtils::GetCompatiblePixelFormat(const PixelFormat &pix_fmt)
{
switch (pix_fmt) {
case VideoParams::kFormatUnsigned8:
return VideoParams::kFormatUnsigned8;
case VideoParams::kFormatUnsigned16:
case VideoParams::kFormatFloat16:
case VideoParams::kFormatFloat32:
return VideoParams::kFormatUnsigned16;
case VideoParams::kFormatInvalid:
case VideoParams::kFormatCount:
case PixelFormat::U8:
return PixelFormat::U8;
case PixelFormat::U16:
case PixelFormat::F16:
case PixelFormat::F32:
return PixelFormat::U16;
case PixelFormat::INVALID:
case PixelFormat::FORMAT_COUNT:
break;
}
return VideoParams::kFormatInvalid;
return PixelFormat::INVALID;
}
}
+3 -3
View File
@@ -37,17 +37,17 @@ public:
/**
* @brief Returns an AVPixelFormat that can be used to convert a frame to a data type Olive supports with minimal data loss
*/
static AVPixelFormat GetCompatiblePixelFormat(const AVPixelFormat& pix_fmt, VideoParams::Format maximum = VideoParams::kFormatInvalid);
static AVPixelFormat GetCompatiblePixelFormat(const AVPixelFormat& pix_fmt, PixelFormat maximum = PixelFormat::INVALID);
/**
* @brief Returns a native pixel format that can be used to convert from a native frame to an AVFrame with minimal data loss
*/
static VideoParams::Format GetCompatiblePixelFormat(const VideoParams::Format& pix_fmt);
static PixelFormat GetCompatiblePixelFormat(const PixelFormat& pix_fmt);
/**
* @brief Returns an FFmpeg pixel format for a given native pixel format
*/
static AVPixelFormat GetFFmpegPixelFormat(const VideoParams::Format& pix_fmt, int channel_layout);
static AVPixelFormat GetFFmpegPixelFormat(const PixelFormat& pix_fmt, int channel_layout);
/**
* @brief Returns a native sample format type for a given AVSampleFormat
+7 -7
View File
@@ -22,22 +22,22 @@
namespace olive {
OCIO::BitDepth OCIOUtils::GetOCIOBitDepthFromPixelFormat(VideoParams::Format format)
OCIO::BitDepth OCIOUtils::GetOCIOBitDepthFromPixelFormat(PixelFormat format)
{
switch (format) {
case VideoParams::kFormatUnsigned8:
case PixelFormat::U8:
return OCIO::BIT_DEPTH_UINT8;
case VideoParams::kFormatUnsigned16:
case PixelFormat::U16:
return OCIO::BIT_DEPTH_UINT16;
break;
case VideoParams::kFormatFloat16:
case PixelFormat::F16:
return OCIO::BIT_DEPTH_F16;
break;
case VideoParams::kFormatFloat32:
case PixelFormat::F32:
return OCIO::BIT_DEPTH_F32;
break;
case VideoParams::kFormatInvalid:
case VideoParams::kFormatCount:
case PixelFormat::INVALID:
case PixelFormat::FORMAT_COUNT:
break;
}
+1 -1
View File
@@ -31,7 +31,7 @@ namespace olive {
class OCIOUtils
{
public:
static OCIO::BitDepth GetOCIOBitDepthFromPixelFormat(VideoParams::Format format);
static OCIO::BitDepth GetOCIOBitDepthFromPixelFormat(PixelFormat format);
};
}
+8 -6
View File
@@ -20,6 +20,8 @@
#include "oiioutils.h"
#include <QDebug>
namespace olive {
void OIIOUtils::FrameToBuffer(const Frame* frame, OIIO::ImageBuf *buf)
@@ -45,7 +47,7 @@ rational OIIOUtils::GetPixelAspectRatioFromOIIO(const OIIO::ImageSpec &spec)
return rational::fromDouble(spec.get_float_attribute("PixelAspectRatio", 1));
}
VideoParams::Format OIIOUtils::GetFormatFromOIIOBasetype(OIIO::TypeDesc::BASETYPE type)
PixelFormat OIIOUtils::GetFormatFromOIIOBasetype(OIIO::TypeDesc::BASETYPE type)
{
switch (type) {
case OIIO::TypeDesc::UNKNOWN:
@@ -66,16 +68,16 @@ VideoParams::Format OIIOUtils::GetFormatFromOIIOBasetype(OIIO::TypeDesc::BASETYP
break;
case OIIO::TypeDesc::UINT8:
return VideoParams::kFormatUnsigned8;
return PixelFormat::U8;
case OIIO::TypeDesc::UINT16:
return VideoParams::kFormatUnsigned16;
return PixelFormat::U16;
case OIIO::TypeDesc::HALF:
return VideoParams::kFormatFloat16;
return PixelFormat::F16;
case OIIO::TypeDesc::FLOAT:
return VideoParams::kFormatFloat32;
return PixelFormat::F32;
}
return VideoParams::kFormatInvalid;
return PixelFormat::INVALID;
}
}
+8 -8
View File
@@ -31,19 +31,19 @@ namespace olive {
class OIIOUtils {
public:
static OIIO::TypeDesc::BASETYPE GetOIIOBaseTypeFromFormat(VideoParams::Format format)
static OIIO::TypeDesc::BASETYPE GetOIIOBaseTypeFromFormat(PixelFormat format)
{
switch (format) {
case VideoParams::kFormatUnsigned8:
case PixelFormat::U8:
return OIIO::TypeDesc::UINT8;
case VideoParams::kFormatUnsigned16:
case PixelFormat::U16:
return OIIO::TypeDesc::UINT16;
case VideoParams::kFormatFloat16:
case PixelFormat::F16:
return OIIO::TypeDesc::HALF;
case VideoParams::kFormatFloat32:
case PixelFormat::F32:
return OIIO::TypeDesc::FLOAT;
case VideoParams::kFormatInvalid:
case VideoParams::kFormatCount:
case PixelFormat::INVALID:
case PixelFormat::FORMAT_COUNT:
break;
}
@@ -54,7 +54,7 @@ public:
static void BufferToFrame(OIIO::ImageBuf* buf, Frame* frame);
static VideoParams::Format GetFormatFromOIIOBasetype(OIIO::TypeDesc::BASETYPE type);
static PixelFormat GetFormatFromOIIOBasetype(OIIO::TypeDesc::BASETYPE type);
static rational GetPixelAspectRatioFromOIIO(const OIIO::ImageSpec& spec);
+30
View File
@@ -22,6 +22,8 @@
#include <QDebug>
#include "common/clamp.h"
namespace olive {
int QtUtils::QFontMetricsWidth(QFontMetrics fm, const QString& s) {
@@ -172,4 +174,32 @@ void QtUtils::SetComboBoxData(QComboBox *cb, int data)
}
}
QColor QtUtils::toQColor(const core::Color &i)
{
QColor c;
// QColor only supports values from 0.0 to 1.0 and are only used for UI representations
c.setRedF(clamp(i.red(), 0.0f, 1.0f));
c.setGreenF(clamp(i.green(), 0.0f, 1.0f));
c.setBlueF(clamp(i.blue(), 0.0f, 1.0f));
c.setAlphaF(clamp(i.alpha(), 0.0f, 1.0f));
return c;
}
namespace core {
uint qHash(const core::rational &r, uint seed)
{
return ::qHash(r.toDouble(), seed);
}
uint qHash(const core::TimeRange &r, uint seed)
{
return qHash(r.in(), seed) ^ qHash(r.out(), seed);
}
}
}
+14
View File
@@ -21,6 +21,7 @@
#ifndef QTVERSIONABSTRACTION_H
#define QTVERSIONABSTRACTION_H
#include <olive/core/core.h>
#include <QComboBox>
#include <QDateTime>
#include <QFileInfo>
@@ -72,8 +73,21 @@ public:
return nullptr;
}
static QColor toQColor(const core::Color &c);
};
namespace core {
uint qHash(const core::rational& r, uint seed = 0);
uint qHash(const core::TimeRange& r, uint seed = 0);
}
}
Q_DECLARE_METATYPE(olive::core::rational);
Q_DECLARE_METATYPE(olive::core::Color);
Q_DECLARE_METATYPE(olive::core::TimeRange);
#endif // QTVERSIONABSTRACTION_H
-2
View File
@@ -23,8 +23,6 @@
#include <QInputDialog>
#include "common/rational.h"
namespace olive {
double GetFloatRatioFromUser(QWidget* parent,
-287
View File
@@ -1,287 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 "rational.h"
namespace olive {
const rational rational::NaN = rational(0, 0);
rational rational::fromDouble(const double &flt, bool* ok)
{
if (qIsNaN(flt)) {
// Return NaN rational
if (ok) *ok = false;
return NaN;
}
// Use FFmpeg function for the time being
AVRational r = av_d2q(flt, INT_MAX);
if (r.den == 0) {
// If den == 0, we were unable to convert to a rational
if (ok) {
*ok = false;
}
} else {
// Otherwise, assume we received a real rational
if (ok) {
*ok = true;
}
}
return r;
}
rational rational::fromString(const QString &str, bool* ok)
{
QStringList elements = str.split('/');
switch (elements.size()) {
case 1:
return rational(elements.first().toInt(ok));
case 2:
return rational(elements.at(0).toInt(ok), elements.at(1).toInt(ok));
default:
// Returns NaN with ok set to false
if (ok) {
*ok = false;
}
return NaN;
}
}
//Function: convert to double
double rational::toDouble() const
{
if (r_.den != 0) {
return av_q2d(r_);
} else {
return qSNaN();
}
}
AVRational rational::toAVRational() const
{
return r_;
}
#ifdef USE_OTIO
opentime::RationalTime rational::toRationalTime(double framerate) const
{
// Is this the best way of doing this?
// Olive can store rationals as 0/0 which causes errors in OTIO
opentime::RationalTime time = opentime::RationalTime(r_.num, r_.den == 0 ? 1 : r_.den);
return time.rescaled_to(framerate);
}
#endif
rational rational::flipped() const
{
rational r = *this;
r.flip();
return r;
}
void rational::flip()
{
if (!isNull()) {
std::swap(r_.den, r_.num);
FixSigns();
}
}
QString rational::toString() const
{
return QStringLiteral("%1/%2").arg(QString::number(r_.num), QString::number(r_.den));
}
void rational::FixSigns()
{
if (r_.den < 0) {
// Normalize so that denominator is always positive
r_.den = -r_.den;
r_.num = -r_.num;
} else if (r_.den == 0) {
// Normalize to 0/0 (aka NaN) if denominator is zero
r_.num = 0;
} else if (r_.num == 0) {
// Normalize to 0/1 if numerator is zero
r_.den = 1;
}
}
void rational::Reduce()
{
av_reduce(&r_.num, &r_.den, r_.num, r_.den, INT_MAX);
}
//Assignment Operators
const rational& rational::operator=(const rational &rhs)
{
r_ = rhs.r_;
return *this;
}
const rational& rational::operator+=(const rational &rhs)
{
Q_ASSERT(*this != RATIONAL_MIN && *this != RATIONAL_MAX && rhs != RATIONAL_MIN && rhs != RATIONAL_MAX);
if (!isNaN()) {
if (rhs.isNaN()) {
*this = NaN;
} else {
r_ = av_add_q(r_, rhs.r_);
FixSigns();
}
}
return *this;
}
const rational& rational::operator-=(const rational &rhs)
{
Q_ASSERT(*this != RATIONAL_MIN && *this != RATIONAL_MAX && rhs != RATIONAL_MIN && rhs != RATIONAL_MAX);
if (!isNaN()) {
if (rhs.isNaN()) {
*this = NaN;
} else {
r_ = av_sub_q(r_, rhs.r_);
FixSigns();
}
}
return *this;
}
const rational& rational::operator*=(const rational &rhs)
{
Q_ASSERT(*this != RATIONAL_MIN && *this != RATIONAL_MAX && rhs != RATIONAL_MIN && rhs != RATIONAL_MAX);
if (!isNaN()) {
if (rhs.isNaN()) {
*this = NaN;
} else {
r_ = av_mul_q(r_, rhs.r_);
FixSigns();
}
}
return *this;
}
const rational& rational::operator/=(const rational &rhs)
{
Q_ASSERT(*this != RATIONAL_MIN && *this != RATIONAL_MAX && rhs != RATIONAL_MIN && rhs != RATIONAL_MAX);
if (!isNaN()) {
if (rhs.isNaN()) {
*this = NaN;
} else {
r_ = av_div_q(r_, rhs.r_);
FixSigns();
}
}
return *this;
}
//Binary math operators
rational rational::operator+(const rational &rhs) const
{
rational answer(*this);
answer += rhs;
return answer;
}
rational rational::operator-(const rational &rhs) const
{
rational answer(*this);
answer -= rhs;
return answer;
}
rational rational::operator/(const rational &rhs) const
{
rational answer(*this);
answer /= rhs;
return answer;
}
rational rational::operator*(const rational &rhs) const
{
rational answer(*this);
answer *= rhs;
return answer;
}
//Relational and equality operators
bool rational::operator<(const rational &rhs) const
{
return av_cmp_q(r_, rhs.r_) == -1;
}
bool rational::operator<=(const rational &rhs) const
{
int cmp = av_cmp_q(r_, rhs.r_);
return cmp == 0 || cmp == -1;
}
bool rational::operator>(const rational &rhs) const
{
return av_cmp_q(r_, rhs.r_) == 1;
}
bool rational::operator>=(const rational &rhs) const
{
int cmp = av_cmp_q(r_, rhs.r_);
return cmp == 0 || cmp == 1;
}
bool rational::operator==(const rational &rhs) const
{
return av_cmp_q(r_, rhs.r_) == 0;
}
bool rational::operator!=(const rational &rhs) const
{
return !(*this == rhs);
}
uint qHash(const rational &r, uint seed)
{
return ::qHash(r.toDouble(), seed);
}
}
QDebug operator<<(QDebug debug, const olive::rational &r)
{
if (r.isNaN()) {
return debug.space() << "NaN";
} else {
return debug.space() << r.toDouble();
}
}
-157
View File
@@ -1,157 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 RATIONAL_H
#define RATIONAL_H
extern "C" {
#include <libavutil/rational.h>
}
#include <iostream>
#include <QDebug>
#include <QMetaType>
#ifdef USE_OTIO
#include <opentime/rationalTime.h>
#endif
#include "common/define.h"
namespace olive {
class rational
{
public:
rational(const int &numerator = 0)
{
r_.num = numerator;
r_.den = 1;
}
rational(const int &numerator, const int &denominator)
{
r_.num = numerator;
r_.den = denominator;
FixSigns();
Reduce();
}
rational(const rational &rhs) = default;
rational(const AVRational& r)
{
r_ = r;
FixSigns();
}
static rational fromDouble(const double& flt, bool *ok = nullptr);
static rational fromString(const QString& str, bool* ok = nullptr);
static const rational NaN;
//Assignment Operators
const rational& operator=(const rational &rhs);
const rational& operator+=(const rational &rhs);
const rational& operator-=(const rational &rhs);
const rational& operator/=(const rational &rhs);
const rational& operator*=(const rational &rhs);
//Binary math operators
rational operator+(const rational &rhs) const;
rational operator-(const rational &rhs) const;
rational operator/(const rational &rhs) const;
rational operator*(const rational &rhs) const;
//Relational and equality operators
bool operator<(const rational &rhs) const;
bool operator<=(const rational &rhs) const;
bool operator>(const rational &rhs) const;
bool operator>=(const rational &rhs) const;
bool operator==(const rational &rhs) const;
bool operator!=(const rational &rhs) const;
//Unary operators
const rational& operator+() const { return *this; }
rational operator-() const { return rational(r_.num, -r_.den); }
bool operator!() const { return !r_.num; }
//Function: convert to double
double toDouble() const;
AVRational toAVRational() const;
#ifdef USE_OTIO
static rational fromRationalTime(const opentime::RationalTime &t)
{
// Is this the best way to do this?
return fromDouble(t.to_seconds());
}
// Convert Olive rationals to opentime rationals with the given framerate (defaults to 24)
opentime::RationalTime toRationalTime(double framerate = 24) const;
#endif
// Produce "flipped" version
rational flipped() const;
void flip();
// Returns whether the rational is valid but equal to zero or not
//
// A NaN is always a null, but a null is not always a NaN
bool isNull() const { return r_.num == 0; }
// Returns whether this rational is not a valid number (denominator == 0)
bool isNaN() const { return r_.den == 0; }
const int& numerator() const { return r_.num; }
const int& denominator() const { return r_.den; }
QString toString() const;
friend std::ostream& operator<<(std::ostream &out, const rational &value)
{
out << value.r_.num << '/' << value.r_.den;
return out;
}
private:
void FixSigns();
void Reduce();
AVRational r_;
};
#define RATIONAL_MIN rational(INT_MIN)
#define RATIONAL_MAX rational(INT_MAX)
uint qHash(const rational& r, uint seed = 0);
}
QDebug operator<<(QDebug debug, const olive::rational& r);
Q_DECLARE_METATYPE(olive::rational)
#endif // RATIONAL_H
-358
View File
@@ -1,358 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 "timecodefunctions.h"
extern "C" {
#include <libavutil/mathematics.h>
}
#include <QRegularExpression>
#include <QtMath>
#include "config/config.h"
namespace olive {
QString padded(int64_t arg, int padding) {
return QStringLiteral("%1").arg(arg, padding, 10, QChar('0'));
}
QString Timecode::time_to_timecode(const rational &time, const rational &timebase, const Timecode::Display &display, bool show_plus_if_positive)
{
if (timebase.isNull()) {
return QStringLiteral("INVALID TIMEBASE");
}
double time_dbl = time.toDouble();
switch (display) {
case kTimecodeNonDropFrame:
case kTimecodeDropFrame:
case kTimecodeSeconds:
{
QString prefix;
if (time_dbl < 0) {
prefix = "-";
} else if (show_plus_if_positive) {
prefix = "+";
}
if (display == kTimecodeSeconds) {
time_dbl = qAbs(time_dbl);
int64_t total_seconds = qFloor(time_dbl);
int64_t hours = total_seconds / 3600;
int64_t mins = total_seconds / 60 - hours * 60;
int64_t secs = total_seconds - mins * 60;
int64_t fraction = qRound64((time_dbl - static_cast<double>(total_seconds)) * 1000);
return QStringLiteral("%1%2:%3:%4.%5").arg(prefix,
padded(hours, 2),
padded(mins, 2),
padded(secs, 2),
padded(fraction, 3));
} else {
// Determine what symbol to separate frames (";" is used for drop frame, ":" is non-drop frame)
QString frame_token;
double frame_rate = timebase.flipped().toDouble();
int rounded_frame_rate = qRound(frame_rate);
int64_t frames, secs, mins, hours;
int64_t f = qAbs(time_to_timestamp(time, timebase));
if (display == kTimecodeDropFrame && TimebaseIsDropFrame(timebase)) {
frame_token = ";";
/**
* CONVERT A FRAME NUMBER TO DROP FRAME TIMECODE
*
* Code by David Heidelberger, adapted from Andrew Duncan, further adapted for Olive by Olive Team
* Given an int called framenumber and a double called framerate
* Framerate should be 29.97, 59.94, or 23.976, otherwise the calculations will be off.
*/
// If frame number is greater than 24 hrs, next operation will rollover clock
f %= (qRound(frame_rate*3600)*24);
// Number of frames per ten minutes
int64_t framesPer10Minutes = qRound(frame_rate * 600);
int64_t d = f / framesPer10Minutes;
int64_t m = f % framesPer10Minutes;
// Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate
int64_t dropFrames = qRound(frame_rate * (2.0/30.0));
// Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames
f += dropFrames*9*d;
if (m > dropFrames) {
f += dropFrames * ((m - dropFrames) / (qRound(frame_rate)*60 - dropFrames));
}
} else {
frame_token = ":";
}
// non-drop timecode
hours = f / (3600*rounded_frame_rate);
mins = f / (60*rounded_frame_rate) % 60;
secs = f / rounded_frame_rate % 60;
frames = f % rounded_frame_rate;
return QStringLiteral("%1%2:%3:%4%5%6").arg(prefix,
padded(hours, 2),
padded(mins, 2),
padded(secs, 2),
frame_token,
padded(frames, 2));
}
}
case kFrames:
return QString::number(time_to_timestamp(time, timebase));
case kMilliseconds:
return QString::number(qRound(time_dbl * 1000));
}
return QStringLiteral("INVALID TIMECODE MODE");
}
int64_t StrToInt64EmptyTolerant(const QString &s, bool *ok)
{
if (s.isEmpty()) {
if (ok) *ok = true;
return 0;
} else {
return s.toLongLong(ok);
}
}
double StrToDoubleEmptyTolerant(const QString &s, bool *ok)
{
if (s.isEmpty()) {
if (ok) *ok = true;
return 0;
} else {
return s.toDouble(ok);
}
}
rational Timecode::timecode_to_time(const QString &timecode, const rational &timebase, const Timecode::Display &display, bool *ok)
{
if (timecode.isEmpty()) {
goto err_fatal;
}
switch (display) {
case kTimecodeNonDropFrame:
case kTimecodeDropFrame:
case kTimecodeSeconds:
{
QStringList timecode_split = timecode.split(QRegularExpression("(:)|(;)"));
const int element_count = display == kTimecodeSeconds ? 3 : 4;
// Remove excess tokens (we're only interested in HH:MM:SS.FF)
while (timecode_split.size() > element_count) {
timecode_split.removeLast();
}
// For easier index calculations, ensure minimum size
while (timecode_split.size() < element_count) {
timecode_split.prepend(QString());
}
bool negative = timecode.trimmed().startsWith('-');
double frame_rate = timebase.flipped().toDouble();
int rounded_frame_rate = qRound(frame_rate);
bool valid;
rational time;
int64_t hours = StrToInt64EmptyTolerant(timecode_split.at(0), &valid);
if (!valid) goto err_fatal;
int64_t mins = StrToInt64EmptyTolerant(timecode_split.at(1), &valid);
if (!valid) goto err_fatal;
if (display == kTimecodeSeconds) {
double secs = StrToDoubleEmptyTolerant(timecode_split.at(2), &valid);
if (!valid) goto err_fatal;
time = rational::fromDouble(hours * 3600 + mins * 60 + secs);
} else {
int64_t secs = StrToInt64EmptyTolerant(timecode_split.at(2), &valid);
if (!valid) goto err_fatal;
int64_t frames = StrToInt64EmptyTolerant(timecode_split.at(3), &valid);
if (!valid) goto err_fatal;
int64_t sec_count = (hours*3600 + mins*60 + secs);
int64_t frame_count = sec_count*rounded_frame_rate + frames;
if (display == kTimecodeDropFrame && TimebaseIsDropFrame(timebase)) {
// Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate
int64_t dropFrames = qRound64(frame_rate * (2.0/30.0));
// d and m need to be calculated from
int64_t real_fr_ts = qRound64(static_cast<double>(sec_count)*frame_rate) + frames;
int64_t framesPer10Minutes = qRound(frame_rate * 600);
int64_t d = real_fr_ts / framesPer10Minutes;
int64_t m = real_fr_ts % framesPer10Minutes;
if (m > dropFrames) {
frame_count -= dropFrames * ((m - dropFrames) / (qRound(frame_rate)*60 - dropFrames));
}
frame_count -= dropFrames*9*d;
}
time = timestamp_to_time(frame_count, timebase);
}
if (ok) *ok = true;
if (negative) time = -time;
return time;
}
case kMilliseconds:
{
bool valid;
double timecode_secs = timecode.toDouble(&valid);
if (valid) {
// Convert milliseconds to seconds
timecode_secs *= 0.001;
// Convert seconds to rational
return rational::fromDouble(timecode_secs, ok);
} else {
goto err_fatal;
}
}
case kFrames:
{
bool valid;
int64_t ts = timecode.toLongLong(&valid);
if (!valid) {
goto err_fatal;
}
if (ok) *ok = true;
return timestamp_to_time(ts, timebase);
}
}
err_fatal:
if (ok) *ok = false;
return 0;
}
rational Timecode::snap_time_to_timebase(const rational &time, const rational &timebase, Rounding floor)
{
// Just convert to a timestamp in timebase units and back
int64_t timestamp = time_to_timestamp(time, timebase, floor);
return timestamp_to_time(timestamp, timebase);
}
rational Timecode::timestamp_to_time(const int64_t &timestamp, const rational &timebase)
{
int64_t num = int64_t(timebase.numerator()) * timestamp;
int64_t den = timebase.denominator();
int num_r, den_r;
av_reduce(&num_r, &den_r, num, den, INT_MAX);
return rational(num_r, den_r);
}
bool Timecode::TimebaseIsDropFrame(const rational &timebase)
{
return (timebase.numerator() != 1);
}
QString Timecode::TimeToString(int64_t ms)
{
int64_t total_seconds = ms / 1000;
int64_t ss = total_seconds % 60;
int64_t mm = (total_seconds / 60) % 60;
int64_t hh = total_seconds / 3600;
return QStringLiteral("%1:%2:%3")
.arg(hh, 2, 10, QChar('0'))
.arg(mm, 2, 10, QChar('0'))
.arg(ss, 2, 10, QChar('0'));
}
int64_t Timecode::time_to_timestamp(const rational &time, const rational &timebase, Rounding floor)
{
return time_to_timestamp(time.toDouble(), timebase, floor);
}
int64_t Timecode::time_to_timestamp(const double &time, const rational &timebase, Rounding floor)
{
const double d = time * timebase.flipped().toDouble();
if (std::isnan(d)) {
return 0;
}
const double eps = 0.000000000001;
switch (floor) {
case kRound:
default:
return qRound64(d);
case kFloor:
if (d > qCeil(d)-eps) {
return qCeil(d);
} else {
return qFloor(d);
}
case kCeil:
if (d < qFloor(d)+eps) {
return qFloor(d);
} else {
return qCeil(d);
}
}
}
int64_t Timecode::rescale_timestamp(const int64_t &ts, const rational &source, const rational &dest)
{
if (source == dest) {
return ts;
}
return av_rescale_q(ts, source.toAVRational(), dest.toAVRational());
}
int64_t Timecode::rescale_timestamp_ceil(const int64_t &ts, const rational &source, const rational &dest)
{
if (source == dest) {
return ts;
}
return av_rescale_q_rnd(ts, source.toAVRational(), dest.toAVRational(), AV_ROUND_UP);
}
}
-80
View File
@@ -1,80 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 TIMECODEFUNCTIONS_H
#define TIMECODEFUNCTIONS_H
#include <QString>
#include "common/rational.h"
namespace olive {
/**
* @brief Functions for converting times/timecodes/timestamps
*
* Olive uses the following terminology through its code:
*
* `time` - time in seconds presented in a rational form
* `timebase` - the base time unit of an audio/video stream in seconds
* `timestamp` - an integer representation of a time in timebase units (in many cases is used like a frame number)
* `timecode` a user-friendly string representation of a time according to Timecode::Display
*/
class Timecode {
public:
enum Display {
kTimecodeDropFrame,
kTimecodeNonDropFrame,
kTimecodeSeconds,
kFrames,
kMilliseconds
};
enum Rounding {
kCeil,
kFloor,
kRound
};
/**
* @brief Convert a timestamp (according to a rational timebase) to a user-friendly string representation
*/
static QString time_to_timecode(const rational& time, const rational& timebase, const Display &display, bool show_plus_if_positive = false);
static rational timecode_to_time(const QString& timecode, const rational& timebase, const Display& display, bool *ok = nullptr);
static rational snap_time_to_timebase(const rational& time, const rational& timebase, Rounding floor = kRound);
static int64_t time_to_timestamp(const rational& time, const rational& timebase, Rounding floor = kRound);
static int64_t time_to_timestamp(const double& time, const rational& timebase, Rounding floor = kRound);
static int64_t rescale_timestamp(const int64_t& ts, const rational& source, const rational& dest);
static int64_t rescale_timestamp_ceil(const int64_t& ts, const rational& source, const rational& dest);
static rational timestamp_to_time(const int64_t& timestamp, const rational& timebase);
static bool TimebaseIsDropFrame(const rational& timebase);
static QString TimeToString(int64_t ms);
};
}
#endif // TIMECODEFUNCTIONS_H
-393
View File
@@ -1,393 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 "timerange.h"
#include <QtMath>
#include <utility>
namespace olive {
TimeRange::TimeRange(const rational &in, const rational &out) :
in_(in),
out_(out)
{
normalize();
}
const rational &TimeRange::in() const
{
return in_;
}
const rational &TimeRange::out() const
{
return out_;
}
const rational &TimeRange::length() const
{
Q_ASSERT(!length_.isNaN());
return length_;
}
void TimeRange::set_in(const rational &in)
{
in_ = in;
normalize();
}
void TimeRange::set_out(const rational &out)
{
out_ = out;
normalize();
}
void TimeRange::set_range(const rational &in, const rational &out)
{
in_ = in;
out_ = out;
normalize();
}
bool TimeRange::operator==(const TimeRange &r) const
{
return in() == r.in() && out() == r.out();
}
bool TimeRange::operator!=(const TimeRange &r) const
{
return in() != r.in() || out() != r.out();
}
bool TimeRange::OverlapsWith(const TimeRange &a, bool in_inclusive, bool out_inclusive) const
{
bool doesnt_overlap_in = (in_inclusive) ? (a.out() < in()) : (a.out() <= in());
bool doesnt_overlap_out = (out_inclusive) ? (a.in() > out()) : (a.in() >= out());
return !doesnt_overlap_in && !doesnt_overlap_out;
}
TimeRange TimeRange::Combined(const TimeRange &a) const
{
return Combine(a, *this);
}
bool TimeRange::Contains(const TimeRange &compare, bool in_inclusive, bool out_inclusive) const
{
bool contains_in = (in_inclusive) ? (compare.in() >= in()) : (compare.in() > in());
bool contains_out = (out_inclusive) ? (compare.out() <= out()) : (compare.out() < out());
return contains_in && contains_out;
}
bool TimeRange::Contains(const rational &r) const
{
return r >= in_ && r < out_;
}
TimeRange TimeRange::Combine(const TimeRange &a, const TimeRange &b)
{
return TimeRange(qMin(a.in(), b.in()),
qMax(a.out(), b.out()));
}
TimeRange TimeRange::Intersected(const TimeRange &a) const
{
return Intersect(a, *this);
}
TimeRange TimeRange::Intersect(const TimeRange &a, const TimeRange &b)
{
return TimeRange(qMax(a.in(), b.in()),
qMin(a.out(), b.out()));
}
TimeRange TimeRange::operator+(const rational &rhs) const
{
TimeRange answer(*this);
answer += rhs;
return answer;
}
TimeRange TimeRange::operator-(const rational &rhs) const
{
TimeRange answer(*this);
answer -= rhs;
return answer;
}
const TimeRange &TimeRange::operator+=(const rational &rhs)
{
set_range(in_ + rhs, out_ + rhs);
return *this;
}
const TimeRange &TimeRange::operator-=(const rational &rhs)
{
set_range(in_ - rhs, out_ - rhs);
return *this;
}
std::list<TimeRange> TimeRange::Split(const int &chunk_size) const
{
std::list<TimeRange> split_ranges;
int start_time = qFloor(this->in().toDouble() / static_cast<double>(chunk_size)) * chunk_size;
int end_time = qCeil(this->out().toDouble() / static_cast<double>(chunk_size)) * chunk_size;
for (int i=start_time; i<end_time; i+=chunk_size) {
split_ranges.push_back(TimeRange(qMax(this->in(), rational(i)),
qMin(this->out(), rational(i + chunk_size))));
}
return split_ranges;
}
void TimeRange::normalize()
{
// If `out` is earlier than `in`, swap them
if (out_ < in_)
{
std::swap(out_, in_);
}
// Calculate length
if (out_ == RATIONAL_MIN || out_ == RATIONAL_MAX || in_ == RATIONAL_MIN || in_ == RATIONAL_MAX) {
length_ = rational::NaN;
} else {
length_ = out_ - in_;
}
}
void TimeRangeList::insert(const TimeRangeList &list_to_add)
{
for (auto it=list_to_add.cbegin(); it!=list_to_add.cend(); it++) {
insert(*it);
}
}
void TimeRangeList::insert(TimeRange range_to_add)
{
// See if list contains this range
if (contains(range_to_add)) {
return;
}
// Does not contain range, so we'll almost certainly be adding it in some way
for (int i=0;i<size();i++) {
const TimeRange& compare = array_.at(i);
if (compare.OverlapsWith(range_to_add)) {
range_to_add = TimeRange::Combine(range_to_add, compare);
array_.removeAt(i);
i--;
}
}
array_.append(range_to_add);
}
void TimeRangeList::remove(const TimeRange &remove)
{
util_remove(&array_, remove);
}
void TimeRangeList::remove(const TimeRangeList &list)
{
for (const TimeRange &r : list) {
remove(r);
}
}
bool TimeRangeList::contains(const TimeRange &range, bool in_inclusive, bool out_inclusive) const
{
for (int i=0;i<size();i++) {
if (array_.at(i).Contains(range, in_inclusive, out_inclusive)) {
return true;
}
}
return false;
}
void TimeRangeList::shift(const rational &diff)
{
for (int i=0; i<array_.size(); i++) {
array_[i] += diff;
}
}
void TimeRangeList::trim_in(const rational &diff)
{
// Re-do list since we want to handle overlaps
TimeRangeList temp = *this;
clear();
foreach (TimeRange r, temp) {
r.set_in(r.in() + diff);
insert(r);
}
}
void TimeRangeList::trim_out(const rational &diff)
{
// Re-do list since we want to handle overlaps
TimeRangeList temp = *this;
clear();
foreach (TimeRange r, temp) {
r.set_out(r.out() + diff);
insert(r);
}
}
TimeRangeList TimeRangeList::Intersects(const TimeRange &range) const
{
TimeRangeList intersect_list;
for (int i=0;i<size();i++) {
const TimeRange& compare = array_.at(i);
if (compare.out() <= range.in() || compare.in() >= range.out()) {
// No intersect
continue;
} else {
// Crop the time range to the range and add it to the list
TimeRange cropped(qMax(range.in(), compare.in()),
qMin(range.out(), compare.out()));
intersect_list.insert(cropped);
}
}
return intersect_list;
}
uint qHash(const TimeRange &r, uint seed)
{
return qHash(r.in(), seed) ^ qHash(r.out(), seed);
}
TimeRangeListFrameIterator::TimeRangeListFrameIterator() :
TimeRangeListFrameIterator(TimeRangeList(), rational::NaN)
{
}
TimeRangeListFrameIterator::TimeRangeListFrameIterator(const TimeRangeList &list, const rational &timebase) :
list_(list),
timebase_(timebase),
range_index_(-1),
size_(-1),
frame_index_(0),
custom_range_(false)
{
if (!list_.isEmpty() && timebase_.isNull()) {
qCritical() << "TimeRangeListFrameIterator created with null timebase but non-empty list, this will likely lead to infinite loops";
}
UpdateIndexIfNecessary();
}
rational TimeRangeListFrameIterator::Snap(const rational &r) const
{
return Timecode::snap_time_to_timebase(r, timebase_, Timecode::kFloor);
}
bool TimeRangeListFrameIterator::GetNext(rational *out)
{
if (!HasNext()) {
return false;
}
// Output current value
*out = current_;
// Determine next value by adding timebase
current_ += timebase_;
// If this time is outside the current range, jump to the next one
UpdateIndexIfNecessary();
// Increment frame index
frame_index_++;
return true;
}
bool TimeRangeListFrameIterator::HasNext() const
{
return range_index_ < list_.size();
}
int TimeRangeListFrameIterator::size()
{
if (size_ == -1) {
// Size isn't calculated automatically for optimization, so we'll calculate it now
size_ = 0;
foreach (const TimeRange &range, list_) {
rational start = Snap(range.in());
rational end = Timecode::snap_time_to_timebase(range.out(), timebase_, Timecode::kFloor);
if (end == range.out()) {
end -= timebase_;
}
int64_t start_ts = Timecode::time_to_timestamp(start, timebase_);
int64_t end_ts = Timecode::time_to_timestamp(end, timebase_);
size_ += 1 + (end_ts - start_ts);
}
}
return size_;
}
void TimeRangeListFrameIterator::UpdateIndexIfNecessary()
{
while (range_index_ < list_.size() && (range_index_ == -1 || current_ >= list_.at(range_index_).out())) {
range_index_++;
if (range_index_ < list_.size()) {
current_ = Snap(list_.at(range_index_).in());
}
}
}
}
QDebug operator<<(QDebug debug, const olive::TimeRange &r)
{
debug.nospace() << r.in().toDouble() << " - " << r.out().toDouble();
return debug.space();
}
QDebug operator<<(QDebug debug, const olive::TimeRangeList &r)
{
debug << r.internal_array();
return debug.space();
}
-298
View File
@@ -1,298 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 TIMERANGE_H
#define TIMERANGE_H
#include "rational.h"
#include "timecodefunctions.h"
namespace olive {
class TimeRange {
public:
TimeRange() = default;
TimeRange(const rational& in, const rational& out);
const rational& in() const;
const rational& out() const;
const rational& length() const;
void set_in(const rational& in);
void set_out(const rational& out);
void set_range(const rational& in, const rational& out);
bool operator==(const TimeRange& r) const;
bool operator!=(const TimeRange& r) const;
bool OverlapsWith(const TimeRange& a, bool in_inclusive = true, bool out_inclusive = true) const;
bool Contains(const TimeRange& a, bool in_inclusive = true, bool out_inclusive = true) const;
bool Contains(const rational& r) const;
TimeRange Combined(const TimeRange& a) const;
static TimeRange Combine(const TimeRange &a, const TimeRange &b);
TimeRange Intersected(const TimeRange& a) const;
static TimeRange Intersect(const TimeRange &a, const TimeRange &b);
TimeRange operator+(const rational& rhs) const;
TimeRange operator-(const rational& rhs) const;
const TimeRange& operator+=(const rational &rhs);
const TimeRange& operator-=(const rational &rhs);
std::list<TimeRange> Split(const int &chunk_size) const;
private:
void normalize();
rational in_;
rational out_;
rational length_;
};
class TimeRangeList {
public:
TimeRangeList() = default;
TimeRangeList(std::initializer_list<TimeRange> r) :
array_(r)
{
}
void insert(const TimeRangeList &list_to_add);
void insert(TimeRange range_to_add);
void remove(const TimeRange& remove);
void remove(const TimeRangeList &list);
template <typename T>
static void util_remove(QVector<T> *list, const TimeRange &remove)
{
int sz = list->size();
for (int i=0;i<sz;i++) {
T& compare = (*list)[i];
if (remove.Contains(compare)) {
// This element is entirely encompassed in this range, remove it
list->removeAt(i);
i--;
sz--;
} else if (compare.Contains(remove, false, false)) {
// The remove range is within this element, only choice is to split the element into two
T new_range = compare;
new_range.set_in(remove.out());
compare.set_out(remove.in());
list->append(new_range);
break;
} else if (compare.in() < remove.in() && compare.out() > remove.in()) {
// This element's out point overlaps the range's in, we'll trim it
compare.set_out(remove.in());
} else if (compare.in() < remove.out() && compare.out() > remove.out()) {
// This element's in point overlaps the range's out, we'll trim it
compare.set_in(remove.out());
}
}
}
bool contains(const TimeRange& range, bool in_inclusive = true, bool out_inclusive = true) const;
bool contains(const rational &r) const
{
for (const TimeRange &range : array_) {
if (range.Contains(r)) {
return true;
}
}
return false;
}
bool OverlapsWith(const TimeRange& r, bool in_inclusive = true, bool out_inclusive = true) const
{
for (const TimeRange &range : array_) {
if (range.OverlapsWith(r, in_inclusive, out_inclusive)) {
return true;
}
}
return false;
}
bool isEmpty() const
{
return array_.isEmpty();
}
void clear()
{
array_.clear();
}
int size() const
{
return array_.size();
}
void shift(const rational& diff);
void trim_in(const rational& diff);
void trim_out(const rational& diff);
TimeRangeList Intersects(const TimeRange& range) const;
using const_iterator = QVector<TimeRange>::const_iterator;
const_iterator begin() const
{
return array_.constBegin();
}
const_iterator end() const
{
return array_.constEnd();
}
const_iterator cbegin() const
{
return begin();
}
const_iterator cend() const
{
return end();
}
const TimeRange& first() const
{
return array_.first();
}
const TimeRange& last() const
{
return array_.last();
}
const TimeRange& at(int index) const
{
return array_.at(index);
}
const QVector<TimeRange>& internal_array() const
{
return array_;
}
bool operator==(const TimeRangeList &rhs) const
{
return array_ == rhs.array_;
}
private:
QVector<TimeRange> array_;
};
class TimeRangeListFrameIterator
{
public:
TimeRangeListFrameIterator();
TimeRangeListFrameIterator(const TimeRangeList &list, const rational &timebase);
rational Snap(const rational &r) const;
bool GetNext(rational *out);
bool HasNext() const;
QVector<rational> ToVector() const
{
TimeRangeListFrameIterator copy(list_, timebase_);
QVector<rational> times;
rational r;
while (copy.GetNext(&r)) {
times.append(r);
}
return times;
}
int size();
void reset()
{
*this = TimeRangeListFrameIterator();
}
void insert(const TimeRange &range)
{
list_.insert(range);
}
void insert(const TimeRangeList &list)
{
list_.insert(list);
}
bool IsCustomRange() const
{
return custom_range_;
}
void SetCustomRange(bool e)
{
custom_range_ = e;
}
int frame_index() const
{
return frame_index_;
}
private:
void UpdateIndexIfNecessary();
TimeRangeList list_;
rational timebase_;
rational current_;
int range_index_;
int size_;
int frame_index_;
bool custom_range_;
};
uint qHash(const TimeRange& r, uint seed = 0);
}
QDebug operator<<(QDebug debug, const olive::TimeRange& r);
QDebug operator<<(QDebug debug, const olive::TimeRangeList& r);
Q_DECLARE_METATYPE(olive::TimeRange)
#endif // TIMERANGE_H
+2 -2
View File
@@ -160,8 +160,8 @@ void Config::SetDefaults()
SetEntryInternal(QStringLiteral("DefaultSequenceAudioLayout"), NodeValue::kInt, QVariant::fromValue(static_cast<int64_t>(AV_CH_LAYOUT_STEREO)));
// Online/offline settings
SetEntryInternal(QStringLiteral("OnlinePixelFormat"), NodeValue::kInt, VideoParams::kFormatFloat32);
SetEntryInternal(QStringLiteral("OfflinePixelFormat"), NodeValue::kInt, VideoParams::kFormatFloat16);
SetEntryInternal(QStringLiteral("OnlinePixelFormat"), NodeValue::kInt, PixelFormat::F32);
SetEntryInternal(QStringLiteral("OfflinePixelFormat"), NodeValue::kInt, PixelFormat::F16);
SetEntryInternal(QStringLiteral("MarkerColor"), NodeValue::kInt, ColorCoding::kLime);
}
-1
View File
@@ -25,7 +25,6 @@
#include <QString>
#include <QVariant>
#include "common/timecodefunctions.h"
#include "node/value.h"
namespace olive {
+3 -3
View File
@@ -105,7 +105,7 @@ Core *Core::instance()
void Core::DeclareTypesForQt()
{
qRegisterMetaType<rational>();
qRegisterMetaType<olive::core::rational>();
qRegisterMetaType<NodeValue>();
qRegisterMetaType<NodeValueTable>();
qRegisterMetaType<NodeValueDatabase>();
@@ -114,8 +114,8 @@ void Core::DeclareTypesForQt()
qRegisterMetaType<AudioParams>();
qRegisterMetaType<NodeKeyframe::Type>();
qRegisterMetaType<Decoder::RetrieveState>();
qRegisterMetaType<olive::TimeRange>();
qRegisterMetaType<Color>();
qRegisterMetaType<olive::core::TimeRange>();
qRegisterMetaType<olive::core::Color>();
qRegisterMetaType<olive::AudioVisualWaveform>();
qRegisterMetaType<olive::VideoParams>();
qRegisterMetaType<olive::VideoParams::Interlacing>();
+1 -2
View File
@@ -21,13 +21,12 @@
#ifndef CORE_H
#define CORE_H
#include <olive/core/core.h>
#include <QFileInfoList>
#include <QList>
#include <QTimer>
#include <QTranslator>
#include "common/rational.h"
#include "common/timecodefunctions.h"
#include "node/project/footage/footage.h"
#include "node/project/project.h"
#include "node/project/projectviewmodel.h"
-1
View File
@@ -24,7 +24,6 @@
#include <QDialog>
#include "node/color/colormanager/colormanager.h"
#include "render/color.h"
#include "render/managedcolor.h"
#include "widget/colorwheel/colorgradientwidget.h"
#include "widget/colorwheel/colorspacechooser.h"
+1 -1
View File
@@ -626,7 +626,7 @@ void ExportDialog::SetDefaults()
video_tab_->height_slider()->SetDefaultValue(vp.height());
video_tab_->SetSelectedFrameRate(vp.frame_rate());
video_tab_->pixel_aspect_combobox()->SetPixelAspectRatio(vp.pixel_aspect_ratio());
video_tab_->pixel_format_field()->SetPixelFormat(static_cast<VideoParams::Format>(OLIVE_CONFIG("OnlinePixelFormat").toInt()));
video_tab_->pixel_format_field()->SetPixelFormat(static_cast<PixelFormat::Format>(OLIVE_CONFIG("OnlinePixelFormat").toInt()));
video_tab_->interlaced_combobox()->SetInterlaceMode(vp.interlacing());
audio_tab_->sample_rate_combobox()->SetSampleRate(ap.sample_rate());
audio_tab_->sample_format_combobox()->SetAttemptToRestoreFormat(false);
-1
View File
@@ -26,7 +26,6 @@
#include <QWidget>
#include "common/qtutils.h"
#include "common/rational.h"
#include "dialog/export/codec/cineformsection.h"
#include "dialog/export/codec/codecstack.h"
#include "dialog/export/codec/h264section.h"
@@ -24,7 +24,6 @@
#include <QGridLayout>
#include "core.h"
#include "common/timecodefunctions.h"
#include "widget/keyframeview/keyframeviewundo.h"
#include "widget/nodeparamview/nodeparamviewundo.h"
-1
View File
@@ -33,7 +33,6 @@
#include "core.h"
#include "common/channellayout.h"
#include "common/qtutils.h"
#include "common/rational.h"
#include "undo/undostack.h"
namespace olive {
@@ -141,7 +141,7 @@ void SequenceDialogParameterTab::UpdatePreviewResolutionLabel()
{
VideoParams test_param(GetSelectedVideoWidth(),
GetSelectedVideoHeight(),
VideoParams::kFormatInvalid,
PixelFormat::INVALID,
VideoParams::kInternalChannelCount,
rational(1),
VideoParams::kInterlaceNone,
@@ -59,7 +59,7 @@ public:
return preview_resolution_field_->GetDivider();
}
VideoParams::Format GetSelectedPreviewFormat() const
PixelFormat GetSelectedPreviewFormat() const
{
return preview_format_field_->GetPixelFormat();
}
@@ -100,7 +100,7 @@ QTreeWidgetItem* SequenceDialogPresetTab::CreateFolder(const QString &name)
QTreeWidgetItem *SequenceDialogPresetTab::CreateHDPresetFolder(const QString &name, int width, int height, int divider)
{
const VideoParams::Format default_format = static_cast<VideoParams::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt());
const PixelFormat default_format = static_cast<PixelFormat::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt());
const bool default_autocache = false;
QTreeWidgetItem* parent = CreateFolder(name);
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 23.976 FPS").arg(name),
@@ -163,7 +163,7 @@ QTreeWidgetItem *SequenceDialogPresetTab::CreateHDPresetFolder(const QString &na
QTreeWidgetItem *SequenceDialogPresetTab::CreateSDPresetFolder(const QString &name, int width, int height, const rational& frame_rate, const rational &standard_par, const rational &wide_par, int divider)
{
const VideoParams::Format default_format = static_cast<VideoParams::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt());
const PixelFormat default_format = static_cast<PixelFormat::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt());
const bool default_autocache = false;
QTreeWidgetItem* parent = CreateFolder(name);
preset_tree_->addTopLevelItem(parent);
+9 -9
View File
@@ -21,9 +21,9 @@
#ifndef SEQUENCEPARAM_H
#define SEQUENCEPARAM_H
#include <olive/core/core.h>
#include <QXmlStreamWriter>
#include "common/rational.h"
#include "common/xmlutils.h"
#include "dialog/sequence/presetmanager.h"
#include "render/videoparams.h"
@@ -43,7 +43,7 @@ public:
int sample_rate,
uint64_t channel_layout,
int preview_divider,
VideoParams::Format preview_format,
PixelFormat preview_format,
bool preview_autocache) :
width_(width),
height_(height),
@@ -69,9 +69,9 @@ public:
} else if (reader->name() == QStringLiteral("height")) {
height_ = reader->readElementText().toInt();
} else if (reader->name() == QStringLiteral("framerate")) {
frame_rate_ = rational::fromString(reader->readElementText());
frame_rate_ = rational::fromString(reader->readElementText().toStdString());
} else if (reader->name() == QStringLiteral("pixelaspect")) {
pixel_aspect_ = rational::fromString(reader->readElementText());
pixel_aspect_ = rational::fromString(reader->readElementText().toStdString());
} else if (reader->name() == QStringLiteral("interlacing")) {
interlacing_ = static_cast<VideoParams::Interlacing>(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("samplerate")) {
@@ -81,7 +81,7 @@ public:
} else if (reader->name() == QStringLiteral("divider")) {
preview_divider_ = reader->readElementText().toInt();
} else if (reader->name() == QStringLiteral("format")) {
preview_format_ = static_cast<VideoParams::Format>(reader->readElementText().toInt());
preview_format_ = static_cast<PixelFormat::Format>(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("autocache")) {
preview_autocache_ = reader->readElementText().toInt();
} else {
@@ -95,8 +95,8 @@ public:
writer->writeTextElement(QStringLiteral("name"), GetName());
writer->writeTextElement(QStringLiteral("width"), QString::number(width_));
writer->writeTextElement(QStringLiteral("height"), QString::number(height_));
writer->writeTextElement(QStringLiteral("framerate"), frame_rate_.toString());
writer->writeTextElement(QStringLiteral("pixelaspect"), pixel_aspect_.toString());
writer->writeTextElement(QStringLiteral("framerate"), QString::fromStdString(frame_rate_.toString()));
writer->writeTextElement(QStringLiteral("pixelaspect"), QString::fromStdString(pixel_aspect_.toString()));
writer->writeTextElement(QStringLiteral("interlacing_"), QString::number(interlacing_));
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(sample_rate_));
writer->writeTextElement(QStringLiteral("chlayout"), QString::number(channel_layout_));
@@ -145,7 +145,7 @@ public:
return preview_divider_;
}
VideoParams::Format preview_format() const
PixelFormat preview_format() const
{
return preview_format_;
}
@@ -164,7 +164,7 @@ private:
int sample_rate_;
uint64_t channel_layout_;
int preview_divider_;
VideoParams::Format preview_format_;
PixelFormat preview_format_;
bool preview_autocache_;
};
-1
View File
@@ -20,7 +20,6 @@
#include "stroke.h"
#include "render/color.h"
#include "widget/slider/floatslider.h"
namespace olive {
+1 -1
View File
@@ -90,7 +90,7 @@ void PolygonGenerator::Retranslate()
ShaderJob PolygonGenerator::GetGenerateJob(const NodeValueRow &value, const VideoParams &params) const
{
VideoParams p = params;
p.set_format(VideoParams::kFormatUnsigned8);
p.set_format(PixelFormat::U8);
auto job = Texture::Job(p, GenerateJob(value));
// Conversion to RGB
-2
View File
@@ -20,8 +20,6 @@
#include "solid.h"
#include "render/color.h"
namespace olive {
const QString SolidGenerator::kColorInput = QStringLiteral("color_in");
+1 -1
View File
@@ -97,7 +97,7 @@ void TextGeneratorV2::Value(const NodeValueRow &value, const NodeGlobals &global
if (!value[kTextInput].toString().isEmpty()) {
GenerateJob job(value);
auto text_params = globals.vparams();
text_params.set_format(VideoParams::kFormatFloat32);
text_params.set_format(PixelFormat::F32);
table->Push(NodeValue::kTexture, Texture::Job(text_params, job), this);
}
}
+1 -1
View File
@@ -117,7 +117,7 @@ void TextGeneratorV3::Value(const NodeValueRow &value, const NodeGlobals &global
TexturePtr base = value[kTextInput].toTexture();
VideoParams text_params = base ? base->params() : globals.vparams();
text_params.set_format(VideoParams::kFormatUnsigned8);
text_params.set_format(PixelFormat::U8);
text_params.set_colorspace(project()->color_manager()->GetDefaultInputColorSpace());
GenerateJob job(value);
+2 -3
View File
@@ -21,7 +21,6 @@
#ifndef DRAGGABLEGIZMO_H
#define DRAGGABLEGIZMO_H
#include "common/rational.h"
#include "gizmo.h"
#include "node/inputdragger.h"
#include "undo/undocommand.h"
@@ -46,7 +45,7 @@ public:
explicit DraggableGizmo(QObject *parent = nullptr);
void DragStart(const NodeValueRow &row, double abs_x, double abs_y, const olive::rational &time);
void DragStart(const NodeValueRow &row, double abs_x, double abs_y, const olive::core::rational &time);
void DragMove(double x, double y, const Qt::KeyboardModifiers &modifiers);
@@ -67,7 +66,7 @@ public:
void SetDragValueBehavior(DragValueBehavior d) { drag_value_behavior_ = d; }
signals:
void HandleStart(const olive::NodeValueRow &row, double x, double y, const olive::rational &time);
void HandleStart(const olive::NodeValueRow &row, double x, double y, const olive::core::rational &time);
void HandleMovement(double x, double y, const Qt::KeyboardModifiers &modifiers);
-1
View File
@@ -23,7 +23,6 @@
#include <QVector2D>
#include "common/timerange.h"
#include "render/audioparams.h"
#include "render/loopmode.h"
#include "render/videoparams.h"
-1
View File
@@ -21,7 +21,6 @@
#ifndef NODEINPUTDRAGGER_H
#define NODEINPUTDRAGGER_H
#include "common/rational.h"
#include "node/keyframe.h"
#include "node/param.h"
#include "undo/undocommand.h"
-1
View File
@@ -21,7 +21,6 @@
#ifndef NODEINPUTIMMEDIATE_H
#define NODEINPUTIMMEDIATE_H
#include "common/timerange.h"
#include "common/xmlutils.h"
#include "node/keyframe.h"
#include "node/value.h"
-2
View File
@@ -25,8 +25,6 @@
#include <QPointF>
#include <QVariant>
#include "common/rational.h"
#include "common/timerange.h"
#include "node/param.h"
namespace olive {
-1
View File
@@ -26,7 +26,6 @@
#include "common/cpuoptimize.h"
#include "common/tohex.h"
#include "node/distort/transform/transformdistortnode.h"
#include "render/color.h"
namespace olive {
+2 -2
View File
@@ -163,7 +163,7 @@ QLinearGradient Node::gradient_color(qreal top, qreal bottom) const
grad.setStart(0, top);
grad.setFinalStop(0, bottom);
QColor c = color().toQColor();
QColor c = QtUtils::toQColor(color());
grad.setColorAt(0.0, c.lighter());
grad.setColorAt(1.0, c);
@@ -176,7 +176,7 @@ QBrush Node::brush(qreal top, qreal bottom) const
if (OLIVE_CONFIG("UseGradients").toBool()) {
return gradient_color(top, bottom);
} else {
return color().toQColor();
return QtUtils::toQColor(color());
}
}
+3 -5
View File
@@ -30,8 +30,6 @@
#include "codec/frame.h"
#include "codec/samplebuffer.h"
#include "common/rational.h"
#include "common/timerange.h"
#include "common/xmlutils.h"
#include "node/gizmo/draggable.h"
#include "node/globals.h"
@@ -1229,7 +1227,7 @@ protected:
}
protected slots:
virtual void GizmoDragStart(const olive::NodeValueRow &row, double x, double y, const olive::rational &time){}
virtual void GizmoDragStart(const olive::NodeValueRow &row, double x, double y, const olive::core::rational &time){}
virtual void GizmoDragMove(double x, double y, const Qt::KeyboardModifiers &modifiers){}
@@ -1379,8 +1377,8 @@ private:
QVector<Node*> GetDependenciesInternal(bool traverse, bool exclusive_only) const;
void ParameterValueChanged(const QString &input, int element, const olive::TimeRange &range);
void ParameterValueChanged(const NodeInput& input, const olive::TimeRange &range)
void ParameterValueChanged(const QString &input, int element, const olive::core::TimeRange &range);
void ParameterValueChanged(const NodeInput& input, const olive::core::TimeRange &range)
{
ParameterValueChanged(input.input(), input.element(), range);
}
+3 -3
View File
@@ -116,7 +116,7 @@ QString ViewerOutput::duration() const
return QString();
} else {
// Return time transformed to timecode
return Timecode::time_to_timecode(GetLength(), using_timebase, using_display);
return QString::fromStdString(Timecode::time_to_timecode(GetLength(), using_timebase, using_display));
}
}
@@ -206,7 +206,7 @@ void ViewerOutput::set_default_parameters()
width,
height,
OLIVE_CONFIG("DefaultSequenceFrameRate").value<rational>(),
static_cast<VideoParams::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt()),
static_cast<PixelFormat::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt()),
VideoParams::kInternalChannelCount,
OLIVE_CONFIG("DefaultSequencePixelAspect").value<rational>(),
OLIVE_CONFIG("DefaultSequenceInterlacing").value<VideoParams::Interlacing>(),
@@ -505,7 +505,7 @@ void ViewerOutput::set_parameters_from_footage(const QVector<ViewerOutput *> foo
SetVideoParams(VideoParams(s.width(),
s.height(),
using_timebase,
static_cast<VideoParams::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt()),
static_cast<PixelFormat::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt()),
VideoParams::kInternalChannelCount,
s.pixel_aspect_ratio(),
s.interlacing(),
-1
View File
@@ -22,7 +22,6 @@
#define VIEWER_H
#include "codec/encoder.h"
#include "common/rational.h"
#include "node/node.h"
#include "node/output/track/track.h"
#include "render/audioparams.h"
+2 -2
View File
@@ -170,12 +170,12 @@ int NodeInput::GetArraySize() const
uint qHash(const NodeInput &i)
{
return qHash(i.node()) ^ qHash(i.input()) ^ qHash(i.element());
return qHash(i.node()) ^ qHash(i.input()) ^ ::qHash(i.element());
}
uint qHash(const NodeKeyframeTrackReference &i)
{
return qHash(i.input()) & qHash(i.track());
return qHash(i.input()) & ::qHash(i.track());
}
uint qHash(const NodeInputPair &i)
-1
View File
@@ -23,7 +23,6 @@
#include <QString>
#include "common/rational.h"
#include "value.h"
namespace olive {
+1 -1
View File
@@ -21,11 +21,11 @@
#ifndef FOOTAGE_H
#define FOOTAGE_H
#include <olive/core/core.h>
#include <QList>
#include <QDateTime>
#include "codec/decoder.h"
#include "common/rational.h"
#include "footagedescription.h"
#include "node/output/viewer/viewer.h"
#include "render/audioparams.h"
@@ -378,7 +378,7 @@ void ProjectSerializer210528::LoadImmediate(QXmlStreamReader *reader, Node *node
if (attr.name() == QStringLiteral("input")) {
key_input = attr.value().toString();
} else if (attr.name() == QStringLiteral("time")) {
key_time = rational::fromString(attr.value().toString());
key_time = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("type")) {
key_type = static_cast<NodeKeyframe::Type>(attr.value().toInt());
} else if (attr.name() == QStringLiteral("inhandlex")) {
@@ -575,9 +575,9 @@ void ProjectSerializer210528::LoadWorkArea(QXmlStreamReader *reader, TimelineWor
if (attr.name() == QStringLiteral("enabled")) {
workarea->set_enabled(attr.value() != QStringLiteral("0"));
} else if (attr.name() == QStringLiteral("in")) {
range_in = rational::fromString(attr.value().toString());
range_in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
range_out = rational::fromString(attr.value().toString());
range_out = rational::fromString(attr.value().toString().toStdString());
}
}
@@ -601,9 +601,9 @@ void ProjectSerializer210528::LoadMarkerList(QXmlStreamReader *reader, TimelineM
if (attr.name() == QStringLiteral("name")) {
name = attr.value().toString();
} else if (attr.name() == QStringLiteral("in")) {
in = rational::fromString(attr.value().toString());
in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
out = rational::fromString(attr.value().toString());
out = rational::fromString(attr.value().toString().toStdString());
}
}
@@ -375,7 +375,7 @@ void ProjectSerializer210907::LoadImmediate(QXmlStreamReader *reader, Node *node
if (attr.name() == QStringLiteral("input")) {
key_input = attr.value().toString();
} else if (attr.name() == QStringLiteral("time")) {
key_time = rational::fromString(attr.value().toString());
key_time = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("type")) {
key_type = static_cast<NodeKeyframe::Type>(attr.value().toInt());
} else if (attr.name() == QStringLiteral("inhandlex")) {
@@ -567,9 +567,9 @@ void ProjectSerializer210907::LoadWorkArea(QXmlStreamReader *reader, TimelineWor
if (attr.name() == QStringLiteral("enabled")) {
workarea->set_enabled(attr.value() != QStringLiteral("0"));
} else if (attr.name() == QStringLiteral("in")) {
range_in = rational::fromString(attr.value().toString());
range_in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
range_out = rational::fromString(attr.value().toString());
range_out = rational::fromString(attr.value().toString().toStdString());
}
}
@@ -593,9 +593,9 @@ void ProjectSerializer210907::LoadMarkerList(QXmlStreamReader *reader, TimelineM
if (attr.name() == QStringLiteral("name")) {
name = attr.value().toString();
} else if (attr.name() == QStringLiteral("in")) {
in = rational::fromString(attr.value().toString());
in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
out = rational::fromString(attr.value().toString());
out = rational::fromString(attr.value().toString().toStdString());
}
}
@@ -425,7 +425,7 @@ void ProjectSerializer211228::LoadImmediate(QXmlStreamReader *reader, Node *node
if (attr.name() == QStringLiteral("input")) {
key_input = attr.value().toString();
} else if (attr.name() == QStringLiteral("time")) {
key_time = rational::fromString(attr.value().toString());
key_time = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("type")) {
key_type = static_cast<NodeKeyframe::Type>(attr.value().toInt());
} else if (attr.name() == QStringLiteral("inhandlex")) {
@@ -617,9 +617,9 @@ void ProjectSerializer211228::LoadWorkArea(QXmlStreamReader *reader, TimelineWor
if (attr.name() == QStringLiteral("enabled")) {
workarea->set_enabled(attr.value() != QStringLiteral("0"));
} else if (attr.name() == QStringLiteral("in")) {
range_in = rational::fromString(attr.value().toString());
range_in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
range_out = rational::fromString(attr.value().toString());
range_out = rational::fromString(attr.value().toString().toStdString());
}
}
@@ -643,9 +643,9 @@ void ProjectSerializer211228::LoadMarkerList(QXmlStreamReader *reader, TimelineM
if (attr.name() == QStringLiteral("name")) {
name = attr.value().toString();
} else if (attr.name() == QStringLiteral("in")) {
in = rational::fromString(attr.value().toString());
in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
out = rational::fromString(attr.value().toString());
out = rational::fromString(attr.value().toString().toStdString());
}
}
@@ -909,7 +909,7 @@ void ProjectSerializer220403::LoadKeyframe(QXmlStreamReader *reader, NodeKeyfram
if (attr.name() == QStringLiteral("input")) {
key_input = attr.value().toString();
} else if (attr.name() == QStringLiteral("time")) {
key->set_time(rational::fromString(attr.value().toString()));
key->set_time(rational::fromString(attr.value().toString().toStdString()));
} else if (attr.name() == QStringLiteral("type")) {
key->set_type_no_bezier_adj(static_cast<NodeKeyframe::Type>(attr.value().toInt()));
} else if (attr.name() == QStringLiteral("inhandlex")) {
@@ -932,7 +932,7 @@ void ProjectSerializer220403::LoadKeyframe(QXmlStreamReader *reader, NodeKeyfram
void ProjectSerializer220403::SaveKeyframe(QXmlStreamWriter *writer, NodeKeyframe *key, NodeValue::Type data_type) const
{
writer->writeAttribute(QStringLiteral("input"), key->input());
writer->writeAttribute(QStringLiteral("time"), key->time().toString());
writer->writeAttribute(QStringLiteral("time"), QString::fromStdString(key->time().toString()));
writer->writeAttribute(QStringLiteral("type"), QString::number(key->type()));
writer->writeAttribute(QStringLiteral("inhandlex"), QString::number(key->bezier_control_in().x()));
writer->writeAttribute(QStringLiteral("inhandley"), QString::number(key->bezier_control_in().y()));
@@ -1214,9 +1214,9 @@ void ProjectSerializer220403::LoadMarker(QXmlStreamReader *reader, TimelineMarke
if (attr.name() == QStringLiteral("name")) {
marker->set_name(attr.value().toString());
} else if (attr.name() == QStringLiteral("in")) {
in = rational::fromString(attr.value().toString());
in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
out = rational::fromString(attr.value().toString());
out = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("color")) {
marker->set_color(attr.value().toInt());
}
@@ -1231,8 +1231,8 @@ void ProjectSerializer220403::LoadMarker(QXmlStreamReader *reader, TimelineMarke
void ProjectSerializer220403::SaveMarker(QXmlStreamWriter *writer, TimelineMarker *marker) const
{
writer->writeAttribute(QStringLiteral("name"), marker->name());
writer->writeAttribute(QStringLiteral("in"), marker->time().in().toString());
writer->writeAttribute(QStringLiteral("out"), marker->time().out().toString());
writer->writeAttribute(QStringLiteral("in"), QString::fromStdString(marker->time().in().toString()));
writer->writeAttribute(QStringLiteral("out"), QString::fromStdString(marker->time().out().toString()));
writer->writeAttribute(QStringLiteral("color"), QString::number(marker->color()));
}
@@ -1245,9 +1245,9 @@ void ProjectSerializer220403::LoadWorkArea(QXmlStreamReader *reader, TimelineWor
if (attr.name() == QStringLiteral("enabled")) {
workarea->set_enabled(attr.value() != QStringLiteral("0"));
} else if (attr.name() == QStringLiteral("in")) {
range_in = rational::fromString(attr.value().toString());
range_in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
range_out = rational::fromString(attr.value().toString());
range_out = rational::fromString(attr.value().toString().toStdString());
}
}
@@ -1263,8 +1263,8 @@ void ProjectSerializer220403::LoadWorkArea(QXmlStreamReader *reader, TimelineWor
void ProjectSerializer220403::SaveWorkArea(QXmlStreamWriter *writer, TimelineWorkArea *workarea) const
{
writer->writeAttribute(QStringLiteral("enabled"), QString::number(workarea->enabled()));
writer->writeAttribute(QStringLiteral("in"), workarea->in().toString());
writer->writeAttribute(QStringLiteral("out"), workarea->out().toString());
writer->writeAttribute(QStringLiteral("in"), QString::fromStdString(workarea->in().toString()));
writer->writeAttribute(QStringLiteral("out"), QString::fromStdString(workarea->out().toString()));
}
void ProjectSerializer220403::LoadMarkerList(QXmlStreamReader *reader, TimelineMarkerList *markers) const
+2 -3
View File
@@ -31,7 +31,6 @@
#include "render/audioparams.h"
#include "render/subtitleparams.h"
#include "render/videoparams.h"
#include "render/color.h"
namespace olive {
@@ -72,7 +71,7 @@ QString NodeValue::ValueToString(Type data_type, const QVariant &value, bool val
QString::number(b.cp2_x()),
QString::number(b.cp2_y()));
} else if (data_type == kRational) {
return value.value<rational>().toString();
return QString::fromStdString(value.value<rational>().toString());
} else if (data_type == kTexture
|| data_type == kSamples
|| data_type == kNone) {
@@ -245,7 +244,7 @@ QVariant NodeValue::StringToValue(Type data_type, const QString &string, bool va
} else if (data_type == kInt) {
return QVariant::fromValue(string.toLongLong());
} else if (data_type == kRational) {
return QVariant::fromValue(rational::fromString(string));
return QVariant::fromValue(rational::fromString(string.toStdString()));
} else {
return string;
}
+3 -3
View File
@@ -28,8 +28,8 @@
#include "codec/samplebuffer.h"
#include "common/bezier.h"
#include "common/qtutils.h"
#include "node/splitvalue.h"
#include "render/color.h"
#include "render/texture.h"
namespace olive {
@@ -338,9 +338,9 @@ public:
bool toBool() const { return value<bool>(); }
double toDouble() const { return value<double>(); }
int64_t toInt() const { return value<int64_t>(); }
rational toRational() const { return value<rational>(); }
rational toRational() const { return value<olive::core::rational>(); }
QString toString() const { return value<QString>(); }
Color toColor() const { return value<Color>(); }
Color toColor() const { return value<olive::core::Color>(); }
QMatrix4x4 toMatrix() const { return value<QMatrix4x4>(); }
VideoParams toVideoParams() const { return value<VideoParams>(); }
AudioParams toAudioParams() const { return value<AudioParams>(); }
-2
View File
@@ -27,8 +27,6 @@ set(OLIVE_SOURCES
render/audiowaveformcache.cpp
render/audiowaveformcache.h
render/cancelatom.h
render/color.cpp
render/color.h
render/colorprocessor.cpp
render/colorprocessor.h
render/colorprocessorcache.h
+2 -2
View File
@@ -203,7 +203,7 @@ void AudioParams::Load(QXmlStreamReader *reader)
} else if (reader->name() == QStringLiteral("duration")) {
set_duration(reader->readElementText().toLongLong());
} else if (reader->name() == QStringLiteral("timebase")) {
set_time_base(rational::fromString(reader->readElementText()));
set_time_base(rational::fromString(reader->readElementText().toStdString()));
} else {
reader->skipCurrentElement();
}
@@ -218,7 +218,7 @@ void AudioParams::Save(QXmlStreamWriter *writer) const
writer->writeTextElement(QStringLiteral("enabled"), QString::number(enabled_));
writer->writeTextElement(QStringLiteral("streamindex"), QString::number(stream_index_));
writer->writeTextElement(QStringLiteral("duration"), QString::number(duration_));
writer->writeTextElement(QStringLiteral("timebase"), timebase_.toString());
writer->writeTextElement(QStringLiteral("timebase"), QString::fromStdString(timebase_.toString()));
}
QString AudioParams::SampleRateToString(const int &sample_rate)
+3 -2
View File
@@ -25,14 +25,15 @@ extern "C" {
#include <libavutil/channel_layout.h>
}
#include <olive/core/core.h>
#include <QtMath>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "common/rational.h"
namespace olive {
using namespace core;
class AudioParams {
public:
// Only append to this list (never insert) because indexes are used in serialized files
-1
View File
@@ -22,7 +22,6 @@
#define AUDIOPLAYBACKCACHE_H
#include "audio/audiovisualwaveform.h"
#include "common/timerange.h"
#include "codec/samplebuffer.h"
#include "render/playbackcache.h"
+2 -2
View File
@@ -97,9 +97,9 @@ void AudioWaveformCache::SetPassthrough(PlaybackCache *cache)
for (const TimeRange &r : c->GetValidatedRanges()) {
WaveformPassthrough t = r;
t.waveform = c->waveforms_;
passthroughs_.append(t);
passthroughs_.push_back(t);
}
passthroughs_.append(c->passthroughs_);
passthroughs_.insert(passthroughs_.end(), c->passthroughs_.begin(), c->passthroughs_.end());
SetParameters(c->GetParameters());
SetSavingEnabled(c->IsSavingEnabled());
+1 -1
View File
@@ -69,7 +69,7 @@ private:
WaveformPtr waveform;
};
QVector<WaveformPassthrough> passthroughs_;
std::vector<WaveformPassthrough> passthroughs_;
};
-300
View File
@@ -1,300 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 "color.h"
#include <OpenImageIO/imagebuf.h>
#include "common/clamp.h"
#include "common/oiioutils.h"
namespace olive {
Color Color::fromHsv(const DataType &h, const DataType &s, const DataType &v)
{
DataType C = s * v;
DataType X = C * (1.0 - abs(fmod(h / 60.0, 2.0) - 1.0));
DataType m = v - C;
DataType Rs, Gs, Bs;
if(h >= 0.0 && h < 60.0) {
Rs = C;
Gs = X;
Bs = 0.0;
}
else if(h >= 60.0 && h < 120.0) {
Rs = X;
Gs = C;
Bs = 0.0;
}
else if(h >= 120.0 && h < 180.0) {
Rs = 0.0;
Gs = C;
Bs = X;
}
else if(h >= 180.0 && h < 240.0) {
Rs = 0.0;
Gs = X;
Bs = C;
}
else if(h >= 240.0 && h < 300.0) {
Rs = X;
Gs = 0.0;
Bs = C;
}
else {
Rs = C;
Gs = 0.0;
Bs = X;
}
return Color(Rs + m, Gs + m, Bs + m);
}
Color::Color(const char *data, const VideoParams::Format &format, int ch_layout)
{
*this = fromData(data, format, ch_layout);
}
Color::Color(const QColor &c)
{
set_red(c.redF());
set_green(c.greenF());
set_blue(c.blueF());
set_alpha(c.alphaF());
}
void Color::toHsv(DataType *hue, DataType *sat, DataType *val) const
{
DataType fCMax = qMax(qMax(red(), green()), blue());
DataType fCMin = qMin(qMin(red(), green()), blue());
DataType fDelta = fCMax - fCMin;
if(fDelta > 0) {
if(fCMax == red()) {
*hue = 60 * (fmod(((green() - blue()) / fDelta), 6));
} else if(fCMax == green()) {
*hue = 60 * (((blue() - red()) / fDelta) + 2);
} else if(fCMax == blue()) {
*hue = 60 * (((red() - green()) / fDelta) + 4);
}
if(fCMax > 0) {
*sat = fDelta / fCMax;
} else {
*sat = 0;
}
*val = fCMax;
} else {
*hue = 0;
*sat = 0;
*val = fCMax;
}
if(*hue < 0) {
*hue = 360 + *hue;
}
}
Color::DataType Color::hsv_hue() const
{
DataType h, s, v;
toHsv(&h, &s, &v);
return h;
}
Color::DataType Color::hsv_saturation() const
{
DataType h, s, v;
toHsv(&h, &s, &v);
return s;
}
Color::DataType Color::value() const
{
DataType h, s, v;
toHsv(&h, &s, &v);
return v;
}
void Color::toHsl(DataType *hue, DataType *sat, DataType *lightness) const
{
DataType fCMin = qMin(red(), qMin(green(), blue()));
DataType fCMax = qMax(red(), qMax(green(), blue()));
*lightness = 0.5 * (fCMin + fCMax);
if (fCMin == fCMax)
{
*sat = 0;
*hue = 0;
return;
}
else if (*lightness < 0.5)
{
*sat = (fCMax - fCMin) / (fCMax + fCMin);
}
else
{
*sat = (fCMax - fCMin) / (2.0 - fCMax - fCMin);
}
if (fCMax == red())
{
*hue = 60 * (green() - blue()) / (fCMax - fCMin);
}
if (fCMax == green())
{
*hue = 60 * (blue() - red()) / (fCMax - fCMin) + 120;
}
if (fCMax == blue())
{
*hue = 60 * (red() - green()) / (fCMax - fCMin) + 240;
}
if (*hue < 0)
{
*hue = *hue + 360;
}
}
Color::DataType Color::hsl_hue() const
{
DataType h, s, l;
toHsl(&h, &s, &l);
return h;
}
Color::DataType Color::hsl_saturation() const
{
DataType h, s, l;
toHsl(&h, &s, &l);
return s;
}
Color::DataType Color::lightness() const
{
DataType h, s, l;
toHsl(&h, &s, &l);
return l;
}
void Color::toData(char *data, const VideoParams::Format &format, int ch_layout) const
{
OIIO::convert_pixel_values(OIIO::TypeDesc::FLOAT,
data_,
OIIOUtils::GetOIIOBaseTypeFromFormat(format),
data,
ch_layout);
}
Color Color::fromData(const char *data, const VideoParams::Format &format, int ch_layout)
{
Color c;
OIIO::convert_pixel_values(OIIOUtils::GetOIIOBaseTypeFromFormat(format),
data,
OIIO::TypeDesc::FLOAT,
c.data_,
ch_layout);
return c;
}
QColor Color::toQColor() const
{
QColor c;
// QColor only supports values from 0.0 to 1.0 and are only used for UI representations
c.setRedF(clamp(red(), 0.0f, 1.0f));
c.setGreenF(clamp(green(), 0.0f, 1.0f));
c.setBlueF(clamp(blue(), 0.0f, 1.0f));
c.setAlphaF(clamp(alpha(), 0.0f, 1.0f));
return c;
}
Color::DataType Color::GetRoughLuminance() const
{
return (2*red()+blue()+3*green())/6.0;
}
Color &Color::operator+=(const Color &rhs)
{
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
data_[i] += rhs.data_[i];
}
return *this;
}
Color &Color::operator-=(const Color &rhs)
{
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
data_[i] -= rhs.data_[i];
}
return *this;
}
Color &Color::operator+=(const DataType &rhs)
{
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
data_[i] += rhs;
}
return *this;
}
Color &Color::operator-=(const DataType &rhs)
{
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
data_[i] -= rhs;
}
return *this;
}
Color &Color::operator*=(const DataType &rhs)
{
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
data_[i] *= rhs;
}
return *this;
}
Color &Color::operator/=(const DataType &rhs)
{
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
data_[i] /= rhs;
}
return *this;
}
}
QDebug operator<<(QDebug debug, const olive::Color &r)
{
debug.nospace() << "[R: " << r.red() << ", G: " << r.green() << ", B: " << r.blue() << ", A: " << r.alpha() << "]";
return debug.space();
}
-161
View File
@@ -1,161 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 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 COLOR_H
#define COLOR_H
#include <QColor>
#include <QDebug>
#include "common/define.h"
#include "render/videoparams.h"
namespace olive {
/**
* @brief High precision 32-bit DataType based RGBA color value
*/
class Color
{
public:
using DataType = float;
Color()
{
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
data_[i] = 0.0;
}
}
Color(const DataType& r, const DataType& g, const DataType& b, const DataType& a = 1.0f)
{
data_[0] = r;
data_[1] = g;
data_[2] = b;
data_[3] = a;
}
Color(const char *data, const VideoParams::Format &format, int ch_layout);
Color(const QColor& c);
/**
* @brief Creates a Color struct from hue/saturation/value
*
* Hue expects a value between 0.0 and 360.0. Saturation and Value expect a value between 0.0 and 1.0.
*/
static Color fromHsv(const DataType& h, const DataType& s, const DataType &v);
const DataType& red() const {return data_[0];}
const DataType& green() const {return data_[1];}
const DataType& blue() const {return data_[2];}
const DataType& alpha() const {return data_[3];}
void toHsv(DataType* hue, DataType* sat, DataType* val) const;
DataType hsv_hue() const;
DataType hsv_saturation() const;
DataType value() const;
void toHsl(DataType* hue, DataType* sat, DataType* lightness) const;
DataType hsl_hue() const;
DataType hsl_saturation() const;
DataType lightness() const;
void set_red(const DataType& red) {data_[0] = red;}
void set_green(const DataType& green) {data_[1] = green;}
void set_blue(const DataType& blue) {data_[2] = blue;}
void set_alpha(const DataType& alpha) {data_[3] = alpha;}
DataType* data() {return data_;}
const DataType* data() const {return data_;}
void toData(char* data, const VideoParams::Format& format, int ch_layout) const;
static Color fromData(const char* data, const VideoParams::Format& format, int ch_layout);
QColor toQColor() const;
// Suuuuper rough luminance value mostly used for UI (determining whether to overlay with black
// or white text)
DataType GetRoughLuminance() const;
// Assignment math operators
Color& operator+=(const Color& rhs);
Color& operator-=(const Color& rhs);
Color& operator+=(const DataType& rhs);
Color& operator-=(const DataType& rhs);
Color& operator*=(const DataType& rhs);
Color& operator/=(const DataType& rhs);
// Binary math operators
Color operator+(const Color& rhs) const
{
Color c(*this);
c += rhs;
return c;
}
Color operator-(const Color& rhs) const
{
Color c(*this);
c -= rhs;
return c;
}
Color operator+(const DataType& rhs) const
{
Color c(*this);
c += rhs;
return c;
}
Color operator-(const DataType& rhs) const
{
Color c(*this);
c -= rhs;
return c;
}
Color operator*(const DataType& rhs) const
{
Color c(*this);
c *= rhs;
return c;
}
Color operator/(const DataType& rhs) const
{
Color c(*this);
c /= rhs;
return c;
}
private:
DataType data_[VideoParams::kRGBAChannelCount];
};
}
QDebug operator<<(QDebug debug, const olive::Color& r);
Q_DECLARE_METATYPE(olive::Color)
#endif // COLOR_H
-1
View File
@@ -23,7 +23,6 @@
#include "codec/frame.h"
#include "common/ocioutils.h"
#include "render/color.h"
#include "render/colortransform.h"
namespace olive {
+11 -11
View File
@@ -158,11 +158,11 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
int div = qMax(1, static_cast<const Imf::IntAttribute&>(file.header()["oliveDivider"]).value());
VideoParams::Format image_format;
PixelFormat image_format;
if (pix_type == Imf::HALF) {
image_format = VideoParams::kFormatFloat16;
image_format = PixelFormat::F16;
} else {
image_format = VideoParams::kFormatFloat32;
image_format = PixelFormat::F32;
}
int channel_count = has_alpha ? VideoParams::kRGBAChannelCount : VideoParams::kRGBChannelCount;
@@ -202,7 +202,7 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
// FIXME: Hardcoded
const int div = 1;
const VideoParams::Format image_format = VideoParams::kFormatUnsigned8;
const PixelFormat image_format = PixelFormat::U8;
const int channel_count = 4;
const rational par(1, 1);
@@ -343,7 +343,7 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename, const FramePtr fram
// Floating point types are stored in EXR
Imf::PixelType pix_type;
if (frame->format() == VideoParams::kFormatFloat16) {
if (frame->format() == PixelFormat::F16) {
pix_type = Imf::HALF;
} else {
pix_type = Imf::FLOAT;
@@ -392,22 +392,22 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename, const FramePtr fram
QImage::Format fmt = QImage::Format_Invalid;
switch (frame->format()) {
case VideoParams::kFormatUnsigned8:
case PixelFormat::U8:
if (frame->channel_count() == VideoParams::kRGBAChannelCount){
fmt = QImage::Format_RGBA8888_Premultiplied;
} else if (frame->channel_count() == VideoParams::kRGBChannelCount){
fmt = QImage::Format_RGB888;
}
break;
case VideoParams::kFormatUnsigned16:
case PixelFormat::U16:
if (frame->channel_count() == VideoParams::kRGBAChannelCount){
fmt = QImage::Format_RGBA64_Premultiplied;
}
break;
case VideoParams::kFormatFloat16:
case VideoParams::kFormatFloat32:
case VideoParams::kFormatCount:
case VideoParams::kFormatInvalid:
case PixelFormat::F16:
case PixelFormat::F32:
case PixelFormat::FORMAT_COUNT:
case PixelFormat::INVALID:
break;
}
-3
View File
@@ -21,9 +21,6 @@
#ifndef VIDEORENDERFRAMECACHE_H
#define VIDEORENDERFRAMECACHE_H
#include "common/rational.h"
#include "common/timecodefunctions.h"
#include "common/timerange.h"
#include "codec/frame.h"
#include "render/playbackcache.h"
#include "render/videoparams.h"
-1
View File
@@ -23,7 +23,6 @@
#include "acceleratedjob.h"
#include "codec/samplebuffer.h"
#include "common/timerange.h"
namespace olive {
+1 -1
View File
@@ -31,7 +31,7 @@ ManagedColor::ManagedColor(const double &r, const double &g, const double &b, co
{
}
ManagedColor::ManagedColor(const char *data, const VideoParams::Format &format, int channel_layout) :
ManagedColor::ManagedColor(const char *data, const PixelFormat &format, int channel_layout) :
Color(data, format, channel_layout)
{
}
+3 -2
View File
@@ -21,7 +21,8 @@
#ifndef MANAGEDCOLOR_H
#define MANAGEDCOLOR_H
#include "color.h"
#include <olive/core/core.h>
#include "colortransform.h"
namespace olive {
@@ -31,7 +32,7 @@ class ManagedColor : public Color
public:
ManagedColor();
ManagedColor(const double& r, const double& g, const double& b, const double& a = 1.0);
ManagedColor(const char *data, const VideoParams::Format &format, int channel_layout);
ManagedColor(const char *data, const PixelFormat &format, int channel_layout);
ManagedColor(const Color& c);
const QString& color_input() const;
+15 -15
View File
@@ -189,7 +189,7 @@ void OpenGLRenderer::ClearDestination(Texture *texture, double r, double g, doub
}
}
QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth, VideoParams::Format format, int channel_count, const void *data, int linesize)
QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth, PixelFormat format, int channel_count, const void *data, int linesize)
{
GL_PREAMBLE;
@@ -673,10 +673,10 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
vao_.destroy();
}
GLint OpenGLRenderer::GetInternalFormat(VideoParams::Format format, int channel_layout)
GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout)
{
switch (format) {
case VideoParams::kFormatUnsigned8:
case PixelFormat::U8:
switch (channel_layout) {
case 1:
return GL_R8;
@@ -688,7 +688,7 @@ GLint OpenGLRenderer::GetInternalFormat(VideoParams::Format format, int channel_
return GL_RGBA8;
}
break;
case VideoParams::kFormatUnsigned16:
case PixelFormat::U16:
switch (channel_layout) {
case 1:
return GL_R16;
@@ -700,7 +700,7 @@ GLint OpenGLRenderer::GetInternalFormat(VideoParams::Format format, int channel_
return GL_RGBA16;
}
break;
case VideoParams::kFormatFloat16:
case PixelFormat::F16:
switch (channel_layout) {
case 1:
return GL_R16F;
@@ -712,7 +712,7 @@ GLint OpenGLRenderer::GetInternalFormat(VideoParams::Format format, int channel_
return GL_RGBA16F;
}
break;
case VideoParams::kFormatFloat32:
case PixelFormat::F32:
switch (channel_layout) {
case 1:
return GL_R32F;
@@ -724,28 +724,28 @@ GLint OpenGLRenderer::GetInternalFormat(VideoParams::Format format, int channel_
return GL_RGBA32F;
}
break;
case VideoParams::kFormatInvalid:
case VideoParams::kFormatCount:
case PixelFormat::INVALID:
case PixelFormat::FORMAT_COUNT:
break;
}
return GL_INVALID_VALUE;
}
GLenum OpenGLRenderer::GetPixelType(VideoParams::Format format)
GLenum OpenGLRenderer::GetPixelType(PixelFormat format)
{
switch (format) {
case VideoParams::kFormatUnsigned8:
case PixelFormat::U8:
return GL_UNSIGNED_BYTE;
case VideoParams::kFormatUnsigned16:
case PixelFormat::U16:
return GL_UNSIGNED_SHORT;
case VideoParams::kFormatFloat16:
case PixelFormat::F16:
return GL_HALF_FLOAT;
case VideoParams::kFormatFloat32:
case PixelFormat::F32:
return GL_FLOAT;
case VideoParams::kFormatInvalid:
case VideoParams::kFormatCount:
case PixelFormat::INVALID:
case PixelFormat::FORMAT_COUNT:
break;
}
+4 -4
View File
@@ -70,16 +70,16 @@ protected:
olive::VideoParams destination_params,
bool clear_destination) override;
virtual QVariant CreateNativeTexture(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override;
virtual QVariant CreateNativeTexture(int width, int height, int depth, PixelFormat format, int channel_count, const void* data = nullptr, int linesize = 0) override;
virtual void DestroyNativeTexture(QVariant texture) override;
virtual void DestroyInternal() override;
private:
static GLint GetInternalFormat(VideoParams::Format format, int channel_layout);
static GLint GetInternalFormat(PixelFormat format, int channel_layout);
static GLenum GetPixelType(VideoParams::Format format);
static GLenum GetPixelType(PixelFormat format);
static GLenum GetPixelFormat(int channel_count);
@@ -105,7 +105,7 @@ private:
int width;
int height;
int depth;
VideoParams::Format format;
PixelFormat format;
int channel_count;
bool operator==(const TextureCacheKey &rhs) const
+7 -5
View File
@@ -115,7 +115,7 @@ void PlaybackCache::LoadState()
Passthrough p = TimeRange(rational(in_num, in_den), rational(out_num, out_den));
p.cache = id;
passthroughs_.append(p);
passthroughs_.push_back(p);
}
break;
@@ -136,7 +136,7 @@ void PlaybackCache::SaveState()
QDir cache_dir = GetThisCacheDirectory();
QFile f(cache_dir.filePath(QStringLiteral("state")));
if (validated_.isEmpty() && passthroughs_.isEmpty()) {
if (validated_.isEmpty() && passthroughs_.empty()) {
if (f.exists()) {
f.remove();
}
@@ -150,7 +150,8 @@ void PlaybackCache::SaveState()
SaveStateEvent(s);
s << validated_.size();
// Using "int" for backwards compatibility with when we used QVector, could potentially overflow
s << int(validated_.size());
for (const TimeRange &r : validated_) {
s << r.in().numerator();
@@ -159,7 +160,8 @@ void PlaybackCache::SaveState()
s << r.out().denominator();
}
s << passthroughs_.size();
// Using "int" for backwards compatibility with when we used QVector, could potentially overflow
s << int(passthroughs_.size());
for (const Passthrough &p : passthroughs_) {
s << p.in().numerator();
@@ -211,7 +213,7 @@ void PlaybackCache::SetPassthrough(PlaybackCache *cache)
passthroughs_.push_back(p);
}
passthroughs_.append(cache->GetPassthroughs());
passthroughs_.insert(passthroughs_.end(), cache->GetPassthroughs().begin(), cache->GetPassthroughs().end());
if (saving_enabled_) {
SaveState();
+10 -8
View File
@@ -21,6 +21,7 @@
#ifndef PLAYBACKCACHE_H
#define PLAYBACKCACHE_H
#include <olive/core/core.h>
#include <QDir>
#include <QMutex>
#include <QObject>
@@ -28,7 +29,8 @@
#include <QUuid>
#include "common/jobtime.h"
#include "common/timerange.h"
using namespace olive::core;
namespace olive {
@@ -96,9 +98,9 @@ public:
QUuid cache;
};
const QVector<Passthrough> &GetPassthroughs() const { return passthroughs_; }
const std::vector<Passthrough> &GetPassthroughs() const { return passthroughs_; }
void ClearRequestRange(const olive::TimeRange &r)
void ClearRequestRange(const TimeRange &r)
{
requested_.remove(r);
}
@@ -113,14 +115,14 @@ public:
public slots:
void InvalidateAll();
void Request(const olive::TimeRange &r);
void Request(const TimeRange &r);
signals:
void Invalidated(const olive::TimeRange& r);
void Invalidated(const TimeRange& r);
void Validated(const olive::TimeRange& r);
void Validated(const TimeRange& r);
void Requested(const olive::TimeRange& r);
void Requested(const TimeRange& r);
void CancelAll();
@@ -146,7 +148,7 @@ private:
QMutex mutex_;
QVector<Passthrough> passthroughs_;
std::vector<Passthrough> passthroughs_;
qint64 last_loaded_state_;
+1 -1
View File
@@ -589,7 +589,7 @@ RenderTicketWatcher* PreviewAutoCacher::RenderFrame(Node *node, const rational&
if (ThumbnailCache *wave_cache = dynamic_cast<ThumbnailCache *>(cache)) {
rvp.video_params.set_divider(VideoParams::GetDividerForTargetResolution(rvp.video_params.width(), rvp.video_params.height(), 160, 120));
rvp.force_color_output = display_color_processor_;
rvp.force_format = VideoParams::kFormatUnsigned8;
rvp.force_format = PixelFormat::U8;
} else {
frame_cache->SetTimebase(viewer_node_->GetVideoParams().frame_rate_as_time_base());
}
+2 -2
View File
@@ -229,7 +229,7 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::Col
}
// Allocate 3D LUT
color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, VideoParams::kFormatFloat32, VideoParams::kRGBChannelCount), values);
color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, PixelFormat::F32, VideoParams::kRGBChannelCount), values);
color_ctx.lut3d_textures[i].name = sampler_name;
color_ctx.lut3d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
}
@@ -259,7 +259,7 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::Col
}
// Allocate 1D LUT
color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, VideoParams::kFormatFloat32, (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? 1 : VideoParams::kRGBChannelCount), values);
color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, PixelFormat::F32, (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? 1 : VideoParams::kRGBChannelCount), values);
color_ctx.lut1d_textures[i].name = sampler_name;
color_ctx.lut1d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
}
+2 -3
View File
@@ -26,7 +26,6 @@
#include <QVariant>
#include "common/define.h"
#include "common/timerange.h"
#include "node/node.h"
#include "render/colorprocessor.h"
#include "render/job/colortransformjob.h"
@@ -106,7 +105,7 @@ protected:
olive::VideoParams destination_params,
bool clear_destination) = 0;
virtual QVariant CreateNativeTexture(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0;
virtual QVariant CreateNativeTexture(int width, int height, int depth, PixelFormat format, int channel_count, const void* data = nullptr, int linesize = 0) = 0;
virtual void DestroyNativeTexture(QVariant texture) = 0;
@@ -139,7 +138,7 @@ private:
int width;
int height;
int depth;
VideoParams::Format format;
PixelFormat format;
int channel_count;
QVariant handle;
qint64 accessed;
+1 -1
View File
@@ -29,7 +29,7 @@ void RenderJobTracker::insert(const TimeRange &range, JobTime job_time)
// Now append the job
TimeRangeWithJob job(range, job_time);
jobs_.append(job);
jobs_.push_back(job);
}
void RenderJobTracker::insert(const TimeRangeList &ranges, JobTime job_time)
+5 -2
View File
@@ -21,11 +21,14 @@
#ifndef RENDERJOBTRACKER_H
#define RENDERJOBTRACKER_H
#include <olive/core/core.h>
#include "common/jobtime.h"
#include "common/timerange.h"
namespace olive {
using namespace core;
class RenderJobTracker
{
public:
@@ -59,7 +62,7 @@ private:
};
QVector<TimeRangeWithJob> jobs_;
std::vector<TimeRangeWithJob> jobs_;
};
+1 -1
View File
@@ -101,7 +101,7 @@ RenderTicketPtr RenderManager::RenderFrame(const RenderVideoParams &params)
ticket->setProperty("time", QVariant::fromValue(params.time));
ticket->setProperty("size", params.force_size);
ticket->setProperty("matrix", params.force_matrix);
ticket->setProperty("format", params.force_format);
ticket->setProperty("format", static_cast<PixelFormat::Format>(params.force_format));
ticket->setProperty("usecache", params.use_cache);
ticket->setProperty("channelcount", params.force_channel_count);
ticket->setProperty("mode", params.mode);
+2 -2
View File
@@ -112,7 +112,7 @@ public:
color_manager = colorman;
use_cache = false;
return_type = kFrame;
force_format = VideoParams::kFormatInvalid;
force_format = PixelFormat::INVALID;
force_color_output = nullptr;
force_size = QSize(0, 0);
force_channel_count = 0;
@@ -144,7 +144,7 @@ public:
QSize force_size;
int force_channel_count;
QMatrix4x4 force_matrix;
VideoParams::Format force_format;
PixelFormat force_format;
ColorProcessorPtr force_color_output;
};
+2 -2
View File
@@ -70,8 +70,8 @@ FramePtr RenderProcessor::GenerateFrame(TexturePtr texture, const rational& time
frame_params.set_height(frame_size.height());
}
VideoParams::Format frame_format = static_cast<VideoParams::Format>(ticket_->property("format").toInt());
if (frame_format != VideoParams::kFormatInvalid) {
PixelFormat frame_format = static_cast<PixelFormat::Format>(ticket_->property("format").toInt());
if (frame_format != PixelFormat::INVALID) {
frame_params.set_format(frame_format);
}
-1
View File
@@ -28,7 +28,6 @@
#include "codec/frame.h"
#include "codec/samplebuffer.h"
#include "common/cancelableobject.h"
#include "common/timerange.h"
#include "node/output/viewer/viewer.h"
namespace olive {
+4 -4
View File
@@ -125,9 +125,9 @@ void SubtitleParams::Load(QXmlStreamReader *reader)
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("in")) {
in = rational::fromString(attr.value().toString());
in = rational::fromString(attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
out = rational::fromString(attr.value().toString());
out = rational::fromString(attr.value().toString().toStdString());
}
}
@@ -152,8 +152,8 @@ void SubtitleParams::Save(QXmlStreamWriter *writer) const
writer->writeStartElement(QStringLiteral("subtitles"));
for (auto it=this->cbegin(); it!=this->cend(); it++) {
writer->writeStartElement(QStringLiteral("subtitle"));
writer->writeAttribute(QStringLiteral("in"), it->time().in().toString());
writer->writeAttribute(QStringLiteral("out"), it->time().out().toString());
writer->writeAttribute(QStringLiteral("in"), QString::fromStdString(it->time().in().toString()));
writer->writeAttribute(QStringLiteral("out"), QString::fromStdString(it->time().out().toString()));
writer->writeCharacters(it->text());
writer->writeEndElement(); // subtitle
}
+2 -1
View File
@@ -21,12 +21,13 @@
#ifndef SUBTITLEPARAMS_H
#define SUBTITLEPARAMS_H
#include <olive/core/core.h>
#include <QRect>
#include <QString>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "common/timerange.h"
using namespace olive::core;
namespace olive {
+1 -1
View File
@@ -121,7 +121,7 @@ public:
return QVector2D(params_.square_pixel_width(), params_.height());
}
VideoParams::Format format() const
PixelFormat format() const
{
return params_.format();
}

Some files were not shown because too many files have changed in this diff Show More