// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm // // Basic input unpacking tests. #include "gpu/testing.hpp" #include "gpu/allocator.hpp" #include "gpu/buffer.hpp" #include "gpu/memcpy.hpp" #include "image/unpack.hpp" #include "libvideostitch/gpu_device.hpp" #include "libvideostitch/allocator.hpp" namespace VideoStitch { namespace Testing { void testRgb888Rgba888(unsigned width, unsigned height) { // Generate data unsigned char* input = new unsigned char[3 * width * height]; for (unsigned i = 0; i < width * height; ++i) { input[3 * i + 0] = (unsigned char)((33 * i) % 123); input[3 * i + 1] = (unsigned char)((31 * i) % 83); input[3 * i + 2] = (unsigned char)((42 * i) % 57); } // alloc auto surf = Core::OffscreenAllocator::createSourceSurface(width, height, "testRgb888Rgba888"); ENSURE(surf.ok(), "no device memory"); auto src = GPU::Buffer<unsigned char>::allocate(3 * width * height, "InputTest"); ENSURE(src.status(), "no device memory"); auto potUniqStream = GPU::UniqueStream::create(); ENSURE(potUniqStream.status()); auto stream = potUniqStream.ref().borrow(); // transfer and convert ENSURE(GPU::memcpyAsync(src.value(), input, stream), "transfer error"); ENSURE(Image::convertRGBToRGBA(*surf->pimpl->surface, src.value(), width, height, stream)); // Check result of conversion uint32_t* outputRgba = new uint32_t[width * height]; ENSURE(GPU::memcpyAsync(outputRgba, *surf->pimpl->surface, stream), "transfer error"); ENSURE(stream.synchronize()); for (unsigned i = 0; i < width * height; ++i) { ENSURE_EQ((int)input[3 * i + 0], (int)((unsigned char*)outputRgba)[4 * i + 0]); ENSURE_EQ((int)input[3 * i + 1], (int)((unsigned char*)outputRgba)[4 * i + 1]); ENSURE_EQ((int)input[3 * i + 2], (int)((unsigned char*)outputRgba)[4 * i + 2]); ENSURE_EQ(255, (int)((unsigned char*)outputRgba)[4 * i + 3]); } delete[] input; delete[] outputRgba; ENSURE(src.value().release()); } void testPYuv420RgbaMinimal(unsigned width, unsigned height, bool display) { ENSURE(!(width & 1), "width must be even"); ENSURE(!(height & 1), "height must be even"); unsigned size = width * height + (width * height) / 4 + (width * height) / 4; // Generate data unsigned char* input = new unsigned char[size]; for (unsigned i = 0; i < width * height; ++i) { input[i] = 128; } for (unsigned i = 0; i < (width * height) / 4; ++i) { input[width * height + i] = 123; } for (unsigned i = 0; i < (width * height) / 4; ++i) { input[width * height + (width * height) / 4 + i] = 156; } // alloc auto surf = Core::OffscreenAllocator::createSourceSurface(width, height, "testPYuv420RgbaMinimal"); ENSURE(surf.ok(), "no device memory"); auto src = GPU::Buffer<unsigned char>::allocate(size, "InputTest"); ENSURE(src.status(), "no device memory"); auto potUniqStream = GPU::UniqueStream::create(); ENSURE(potUniqStream.status()); auto stream = potUniqStream.ref().borrow(); // transfer and convert ENSURE(GPU::memcpyAsync(src.value(), input, size, stream), "transfer error"); ENSURE(Image::convertYV12ToRGBA(*surf->pimpl->surface, src.value(), width, height, stream)); // Check result of conversion (should be uniform) uint32_t* outputRgba = new uint32_t[width * height]; ENSURE(GPU::memcpyAsync(outputRgba, *surf->pimpl->surface, stream), "transfer error"); ENSURE(stream.synchronize()); if (display) { for (unsigned i = 0; i < height; ++i) { for (unsigned j = 0; j < width; ++j) { printf("%i %i %i %i\t\t", ((unsigned char*)outputRgba)[width * i + j], ((unsigned char*)outputRgba)[width * i + j + 1], ((unsigned char*)outputRgba)[width * i + j + 2], ((unsigned char*)outputRgba)[width * i + j + 3]); } printf("\n"); std::cout << std::endl; } } for (unsigned i = 0; i < width * height; ++i) { ENSURE_EQ((int)((unsigned char*)outputRgba)[0], (int)((unsigned char*)outputRgba)[4 * i + 0]); ENSURE_EQ((int)((unsigned char*)outputRgba)[1], (int)((unsigned char*)outputRgba)[4 * i + 1]); ENSURE_EQ((int)((unsigned char*)outputRgba)[2], (int)((unsigned char*)outputRgba)[4 * i + 2]); ENSURE_EQ(255, (int)((unsigned char*)outputRgba)[4 * i + 3]); } delete[] input; delete[] outputRgba; ENSURE(src.value().release()); } } // namespace Testing } // namespace VideoStitch int main() { VideoStitch::Testing::initTest(); VideoStitch::Testing::ENSURE(VideoStitch::GPU::setDefaultBackendDevice(0)); VideoStitch::Testing::testRgb888Rgba888(312, 531); VideoStitch::Testing::testPYuv420RgbaMinimal(16, 16, true); VideoStitch::Testing::testPYuv420RgbaMinimal(312, 532, false); return 0; }