1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// 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