jeudi 28 février 2019

unable to create FFMpeg filters via c++ application

I am trying to follow ffmpeg filter_audio.c example .

i am constructing the filter graph as below, but not able to get volume level after processing , silence filter working well but not volumedetect filter.

int Filter :: audio_filter_init(AVCodecContext *aCodecctx)
{

        AVCodecContext  *aCodecCtx = aCodecctx;
    char ch_layout[64];
    int err;

    //AVRational time_base = pFormatCtx->streams[audioindex]->time_base; 
        AVRational time_base = aCodecctx->time_base;  
    /* Create a new filtergraph, which will contain all the filters. */
    filter_graph = avfilter_graph_alloc();
    if (!filter_graph) {
        fprintf(stderr, "Unable to create filter graph.\n");
        return AVERROR(ENOMEM);
    }

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

    abuffer_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "src");
    if (!abuffer_ctx) {
        fprintf(stderr, "Could not allocate the abuffer instance.\n");
        return AVERROR(ENOMEM);
    }


    if (!aCodecCtx->channel_layout)
        aCodecCtx->channel_layout = av_get_default_channel_layout(aCodecCtx->channels);


    /* Set the filter options through the AVOptions API. */
    av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, aCodecCtx->channel_layout);    
    av_opt_set    (abuffer_ctx, "channel_layout",ch_layout , AV_OPT_SEARCH_CHILDREN);
    av_opt_set    (abuffer_ctx, "sample_fmt",     av_get_sample_fmt_name(aCodecCtx->sample_fmt), AV_OPT_SEARCH_CHILDREN);
    av_opt_set_q  (abuffer_ctx, "time_base",      (AVRational){ 1, aCodecCtx->sample_rate},  AV_OPT_SEARCH_CHILDREN);
    av_opt_set_int(abuffer_ctx, "sample_rate",    aCodecCtx->sample_rate, AV_OPT_SEARCH_CHILDREN);

    /* Now initialize the filter; we pass NULL options, since we have already
     * set all the options above. */
    err = avfilter_init_str(abuffer_ctx, NULL);
    if (err < 0) {
        fprintf(stderr, "Could not initialize the abuffer filter.\n");
        return err;
    }

    silence = avfilter_get_by_name("silencedetect");

    if (!silence) {
        fprintf(stderr, "Could not find the silencedetect filter.\n");
        return AVERROR_FILTER_NOT_FOUND;
    }
    silent_ctx = avfilter_graph_alloc_filter(filter_graph, silence, "silencedetect");
    if (!silent_ctx) {
        fprintf(stderr, "Could not allocate the silencedetect instance.\n");
        return AVERROR(ENOMEM);
    }

    av_opt_set_dict_val (silent_ctx, "duration", (const AVDictionary*)AV_STRINGIFY(5),0);
    av_opt_set_dict_val (silent_ctx, "noise",  (const AVDictionary*)AV_STRINGIFY(-30db),0); 
    err = avfilter_init_str(silent_ctx, NULL);
    if (err < 0) {
        fprintf(stderr, "Could not initialize the silencedetect filter.\n");
        return err;
    }

        std::cout << "volume" << std::endl;
    volumedet = avfilter_get_by_name("volumedetect");
    if (!volumedet) {
        fprintf(stderr, "Could not find the volumedetect filter.\n");
        return AVERROR_FILTER_NOT_FOUND;
    } 
    volume_ctx = avfilter_graph_alloc_filter(filter_graph, volumedet, "volumedetect");
    if (!volume_ctx) {
        fprintf(stderr, "Could not allocate the volumedetect instance.\n");
        return AVERROR(ENOMEM);
    }
    /* 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) {
        fprintf(stderr, "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) {
        fprintf(stderr, "Could not allocate the abuffersink instance.\n");
        return AVERROR(ENOMEM);
    }
    /* This filter takes no options. */
    err = avfilter_init_str(abuffersink_ctx, NULL);
    if (err < 0) {
        fprintf(stderr, "Could not initialize the abuffersink instance.\n");
        return err;
    }
    /* Connect the filters;
     * in this simple case the filters just form a linear chain. */
    err = avfilter_link(abuffer_ctx, 0, silent_ctx, 0);    
    if (err >= 0)
        err = avfilter_link(abuffer_ctx, 0, volume_ctx, 0);
    if (err >= 0)
        err = avfilter_link(volume_ctx, 0, abuffersink_ctx, 0);    
    if (err < 0) {
        fprintf(stderr, "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 configuring the filter graph\n");
        return err;
    }

        return 0;

}



below information i am getting in vprintf tb:1/44100 samplefmt:fltp samplerate:44100 chlayout:stereo auto-inserting filter 'auto_resampler_0' between the filter 'src' and the filter 'volumedetect' query_formats: 4 queried, 6 merged, 3 already done, 0 delayed Using fltp internally between filters ch:2 chl:stereo fmt:fltp r:44100Hz -> ch:2 chl:stereo fmt:s16 r:44100Hz Using fltp internally between filters

can someone help to detect volume level

Aucun commentaire:

Enregistrer un commentaire