// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #pragma once #include "frameBuffer.hpp" #include "stereoOutput.hpp" #include "stitchOutput.hpp" #include "libvideostitch/gpu_device.hpp" #include "libvideostitch/controller.hpp" #include "libvideostitch/output.hpp" #include <memory> #include <vector> namespace VideoStitch { namespace Core { /** * A StitchOutput implementation that writes a video frame synchronously to a writer. * * Not thread safe. */ class BlockingSourceOutput : public ExtractOutput::Pimpl, WriterPusher<SourceFrameBuffer> { public: static Potential<BlockingSourceOutput> create(std::shared_ptr<SourceSurface> surface, const std::vector<std::shared_ptr<SourceRenderer>>& renderers, const std::vector<std::shared_ptr<Output::VideoWriter>>& writers, int source) { std::unique_ptr<BlockingSourceOutput> bso(new BlockingSourceOutput(surface, renderers, writers, source)); FAIL_RETURN(GPU::useDefaultBackendDevice()); Potential<SourceFrameBuffer> frameBuffer = SourceFrameBuffer::create(surface, writers); FAIL_RETURN(frameBuffer.status()); bso->delegate = frameBuffer.release(); return bso.release(); } virtual ~BlockingSourceOutput() { delete delegate; } Status pushVideo(mtime_t date) override; virtual GPU::Surface& acquireFrame(mtime_t date, GPU::Stream& stream) override; virtual bool setRenderers(const std::vector<std::shared_ptr<SourceRenderer>>& r) override { return WriterPusher<SourceFrameBuffer>::setRenderers(r); } virtual bool addRenderer(std::shared_ptr<SourceRenderer> r) override { return WriterPusher<SourceFrameBuffer>::addRenderer(r); } virtual bool removeRenderer(const std::string& id) override { return WriterPusher<SourceFrameBuffer>::removeRenderer(id); } virtual bool setWriters(const std::vector<std::shared_ptr<Output::VideoWriter>>& ws) override { return WriterPusher<SourceFrameBuffer>::setWriters(ws); } virtual bool addWriter(std::shared_ptr<Output::VideoWriter> w) override { return WriterPusher<SourceFrameBuffer>::addWriter(w); } virtual bool removeWriter(const std::string& id) override { return WriterPusher<SourceFrameBuffer>::removeWriter(id); } virtual bool updateWriter(const std::string& id, const Ptv::Value& config) override { return WriterPusher<SourceFrameBuffer>::updateWriter(id, config); } private: BlockingSourceOutput(std::shared_ptr<SourceSurface> surface, const std::vector<std::shared_ptr<SourceRenderer>>& renderers, const std::vector<std::shared_ptr<Output::VideoWriter>>& writers, int source) : Pimpl(surface->getWidth(), surface->getHeight(), source), WriterPusher<SourceFrameBuffer>(surface->getWidth(), surface->getHeight(), writers) { setRenderers(renderers); } SourceFrameBuffer* delegate; }; class BlockingStitchOutput : public StitchOutput::Pimpl, WriterPusher<PanoFrameBuffer> { public: static Potential<BlockingStitchOutput> create(std::shared_ptr<PanoSurface> surface, const std::vector<std::shared_ptr<PanoRenderer>>& renderers, const std::vector<std::shared_ptr<Output::VideoWriter>>& writers) { std::unique_ptr<BlockingStitchOutput> bso(new BlockingStitchOutput(surface, renderers, writers)); FAIL_RETURN(GPU::useDefaultBackendDevice()); Potential<PanoFrameBuffer> frameBuffer = PanoFrameBuffer::create(surface, writers); FAIL_RETURN(frameBuffer.status()); bso->delegate = frameBuffer.release(); return bso.release(); } virtual ~BlockingStitchOutput() { delete delegate; } Status pushVideo(mtime_t date) override; virtual PanoSurface& acquireFrame(mtime_t) override; virtual bool setRenderers(const std::vector<std::shared_ptr<PanoRenderer>>& r) override { return WriterPusher<PanoFrameBuffer>::setRenderers(r); } virtual bool addRenderer(std::shared_ptr<PanoRenderer> r) override { return WriterPusher<PanoFrameBuffer>::addRenderer(r); } virtual bool removeRenderer(const std::string& id) override { return WriterPusher<PanoFrameBuffer>::removeRenderer(id); } virtual void setCompositor(const std::shared_ptr<GPU::Overlayer>& c) override { WriterPusher<PanoFrameBuffer>::setCompositor(c); } virtual bool setWriters(const std::vector<std::shared_ptr<Output::VideoWriter>>& ws) override { return WriterPusher<PanoFrameBuffer>::setWriters(ws); } virtual bool addWriter(std::shared_ptr<Output::VideoWriter> w) override { return WriterPusher<PanoFrameBuffer>::addWriter(w); } virtual bool removeWriter(const std::string& id) override { return WriterPusher<PanoFrameBuffer>::removeWriter(id); } virtual bool updateWriter(const std::string& id, const Ptv::Value& config) override { return WriterPusher<PanoFrameBuffer>::updateWriter(id, config); } private: BlockingStitchOutput(std::shared_ptr<PanoSurface> surface, const std::vector<std::shared_ptr<PanoRenderer>>& renderers, const std::vector<std::shared_ptr<Output::VideoWriter>>& writers) : Pimpl(surface->getWidth(), surface->getHeight()), WriterPusher<PanoFrameBuffer>(surface->getWidth(), surface->getHeight(), writers) { setRenderers(renderers); } PanoFrameBuffer* delegate; }; /** * @brief A StereoOutput that writes a stereoscopic frame synchronously to a writer. * * Not thread safe. */ class BlockingStereoOutput : public StitcherOutput<Output::StereoWriter>::Pimpl, StereoWriterPusher { public: static Potential<BlockingStereoOutput> create(std::shared_ptr<PanoSurface> surf, const std::vector<std::shared_ptr<PanoRenderer>>& renderers, const std::vector<std::shared_ptr<Output::StereoWriter>>& writers); virtual ~BlockingStereoOutput() { delete left; delete right; } Status pushVideo(mtime_t date, Eye eye) override; virtual PanoSurface& acquireLeftFrame(mtime_t) override; virtual PanoSurface& acquireRightFrame(mtime_t) override; virtual bool setRenderers(const std::vector<std::shared_ptr<PanoRenderer>>& r) override { return StereoWriterPusher::setRenderers(r); } virtual bool addRenderer(std::shared_ptr<PanoRenderer> r) override { return StereoWriterPusher::addRenderer(r); } virtual bool removeRenderer(const std::string& id) override { return StereoWriterPusher::removeRenderer(id); } virtual bool setWriters(const std::vector<std::shared_ptr<Output::StereoWriter>>& ws) override { return StereoWriterPusher::setWriters(ws); } virtual bool addWriter(std::shared_ptr<Output::StereoWriter> w) override { return StereoWriterPusher::addWriter(w); } virtual bool removeWriter(const std::string& id) override { return StereoWriterPusher::removeWriter(id); } virtual bool updateWriter(const std::string& id, const Ptv::Value& config) override { return StereoWriterPusher::updateWriter(id, config); } protected: BlockingStereoOutput(std::shared_ptr<PanoSurface> surf, const std::vector<std::shared_ptr<PanoRenderer>>& renderers, const std::vector<std::shared_ptr<Output::StereoWriter>>& writers) : Pimpl(surf->getWidth(), surf->getHeight()), StereoWriterPusher(surf->getWidth(), surf->getHeight(), writers) { setRenderers(renderers); } private: StereoFrameBuffer* left; StereoFrameBuffer* right; }; } // namespace Core } // namespace VideoStitch