static int init_filters(const char *filters_descr) { char args[512]; int ret; AVFilter *buffersrc = avfilter_get_by_name("buffer"); AVFilter *buffersink = avfilter_get_by_name("ffbuffersink"); AVFilterInOut *outputs = avfilter_inout_alloc(); AVFilterInOut *inputs = avfilter_inout_alloc(); enum PixelFormat pix_fmts[] = { PIX_FMT_BGRA, PIX_FMT_NONE }; AVBufferSinkParams *buffersink_params; filter_graph = avfilter_graph_alloc(); /* buffer video source: the decoded frames from the decoder will be inserted here. */ snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, fmt_ctx->streams[video_stream_index]->time_base.num, fmt_ctx->streams[video_stream_index]->time_base.den, dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den); ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", args, NULL, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n"); return ret; } /* buffer video sink: to terminate the filter chain. */ buffersink_params = av_buffersink_params_alloc(); buffersink_params->pixel_fmts = pix_fmts; ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", NULL, buffersink_params, filter_graph); av_free(buffersink_params); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n"); return ret; } /* Endpoints for the filter graph. */ outputs->name = av_strdup("in"); outputs->filter_ctx = buffersrc_ctx; outputs->pad_idx = 0; outputs->next = NULL; inputs->name = av_strdup("out"); inputs->filter_ctx = buffersink_ctx; inputs->pad_idx = 0; inputs->next = NULL; if ((ret = avfilter_graph_parse(filter_graph, filters_descr, &inputs, &outputs, NULL)) < 0) return ret; if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) return ret; return 0; }
JNIEXPORT jint JNICALL Java_org_jitsi_impl_neomedia_codec_FFmpeg_avfilter_1graph_1parse (JNIEnv *env, jclass clazz, jlong graph, jstring filters, jlong inputs, jlong outputs, jlong log_ctx) { const char *filters_ = (*env)->GetStringUTFChars(env, filters, NULL); int ret; if (filters_) { AVFilterGraph *graph_ = (AVFilterGraph *) (intptr_t) graph; ret = avfilter_graph_parse( graph_, filters_, (AVFilterInOut **) (intptr_t) inputs, (AVFilterInOut **) (intptr_t) outputs, (AVClass *) (intptr_t) log_ctx); /* * FIXME The implementation at the time of this writing presumes that * the first filter is buffer, the last filter is nullsink meant to be * ffsink and the ffsink is expected to output in the format in which * the buffer inputs. */ if (0 == ret) { /* Turn nullsink into ffsink. */ unsigned filterCount = graph_->filter_count; if (filterCount) { AVFilterContext *ffsink = graph_->filters[filterCount - 1]; /* * Make sure query_format of ffsink outputs in the format in * which buffer inputs. Otherwise, the output format may end up * different on the C and Java sides. */ ffsink->filter->uninit = ffsink_uninit; ffsink->priv = NULL; ffsink->filter->query_formats = ffsink_query_formats; ffsink->input_pads->end_frame = ffsink_end_frame; ffsink->input_pads->min_perms = AV_PERM_READ; ffsink->input_pads->start_frame = NULL; } } (*env)->ReleaseStringUTFChars(env, filters, filters_); } else ret = AVERROR(ENOMEM); return (jint) ret; }
void configure_filtergraph( AVFilterGraph& graph, const std::string& filtergraph, AVFilterContext& source_ctx, AVFilterContext& sink_ctx) { AVFilterInOut* outputs = nullptr; AVFilterInOut* inputs = nullptr; try { if(!filtergraph.empty()) { outputs = avfilter_inout_alloc(); inputs = avfilter_inout_alloc(); CASPAR_VERIFY(outputs && inputs); outputs->name = av_strdup("in"); outputs->filter_ctx = &source_ctx; outputs->pad_idx = 0; outputs->next = nullptr; inputs->name = av_strdup("out"); inputs->filter_ctx = &sink_ctx; inputs->pad_idx = 0; inputs->next = nullptr; FF(avfilter_graph_parse( &graph, filtergraph.c_str(), inputs, outputs, nullptr)); } else { FF(avfilter_link( &source_ctx, 0, &sink_ctx, 0)); } FF(avfilter_graph_config( &graph, nullptr)); } catch(...) { avfilter_inout_free(&outputs); avfilter_inout_free(&inputs); throw; } }
int init_filters(const char *filters_descr, const AVCodecContext *dec_ctx) { char args[512]; int ret; AVFilter *buffersrc = avfilter_get_by_name("buffer"); AVFilter *buffersink = avfilter_get_by_name("buffersink"); AVFilterInOut *outputs = avfilter_inout_alloc(); AVFilterInOut *inputs = avfilter_inout_alloc(); enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_GRAY8, PIX_FMT_NONE }; filter_graph = avfilter_graph_alloc(); /* buffer video source: the decoded frames from the decoder will be inserted here. */ snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den); ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", args, NULL, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n"); return ret; } /* buffer video sink: to terminate the filter chain. */ ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", NULL, pix_fmts, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n"); return ret; } /* Endpoints for the filter graph. */ outputs->name = av_strdup("in"); outputs->filter_ctx = buffersrc_ctx; outputs->pad_idx = 0; outputs->next = NULL; inputs->name = av_strdup("out"); inputs->filter_ctx = buffersink_ctx; inputs->pad_idx = 0; inputs->next = NULL; if ((ret = avfilter_graph_parse(filter_graph, filters_descr, &inputs, &outputs, NULL)) < 0) return ret; if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) return ret; }
int main(int argc, char **argv) { const char *outfilename = NULL; const char *infilename = NULL; FILE *outfile = NULL; FILE *infile = NULL; char *graph_string = NULL; AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph)); char c; av_log_set_level(AV_LOG_DEBUG); while ((c = getopt(argc, argv, "hi:o:")) != -1) { switch (c) { case 'h': usage(); return 0; case 'i': infilename = optarg; break; case 'o': outfilename = optarg; break; case '?': return 1; } } if (!infilename || !strcmp(infilename, "-")) infilename = "/dev/stdin"; infile = fopen(infilename, "r"); if (!infile) { fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno)); return 1; } if (!outfilename || !strcmp(outfilename, "-")) outfilename = "/dev/stdout"; outfile = fopen(outfilename, "w"); if (!outfile) { fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno)); return 1; } /* read from infile and put it in a buffer */ { unsigned int count = 0; struct line *line, *last_line, *first_line; char *p; last_line = first_line = av_malloc(sizeof(struct line)); while (fgets(last_line->data, sizeof(last_line->data), infile)) { struct line *new_line = av_malloc(sizeof(struct line)); count += strlen(last_line->data); last_line->next = new_line; last_line = new_line; } last_line->next = NULL; graph_string = av_malloc(count + 1); p = graph_string; for (line = first_line; line->next; line = line->next) { unsigned int l = strlen(line->data); memcpy(p, line->data, l); p += l; } *p = '\0'; } avfilter_register_all(); if (avfilter_graph_parse(graph, graph_string, NULL, NULL, NULL) < 0) { fprintf(stderr, "Impossible to parse the graph description\n"); return 1; } if (avfilter_graph_config(graph, NULL) < 0) return 1; print_digraph(outfile, graph); fflush(outfile); return 0; }
static int lavfi_open(struct vf_instance *vf, char *args) { AVFilterInOut *outputs; AVFilterInOut *inputs; int ret; avfilter_register_all(); if (!args) { mp_msg(MSGT_VFILTER, MSGL_ERR, "lavfi: filtergraph needed\n"); goto fail; } if (args[0] == '$') { char *e = getenv(args + 1); if (!e) { mp_msg(MSGT_VFILTER, MSGL_ERR, "lavfi: %s not defined\n", args); goto fail; } args = e; } vf->priv = av_mallocz(sizeof(struct vf_priv_s)); if (!vf->priv) return 0; vf->priv->graph = avfilter_graph_alloc(); if (!vf->priv->graph) goto fail; ret = avfilter_graph_create_filter(&vf->priv->in, &mpsrc, "in", NULL, vf, vf->priv->graph); if (ret < 0) goto fail; ret = avfilter_graph_create_filter(&vf->priv->out, &mpsink, "out", NULL, vf, vf->priv->graph); if (ret < 0) return 0; outputs = avfilter_inout_alloc(); inputs = avfilter_inout_alloc(); if (!outputs || !inputs) goto fail; outputs->name = av_strdup("in"); outputs->filter_ctx = vf->priv->in; outputs->pad_idx = 0; outputs->next = NULL; inputs->name = av_strdup("out"); inputs->filter_ctx = vf->priv->out; inputs->pad_idx = 0; inputs->next = NULL; ret = avfilter_graph_parse(vf->priv->graph, args, &inputs, &outputs, NULL); if (ret < 0) goto fail; vf->config = config; vf->uninit = uninit; vf->put_image = put_image; vf->get_image = get_image; return 1; fail: avfilter_inout_free(&inputs); avfilter_inout_free(&outputs); avfilter_graph_free(&vf->priv->graph); av_free(vf->priv); return 0; }
static int init_filters(const char *filters_descr) { char args[512]; int ret; AVFilter *abuffersrc = avfilter_get_by_name("abuffer"); AVFilter *abuffersink = avfilter_get_by_name("abuffersink"); AVFilterInOut *outputs = avfilter_inout_alloc(); AVFilterInOut *inputs = avfilter_inout_alloc(); const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 }; AVABufferSinkParams *abuffersink_params; const AVFilterLink *outlink; AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base; filter_graph = avfilter_graph_alloc(); /* buffer audio source: the decoded frames from the decoder will be inserted here. */ if (!dec_ctx->channel_layout) dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels); snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64, time_base.num, time_base.den, dec_ctx->sample_rate, av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout); ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in", args, NULL, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n"); return ret; } /* buffer audio sink: to terminate the filter chain. */ abuffersink_params = av_abuffersink_params_alloc(); abuffersink_params->sample_fmts = sample_fmts; ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "out", NULL, abuffersink_params, filter_graph); av_free(abuffersink_params); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n"); return ret; } /* Endpoints for the filter graph. */ outputs->name = av_strdup("in"); outputs->filter_ctx = buffersrc_ctx; outputs->pad_idx = 0; outputs->next = NULL; inputs->name = av_strdup("out"); inputs->filter_ctx = buffersink_ctx; inputs->pad_idx = 0; inputs->next = NULL; if ((ret = avfilter_graph_parse(filter_graph, filters_descr, &inputs, &outputs, NULL)) < 0) return ret; if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) return ret; /* Print summary of the sink buffer * Note: args buffer is reused to store channel layout string */ outlink = buffersink_ctx->inputs[0]; av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout); av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n", (int)outlink->sample_rate, (char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"), args); return 0; }
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; } } }