improved render channel count system
This commit is contained in:
@@ -37,8 +37,6 @@ set(OLIVE_SOURCES
|
||||
render/framehashcache.h
|
||||
render/managedcolor.cpp
|
||||
render/managedcolor.h
|
||||
render/pixelformat.cpp
|
||||
render/pixelformat.h
|
||||
render/playbackcache.cpp
|
||||
render/playbackcache.h
|
||||
render/previewautocacher.cpp
|
||||
|
||||
+32
-10
@@ -49,6 +49,8 @@ const QVector<uint64_t> AudioParams::kSupportedChannelLayouts = {
|
||||
AV_CH_LAYOUT_7POINT1
|
||||
};
|
||||
|
||||
const AudioParams::Format AudioParams::kInternalFormat = AudioParams::kFormatFloat32;
|
||||
|
||||
qint64 AudioParams::time_to_bytes(const double &time) const
|
||||
{
|
||||
Q_ASSERT(is_valid());
|
||||
@@ -68,6 +70,26 @@ bool AudioParams::operator!=(const AudioParams &other) const
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
QAudioFormat::SampleType AudioParams::GetQtSampleType(AudioParams::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case kFormatUnsigned8:
|
||||
return QAudioFormat::UnSignedInt;
|
||||
case kFormatSigned16:
|
||||
case kFormatSigned32:
|
||||
case kFormatSigned64:
|
||||
return QAudioFormat::SignedInt;
|
||||
case kFormatFloat32:
|
||||
case kFormatFloat64:
|
||||
return QAudioFormat::Float;
|
||||
case kFormatInvalid:
|
||||
case kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return QAudioFormat::Unknown;
|
||||
}
|
||||
|
||||
qint64 AudioParams::time_to_bytes(const rational &time) const
|
||||
{
|
||||
return time_to_bytes(time.toDouble());
|
||||
@@ -119,18 +141,18 @@ int AudioParams::channel_count() const
|
||||
int AudioParams::bytes_per_sample_per_channel() const
|
||||
{
|
||||
switch (format_) {
|
||||
case SampleFormat::SAMPLE_FMT_U8:
|
||||
case kFormatUnsigned8:
|
||||
return 1;
|
||||
case SampleFormat::SAMPLE_FMT_S16:
|
||||
case kFormatSigned16:
|
||||
return 2;
|
||||
case SampleFormat::SAMPLE_FMT_S32:
|
||||
case SampleFormat::SAMPLE_FMT_FLT:
|
||||
case kFormatSigned32:
|
||||
case kFormatFloat32:
|
||||
return 4;
|
||||
case SampleFormat::SAMPLE_FMT_DBL:
|
||||
case SampleFormat::SAMPLE_FMT_S64:
|
||||
case kFormatSigned64:
|
||||
case kFormatFloat64:
|
||||
return 8;
|
||||
case SampleFormat::SAMPLE_FMT_INVALID:
|
||||
case SampleFormat::SAMPLE_FMT_COUNT:
|
||||
case kFormatInvalid:
|
||||
case kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -146,8 +168,8 @@ bool AudioParams::is_valid() const
|
||||
{
|
||||
return (sample_rate() > 0
|
||||
&& channel_layout() > 0
|
||||
&& format_ != SampleFormat::SAMPLE_FMT_INVALID
|
||||
&& format_ != SampleFormat::SAMPLE_FMT_COUNT);
|
||||
&& format_ > kFormatInvalid
|
||||
&& format_ < kFormatCount);
|
||||
}
|
||||
|
||||
QString AudioParams::SampleRateToString(const int &sample_rate)
|
||||
|
||||
@@ -21,23 +21,51 @@
|
||||
#ifndef AUDIOPARAMS_H
|
||||
#define AUDIOPARAMS_H
|
||||
|
||||
#include <QAudioFormat>
|
||||
#include <QtMath>
|
||||
|
||||
#include "audio/sampleformat.h"
|
||||
#include "common/rational.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class AudioParams {
|
||||
public:
|
||||
enum Format {
|
||||
/// Invalid
|
||||
kFormatInvalid = -1,
|
||||
|
||||
/// 8-bit unsigned integer
|
||||
kFormatUnsigned8,
|
||||
|
||||
/// 16-bit signed integer
|
||||
kFormatSigned16,
|
||||
|
||||
/// 32-bit signed integer
|
||||
kFormatSigned32,
|
||||
|
||||
/// 64-bit signed integer
|
||||
kFormatSigned64,
|
||||
|
||||
/// 32-bit float
|
||||
kFormatFloat32,
|
||||
|
||||
/// 64-bit float
|
||||
kFormatFloat64,
|
||||
|
||||
/// Total format count
|
||||
kFormatCount
|
||||
};
|
||||
|
||||
static const Format kInternalFormat;
|
||||
|
||||
AudioParams() :
|
||||
sample_rate_(0),
|
||||
channel_layout_(0),
|
||||
format_(SampleFormat::SAMPLE_FMT_INVALID)
|
||||
format_(kFormatInvalid)
|
||||
{
|
||||
}
|
||||
|
||||
AudioParams(const int& sample_rate, const uint64_t& channel_layout, const SampleFormat::Format& format) :
|
||||
AudioParams(const int& sample_rate, const uint64_t& channel_layout, const Format& format) :
|
||||
sample_rate_(sample_rate),
|
||||
channel_layout_(channel_layout),
|
||||
format_(format)
|
||||
@@ -59,7 +87,7 @@ public:
|
||||
return rational(1, sample_rate());
|
||||
}
|
||||
|
||||
const SampleFormat::Format &format() const
|
||||
const Format &format() const
|
||||
{
|
||||
return format_;
|
||||
}
|
||||
@@ -80,6 +108,8 @@ public:
|
||||
bool operator==(const AudioParams& other) const;
|
||||
bool operator!=(const AudioParams& other) const;
|
||||
|
||||
static QAudioFormat::SampleType GetQtSampleType(Format format);
|
||||
|
||||
static const QVector<uint64_t> kSupportedChannelLayouts;
|
||||
static const QVector<int> kSupportedSampleRates;
|
||||
|
||||
@@ -98,7 +128,7 @@ private:
|
||||
|
||||
uint64_t channel_layout_;
|
||||
|
||||
SampleFormat::Format format_;
|
||||
Format format_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
+21
-18
@@ -20,7 +20,10 @@
|
||||
|
||||
#include "color.h"
|
||||
|
||||
#include <OpenImageIO/imagebuf.h>
|
||||
|
||||
#include "common/clamp.h"
|
||||
#include "common/oiioutils.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
@@ -65,9 +68,9 @@ Color Color::fromHsv(const double &h, const double &s, const double &v)
|
||||
return Color(Rs + m, Gs + m, Bs + m);
|
||||
}
|
||||
|
||||
Color::Color(const char *data, const PixelFormat::Format &format)
|
||||
Color::Color(const char *data, const VideoParams::Format &format, int ch_layout)
|
||||
{
|
||||
*this = fromData(data, format);
|
||||
*this = fromData(data, format, ch_layout);
|
||||
}
|
||||
|
||||
Color::Color(const QColor &c)
|
||||
@@ -194,24 +197,24 @@ double Color::lightness() const
|
||||
return l;
|
||||
}
|
||||
|
||||
void Color::toData(char *data, const PixelFormat::Format &format) const
|
||||
void Color::toData(char *data, const VideoParams::Format &format, int ch_layout) const
|
||||
{
|
||||
OIIO::convert_types(OIIO::TypeDesc::DOUBLE,
|
||||
data_,
|
||||
PixelFormat::GetOIIOTypeDesc(format),
|
||||
data,
|
||||
kRGBAChannels);
|
||||
OIIO::convert_pixel_values(OIIO::TypeDesc::DOUBLE,
|
||||
data_,
|
||||
OIIOUtils::GetOIIOBaseTypeFromFormat(format),
|
||||
data,
|
||||
ch_layout);
|
||||
}
|
||||
|
||||
Color Color::fromData(const char *data, const PixelFormat::Format &format)
|
||||
Color Color::fromData(const char *data, const VideoParams::Format &format, int ch_layout)
|
||||
{
|
||||
Color c;
|
||||
|
||||
OIIO::convert_types(PixelFormat::GetOIIOTypeDesc(format),
|
||||
data,
|
||||
OIIO::TypeDesc::DOUBLE,
|
||||
c.data_,
|
||||
kRGBAChannels);
|
||||
OIIO::convert_pixel_values(OIIOUtils::GetOIIOBaseTypeFromFormat(format),
|
||||
data,
|
||||
OIIO::TypeDesc::DOUBLE,
|
||||
c.data_,
|
||||
ch_layout);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -236,7 +239,7 @@ double Color::GetRoughLuminance() const
|
||||
|
||||
const Color &Color::operator+=(const Color &rhs)
|
||||
{
|
||||
for (int i=0;i<kRGBAChannels;i++) {
|
||||
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
|
||||
data_[i] += rhs.data_[i];
|
||||
}
|
||||
|
||||
@@ -245,7 +248,7 @@ const Color &Color::operator+=(const Color &rhs)
|
||||
|
||||
const Color &Color::operator-=(const Color &rhs)
|
||||
{
|
||||
for (int i=0;i<kRGBAChannels;i++) {
|
||||
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
|
||||
data_[i] -= rhs.data_[i];
|
||||
}
|
||||
|
||||
@@ -254,7 +257,7 @@ const Color &Color::operator-=(const Color &rhs)
|
||||
|
||||
const Color &Color::operator*=(const double &rhs)
|
||||
{
|
||||
for (int i=0;i<kRGBAChannels;i++) {
|
||||
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
|
||||
data_[i] *= rhs;
|
||||
}
|
||||
|
||||
@@ -263,7 +266,7 @@ const Color &Color::operator*=(const double &rhs)
|
||||
|
||||
const Color &Color::operator/=(const double &rhs)
|
||||
{
|
||||
for (int i=0;i<kRGBAChannels;i++) {
|
||||
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
|
||||
data_[i] /= rhs;
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -25,7 +25,7 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "common/define.h"
|
||||
#include "render/pixelformat.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
@@ -37,7 +37,7 @@ class Color
|
||||
public:
|
||||
Color()
|
||||
{
|
||||
for (int i=0;i<kRGBAChannels;i++) {
|
||||
for (int i=0;i<VideoParams::kRGBAChannelCount;i++) {
|
||||
data_[i] = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
data_[3] = a;
|
||||
}
|
||||
|
||||
Color(const char *data, const PixelFormat::Format &format);
|
||||
Color(const char *data, const VideoParams::Format &format, int ch_layout);
|
||||
|
||||
Color(const QColor& c);
|
||||
|
||||
@@ -84,9 +84,9 @@ public:
|
||||
double* data() {return data_;}
|
||||
const double* data() const {return data_;}
|
||||
|
||||
void toData(char* data, const PixelFormat::Format& format) const;
|
||||
void toData(char* data, const VideoParams::Format& format, int ch_layout) const;
|
||||
|
||||
static Color fromData(const char* data, const PixelFormat::Format& format);
|
||||
static Color fromData(const char* data, const VideoParams::Format& format, int ch_layout);
|
||||
|
||||
QColor toQColor() const;
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
Color operator/(const double& rhs) const;
|
||||
|
||||
private:
|
||||
double data_[kRGBAChannels];
|
||||
double data_[VideoParams::kRGBAChannelCount];
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -149,21 +149,6 @@ void ColorManager::SetConfigAndDefaultInput(const QString &filename, const QStri
|
||||
}
|
||||
}
|
||||
|
||||
void ColorManager::DisassociateAlpha(FramePtr f)
|
||||
{
|
||||
AssociateAlphaPixFmtFilter(kDisassociate, f);
|
||||
}
|
||||
|
||||
void ColorManager::AssociateAlpha(FramePtr f)
|
||||
{
|
||||
AssociateAlphaPixFmtFilter(kAssociate, f);
|
||||
}
|
||||
|
||||
void ColorManager::ReassociateAlpha(FramePtr f)
|
||||
{
|
||||
AssociateAlphaPixFmtFilter(kReassociate, f);
|
||||
}
|
||||
|
||||
QStringList ColorManager::ListAvailableDisplays()
|
||||
{
|
||||
QStringList displays;
|
||||
@@ -322,50 +307,6 @@ Color ColorManager::GetDefaultLumaCoefs() const
|
||||
return c;
|
||||
}
|
||||
|
||||
void ColorManager::AssociateAlphaPixFmtFilter(ColorManager::AlphaAction action, FramePtr f)
|
||||
{
|
||||
int pixel_count = f->width() * f->height() * kRGBAChannels;
|
||||
|
||||
switch (static_cast<PixelFormat::Format>(f->format())) {
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
qWarning() << "Alpha association functions received an invalid pixel format";
|
||||
break;
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
qWarning() << "Alpha association functions only works on float-based pixel formats at this time";
|
||||
break;
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
{
|
||||
AssociateAlphaInternal<qfloat16>(action, reinterpret_cast<qfloat16*>(f->data()), pixel_count);
|
||||
break;
|
||||
}
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
{
|
||||
AssociateAlphaInternal<float>(action, reinterpret_cast<float*>(f->data()), pixel_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ColorManager::AssociateAlphaInternal(ColorManager::AlphaAction action, T *data, int pix_count)
|
||||
{
|
||||
for (int i=0;i<pix_count;i+=kRGBAChannels) {
|
||||
T alpha = data[i+kRGBChannels];
|
||||
|
||||
if (action == kAssociate || alpha > 0) {
|
||||
for (int j=0;j<kRGBChannels;j++) {
|
||||
if (action == kDisassociate) {
|
||||
data[i+j] /= alpha;
|
||||
} else {
|
||||
data[i+j] *= alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColorManager::SetLocale::SetLocale(const char* new_locale)
|
||||
{
|
||||
old_locale_ = setlocale(LC_NUMERIC, nullptr);
|
||||
|
||||
@@ -50,12 +50,6 @@ public:
|
||||
|
||||
void SetConfigAndDefaultInput(const QString& filename, const QString& s);
|
||||
|
||||
static void DisassociateAlpha(FramePtr f);
|
||||
|
||||
static void AssociateAlpha(FramePtr f);
|
||||
|
||||
static void ReassociateAlpha(FramePtr f);
|
||||
|
||||
QStringList ListAvailableDisplays();
|
||||
|
||||
QString GetDefaultDisplay();
|
||||
@@ -109,17 +103,6 @@ private:
|
||||
|
||||
OCIO::ConstConfigRcPtr config_;
|
||||
|
||||
enum AlphaAction {
|
||||
kAssociate,
|
||||
kDisassociate,
|
||||
kReassociate
|
||||
};
|
||||
|
||||
static void AssociateAlphaPixFmtFilter(AlphaAction action, FramePtr f);
|
||||
|
||||
template<typename T>
|
||||
static void AssociateAlphaInternal(AlphaAction action, T* data, int pix_count);
|
||||
|
||||
QString config_filename_;
|
||||
|
||||
QString default_input_color_space_;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "colorprocessor.h"
|
||||
|
||||
#include "common/define.h"
|
||||
#include "common/ocioutils.h"
|
||||
#include "colormanager.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
@@ -77,7 +78,7 @@ ColorProcessor::ColorProcessor(ColorManager *config, const QString &input, const
|
||||
|
||||
void ColorProcessor::ConvertFrame(Frame *f)
|
||||
{
|
||||
OCIO::BitDepth ocio_bit_depth = PixelFormat::GetOCIOBitDepthFromPixelFormat(f->format());
|
||||
OCIO::BitDepth ocio_bit_depth = OCIOUtils::GetOCIOBitDepthFromPixelFormat(f->format());
|
||||
|
||||
if (ocio_bit_depth == OCIO::BIT_DEPTH_UNKNOWN) {
|
||||
qCritical() << "Tried to color convert frame with no format";
|
||||
@@ -87,7 +88,7 @@ void ColorProcessor::ConvertFrame(Frame *f)
|
||||
OCIO::PackedImageDesc img(f->data(),
|
||||
f->width(),
|
||||
f->height(),
|
||||
kRGBAChannels,
|
||||
VideoParams::kRGBAChannelCount,
|
||||
ocio_bit_depth,
|
||||
OCIO::AutoStride,
|
||||
OCIO::AutoStride,
|
||||
|
||||
@@ -243,24 +243,27 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
|
||||
int height = dw.max.y - dw.min.y + 1;
|
||||
bool has_alpha = file.header().channels().findChannel("A");
|
||||
|
||||
PixelFormat::Format image_format;
|
||||
VideoParams::Format image_format;
|
||||
if (pix_type == Imf::HALF) {
|
||||
image_format = PixelFormat::PIX_FMT_RGBA16F;
|
||||
image_format = VideoParams::kFormatFloat16;
|
||||
} else {
|
||||
image_format = PixelFormat::PIX_FMT_RGBA32F;
|
||||
image_format = VideoParams::kFormatFloat32;
|
||||
}
|
||||
|
||||
int channel_count = has_alpha ? VideoParams::kRGBAChannelCount : VideoParams::kRGBChannelCount;
|
||||
|
||||
frame = Frame::Create();
|
||||
frame->set_video_params(VideoParams(width,
|
||||
height,
|
||||
image_format,
|
||||
channel_count,
|
||||
rational::fromDouble(file.header().pixelAspectRatio())));
|
||||
|
||||
frame->allocate();
|
||||
|
||||
int bpc = PixelFormat::BytesPerChannel(image_format);
|
||||
int bpc = VideoParams::GetBytesPerChannel(image_format);
|
||||
|
||||
size_t xs = kRGBAChannels * bpc;
|
||||
size_t xs = channel_count * bpc;
|
||||
size_t ys = frame->linesize_bytes();
|
||||
|
||||
Imf::FrameBuffer framebuffer;
|
||||
@@ -398,12 +401,15 @@ QString FrameHashCache::CachePathName(const QString &cache_path, const QByteArra
|
||||
|
||||
bool FrameHashCache::SaveCacheFrame(const QString &filename, char *data, const VideoParams &vparam, int linesize_bytes) const
|
||||
{
|
||||
Q_ASSERT(PixelFormat::FormatIsFloat(vparam.format()));
|
||||
if (!VideoParams::FormatIsFloat(vparam.format())) {
|
||||
qCritical() << "Tried to cache frame with non-float pixel format";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Floating point types are stored in EXR
|
||||
Imf::PixelType pix_type;
|
||||
|
||||
if (vparam.format() == PixelFormat::PIX_FMT_RGBA16F) {
|
||||
if (vparam.format() == VideoParams::kFormatFloat16) {
|
||||
pix_type = Imf::HALF;
|
||||
} else {
|
||||
pix_type = Imf::FLOAT;
|
||||
@@ -414,7 +420,9 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename, char *data, const V
|
||||
header.channels().insert("R", Imf::Channel(pix_type));
|
||||
header.channels().insert("G", Imf::Channel(pix_type));
|
||||
header.channels().insert("B", Imf::Channel(pix_type));
|
||||
header.channels().insert("A", Imf::Channel(pix_type));
|
||||
if (vparam.channel_count() == VideoParams::kRGBAChannelCount) {
|
||||
header.channels().insert("A", Imf::Channel(pix_type));
|
||||
}
|
||||
|
||||
header.compression() = Imf::DWAA_COMPRESSION;
|
||||
header.insert("dwaCompressionLevel", Imf::FloatAttribute(200.0f));
|
||||
@@ -422,16 +430,18 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename, char *data, const V
|
||||
|
||||
Imf::OutputFile out(filename.toUtf8(), header, 0);
|
||||
|
||||
int bpc = PixelFormat::BytesPerChannel(vparam.format());
|
||||
int bpc = VideoParams::GetBytesPerChannel(vparam.format());
|
||||
|
||||
size_t xs = kRGBAChannels * bpc;
|
||||
size_t xs = vparam.channel_count() * bpc;
|
||||
size_t ys = linesize_bytes;
|
||||
|
||||
Imf::FrameBuffer framebuffer;
|
||||
framebuffer.insert("R", Imf::Slice(pix_type, data, xs, ys));
|
||||
framebuffer.insert("G", Imf::Slice(pix_type, data + bpc, xs, ys));
|
||||
framebuffer.insert("B", Imf::Slice(pix_type, data + 2*bpc, xs, ys));
|
||||
framebuffer.insert("A", Imf::Slice(pix_type, data + 3*bpc, xs, ys));
|
||||
if (vparam.channel_count() == VideoParams::kRGBAChannelCount) {
|
||||
framebuffer.insert("A", Imf::Slice(pix_type, data + 3*bpc, xs, ys));
|
||||
}
|
||||
out.setFrameBuffer(framebuffer);
|
||||
|
||||
out.writePixels(vparam.effective_height());
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "common/timerange.h"
|
||||
#include "render/pixelformat.h"
|
||||
#include "codec/frame.h"
|
||||
#include "render/playbackcache.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ ManagedColor::ManagedColor()
|
||||
{
|
||||
}
|
||||
|
||||
ManagedColor::ManagedColor(const float &r, const float &g, const float &b, const float &a) :
|
||||
ManagedColor::ManagedColor(const double &r, const double &g, const double &b, const double &a) :
|
||||
Color(r, g, b, a)
|
||||
{
|
||||
}
|
||||
|
||||
ManagedColor::ManagedColor(const char *data, const PixelFormat::Format &format) :
|
||||
Color(data, format)
|
||||
ManagedColor::ManagedColor(const char *data, const VideoParams::Format &format, int channel_layout) :
|
||||
Color(data, format, channel_layout)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ class ManagedColor : public Color
|
||||
{
|
||||
public:
|
||||
ManagedColor();
|
||||
ManagedColor(const float& r, const float& g, const float& b, const float& a = 1.0f);
|
||||
ManagedColor(const char *data, const PixelFormat::Format &format);
|
||||
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 Color& c);
|
||||
|
||||
const QString& color_input() const;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "openglrenderer.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFloat16>
|
||||
#include <QOpenGLExtraFunctions>
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
@@ -128,7 +128,7 @@ void OpenGLRenderer::ClearDestination(double r, double g, double b, double a)
|
||||
functions_->glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
QVariant OpenGLRenderer::CreateNativeTexture2D(int width, int height, PixelFormat::Format format, Texture::ChannelFormat channel_format, const void *data, int linesize)
|
||||
QVariant OpenGLRenderer::CreateNativeTexture2D(int width, int height, VideoParams::Format format, int channel_count, const void *data, int linesize)
|
||||
{
|
||||
GLuint texture;
|
||||
functions_->glGenTextures(1, &texture);
|
||||
@@ -140,8 +140,8 @@ QVariant OpenGLRenderer::CreateNativeTexture2D(int width, int height, PixelForma
|
||||
|
||||
functions_->glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
functions_->glTexImage2D(GL_TEXTURE_2D, 0, GetInternalFormat(format, channel_format),
|
||||
width, height, 0, GetPixelFormat(channel_format),
|
||||
functions_->glTexImage2D(GL_TEXTURE_2D, 0, GetInternalFormat(format, channel_count),
|
||||
width, height, 0, GetPixelFormat(channel_count),
|
||||
GetPixelType(format), data);
|
||||
|
||||
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
@@ -151,7 +151,7 @@ QVariant OpenGLRenderer::CreateNativeTexture2D(int width, int height, PixelForma
|
||||
return texture;
|
||||
}
|
||||
|
||||
QVariant OpenGLRenderer::CreateNativeTexture3D(int width, int height, int depth, PixelFormat::Format format, Texture::ChannelFormat channel_format, const void *data, int linesize)
|
||||
QVariant OpenGLRenderer::CreateNativeTexture3D(int width, int height, int depth, VideoParams::Format format, int channel_count, const void *data, int linesize)
|
||||
{
|
||||
GLuint texture;
|
||||
functions_->glGenTextures(1, &texture);
|
||||
@@ -163,8 +163,8 @@ QVariant OpenGLRenderer::CreateNativeTexture3D(int width, int height, int depth,
|
||||
|
||||
functions_->glBindTexture(GL_TEXTURE_3D, texture);
|
||||
|
||||
context_->extraFunctions()->glTexImage3D(GL_TEXTURE_3D, 0, GetInternalFormat(format, channel_format),
|
||||
width, height, depth, 0, GetPixelFormat(channel_format),
|
||||
context_->extraFunctions()->glTexImage3D(GL_TEXTURE_3D, 0, GetInternalFormat(format, channel_count),
|
||||
width, height, depth, 0, GetPixelFormat(channel_count),
|
||||
GetPixelType(format), data);
|
||||
|
||||
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
@@ -241,7 +241,7 @@ void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int lin
|
||||
|
||||
functions_->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
|
||||
p.effective_width(), p.effective_height(),
|
||||
GL_RGBA, GetPixelType(p.format()),
|
||||
GetPixelFormat(p.channel_count()), GetPixelType(p.format()),
|
||||
data);
|
||||
|
||||
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
@@ -264,7 +264,7 @@ void OpenGLRenderer::DownloadFromTexture(Texture* texture, void *data, int lines
|
||||
0,
|
||||
p.width(),
|
||||
p.height(),
|
||||
GL_RGBA,
|
||||
GetPixelFormat(p.channel_count()),
|
||||
GetPixelType(p.format()),
|
||||
data);
|
||||
|
||||
@@ -360,7 +360,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
GLuint tex_id = texture ? texture->id().value<GLuint>() : 0;
|
||||
textures_to_bind.append({texture, job.GetInterpolation(it.key())});
|
||||
|
||||
if (texture && texture->has_meaningful_alpha()) {
|
||||
if (texture && texture->channel_count() == VideoParams::kRGBAChannelCount) {
|
||||
input_textures_have_alpha = true;
|
||||
}
|
||||
|
||||
@@ -440,6 +440,13 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
destination_params.effective_width(),
|
||||
destination_params.effective_height());
|
||||
|
||||
// Set whether our destination texture needs an alpha channel
|
||||
if (input_textures_have_alpha || job.GetAlphaChannelRequired()) {
|
||||
destination_params.set_channel_count(VideoParams::kRGBAChannelCount);
|
||||
} else {
|
||||
destination_params.set_channel_count(VideoParams::kRGBChannelCount);
|
||||
}
|
||||
|
||||
// Bind vertex array object
|
||||
QOpenGLVertexArrayObject vao_;
|
||||
vao_.create();
|
||||
@@ -533,9 +540,6 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
if (destination) {
|
||||
// Reset framebuffer to default if we were drawing to a texture
|
||||
DetachTextureAsDestination();
|
||||
|
||||
// Set metadata for whether this texture has a meaningful alpha channel
|
||||
destination->set_has_meaningful_alpha((input_textures_have_alpha || job.GetAlphaChannelRequired()));
|
||||
}
|
||||
|
||||
// Release any textures we bound before
|
||||
@@ -555,58 +559,97 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
vao_.destroy();
|
||||
}
|
||||
|
||||
GLint OpenGLRenderer::GetInternalFormat(PixelFormat::Format format, bool with_alpha)
|
||||
GLint OpenGLRenderer::GetInternalFormat(VideoParams::Format format, int channel_layout)
|
||||
{
|
||||
switch (format) {
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
return with_alpha ? GL_RGBA8 : GL_RGB8;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
return with_alpha ? GL_RGBA16 : GL_RGB16;
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
return with_alpha ? GL_RGBA16F : GL_RGB16F;
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
return with_alpha ? GL_RGBA32F : GL_RGB32F;
|
||||
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
case VideoParams::kFormatUnsigned8:
|
||||
switch (channel_layout) {
|
||||
case 1:
|
||||
return GL_R8;
|
||||
case 2:
|
||||
return GL_RG8;
|
||||
case 3:
|
||||
return GL_RGB8;
|
||||
case 4:
|
||||
return GL_RGBA8;
|
||||
}
|
||||
break;
|
||||
case VideoParams::kFormatUnsigned16:
|
||||
switch (channel_layout) {
|
||||
case 1:
|
||||
return GL_R16;
|
||||
case 2:
|
||||
return GL_RG16;
|
||||
case 3:
|
||||
return GL_RGB16;
|
||||
case 4:
|
||||
return GL_RGBA16;
|
||||
}
|
||||
break;
|
||||
case VideoParams::kFormatFloat16:
|
||||
switch (channel_layout) {
|
||||
case 1:
|
||||
return GL_R16F;
|
||||
case 2:
|
||||
return GL_RG16F;
|
||||
case 3:
|
||||
return GL_RGB16F;
|
||||
case 4:
|
||||
return GL_RGBA16F;
|
||||
}
|
||||
break;
|
||||
case VideoParams::kFormatFloat32:
|
||||
switch (channel_layout) {
|
||||
case 1:
|
||||
return GL_R32F;
|
||||
case 2:
|
||||
return GL_RG32F;
|
||||
case 3:
|
||||
return GL_RGB32F;
|
||||
case 4:
|
||||
return GL_RGBA32F;
|
||||
}
|
||||
break;
|
||||
case VideoParams::kFormatInvalid:
|
||||
case VideoParams::kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return GL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
GLenum OpenGLRenderer::GetPixelType(PixelFormat::Format format)
|
||||
GLenum OpenGLRenderer::GetPixelType(VideoParams::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
case VideoParams::kFormatUnsigned8:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
case VideoParams::kFormatUnsigned16:
|
||||
return GL_UNSIGNED_SHORT;
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
case VideoParams::kFormatFloat16:
|
||||
return GL_HALF_FLOAT;
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
case VideoParams::kFormatFloat32:
|
||||
return GL_FLOAT;
|
||||
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
case VideoParams::kFormatInvalid:
|
||||
case VideoParams::kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return GL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
GLenum OpenGLRenderer::GetPixelFormat(Texture::ChannelFormat format)
|
||||
GLenum OpenGLRenderer::GetPixelFormat(int channel_count)
|
||||
{
|
||||
switch (format) {
|
||||
case Texture::kRGBA:
|
||||
return GL_RGBA;
|
||||
case Texture::kRGB:
|
||||
return GL_RGB;
|
||||
case Texture::kRedOnly:
|
||||
switch (channel_count) {
|
||||
case 1:
|
||||
return GL_RED;
|
||||
case 3:
|
||||
return GL_RGB;
|
||||
case 4:
|
||||
return GL_RGBA;
|
||||
default:
|
||||
return GL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::PrepareInputTexture(GLenum target, Texture::Interpolation interp)
|
||||
|
||||
@@ -51,8 +51,8 @@ public slots:
|
||||
|
||||
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override;
|
||||
|
||||
virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) override;
|
||||
virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) override;
|
||||
virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override;
|
||||
virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) override;
|
||||
|
||||
@@ -71,11 +71,11 @@ protected slots:
|
||||
OLIVE_NAMESPACE::VideoParams destination_params) override;
|
||||
|
||||
private:
|
||||
static GLint GetInternalFormat(PixelFormat::Format format, bool with_alpha);
|
||||
static GLint GetInternalFormat(VideoParams::Format format, int channel_layout);
|
||||
|
||||
static GLenum GetPixelType(PixelFormat::Format format);
|
||||
static GLenum GetPixelType(VideoParams::Format format);
|
||||
|
||||
static GLenum GetPixelFormat(Texture::ChannelFormat format);
|
||||
static GLenum GetPixelFormat(int channel_count);
|
||||
|
||||
void AttachTextureAsDestination(OLIVE_NAMESPACE::Texture* texture);
|
||||
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "pixelformat.h"
|
||||
|
||||
#include "OpenImageIO/imagebuf.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QFloat16>
|
||||
|
||||
#include "codec/oiio/oiiocommon.h"
|
||||
#include "common/define.h"
|
||||
#include "core.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
bool PixelFormat::FormatIsFloat(const PixelFormat::Format &format)
|
||||
{
|
||||
switch (format) {
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
return true;
|
||||
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
OIIO::TypeDesc::BASETYPE PixelFormat::GetOIIOTypeDesc(const PixelFormat::Format &format)
|
||||
{
|
||||
switch (format) {
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
return OIIO::TypeDesc::UINT8;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
return OIIO::TypeDesc::UINT16;
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
return OIIO::TypeDesc::HALF;
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
return OIIO::TypeDesc::FLOAT;
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
return OIIO::TypeDesc::UNKNOWN;
|
||||
}
|
||||
|
||||
QString PixelFormat::GetName(const PixelFormat::Format &format)
|
||||
{
|
||||
switch (format) {
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
return tr("8-bit");
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
return tr("16-bit Integer");
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
return tr("Half-Float (16-bit)");
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
return tr("Full-Float (32-bit)");
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
return tr("Unknown (%1)").arg(format);
|
||||
}
|
||||
|
||||
OCIO::BitDepth PixelFormat::GetOCIOBitDepthFromPixelFormat(PixelFormat::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
return OCIO::BIT_DEPTH_UINT8;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
return OCIO::BIT_DEPTH_UINT16;
|
||||
break;
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
return OCIO::BIT_DEPTH_F16;
|
||||
break;
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
return OCIO::BIT_DEPTH_F32;
|
||||
break;
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
return OCIO::BIT_DEPTH_UNKNOWN;
|
||||
}
|
||||
|
||||
PixelFormat* PixelFormat::instance_ = nullptr;
|
||||
|
||||
void PixelFormat::CreateInstance()
|
||||
{
|
||||
instance_ = new PixelFormat();
|
||||
}
|
||||
|
||||
void PixelFormat::DestroyInstance()
|
||||
{
|
||||
delete instance_;
|
||||
}
|
||||
|
||||
PixelFormat *PixelFormat::instance()
|
||||
{
|
||||
return instance_;
|
||||
}
|
||||
|
||||
PixelFormat::Format PixelFormat::GetConfiguredFormatForMode(RenderMode::Mode mode)
|
||||
{
|
||||
return static_cast<PixelFormat::Format>(
|
||||
Core::GetPreferenceForRenderMode(mode, QStringLiteral("PixelFormat")).toInt());
|
||||
}
|
||||
|
||||
void PixelFormat::SetConfiguredFormatForMode(RenderMode::Mode mode, PixelFormat::Format format)
|
||||
{
|
||||
if (format != GetConfiguredFormatForMode(mode)) {
|
||||
Core::SetPreferenceForRenderMode(mode, QStringLiteral("PixelFormat"), format);
|
||||
|
||||
emit FormatChanged();
|
||||
}
|
||||
}
|
||||
|
||||
PixelFormat::Format PixelFormat::OIIOFormatToOliveFormat(OIIO::TypeDesc desc)
|
||||
{
|
||||
if (desc == OIIO::TypeDesc::UINT8) {
|
||||
return PixelFormat::PIX_FMT_RGBA8;
|
||||
} else if (desc == OIIO::TypeDesc::UINT16) {
|
||||
return PixelFormat::PIX_FMT_RGBA16U;
|
||||
} else if (desc == OIIO::TypeDesc::HALF) {
|
||||
return PixelFormat::PIX_FMT_RGBA16F;
|
||||
} else if (desc == OIIO::TypeDesc::FLOAT) {
|
||||
return PixelFormat::PIX_FMT_RGBA32F;
|
||||
}
|
||||
|
||||
return PixelFormat::PIX_FMT_INVALID;
|
||||
}
|
||||
|
||||
int PixelFormat::GetBufferSize(const PixelFormat::Format &format, const int &width, const int &height)
|
||||
{
|
||||
return BytesPerPixel(format) * width * height;
|
||||
}
|
||||
|
||||
int PixelFormat::BytesPerPixel(const PixelFormat::Format &format)
|
||||
{
|
||||
return BytesPerChannel(format) * kRGBAChannels;
|
||||
}
|
||||
|
||||
int PixelFormat::BytesPerChannel(const PixelFormat::Format &format)
|
||||
{
|
||||
switch (format) {
|
||||
case PixelFormat::PIX_FMT_RGBA8:
|
||||
return 1;
|
||||
case PixelFormat::PIX_FMT_RGBA16U:
|
||||
case PixelFormat::PIX_FMT_RGBA16F:
|
||||
return 2;
|
||||
case PixelFormat::PIX_FMT_RGBA32F:
|
||||
return 4;
|
||||
case PixelFormat::PIX_FMT_INVALID:
|
||||
case PixelFormat::PIX_FMT_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
qFatal("Invalid pixel format requested");
|
||||
|
||||
// qFatal will abort so we won't get here, but this suppresses compiler warnings
|
||||
return 0;
|
||||
}
|
||||
|
||||
FramePtr PixelFormat::ConvertPixelFormat(FramePtr frame, const PixelFormat::Format &dest_format)
|
||||
{
|
||||
if (frame->format() == dest_format) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Create a destination frame with the same parameters
|
||||
FramePtr converted = Frame::Create();
|
||||
converted->set_video_params(VideoParams(frame->video_params().width(),
|
||||
frame->video_params().height(),
|
||||
dest_format));
|
||||
converted->set_timestamp(frame->timestamp());
|
||||
converted->allocate();
|
||||
|
||||
// Do the conversion through OIIO - create a buffer for the source image
|
||||
OIIO::ImageBuf src(OIIO::ImageSpec(frame->width(),
|
||||
frame->height(),
|
||||
kRGBAChannels,
|
||||
GetOIIOTypeDesc(frame->format())));
|
||||
|
||||
// Set the pixels (this is necessary as opposed to an OIIO buffer wrapper since Frame has
|
||||
// linesizes)
|
||||
OIIOCommon::FrameToBuffer(frame, &src);
|
||||
|
||||
// Create a destination OIIO buffer with our destination format
|
||||
OIIO::ImageBuf dst(OIIO::ImageSpec(converted->width(),
|
||||
converted->height(),
|
||||
kRGBAChannels,
|
||||
GetOIIOTypeDesc(converted->format())));
|
||||
|
||||
if (dst.copy_pixels(src)) {
|
||||
|
||||
// Convert our buffer back to a frame
|
||||
OIIOCommon::BufferToFrame(&dst, converted);
|
||||
|
||||
return converted;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
@@ -1,134 +0,0 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef BITDEPTHS_H
|
||||
#define BITDEPTHS_H
|
||||
|
||||
#include <memory>
|
||||
#include <OpenImageIO/imageio.h>
|
||||
#include <QOpenGLExtraFunctions>
|
||||
#include <QString>
|
||||
|
||||
#include "common/ocioutils.h"
|
||||
#include "render/rendermodes.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class Frame;
|
||||
using FramePtr = std::shared_ptr<Frame>;
|
||||
|
||||
class PixelFormat : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief Olive's internal supported pixel formats.
|
||||
*/
|
||||
enum Format {
|
||||
PIX_FMT_INVALID = -1,
|
||||
|
||||
PIX_FMT_RGBA8,
|
||||
PIX_FMT_RGBA16U,
|
||||
PIX_FMT_RGBA16F,
|
||||
PIX_FMT_RGBA32F,
|
||||
|
||||
PIX_FMT_COUNT
|
||||
};
|
||||
|
||||
static void CreateInstance();
|
||||
static void DestroyInstance();
|
||||
static PixelFormat* instance();
|
||||
|
||||
/**
|
||||
* @brief Returns the configured pixel format for a given mode
|
||||
*/
|
||||
Format GetConfiguredFormatForMode(RenderMode::Mode mode);
|
||||
void SetConfiguredFormatForMode(RenderMode::Mode mode, PixelFormat::Format format);
|
||||
|
||||
static Format OIIOFormatToOliveFormat(OIIO::TypeDesc desc);
|
||||
|
||||
/**
|
||||
* @brief Returns the minimum buffer size (in bytes) necessary for a given format, width, and height.
|
||||
*
|
||||
* @param format
|
||||
*
|
||||
* The format of the data the buffer should contain. Must be a member of the olive::PixelFormat enum.
|
||||
*
|
||||
* @param width
|
||||
*
|
||||
* The width (in pixels) of the buffer.
|
||||
*
|
||||
* @param height
|
||||
*
|
||||
* The height (in pixels) of the buffer.
|
||||
*/
|
||||
static int GetBufferSize(const Format &format, const int& width, const int& height);
|
||||
|
||||
/**
|
||||
* @brief Returns the number of bytes per pixel for a certain format
|
||||
*
|
||||
* Different formats use different sizes of data for pixels. Use this function to determine how many bytes a pixel
|
||||
* requires for a certain format. The number of bytes will always be a multiple of 4 since all formats use RGBA and
|
||||
* are at least 1 bpc.
|
||||
*/
|
||||
static int BytesPerPixel(const Format &format);
|
||||
|
||||
/**
|
||||
* @brief Returns the number of bytes per channel for a certain format
|
||||
*/
|
||||
static int BytesPerChannel(const Format& format);
|
||||
|
||||
/**
|
||||
* @brief Convert a frame to a pixel format
|
||||
*
|
||||
* If the frame's pixel format == the destination format, this just returns `frame`.
|
||||
*/
|
||||
static FramePtr ConvertPixelFormat(FramePtr frame, const Format &dest_format);
|
||||
|
||||
/**
|
||||
* @brief Simple convenience function returning whether a pixel format is float-based or integer-based
|
||||
*/
|
||||
static bool FormatIsFloat(const Format& format);
|
||||
|
||||
/**
|
||||
* @brief Get corresponding OpenImageIO TypeDesc for a given pixel format
|
||||
*/
|
||||
static OIIO::TypeDesc::BASETYPE GetOIIOTypeDesc(const Format& format);
|
||||
|
||||
/**
|
||||
* @brief Get format name
|
||||
*/
|
||||
static QString GetName(const Format& format);
|
||||
|
||||
static OCIO::BitDepth GetOCIOBitDepthFromPixelFormat(PixelFormat::Format format);
|
||||
|
||||
signals:
|
||||
void FormatChanged();
|
||||
|
||||
private:
|
||||
PixelFormat() = default;
|
||||
|
||||
static PixelFormat* instance_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
#endif // BITDEPTHS_H
|
||||
+23
-8
@@ -32,16 +32,16 @@ Renderer::Renderer(QObject *parent) :
|
||||
|
||||
}
|
||||
|
||||
TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, Texture::Type type, Texture::ChannelFormat channel_format, const void *data, int linesize)
|
||||
TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, Texture::Type type, const void *data, int linesize)
|
||||
{
|
||||
QVariant v;
|
||||
|
||||
if (type == Texture::k3D) {
|
||||
v = CreateNativeTexture3D(params.effective_width(), params.effective_height(),
|
||||
params.effective_depth(), params.format(), channel_format, data, linesize);
|
||||
params.effective_depth(), params.format(), params.channel_count(), data, linesize);
|
||||
} else {
|
||||
v = CreateNativeTexture2D(params.effective_width(), params.effective_height(), params.format(),
|
||||
channel_format, data, linesize);
|
||||
params.channel_count(), data, linesize);
|
||||
}
|
||||
|
||||
if (v.isNull()) {
|
||||
@@ -53,7 +53,7 @@ TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, Texture::Type type
|
||||
|
||||
TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, const void *data, int linesize)
|
||||
{
|
||||
return CreateTexture(params, Texture::k2D, Texture::kRGBA, data, linesize);
|
||||
return CreateTexture(params, Texture::k2D, data, linesize);
|
||||
}
|
||||
|
||||
void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, bool source_is_premultiplied, Texture *destination, const QMatrix4x4 &matrix)
|
||||
@@ -104,6 +104,7 @@ bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::Colo
|
||||
"uniform int ove_maintex_alpha;\n"
|
||||
"\n"
|
||||
"// Macros defining `ove_maintex_alpha` state\n"
|
||||
"// Matches `AlphaAssociated` C++ enum\n"
|
||||
"#define ALPHA_NONE 0\n"
|
||||
"#define ALPHA_UNASSOC 1\n"
|
||||
"#define ALPHA_ASSOC 2\n"
|
||||
@@ -185,8 +186,8 @@ bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::Colo
|
||||
}
|
||||
|
||||
// Allocate 3D LUT
|
||||
color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, PixelFormat::PIX_FMT_RGBA32F),
|
||||
Texture::k3D, Texture::kRGB, values);
|
||||
color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, VideoParams::kFormatFloat32, VideoParams::kRGBChannelCount),
|
||||
Texture::k3D, values);
|
||||
color_ctx.lut3d_textures[i].name = sampler_name;
|
||||
color_ctx.lut3d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
|
||||
}
|
||||
@@ -216,9 +217,8 @@ bool Renderer::GetColorContext(ColorProcessorPtr color_processor, Renderer::Colo
|
||||
}
|
||||
|
||||
// Allocate 1D LUT
|
||||
color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, PixelFormat::PIX_FMT_RGBA32F),
|
||||
color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, VideoParams::kFormatFloat32, (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? 1 : VideoParams::kRGBChannelCount),
|
||||
Texture::k2D,
|
||||
(channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? Texture::kRedOnly : Texture::kRGB,
|
||||
values);
|
||||
color_ctx.lut1d_textures[i].name = sampler_name;
|
||||
color_ctx.lut1d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
|
||||
@@ -244,6 +244,21 @@ void Renderer::BlitColorManagedInternal(ColorProcessorPtr color_processor, Textu
|
||||
job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture));
|
||||
job.InsertValue(QStringLiteral("ove_mvpmat"), ShaderValue(matrix, NodeParam::kMatrix));
|
||||
|
||||
AlphaAssociated associated;
|
||||
if (source->channel_count() == VideoParams::kRGBAChannelCount) {
|
||||
if (source_is_premultiplied) {
|
||||
// De-assoc/re-assoc required for color management
|
||||
associated = kAlphaAssociated;
|
||||
} else {
|
||||
// Just assoc at the end
|
||||
associated = kAlphaUnassociated;
|
||||
}
|
||||
} else {
|
||||
// No assoc/deassoc required
|
||||
associated = kAlphaNone;
|
||||
}
|
||||
job.InsertValue(QStringLiteral("ove_maintex_alpha"), ShaderValue(associated, NodeParam::kInt));
|
||||
|
||||
foreach (const ColorContext::LUT& l, color_ctx.lut3d_textures) {
|
||||
job.InsertValue(l.name, ShaderValue(QVariant::fromValue(l.texture), NodeParam::kTexture));
|
||||
job.SetInterpolation(l.name, l.interpolation);
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
virtual bool Init() = 0;
|
||||
|
||||
TexturePtr CreateTexture(const VideoParams& params, Texture::Type type, Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0);
|
||||
TexturePtr CreateTexture(const VideoParams& params, Texture::Type type, const void* data = nullptr, int linesize = 0);
|
||||
TexturePtr CreateTexture(const VideoParams& params, const void *data = nullptr, int linesize = 0);
|
||||
|
||||
void BlitToTexture(QVariant shader,
|
||||
@@ -72,8 +72,8 @@ public slots:
|
||||
|
||||
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) = 0;
|
||||
|
||||
virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) = 0;
|
||||
virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) = 0;
|
||||
virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0;
|
||||
virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) = 0;
|
||||
|
||||
@@ -105,6 +105,12 @@ private:
|
||||
|
||||
};
|
||||
|
||||
enum AlphaAssociated {
|
||||
kAlphaNone,
|
||||
kAlphaUnassociated,
|
||||
kAlphaAssociated
|
||||
};
|
||||
|
||||
bool GetColorContext(ColorProcessorPtr color_processor, ColorContext* ctx);
|
||||
|
||||
void BlitColorManagedInternal(ColorProcessorPtr color_processor, TexturePtr source,
|
||||
|
||||
@@ -76,7 +76,7 @@ void RendererThreadWrapper::ClearDestination(double r, double g, double b, doubl
|
||||
Q_ARG(double, a));
|
||||
}
|
||||
|
||||
QVariant RendererThreadWrapper::CreateNativeTexture2D(int width, int height, PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void *data, int linesize)
|
||||
QVariant RendererThreadWrapper::CreateNativeTexture2D(int width, int height, VideoParams::Format format, int channel_count, const void *data, int linesize)
|
||||
{
|
||||
QVariant v;
|
||||
|
||||
@@ -84,15 +84,15 @@ QVariant RendererThreadWrapper::CreateNativeTexture2D(int width, int height, Pix
|
||||
Q_RETURN_ARG(QVariant, v),
|
||||
Q_ARG(int, width),
|
||||
Q_ARG(int, height),
|
||||
OLIVE_NS_ARG(PixelFormat::Format, format),
|
||||
OLIVE_NS_ARG(Texture::ChannelFormat, channel_format),
|
||||
OLIVE_NS_ARG(VideoParams::Format, format),
|
||||
Q_ARG(int, channel_count),
|
||||
Q_ARG(const void*, data),
|
||||
Q_ARG(int, linesize));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
QVariant RendererThreadWrapper::CreateNativeTexture3D(int width, int height, int depth, PixelFormat::Format format, Texture::ChannelFormat channel_format, const void *data, int linesize)
|
||||
QVariant RendererThreadWrapper::CreateNativeTexture3D(int width, int height, int depth, VideoParams::Format format, int channel_count, const void *data, int linesize)
|
||||
{
|
||||
QVariant v;
|
||||
|
||||
@@ -101,8 +101,8 @@ QVariant RendererThreadWrapper::CreateNativeTexture3D(int width, int height, int
|
||||
Q_ARG(int, width),
|
||||
Q_ARG(int, height),
|
||||
Q_ARG(int, depth),
|
||||
OLIVE_NS_ARG(PixelFormat::Format, format),
|
||||
OLIVE_NS_ARG(Texture::ChannelFormat, channel_format),
|
||||
OLIVE_NS_ARG(VideoParams::Format, format),
|
||||
Q_ARG(int, channel_count),
|
||||
Q_ARG(const void*, data),
|
||||
Q_ARG(int, linesize));
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@ public slots:
|
||||
|
||||
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override;
|
||||
|
||||
virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) override;
|
||||
virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::PixelFormat::Format format, OLIVE_NAMESPACE::Texture::ChannelFormat channel_format, const void* data = nullptr, int linesize = 0) override;
|
||||
virtual QVariant CreateNativeTexture2D(int width, int height, OLIVE_NAMESPACE::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override;
|
||||
virtual QVariant CreateNativeTexture3D(int width, int height, int depth, OLIVE_NAMESPACE::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) override;
|
||||
|
||||
|
||||
@@ -86,11 +86,11 @@ QByteArray RenderManager::Hash(const Node *n, const VideoParams ¶ms, const r
|
||||
// Embed video parameters into this hash
|
||||
int width = params.effective_width();
|
||||
int height = params.effective_height();
|
||||
PixelFormat::Format format = params.format();
|
||||
VideoParams::Format format = params.format();
|
||||
|
||||
hasher.addData(reinterpret_cast<const char*>(&width), sizeof(int));
|
||||
hasher.addData(reinterpret_cast<const char*>(&height), sizeof(int));
|
||||
hasher.addData(reinterpret_cast<const char*>(&format), sizeof(PixelFormat::Format));
|
||||
hasher.addData(reinterpret_cast<const char*>(&format), sizeof(VideoParams::Format));
|
||||
|
||||
if (n) {
|
||||
n->Hash(hasher, time);
|
||||
@@ -111,7 +111,7 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* c
|
||||
viewer->audio_params(),
|
||||
QSize(0, 0),
|
||||
QMatrix4x4(),
|
||||
PixelFormat::PIX_FMT_INVALID,
|
||||
VideoParams::kFormatInvalid,
|
||||
nullptr,
|
||||
cache,
|
||||
prioritize);
|
||||
@@ -121,7 +121,7 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* c
|
||||
const rational& time, RenderMode::Mode mode,
|
||||
const VideoParams &video_params, const AudioParams &audio_params,
|
||||
const QSize& force_size,
|
||||
const QMatrix4x4& force_matrix, PixelFormat::Format force_format,
|
||||
const QMatrix4x4& force_matrix, VideoParams::Format force_format,
|
||||
ColorProcessorPtr force_color_output,
|
||||
FrameHashCache* cache, bool prioritize)
|
||||
{
|
||||
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
const rational& time, RenderMode::Mode mode,
|
||||
const VideoParams& video_params, const AudioParams& audio_params,
|
||||
const QSize& force_size,
|
||||
const QMatrix4x4& force_matrix, PixelFormat::Format force_format,
|
||||
const QMatrix4x4& force_matrix, VideoParams::Format force_format,
|
||||
ColorProcessorPtr force_color_output,
|
||||
FrameHashCache* cache = nullptr, bool prioritize = false);
|
||||
|
||||
|
||||
@@ -67,11 +67,15 @@ void RenderProcessor::Run()
|
||||
frame_params.set_height(frame_size.height());
|
||||
}
|
||||
|
||||
PixelFormat::Format frame_format = static_cast<PixelFormat::Format>(ticket_->property("format").toInt());
|
||||
if (frame_format != PixelFormat::PIX_FMT_INVALID) {
|
||||
VideoParams::Format frame_format = static_cast<VideoParams::Format>(ticket_->property("format").toInt());
|
||||
if (frame_format != VideoParams::kFormatInvalid) {
|
||||
frame_params.set_format(frame_format);
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
frame_params.set_channel_count(texture->channel_count());
|
||||
}
|
||||
|
||||
FramePtr frame = Frame::Create();
|
||||
frame->set_timestamp(time);
|
||||
frame->set_video_params(frame_params);
|
||||
@@ -448,9 +452,14 @@ QVariant RenderProcessor::ProcessFrameGeneration(const Node *node, const Generat
|
||||
{
|
||||
FramePtr frame = Frame::Create();
|
||||
|
||||
const VideoParams& video_params = ticket_->property("vparam").value<VideoParams>();
|
||||
VideoParams frame_params = ticket_->property("vparam").value<VideoParams>();
|
||||
if (job.GetAlphaChannelRequired()) {
|
||||
frame_params.set_channel_count(VideoParams::kRGBAChannelCount);
|
||||
} else {
|
||||
frame_params.set_channel_count(VideoParams::kRGBChannelCount);
|
||||
}
|
||||
|
||||
frame->set_video_params(video_params);
|
||||
frame->set_video_params(frame_params);
|
||||
frame->allocate();
|
||||
|
||||
node->GenerateFrame(frame, job);
|
||||
@@ -459,8 +468,6 @@ QVariant RenderProcessor::ProcessFrameGeneration(const Node *node, const Generat
|
||||
frame->data(),
|
||||
frame->linesize_pixels());
|
||||
|
||||
texture->set_has_meaningful_alpha(job.GetAlphaChannelRequired());
|
||||
|
||||
return QVariant::fromValue(texture);
|
||||
}
|
||||
|
||||
|
||||
+6
-20
@@ -41,19 +41,12 @@ public:
|
||||
kMipmappedLinear
|
||||
};
|
||||
|
||||
enum ChannelFormat {
|
||||
kRGBA,
|
||||
kRGB,
|
||||
kRedOnly
|
||||
};
|
||||
|
||||
static const Interpolation kDefaultInterpolation;
|
||||
|
||||
Texture(Renderer* renderer, const QVariant& native, const VideoParams& param, Type type) :
|
||||
renderer_(renderer),
|
||||
params_(param),
|
||||
id_(native),
|
||||
meaningful_alpha_(true),
|
||||
type_(type)
|
||||
{
|
||||
}
|
||||
@@ -82,11 +75,16 @@ public:
|
||||
return params_.height();
|
||||
}
|
||||
|
||||
PixelFormat::Format format() const
|
||||
VideoParams::Format format() const
|
||||
{
|
||||
return params_.format();
|
||||
}
|
||||
|
||||
int channel_count() const
|
||||
{
|
||||
return params_.channel_count();
|
||||
}
|
||||
|
||||
int divider() const
|
||||
{
|
||||
return params_.divider();
|
||||
@@ -97,16 +95,6 @@ public:
|
||||
return params_.pixel_aspect_ratio();
|
||||
}
|
||||
|
||||
bool has_meaningful_alpha() const
|
||||
{
|
||||
return meaningful_alpha_;
|
||||
}
|
||||
|
||||
void set_has_meaningful_alpha(bool e)
|
||||
{
|
||||
meaningful_alpha_ = e;
|
||||
}
|
||||
|
||||
Type type() const
|
||||
{
|
||||
return type_;
|
||||
@@ -119,8 +107,6 @@ private:
|
||||
|
||||
QVariant id_;
|
||||
|
||||
bool meaningful_alpha_;
|
||||
|
||||
Type type_;
|
||||
|
||||
};
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
OLIVE_NAMESPACE_ENTER;
|
||||
|
||||
const int VideoParams::kInternalChannelCount = kRGBAChannelCount;
|
||||
|
||||
const rational VideoParams::kPixelAspectSquare(1);
|
||||
const rational VideoParams::kPixelAspectNTSCStandard(8, 9);
|
||||
@@ -63,16 +65,18 @@ VideoParams::VideoParams() :
|
||||
width_(0),
|
||||
height_(0),
|
||||
depth_(0),
|
||||
format_(PixelFormat::PIX_FMT_INVALID),
|
||||
format_(kFormatInvalid),
|
||||
channel_count_(0),
|
||||
interlacing_(Interlacing::kInterlaceNone)
|
||||
{
|
||||
}
|
||||
|
||||
VideoParams::VideoParams(const int &width, const int &height, const PixelFormat::Format &format, const rational& pixel_aspect_ratio, const Interlacing &interlacing, const int& divider) :
|
||||
VideoParams::VideoParams(int width, int height, Format format, int nb_channels, const rational& pixel_aspect_ratio, Interlacing interlacing, int divider) :
|
||||
width_(width),
|
||||
height_(height),
|
||||
depth_(0),
|
||||
format_(format),
|
||||
channel_count_(nb_channels),
|
||||
pixel_aspect_ratio_(pixel_aspect_ratio),
|
||||
interlacing_(interlacing),
|
||||
divider_(divider)
|
||||
@@ -81,11 +85,12 @@ VideoParams::VideoParams(const int &width, const int &height, const PixelFormat:
|
||||
validate_pixel_aspect_ratio();
|
||||
}
|
||||
|
||||
VideoParams::VideoParams(const int &width, const int &height, const int &depth, const PixelFormat::Format &format, const rational &pixel_aspect_ratio, const VideoParams::Interlacing &interlacing, const int ÷r) :
|
||||
VideoParams::VideoParams(int width, int height, int depth, Format format, int nb_channels, const rational &pixel_aspect_ratio, VideoParams::Interlacing interlacing, int divider) :
|
||||
width_(width),
|
||||
height_(height),
|
||||
depth_(depth),
|
||||
format_(format),
|
||||
channel_count_(nb_channels),
|
||||
pixel_aspect_ratio_(pixel_aspect_ratio),
|
||||
interlacing_(interlacing),
|
||||
divider_(divider)
|
||||
@@ -94,12 +99,13 @@ VideoParams::VideoParams(const int &width, const int &height, const int &depth,
|
||||
validate_pixel_aspect_ratio();
|
||||
}
|
||||
|
||||
VideoParams::VideoParams(const int &width, const int &height, const rational &time_base, const PixelFormat::Format &format, const rational& pixel_aspect_ratio, const Interlacing &interlacing, const int ÷r) :
|
||||
VideoParams::VideoParams(int width, int height, const rational &time_base, Format format, int nb_channels, const rational& pixel_aspect_ratio, Interlacing interlacing, int divider) :
|
||||
width_(width),
|
||||
height_(height),
|
||||
depth_(0),
|
||||
time_base_(time_base),
|
||||
format_(format),
|
||||
channel_count_(nb_channels),
|
||||
pixel_aspect_ratio_(pixel_aspect_ratio),
|
||||
interlacing_(interlacing),
|
||||
divider_(divider)
|
||||
@@ -159,6 +165,64 @@ bool VideoParams::operator!=(const VideoParams &rhs) const
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
int VideoParams::GetBytesPerChannel(VideoParams::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case kFormatInvalid:
|
||||
case kFormatCount:
|
||||
break;
|
||||
case kFormatUnsigned8:
|
||||
return 1;
|
||||
case kFormatUnsigned16:
|
||||
case kFormatFloat16:
|
||||
return 2;
|
||||
case kFormatFloat32:
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VideoParams::GetBytesPerPixel(VideoParams::Format format, int channels)
|
||||
{
|
||||
return GetBytesPerChannel(format) * channels;
|
||||
}
|
||||
|
||||
bool VideoParams::FormatIsFloat(VideoParams::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case kFormatFloat16:
|
||||
case kFormatFloat32:
|
||||
return true;
|
||||
case kFormatUnsigned8:
|
||||
case kFormatUnsigned16:
|
||||
case kFormatInvalid:
|
||||
case kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString VideoParams::GetFormatName(VideoParams::Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case kFormatUnsigned8:
|
||||
return QCoreApplication::translate("VideoParams", "8-bit");
|
||||
case kFormatUnsigned16:
|
||||
return QCoreApplication::translate("VideoParams", "16-bit Integer");
|
||||
case kFormatFloat16:
|
||||
return QCoreApplication::translate("VideoParams", "Half-Float (16-bit)");
|
||||
case kFormatFloat32:
|
||||
return QCoreApplication::translate("VideoParams", "Full-Float (32-bit)");
|
||||
case kFormatInvalid:
|
||||
case kFormatCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return QCoreApplication::translate("VideoParams", "Unknown (0x%1)").arg(format, 0, 16);
|
||||
}
|
||||
|
||||
void VideoParams::calculate_effective_size()
|
||||
{
|
||||
effective_width_ = GetScaledDimension(width(), divider_);
|
||||
@@ -178,8 +242,8 @@ bool VideoParams::is_valid() const
|
||||
return (width() > 0
|
||||
&& height() > 0
|
||||
&& !pixel_aspect_ratio_.isNull()
|
||||
&& format_ != PixelFormat::PIX_FMT_INVALID
|
||||
&& format_ != PixelFormat::PIX_FMT_COUNT);
|
||||
&& format_ > kFormatInvalid && format_ < kFormatCount
|
||||
&& channel_count_ > 0);
|
||||
}
|
||||
|
||||
QString VideoParams::FrameRateToString(const rational &frame_rate)
|
||||
|
||||
+78
-12
@@ -22,13 +22,35 @@
|
||||
#define VIDEOPARAMS_H
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "pixelformat.h"
|
||||
#include "rendermodes.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class VideoParams {
|
||||
public:
|
||||
enum Format {
|
||||
/// Invalid or no format
|
||||
kFormatInvalid = -1,
|
||||
|
||||
/// 8-bit unsigned integer
|
||||
kFormatUnsigned8,
|
||||
|
||||
/// 16-bit unsigned integer
|
||||
kFormatUnsigned16,
|
||||
|
||||
/// 16-bit half float
|
||||
kFormatFloat16,
|
||||
|
||||
/// 32-bit full float
|
||||
kFormatFloat32,
|
||||
|
||||
/// 64-bit double float - disabled since very, very few libs support 64-bit buffers
|
||||
//kFormatFloat64,
|
||||
|
||||
/// Total format count
|
||||
kFormatCount
|
||||
};
|
||||
|
||||
enum Interlacing {
|
||||
kInterlaceNone,
|
||||
kInterlacedTopFirst,
|
||||
@@ -36,16 +58,17 @@ public:
|
||||
};
|
||||
|
||||
VideoParams();
|
||||
VideoParams(const int& width, const int& height, const PixelFormat::Format& format,
|
||||
VideoParams(int width, int height, Format format, int nb_channels,
|
||||
const rational& pixel_aspect_ratio = 1,
|
||||
const Interlacing& interlacing = kInterlaceNone, const int& divider = 1);
|
||||
VideoParams(const int& width, const int& height, const int& depth,
|
||||
const PixelFormat::Format& format,
|
||||
Interlacing interlacing = kInterlaceNone, int divider = 1);
|
||||
VideoParams(int width, int height, int depth,
|
||||
Format format, int nb_channels,
|
||||
const rational& pixel_aspect_ratio = 1,
|
||||
const Interlacing& interlacing = kInterlaceNone, const int& divider = 1);
|
||||
VideoParams(const int& width, const int& height, const rational& time_base,
|
||||
const PixelFormat::Format& format, const rational& pixel_aspect_ratio = 1,
|
||||
const Interlacing& interlacing = kInterlaceNone, const int& divider = 1);
|
||||
Interlacing interlacing = kInterlaceNone, int divider = 1);
|
||||
VideoParams(int width, int height, const rational& time_base,
|
||||
Format format, int nb_channels,
|
||||
const rational& pixel_aspect_ratio = 1,
|
||||
Interlacing interlacing = kInterlaceNone, int divider = 1);
|
||||
|
||||
int width() const
|
||||
{
|
||||
@@ -116,16 +139,26 @@ public:
|
||||
return effective_depth_;
|
||||
}
|
||||
|
||||
PixelFormat::Format format() const
|
||||
Format format() const
|
||||
{
|
||||
return format_;
|
||||
}
|
||||
|
||||
void set_format(PixelFormat::Format f)
|
||||
void set_format(Format f)
|
||||
{
|
||||
format_ = f;
|
||||
}
|
||||
|
||||
int channel_count() const
|
||||
{
|
||||
return channel_count_;
|
||||
}
|
||||
|
||||
void set_channel_count(int c)
|
||||
{
|
||||
channel_count_ = c;
|
||||
}
|
||||
|
||||
const rational& pixel_aspect_ratio() const
|
||||
{
|
||||
return pixel_aspect_ratio_;
|
||||
@@ -154,6 +187,33 @@ public:
|
||||
bool operator==(const VideoParams& rhs) const;
|
||||
bool operator!=(const VideoParams& rhs) const;
|
||||
|
||||
static int GetBytesPerChannel(Format format);
|
||||
int GetBytesPerChannel() const
|
||||
{
|
||||
return GetBytesPerChannel(format_);
|
||||
}
|
||||
|
||||
static int GetBytesPerPixel(Format format, int channels);
|
||||
int GetBytesPerPixel() const
|
||||
{
|
||||
return GetBytesPerPixel(format_, channel_count_);
|
||||
}
|
||||
|
||||
static int GetBufferSize(int width, int height, Format format, int channels)
|
||||
{
|
||||
return width * height * GetBytesPerPixel(format, channels);
|
||||
}
|
||||
int GetBufferSize() const
|
||||
{
|
||||
return GetBufferSize(width_, height_, format_, channel_count_);
|
||||
}
|
||||
|
||||
static bool FormatIsFloat(Format format);
|
||||
|
||||
static QString GetFormatName(Format format);
|
||||
|
||||
static const int kInternalChannelCount;
|
||||
|
||||
static const rational kPixelAspectSquare;
|
||||
static const rational kPixelAspectNTSCStandard;
|
||||
static const rational kPixelAspectNTSCWidescreen;
|
||||
@@ -165,6 +225,10 @@ public:
|
||||
static const QVector<rational> kStandardPixelAspects;
|
||||
static const QVector<int> kSupportedDividers;
|
||||
|
||||
static const int kHSVChannelCount = 3;
|
||||
static const int kRGBChannelCount = 3;
|
||||
static const int kRGBAChannelCount = 4;
|
||||
|
||||
/**
|
||||
* @brief Convert rational frame rate (i.e. flipped timebase) to a user-friendly string
|
||||
*/
|
||||
@@ -185,7 +249,9 @@ private:
|
||||
int depth_;
|
||||
rational time_base_;
|
||||
|
||||
PixelFormat::Format format_;
|
||||
Format format_;
|
||||
|
||||
int channel_count_;
|
||||
|
||||
rational pixel_aspect_ratio_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user