24#include <libavfilter/buffersink.h>
25#include <libavfilter/buffersrc.h>
57 return fail(
"Failed to allocate filter graph",
AVERROR(
ENOMEM));
59 graph_->nb_threads = std::max(1u, std::min(8u, std::thread::hardware_concurrency() / 2));
64 return fail(
"Failed to parse filter graph",
ret);
71 return fail(
"Filters with multiple outputs are not supported",
AVERROR(
ENOTSUP));
73 if ((
ret = initOutputFilter(
outputs.get())) < 0)
74 return fail(
"Failed to create output for filter graph",
ret);
81 if (count !=
msps.size())
83 "Size mismatch between number of inputs in filter graph and input parameter array",
88 return fail(
"Filters require non empty names",
AVERROR(
EINVAL));
89 std::string_view name =
current->name;
91 return msp.name == name;
95 return fail(fmt::format(
"Failed to initialize input: {}", name),
ret);
98 return fail(fmt::format(
"Failed to find matching parameters for: {}", name),
ret);
103 return fail(
"Failed to configure filter graph",
ret);
105 JAMI_DBG() <<
"Filter graph initialized with: " << desc_;
113 for (
const auto& ms : inputParams_)
116 throw std::out_of_range(
"Input '" +
inputName +
"' not found");
123 if (!output_ || !initialized_) {
124 fail(
"Filter not initialized", -1);
130 output.name =
"videoOutput";
140 output.name =
"audioOutput";
159 return fail(
"Filter not initialized", -1);
164 for (
size_t i = 0;
i < inputs_.size(); ++
i) {
165 auto& ms = inputParams_[
i];
169 if (ms.format !=
frame->format
170 || (ms.isVideo && (ms.width !=
frame->width || ms.height !=
frame->height))
172 && (ms.sampleRate !=
frame->sample_rate || ms.nbChannels !=
frame->ch_layout.nb_channels))) {
174 if ((
ret = reinitialize()) < 0)
175 return fail(
"Failed to reinitialize filter with new input parameters",
ret);
180 return fail(
"Unable to pass frame to filters",
ret);
187std::unique_ptr<MediaFrame>
191 fail(
"Not properly initialized", -1);
195 std::unique_ptr<MediaFrame>
frame;
199 frame = std::make_unique<libjami::VideoFrame>();
203 frame = std::make_unique<AudioFrame>();
214 JAMI_WARN() <<
"Filters have reached EOF, no more frames will be output";
216 fail(
"Error occurred while pulling from filter graph",
err);
224 for (
size_t i = 0;
i < inputs_.size(); ++
i) {
227 JAMI_ERR() <<
"Failed to flush filter '" << inputParams_[
i].name
250 return fail(
"Failed to create buffer sink",
ret);
255 return fail(
"Unable to link buffer sink to graph",
ret);
288 snprintf(name,
sizeof(name),
"buffersrc_%s_%d",
in->name,
in->pad_idx);
293 return fail(
"Failed to allocate filter graph input",
AVERROR(
ENOMEM));
298 return fail(
"Failed to set filter graph input parameters",
ret);
301 return fail(
"Failed to initialize buffer source",
ret);
304 return fail(
"Failed to link buffer source to graph",
ret);
307 inputParams_.emplace_back(
msp);
308 inputParams_.back().name =
in->name;
313MediaFilter::reinitialize()
316 auto params = std::move(inputParams_);
317 auto desc = std::move(desc_);
321 JAMI_DBG() <<
"Filter graph reinitialized";
326MediaFilter::fail(std::string_view
msg,
int err)
const
336 initialized_ =
false;
341 inputParams_.clear();
std::string getError(int err)
void emitSignal(Args... args)