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