From a2cba8c103b9109833339db71fc6aa6007b82075 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 1 May 2020 03:42:31 +1000 Subject: [PATCH] pixelformat: respect linesizes when converting pixel formats --- app/codec/oiio/oiiodecoder.h | 4 ++-- app/render/pixelformat.cpp | 29 +++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/app/codec/oiio/oiiodecoder.h b/app/codec/oiio/oiiodecoder.h index aaa8be388..249a1a346 100644 --- a/app/codec/oiio/oiiodecoder.h +++ b/app/codec/oiio/oiiodecoder.h @@ -48,6 +48,8 @@ public: virtual QString GetIndexFilename() override; + static void BufferToFrame(OIIO::ImageBuf* buf, FramePtr frame); + private: #if OIIO_VERSION < 10903 OIIO::ImageInput* image_; @@ -55,8 +57,6 @@ private: std::unique_ptr image_; #endif - static void BufferToFrame(OIIO::ImageBuf* buf, FramePtr frame); - static bool FileTypeIsSupported(const QString& fn); static int GetImageSequenceDigitCount(const QString& filename); diff --git a/app/render/pixelformat.cpp b/app/render/pixelformat.cpp index aa05beac8..2ddd251c1 100644 --- a/app/render/pixelformat.cpp +++ b/app/render/pixelformat.cpp @@ -25,6 +25,7 @@ #include #include +#include "codec/oiio/oiiodecoder.h" #include "common/define.h" #include "core.h" @@ -213,19 +214,39 @@ FramePtr PixelFormat::ConvertPixelFormat(FramePtr frame, const PixelFormat::Form return frame; } + // Create a destination frame with the same parameters FramePtr converted = Frame::Create(); - - // Copy parameters converted->set_video_params(VideoRenderingParams(frame->video_params().width(), frame->video_params().height(), dest_format)); converted->set_timestamp(frame->timestamp()); converted->allocate(); - OIIO::ImageBuf src(OIIO::ImageSpec(frame->width(), frame->height(), ChannelCount(frame->format()), GetOIIOTypeDesc(frame->format())), frame->data()); - OIIO::ImageBuf dst(OIIO::ImageSpec(converted->width(), converted->height(), ChannelCount(converted->format()), GetOIIOTypeDesc(converted->format())), converted->data()); + // Do the conversion through OIIO - create a buffer for the source image + OIIO::ImageBuf src(OIIO::ImageSpec(frame->width(), + frame->height(), + ChannelCount(frame->format()), + GetOIIOTypeDesc(frame->format()))); + + // Set the pixels (this is necessary as opposed to an OIIO buffer wrapper since Frame has + // linesizes) + src.set_pixels(OIIO::ROI(), + GetOIIOTypeDesc(frame->format()), + frame->const_data(), + OIIO::AutoStride, + frame->linesize_bytes()); + + // Create a destination OIIO buffer with our destination format + OIIO::ImageBuf dst(OIIO::ImageSpec(converted->width(), + converted->height(), + ChannelCount(converted->format()), + GetOIIOTypeDesc(converted->format()))); if (dst.copy_pixels(src)) { + + // Convert our buffer back to a frame + OIIODecoder::BufferToFrame(&dst, converted); + return converted; } else { return nullptr;