void FilterContext::link(unsigned srcPad, FilterContext &dstFilter, unsigned dstPad, error_code &ec) { clear_if(ec); if (!m_raw || !dstFilter) { throws_if(ec, Errors::Unallocated); return; } int sts = avfilter_link(m_raw, srcPad, dstFilter.raw(), dstPad); if (sts < 0) { throws_if(ec, sts, ffmpeg_category()); return; } }
void FilterGraph::parse(const string &graphDescription, FilterContext &srcFilterCtx, FilterContext &sinkFilterCtx, error_code &ec) { clear_if(ec); if (!m_raw || !srcFilterCtx || !sinkFilterCtx) { throws_if(ec, Errors::Unallocated); return; } auto srcf = srcFilterCtx.raw(); auto sinkf = sinkFilterCtx.raw(); bool srcfFound = false; bool sinkfFound = false; for (size_t i = 0; i < (size_t)filtersCount(); ++i) { if (m_raw->filters[i] == srcf) srcfFound = true; if (m_raw->filters[i] == sinkf) sinkfFound = true; if (srcfFound && sinkfFound) // search completed break; } if (!srcfFound) { fflog(AV_LOG_ERROR, "Source filter does not present in filter graph"); throws_if(ec, Errors::FilterNotInFilterGraph); return; } if (!sinkfFound) { fflog(AV_LOG_ERROR, "Sink filter does not present in filter graph"); throws_if(ec, Errors::FilterNotInFilterGraph); return; } struct FilterInOutDeleter { void operator()(AVFilterInOut *&ptr) { avfilter_inout_free(&ptr); } }; using FilterInOutPtr = std::unique_ptr<AVFilterInOut, FilterInOutDeleter>; FilterInOutPtr inputs; FilterInOutPtr outputs; if (graphDescription.empty()) { fflog(AV_LOG_ERROR, "Empty graph description"); throws_if(ec, Errors::FilterGraphDescriptionEmpty); return; } else { outputs.reset(avfilter_inout_alloc()); inputs.reset(avfilter_inout_alloc()); if (!outputs || !inputs) { throws_if(ec, errc::not_enough_memory); return; } outputs->name = av_strdup("in"); outputs->filter_ctx = srcFilterCtx.raw(); outputs->pad_idx = 0; outputs->next = 0; inputs->name = av_strdup("out"); inputs->filter_ctx = sinkFilterCtx.raw(); inputs->pad_idx = 0; inputs->next = 0; int sts = avfilter_graph_parse(m_raw, graphDescription.c_str(), inputs.get(), outputs.get(), nullptr); if (sts < 0) { throws_if(ec, sts, ffmpeg_category()); return; } } }