allow setting of pixel format/ocio method/sample format in preferences
Implementation isn't perfect yet, viewer/renderer doesn't update yet when the preference is changed so a sequence needs to be re-opened for the change to take effect.
This commit is contained in:
@@ -185,17 +185,15 @@ void OpenGLTexture::CreateInternal(QOpenGLContext* create_ctx, GLuint* tex, cons
|
||||
// Allocate storage for texture
|
||||
const PixelFormat::Info& bit_depth = PixelService::GetPixelFormatInfo(format_);
|
||||
|
||||
f->glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
bit_depth.internal_format,
|
||||
width_,
|
||||
height_,
|
||||
0,
|
||||
bit_depth.pixel_format,
|
||||
bit_depth.gl_pixel_type,
|
||||
data
|
||||
);
|
||||
f->glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
bit_depth.internal_format,
|
||||
width_,
|
||||
height_,
|
||||
0,
|
||||
bit_depth.pixel_format,
|
||||
bit_depth.gl_pixel_type,
|
||||
data);
|
||||
|
||||
// Set texture filtering to bilinear
|
||||
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
@@ -71,8 +71,10 @@ void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable
|
||||
color_cache()->Add(video_stream->colorspace(), color_processor);
|
||||
}
|
||||
|
||||
ColorManager::OCIOMethod ocio_method = ColorManager::GetOCIOMethodForMode(video_params().mode());
|
||||
|
||||
// OCIO's CPU conversion is more accurate, so for online we render on CPU but offline we render GPU
|
||||
if (video_params().mode() == RenderMode::kOnline) {
|
||||
if (ocio_method == ColorManager::kOCIOAccurate) {
|
||||
// If alpha is associated, disassociate for the color transform
|
||||
if (video_stream->premultiplied_alpha()) {
|
||||
ColorManager::DisassociateAlpha(frame);
|
||||
@@ -96,7 +98,7 @@ void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable
|
||||
|
||||
OpenGLTextureCache::ReferencePtr footage_tex_ref = texture_cache_->Get(ctx_, footage_params, frame->data());
|
||||
|
||||
if (video_params().mode() == RenderMode::kOffline) {
|
||||
if (ocio_method == ColorManager::kOCIOFast) {
|
||||
if (!color_processor->IsEnabled()) {
|
||||
color_processor->Enable(ctx_, video_stream->premultiplied_alpha());
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ const char *VideoRenderBackend::GetCachedFrame(const rational &time)
|
||||
QByteArray frame_hash = frame_cache_.TimeToHash(time);
|
||||
|
||||
if (!frame_hash.isEmpty()) {
|
||||
QString fn = frame_cache_.CachePathName(frame_hash);
|
||||
QString fn = frame_cache_.CachePathName(frame_hash, params_.format());
|
||||
|
||||
if (QFileInfo::exists(fn)) {
|
||||
auto in = OIIO::ImageInput::open(fn.toStdString());
|
||||
@@ -304,7 +304,7 @@ void VideoRenderBackend::ThreadCompletedDownload(NodeDependency dep, qint64 job_
|
||||
|
||||
// Register frame with the disk manager
|
||||
if (operating_mode_ & VideoRenderWorker::kDownloadOnly) {
|
||||
DiskManager::instance()->CreatedFile(frame_cache()->CachePathName(hash), hash);
|
||||
DiskManager::instance()->CreatedFile(frame_cache()->CachePathName(hash, params_.format()), hash);
|
||||
}
|
||||
|
||||
QList<rational> hashes_with_time = frame_cache()->FramesWithHash(hash);
|
||||
@@ -322,7 +322,7 @@ void VideoRenderBackend::ThreadSkippedFrame(NodeDependency dep, qint64 job_time,
|
||||
SetWorkerBusyState(static_cast<RenderWorker*>(sender()), false);
|
||||
|
||||
if (SetFrameHash(dep, hash, job_time)
|
||||
&& frame_cache_.HasHash(hash)) {
|
||||
&& frame_cache_.HasHash(hash, params_.format())) {
|
||||
emit CachedTimeReady(dep.in(), job_time);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ void VideoRenderFrameCache::Clear()
|
||||
cache_id_.clear();
|
||||
}
|
||||
|
||||
bool VideoRenderFrameCache::HasHash(const QByteArray &hash)
|
||||
bool VideoRenderFrameCache::HasHash(const QByteArray &hash, const PixelFormat::Format& format)
|
||||
{
|
||||
return QFileInfo::exists(CachePathName(hash)) && !IsCaching(hash);
|
||||
return QFileInfo::exists(CachePathName(hash, format)) && !IsCaching(hash);
|
||||
}
|
||||
|
||||
bool VideoRenderFrameCache::IsCaching(const QByteArray &hash)
|
||||
@@ -114,12 +114,21 @@ const QMap<rational, QByteArray> &VideoRenderFrameCache::time_hash_map() const
|
||||
return time_hash_map_;
|
||||
}
|
||||
|
||||
QString VideoRenderFrameCache::CachePathName(const QByteArray &hash) const
|
||||
QString VideoRenderFrameCache::CachePathName(const QByteArray &hash, const PixelFormat::Format& pix_fmt) const
|
||||
{
|
||||
QDir this_cache_dir = QDir(GetMediaCacheLocation());
|
||||
this_cache_dir.mkpath(".");
|
||||
|
||||
QString filename = QStringLiteral("%1.exr").arg(QString(hash.toHex()));
|
||||
QString ext;
|
||||
|
||||
if (pix_fmt == PixelFormat::PIX_FMT_RGBA8) {
|
||||
// For some reason, 8-bit EXRs are extremely slow to load, so we use TIFF instead.
|
||||
ext = QStringLiteral("tiff");
|
||||
} else {
|
||||
ext = QStringLiteral("exr");
|
||||
}
|
||||
|
||||
QString filename = QStringLiteral("%1.%2").arg(QString(hash.toHex()), ext);
|
||||
|
||||
return this_cache_dir.filePath(filename);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QMutex>
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "render/pixelformat.h"
|
||||
|
||||
class VideoRenderFrameCache
|
||||
{
|
||||
@@ -15,7 +16,7 @@ public:
|
||||
/**
|
||||
* @brief Return whether a frame with this hash already exists
|
||||
*/
|
||||
bool HasHash(const QByteArray& hash);
|
||||
bool HasHash(const QByteArray& hash, const PixelFormat::Format &format);
|
||||
|
||||
/**
|
||||
* @brief Return whether a frame is currently being cached
|
||||
@@ -30,7 +31,7 @@ public:
|
||||
/**
|
||||
* @brief Return the path of the cached image at this time
|
||||
*/
|
||||
QString CachePathName(const QByteArray &hash) const;
|
||||
QString CachePathName(const QByteArray &hash, const PixelFormat::Format& pix_fmt) const;
|
||||
|
||||
void SetCacheID(const QString& id);
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ NodeValueTable VideoRenderWorker::RenderInternal(const NodeDependency& path, con
|
||||
// Emit only the hash
|
||||
emit CompletedDownload(path, job_time, hash);
|
||||
|
||||
} else if ((operating_mode_ & kHashOnly) && frame_cache_->HasHash(hash)) {
|
||||
} else if ((operating_mode_ & kHashOnly) && frame_cache_->HasHash(hash, video_params_.format())) {
|
||||
|
||||
// We've already cached this hash, no need to continue
|
||||
emit HashAlreadyExists(path, job_time, hash);
|
||||
@@ -67,7 +67,7 @@ NodeValueTable VideoRenderWorker::RenderInternal(const NodeDependency& path, con
|
||||
|
||||
// If we actually have a texture, download it into the disk cache
|
||||
if ((operating_mode_ & kDownloadOnly) && !texture.isNull()) {
|
||||
Download(path, hash, texture, frame_cache_->CachePathName(hash));
|
||||
Download(path, hash, texture, frame_cache_->CachePathName(hash, video_params_.format()));
|
||||
}
|
||||
|
||||
frame_cache_->RemoveHashFromCurrentlyCaching(hash);
|
||||
@@ -212,7 +212,11 @@ void VideoRenderWorker::Download(NodeDependency dep, QByteArray hash, QVariant t
|
||||
|
||||
// Set up OIIO::ImageSpec for compressing cached images on disk
|
||||
OIIO::ImageSpec spec(video_params().effective_width(), video_params().effective_height(), kRGBAChannels, format_info.oiio_desc);
|
||||
spec.attribute("compression", "dwaa:200");
|
||||
|
||||
if (video_params_.format() != PixelFormat::PIX_FMT_RGBA8) {
|
||||
// 8-bit doesn't use EXR because EXR loading is really slow on 8-bit
|
||||
spec.attribute("compression", "dwaa:200");
|
||||
}
|
||||
|
||||
TextureToBuffer(texture, download_buffer_);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user