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
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm
#include "libvideostitch/logging.hpp"
#include "libvideostitch/postprocessor.hpp"
#include "libvideostitch/parse.hpp"
#include "libvideostitch/ptv.hpp"
#include <iostream>
#include <memory>
namespace VideoStitch {
namespace Core {
namespace {
/**
* A PostProcessor that just chains several PostProcessors.
*/
class MultiPostProcessor : public PostProcessor {
public:
~MultiPostProcessor() {
for (auto postprocessor = postprocessors.begin(); postprocessor != postprocessors.end(); ++postprocessor) {
delete *postprocessor;
}
}
void add(PostProcessor* postprocessor) { postprocessors.push_back(postprocessor); }
Status process(GPU::Buffer<uint32_t>& devBuffer, const PanoDefinition& pano, frameid_t frame,
GPU::Stream& stream) const {
for (auto postprocessor = postprocessors.begin(); postprocessor != postprocessors.end(); ++postprocessor) {
PROPAGATE_FAILURE_STATUS((*postprocessor)->process(devBuffer, pano, frame, stream));
}
return Status::OK();
}
private:
std::vector<PostProcessor*> postprocessors;
};
} // namespace
Potential<PostProcessor> PostProcessor::create(const Ptv::Value& config) {
// We accept either lists of processors or single objects.
if (config.getType() == Ptv::Value::LIST) {
if (config.asList().size() == 0) {
return {Origin::PostProcessor, ErrType::InvalidConfiguration, "Configuration is empty"};
} else if (config.asList().size() == 1) {
return create(*config.asList()[0]);
} else {
std::unique_ptr<MultiPostProcessor> multiPostprocessor(new MultiPostProcessor());
for (auto subConfig = config.asList().begin(); subConfig != config.asList().end(); ++subConfig) {
Potential<PostProcessor> postprocessor = PostProcessor::create(*(*subConfig));
FAIL_RETURN(postprocessor.status());
multiPostprocessor->add(postprocessor.release());
}
return Potential<PostProcessor>(multiPostprocessor.release());
}
}
if (!Parse::checkType("PostProcessor", config, Ptv::Value::OBJECT)) {
return {Origin::PostProcessor, ErrType::InvalidConfiguration, "Invalid 'PostProcessor' configuration type"};
}
std::string strType;
if (Parse::populateString("PostProcessor", config, "type", strType, true) == Parse::PopulateResult_WrongType) {
return {Origin::PostProcessor, ErrType::InvalidConfiguration,
"Invalid 'PostProcessor' configuration type, expected string"};
}
return {Origin::PostProcessor, ErrType::InvalidConfiguration, "No such PostProcessor: '" + strType + "'"};
}
} // namespace Core
} // namespace VideoStitch