[FFmpeg-user] Delay filter reconfiguration

androiddevmar11 androiddevmar11 at gmail.com
Wed Jun 11 13:00:13 CEST 2014


Hello, 
Actually there can be more than two inputs. To be specific, in most typical
scenario I will have one AAC file and more than one video files. I want to
get some frames from specific time stamp of video file and add them to
specific time stamp in AAC file. More than one pieces of audio can be taken
from one video input and added to one or more places in AAC file. I am doing
proof of concept based on this code:
https://gist.github.com/MrArtichaut/11136813. My init_filter_graph function
looks like this:

static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src0,
AVFilterContext **src1,
AVFilterContext **sink)
{
    AVFilterGraph *filter_graph;
    AVFilterContext *abuffer1_ctx;
    AVFilter        *abuffer1;
	AVFilterContext *abuffer0_ctx;
    AVFilter        *abuffer0;
    AVFilterContext *adelay_ctx;
    AVFilter        *adelay;
    AVFilterContext *mix_ctx;
    AVFilter        *mix_filter;
    AVFilterContext *abuffersink_ctx;
    AVFilter        *abuffersink;

	char args[512];

    int err;

    /* Create a new filter graph, which will contain all the filters. */
    filter_graph = avfilter_graph_alloc();
    if (!filter_graph) {
        //av_log(NULL, AV_LOG_ERROR, "Unable to create filter graph.\n");
        LOGE("Unable to create filter graph.\n");
        return AVERROR(ENOMEM);
    }

	/****** abuffer 0 ********/

    /* Create the abuffer filter, it will be used for feeding the data into
the graph. */
    abuffer0 = avfilter_get_by_name("abuffer");
    if (!abuffer0) {
        //av_log(NULL, AV_LOG_ERROR, "Could not find the abuffer
filter.\n");
        LOGE("Could not find the abuffer filter.\n");
        return AVERROR_FILTER_NOT_FOUND;
    }

	/* buffer audio source: the decoded frames from the decoder will be
inserted here. */
    if (!input_codec_context_0->channel_layout)
        input_codec_context_0->channel_layout =
av_get_default_channel_layout(input_codec_context_0->channels);
    		 snprintf(args, sizeof(args),
			 "sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
             input_codec_context_0->sample_rate,
             av_get_sample_fmt_name(input_codec_context_0->sample_fmt),
input_codec_context_0->channel_layout);


	err = avfilter_graph_create_filter(&abuffer0_ctx, abuffer0, "src0",
                                       args, NULL, filter_graph);
    if (err < 0) {
        //av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
        LOGE("Cannot create audio buffer source\n");
        return err;
    }

	/****** abuffer 1 ******* */

	/* Create the abuffer filter;
     * it will be used for feeding the data into the graph. */
    abuffer1 = avfilter_get_by_name("abuffer");
    if (!abuffer1) {
        //av_log(NULL, AV_LOG_ERROR, "Could not find the abuffer
filter.\n");
        LOGE("Could not find the abuffer filter.\n");
        return AVERROR_FILTER_NOT_FOUND;
    }

	/* buffer audio source: the decoded frames from the decoder will be
inserted here. */
    if (!input_codec_context_1->channel_layout)
        input_codec_context_1->channel_layout =
av_get_default_channel_layout(input_codec_context_1->channels);
    	snprintf(args,
sizeof(args),"sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
             input_codec_context_1->sample_rate,
             av_get_sample_fmt_name(input_codec_context_1->sample_fmt),
input_codec_context_1->channel_layout);


	err = avfilter_graph_create_filter(&abuffer1_ctx, abuffer1, "src1",
                                       args, NULL, filter_graph);
    if (err < 0) {
        //av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
    	LOGE("Cannot create audio buffer source\n");
        return err;
    }

    /****** adelay ******* */
    adelay = avfilter_get_by_name("adelay");
    if (!adelay) {
        LOGE("Could not find the adelay filter.\n");
        return AVERROR_FILTER_NOT_FOUND;
    }
	/* buffer audio source: the decoded frames from the decoder will be
inserted here. */
   	snprintf(args, sizeof(args),"delays=%d", 1000);
	err = avfilter_graph_create_filter(&adelay_ctx, adelay, "del1", args, NULL,
filter_graph);

    /* ***** amix ******* */
    /* Create mix filter. */
    mix_filter = avfilter_get_by_name("amix");
    if (!mix_filter) {
        //av_log(NULL, AV_LOG_ERROR, "Could not find the mix filter.\n");
        LOGE("Could not find the mix filter.\n");
        return AVERROR_FILTER_NOT_FOUND;
    }

    snprintf(args, sizeof(args), "inputs=2:duration=shortest");

	err = avfilter_graph_create_filter(&mix_ctx, mix_filter, "amix",
                                       args, NULL, filter_graph);

    if (err < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot create audio amix filter\n");
        LOGE("Cannot create audio amix filter\n");
        return err;
    }

    /* Finally create the abuffersink filter;
     * it will be used to get the filtered data out of the graph. */
    abuffersink = avfilter_get_by_name("abuffersink");
    if (!abuffersink) {
        //av_log(NULL, AV_LOG_ERROR, "Could not find the abuffersink
filter.\n");
        LOGE("Could not find the abuffersink filter.\n");
        return AVERROR_FILTER_NOT_FOUND;
    }

    abuffersink_ctx = avfilter_graph_alloc_filter(filter_graph, abuffersink,
"sink");
    if (!abuffersink_ctx) {
        //av_log(NULL, AV_LOG_ERROR, "Could not allocate the abuffersink
instance.\n");
        LOGE("Could not allocate the abuffersink instance.\n");
        return AVERROR(ENOMEM);
    }

    /* Same sample fmts as the output file. */
    err = av_opt_set_int_list(abuffersink_ctx, "sample_fmts",
                              ((int[]){ SAMPLE_FORMAT, AV_SAMPLE_FMT_NONE
}),
                              AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN);

    uint8_t ch_layout[64];
    av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0,
OUTPUT_CHANNELS);
    av_opt_set    (abuffersink_ctx, "channel_layout", ch_layout,
AV_OPT_SEARCH_CHILDREN);

    if (err < 0) {
        //av_log(NULL, AV_LOG_ERROR, "Could set options to the abuffersink
instance.\n");
        LOGE("Could set options to the abuffersink instance.\n");
        return err;
    }

    err = avfilter_init_str(abuffersink_ctx, NULL);
    if (err < 0) {
        //av_log(NULL, AV_LOG_ERROR, "Could not initialize the abuffersink
instance.\n");
        LOGE("Could not initialize the abuffersink instance.\n");
        return err;
    }


    /* Connect the filters; */
    err = avfilter_link(abuffer0_ctx, 0, adelay_ctx, 0);
	err = avfilter_link(adelay_ctx, 0, mix_ctx, 0);
	if (err >= 0)
        err = avfilter_link(abuffer1_ctx, 0, mix_ctx, 1);
	if (err >= 0)
        err = avfilter_link(mix_ctx, 0, abuffersink_ctx, 0);
    if (err < 0) {
        av_log(NULL, AV_LOG_ERROR, "Error connecting filters\n");
        return err;
    }

    /* Configure the graph. */
    err = avfilter_graph_config(filter_graph, NULL);
    if (err < 0) {
        //av_log(NULL, AV_LOG_ERROR, "Error while configuring graph : %s\n",
get_error_text(err));
        LOGE("Error while configuring graph : %s\n", get_error_text(err));
        return err;
    }

    // ------------------------------------------------
    // reconfigure delay filter:
	avfilter_free(adelay_ctx);

	snprintf(args, sizeof(args),"delays=%d", 2000);
	err = avfilter_graph_create_filter(&adelay_ctx, adelay, "del1", args, NULL,
filter_graph);

    err = avfilter_link(abuffer0_ctx, 0, adelay_ctx, 0);
	err = avfilter_link(adelay_ctx, 0, mix_ctx, 0);
	err = avfilter_graph_config(filter_graph, NULL);
    // ------------------------------------------------

    char* dump = avfilter_graph_dump(filter_graph, NULL);
    //av_log(NULL, AV_LOG_ERROR, "Graph :\n%s\n", dump);
    LOGE("Graph :\n%s\n", dump);

    *graph = filter_graph;
    *src0   = abuffer0_ctx;
	*src1   = abuffer1_ctx;
    *sink  = abuffersink_ctx;

    return 0;
}

Please have a look at "reconfigure delay filter" part. Program crashes at
av_buffersink_get_frame (funciton process_all() from link) giving error:

Execution stopped at: 0x6AEF0400
In thread 1 (OS thread id 2758)
In buffersink.c

You mentioned that using adelay is not optimal. What is the better solution?
Other filter?  Thank you for help.





--
View this message in context: http://ffmpeg-users.933282.n4.nabble.com/Delay-filter-reconfiguration-tp4665727p4665765.html
Sent from the FFmpeg-users mailing list archive at Nabble.com.


More information about the ffmpeg-user mailing list