--- /dev/null
+#include"simp.h"
+
+static int _init_filters(simp_filter_t* f, const char* vfilters_descr, const char* afilters_descr)
+{
+ char args[512];
+ int ret = 0;
+
+ const AVFilter *buffersrc = avfilter_get_by_name("buffer");
+ const AVFilter *buffersink = avfilter_get_by_name("buffersink");
+ const AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
+ const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
+
+ AVFilterInOut *voutputs = NULL;
+ AVFilterInOut *vinputs = NULL;
+ AVFilterInOut *aoutputs = NULL;
+ AVFilterInOut *ainputs = NULL;
+ AVFilterInOut *tmp = NULL;
+
+ f->vgraph = avfilter_graph_alloc();
+ if (!f->vgraph) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ f->agraph = avfilter_graph_alloc();
+ if (!f->agraph) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ simp_avio_t* io;
+ scf_list_t* l;
+
+ int n = 0;
+ for (l = scf_list_head(&f->inputs); l !=scf_list_sentinel(&f->inputs); l = scf_list_next(l))
+ {
+ io = scf_list_data(l, simp_avio_t, list);
+
+ if (io->width > 0 && io->height > 0 && io->vopen) {
+
+ snprintf(args, sizeof(args),
+ "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
+ io->width, io->height, io->pix_fmt,
+ io->frame_rate.num, io->frame_rate.den,
+ io->sample_aspect_ratio.num, io->sample_aspect_ratio.den);
+
+ ret = avfilter_graph_create_filter(&io->vbuffersrc_ctx, buffersrc, "in", args, NULL, f->vgraph);
+ if (ret < 0)
+ goto end;
+
+ tmp = avfilter_inout_alloc();
+ if (!tmp) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ tmp->name = av_strdup("in");
+ tmp->filter_ctx = io->vbuffersrc_ctx;
+ tmp->pad_idx = n;
+
+ tmp->next = voutputs;
+ voutputs = tmp;
+ }
+
+ if (io->sample_rate > 0 && io->channels > 0 && io->aopen) {
+
+ snprintf(args, sizeof(args),
+ "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
+ io->sample_rate.num, io->sample_rate.den,
+ io->sample_rate.den /io->sample_rate.num,
+ av_get_sample_fmt_name(io->sample_fmt),
+ av_get_default_channel_layout(io->channel_layout));
+
+ ret = avfilter_graph_create_filter(&io->abuffersrc_ctx, abuffersrc, "in", args, NULL, f->agraph);
+ if (ret < 0)
+ goto end;
+
+ tmp = avfilter_inout_alloc();
+ if (!tmp) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ tmp->name = av_strdup("in");
+ tmp->filter_ctx = io->abuffersrc_ctx;
+ tmp->pad_idx = n;
+
+ tmp->next = aoutputs;
+ aoutputs = tmp;
+ }
+
+ n++;
+ }
+
+ const enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE};
+ const enum AVSampleFormat sample_fmts[] = {AV_SAMPLE_FMT_S16, -1};
+ const int sample_rates[] = {44100, -1 };
+ const int64_t layouts[] = {AV_CH_LAYOUT_STEREO, -1};
+
+ ret = avfilter_graph_create_filter(&f->vbuffersink_ctx, buffersink, "out", NULL, NULL, f->vgraph);
+ if (ret < 0)
+ goto end;
+
+ ret = av_opt_set_int_list(f->vbuffersink_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0)
+ goto end;
+
+ vinputs = avfilter_inout_alloc();
+ if (!vinputs) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ vinputs->name = av_strdup("out");
+ vinputs->filter_ctx = f->vbuffersink_ctx;
+ vinputs->pad_idx = 0;
+ vinputs->next = NULL;
+
+ if ((ret = avfilter_graph_parse_ptr(f->vgraph, vfilters_descr, &vinputs, &voutputs, NULL)) < 0)
+ goto end;
+
+ if ((ret = avfilter_graph_config(f->vgraph, NULL)) < 0)
+ goto end;
+
+ ret = avfilter_graph_create_filter(&f->abuffersink_ctx, abuffersink, "out", NULL, NULL, f->agraph);
+ if (ret < 0)
+ goto end;
+
+ ainputs = avfilter_inout_alloc();
+ if (!ainputs) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ ainputs->name = av_strdup("out");
+ ainputs->filter_ctx = f->abuffersink_ctx;
+ ainputs->pad_idx = 0;
+ ainputs->next = NULL;
+
+ ret = av_opt_set_int_list(f->abuffersink_ctx, "sample_fmts", sample_fmts, -1, AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0)
+ goto end;
+
+ ret = av_opt_set_int_list(f->abuffersink_ctx, "channel_layouts", layouts, -1, AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0)
+ goto end;
+
+ ret = av_opt_set_int_list(f->abuffersink_ctx, "sample_rates", sample_rates, -1, AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0)
+ goto end;
+
+ if ((ret = avfilter_graph_parse_ptr(f->agraph, afilters_descr, &ainputs, &aoutputs, NULL)) < 0)
+ goto end;
+
+ if ((ret = avfilter_graph_config(f->agraph, NULL)) < 0)
+ goto end;
+
+end:
+ avfilter_inout_free(&vinputs);
+ avfilter_inout_free(&voutputs);
+ avfilter_inout_free(&ainputs);
+ avfilter_inout_free(&aoutputs);
+ return ret;
+}
+
+int simp_filter_open(simp_filter_t** pf)
+{
+ simp_filter_t* f = calloc(1, sizeof(simp_filter_t));
+ if (!f)
+ return -ENOMEM;
+
+ scf_list_init(&f->inputs);
+ scf_list_init(&f->outputs);
+ return 0;
+}
+
+int simp_filter_close(simp_filter_t* f)
+{
+ scf_loge("\n");
+ return -1;
+}
+
+int simp_filter_run(simp_filter_t* f)
+{
+
+}
+
+int simp_filter_add_input(simp_filter_t* f, simp_avio_t* input)
+{
+ if (f && input) {
+ scf_list_add_tail(&f->inputs, input);
+ return 0;
+ }
+
+ scf_loge("\n");
+ return -1;
+}
+
+int simp_filter_add_output(simp_filter_t* f, simp_avio_t* output)
+{
+ if (f && output) {
+ scf_list_add_tail(&f->outputs, output);
+ return 0;
+ }
+
+ scf_loge("\n");
+ return -1;
+}
+