Esempio n. 1
0
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;
}
Esempio n. 3
0
	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;
		}
	}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
        }
    }
}