From 3eee9893f8078433b19d47c55159da6f59eac193 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 12 Aug 2019 18:24:52 +1000 Subject: [PATCH] implemented conversions between internal pixel formats --- app/node/input/media/media.cpp | 5 + app/render/CMakeLists.txt | 2 + app/render/colorservice.cpp | 20 ++++ app/render/colorservice.h | 20 ++++ app/render/pixelservice.cpp | 181 +++++++++++++++++++++++++++++++++ app/render/pixelservice.h | 9 +- 6 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 app/render/colorservice.cpp create mode 100644 app/render/colorservice.h diff --git a/app/node/input/media/media.cpp b/app/node/input/media/media.cpp index a31a134ca..e2e1cba3e 100644 --- a/app/node/input/media/media.cpp +++ b/app/node/input/media/media.cpp @@ -27,6 +27,7 @@ // FIXME: Test code only #include "decoder/ffmpeg/ffmpegdecoder.h" +#include "render/colorservice.h" #include "render/pixelservice.h" // End test code @@ -112,6 +113,10 @@ void MediaInput::Process(const rational &time) return; } + // Use OCIO + frame = PixelService::ConvertPixelFormat(frame, olive::PIX_FMT_RGBA32F); + ColorService::ConvertFrame(frame); + // FIXME: Test code if (tex_buf_.IsCreated()) { tex_buf_.Upload(frame->data()); diff --git a/app/render/CMakeLists.txt b/app/render/CMakeLists.txt index e0b5f9616..30bb964c7 100644 --- a/app/render/CMakeLists.txt +++ b/app/render/CMakeLists.txt @@ -18,6 +18,8 @@ add_subdirectory(gl) set(OLIVE_SOURCES ${OLIVE_SOURCES} + render/colorservice.h + render/colorservice.cpp #render/imagecache.h #render/imagecache.cpp #render/memorybuffer.h diff --git a/app/render/colorservice.cpp b/app/render/colorservice.cpp new file mode 100644 index 000000000..f8967dd03 --- /dev/null +++ b/app/render/colorservice.cpp @@ -0,0 +1,20 @@ +#include "colorservice.h" + +const int kRGBAChannels = 4; + +ColorService::ColorService() +{ + +} + +void ColorService::ConvertFrame(FramePtr f) +{ + OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); + + OCIO::ConstProcessorRcPtr processor = config->getProcessor("srgb", + OCIO::ROLE_SCENE_LINEAR); + + OCIO::PackedImageDesc img(reinterpret_cast(f->data()), f->width(), f->height(), kRGBAChannels); + + processor->apply(img); +} diff --git a/app/render/colorservice.h b/app/render/colorservice.h new file mode 100644 index 000000000..b132710d9 --- /dev/null +++ b/app/render/colorservice.h @@ -0,0 +1,20 @@ +#ifndef COLORSERVICE_H +#define COLORSERVICE_H + +#include +namespace OCIO = OCIO_NAMESPACE; + +#include "decoder/frame.h" + +class ColorService +{ +public: + ColorService(); + + static void ConvertFrame(FramePtr f); + +private: + +}; + +#endif // COLORSERVICE_H diff --git a/app/render/pixelservice.cpp b/app/render/pixelservice.cpp index b73116e11..da79e129e 100644 --- a/app/render/pixelservice.cpp +++ b/app/render/pixelservice.cpp @@ -21,9 +21,13 @@ #include "pixelservice.h" #include +#include +#include const int kRGBAChannels = 4; +PixelService olive::pixel_service; + PixelService::PixelService() { } @@ -87,3 +91,180 @@ int PixelService::BytesPerChannel(const olive::PixelFormat &format) qFatal("Invalid pixel format requested"); } } + +FramePtr PixelService::ConvertPixelFormat(FramePtr frame, const olive::PixelFormat &dest_format) +{ + if (frame->format() == dest_format) { + return frame; + } + + FramePtr converted = std::make_shared(); + + // Copy parameters + converted->set_width(frame->width()); + converted->set_height(frame->height()); + converted->set_timestamp(frame->timestamp()); + converted->set_format(dest_format); + converted->allocate(); + + int pix_count = frame->width() * frame->height() * kRGBAChannels; + + bool valid = true; + + switch (static_cast(frame->format())) { + case olive::PIX_FMT_RGBA8: + { + uint8_t* source = frame->data(); + + switch (dest_format) { + case olive::PIX_FMT_RGBA16: // 8-bit Integer -> 16-bit Integer + { + uint16_t* destination = reinterpret_cast(converted->data()); + for (int i=0;i(source[i] * 257); + } + break; + } + case olive::PIX_FMT_RGBA16F: // 8-bit Integer -> 16-bit Float + { + qfloat16* destination = reinterpret_cast(converted->data()); + for (int i=0;i 32-bit Float + { + float* destination = reinterpret_cast(converted->data()); + for (int i=0;i(frame->data()); + + switch (dest_format) { + case olive::PIX_FMT_RGBA8: // 16-bit Integer -> 8-bit Integer + { + uint8_t* destination = converted->data(); + for (int i=0;i(source[i] / 257); + } + break; + } + case olive::PIX_FMT_RGBA16F: // 16-bit Integer -> 16-bit Integer + { + qfloat16* destination = reinterpret_cast(converted->data()); + for (int i=0;i 16-bit Integer + { + float* destination = reinterpret_cast(converted->data()); + for (int i=0;i(frame->data()); + + switch (dest_format) { + case olive::PIX_FMT_RGBA8: // 16-bit Float -> 8-bit Integer + { + uint8_t* destination = converted->data(); + for (int i=0;i(source[i] * 255.0f); + } + break; + } + case olive::PIX_FMT_RGBA16: // 16-bit Float -> 16-bit Integer + { + uint16_t* destination = reinterpret_cast(converted->data()); + for (int i=0;i(source[i] * 65535.0f); + } + break; + } + case olive::PIX_FMT_RGBA32F: // 16-bit Float -> 32-bit Float + { + float* destination = reinterpret_cast(converted->data()); + for (int i=0;i(frame->data()); + + switch (dest_format) { + case olive::PIX_FMT_RGBA8: // 32-bit Float -> 8-bit Integer + { + uint8_t* destination = converted->data(); + for (int i=0;i(source[i] * 255.0f); + } + break; + } + case olive::PIX_FMT_RGBA16: // 32-bit Float -> 16-bit Integer + { + uint16_t* destination = reinterpret_cast(converted->data()); + for (int i=0;i(source[i] * 255.0f); + } + break; + } + case olive::PIX_FMT_RGBA16F: // 32-bit Float -> 16-bit Float + { + qfloat16* destination = reinterpret_cast(converted->data()); + for (int i=0;i #include +#include "decoder/frame.h" #include "pixelformat.h" /** @@ -87,7 +88,13 @@ public: */ static int BytesPerChannel(const olive::PixelFormat& format); -private: + /** + * @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 olive::PixelFormat &dest_format); + }; #endif // PIXELSERVICE_H