// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #include "maskedReader.hpp" #include <gpu/buffer.hpp> #include <gpu/memcpy.hpp> #include "gpu/input/maskInput.hpp" #include <cassert> #include <iostream> #include <sstream> #include <string> #include <cstring> namespace VideoStitch { namespace Input { MaskedReader* MaskedReader::create(VideoReader* delegate, const unsigned char* maskHostBuffer) { if (!maskHostBuffer) { return NULL; } const size_t bufferSize = (size_t)(delegate->getSpec().width * delegate->getSpec().height); unsigned char* ownedBuffer = new unsigned char[bufferSize]; if (!ownedBuffer) { return NULL; } memcpy(ownedBuffer, maskHostBuffer, bufferSize); return new MaskedReader(delegate, ownedBuffer); } MaskedReader::MaskedReader(VideoReader* delegate, unsigned char* maskHostBuffer) : Reader(delegate->id), StatefulBase(delegate->getSpec().width, delegate->getSpec().height, delegate->getFrameDataSize(), delegate->getSpec().format, delegate->getSpec().addressSpace, delegate->getSpec().frameRate, delegate->getFirstFrame(), delegate->getLastFrame(), delegate->getSpec().frameRateIsProcedural, maskHostBuffer), delegate(delegate), maskHostBuffer(maskHostBuffer) {} MaskedReader::~MaskedReader() { delete[] maskHostBuffer; delete delegate; } Status MaskedReader::perThreadInit() { FAIL_RETURN(delegate->perThreadInit()); const size_t bufferSize = (size_t)(getSpec().width * getSpec().height); auto maskDevBuffer = GPU::Buffer<unsigned char>::allocate(bufferSize, "Masked Reader"); if (!maskDevBuffer.ok()) { return maskDevBuffer.status(); } FAIL_RETURN(GPU::memcpyBlocking(maskDevBuffer.value(), maskHostBuffer, bufferSize)); return setCurrentDeviceData(maskDevBuffer.value()); } void MaskedReader::perThreadCleanup() { delegate->perThreadCleanup(); auto maskDevBufferP = getCurrentDeviceData(); if (maskDevBufferP) { maskDevBufferP->release(); } StatefulBase::perThreadCleanup(); } Status MaskedReader::unpackDevBuffer(GPU::Surface& dst, const GPU::Buffer<const unsigned char>& src, GPU::Stream& stream) const { FAIL_RETURN(delegate->unpackDevBuffer(dst, src, stream)); auto maskDevBufferP = getCurrentDeviceData(); assert(maskDevBufferP); if (!maskDevBufferP) { // We should always have gone through perThreadInit(). return {Origin::Input, ErrType::ImplementationError, "Uninitialized masked reader"}; } maskInput(dst, *maskDevBufferP, (unsigned)getSpec().width, (unsigned)getSpec().height, stream); return Status::OK(); } } // namespace Input } // namespace VideoStitch /// @endcond