From d3090a98b45afd0eb61cf91b80c87dd7f4d0f027 Mon Sep 17 00:00:00 2001 From: GeorgH93 Date: Wed, 26 May 2021 17:17:17 +0200 Subject: [PATCH] Add YuvUtils to assist with nv12 to planar yuv conversions --- openVulkanoCpp/Image/YuvUtils.hpp | 72 +++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 openVulkanoCpp/Image/YuvUtils.hpp diff --git a/openVulkanoCpp/Image/YuvUtils.hpp b/openVulkanoCpp/Image/YuvUtils.hpp new file mode 100644 index 0000000..672b690 --- /dev/null +++ b/openVulkanoCpp/Image/YuvUtils.hpp @@ -0,0 +1,72 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include + +namespace openVulkanoCpp +{ + namespace YuvUtils + { + void NV12FromChromaPlanes(unsigned char* __restrict src, unsigned char* __restrict dest, int chromaChannelPixelCount) + { + for(int i = 0; i < chromaChannelPixelCount; i++) + { + dest[i * 2] = src[i]; + } + for(int i=0; i < chromaChannelPixelCount; i++) + { + dest[i * 2 + 1] = src[i + chromaChannelPixelCount]; + } + } + + void ChromaPlanesFromNV12(unsigned char* __restrict src, unsigned char* __restrict dest, int chromaChannelPixelCount) + { + for (int i = 0; i < chromaChannelPixelCount; i++) + { + dest[i] = src[i * 2]; + dest[i + chromaChannelPixelCount] = src[i * 2 + 1]; + } + } + + std::unique_ptr PlansFromNV12( + unsigned char* __restrict srcLum, unsigned char* __restrict srcChroma, uint32_t sizeLumX, uint32_t sizeLumY, + uint32_t sizeChromaComponentX, uint32_t sizeChromaComponentY, uint32_t strideX = 1, uint32_t strideY = 1) + { + std::unique_ptr buffer(new uint8_t[(sizeLumX / strideX) * (sizeLumY / strideY) + 2 * (sizeChromaComponentX / strideX) * (sizeChromaComponentY / strideY)]); + if (strideX == 1 && strideY == 1) + { + memcpy(buffer.get(), srcLum, sizeLumX * sizeLumY); + ChromaPlanesFromNV12(srcChroma, buffer.get() + sizeLumX * sizeLumY, sizeChromaComponentX * sizeChromaComponentY); + } + else + { + uint8_t* dest = buffer.get(); + size_t rowStride = strideY * sizeLumX; + for(int y = 0; y < sizeLumY; y += strideY, srcLum += rowStride) + { + for(int x = 0; x < sizeLumX; x += strideX, dest++) + { + *dest = srcLum[x]; + } + } + uint32_t chromaCount = (sizeChromaComponentX / strideX) * (sizeChromaComponentY / strideY); + rowStride = strideY * sizeChromaComponentX * 2; + for(int y = 0; y < sizeChromaComponentY; y += strideY, srcChroma += rowStride) + { + for (int x = 0; x < sizeChromaComponentX * 2; x += 2 * strideX, dest++) + { + dest[0] = srcChroma[x]; + dest[chromaCount] = srcChroma[x + 1]; + } + } + } + return buffer; + } + } +}