简体   繁体   English

FFMPEG C++ 容积过滤器

[英]FFMPEG C++ Volume Filter

I seem to be having a bit of trouble using FFMPEG audio filters in C++ code.在 C++ 代码中使用 FFMPEG 音频过滤器似乎有点麻烦。 If I only have "abuffer" and "abuffersink" filters, and grab the audio frame from the filtergraph, it sounds perfect.如果我只有“abuffer”和“abuffersink”过滤器,并从过滤器图中抓取音频帧,那听起来很完美。 Once I add another filter into the graph (in this case, it's a "volume" filter), there is a lot of noise introduced.一旦我在图中添加了另一个过滤器(在这种情况下,它是一个“音量”过滤器),就会引入很多噪声。 I can't figure out what would be causing this.我不知道是什么原因造成的。

This isn't the case for all filters - "aecho" works just fine, for example.并非所有过滤器都是这种情况——例如,“aecho”工作得很好。 Any thoughts?有什么想法吗? Here's the relevant code:以下是相关代码:

Filter Creation过滤器创建

char args[512];
int ret = 0;

_filterGraph = avfilter_graph_alloc();

// abuffer must be the first filter used -- it feeds data into the filter graph
/******************
ABUFFER FILTER
*******************/
_abufferFilter = avfilter_get_by_name("abuffer");

/*buffer audio source : decoded frames will be
inserted here. */
if (!_inAudioCodecContext->channel_layout)
{
    _inAudioCodecContext->channel_layout = av_get_default_channel_layout(_inAudioStream->codec->channels);
}

snprintf(args, sizeof(args),
    "sample_rate=%d:sample_fmt=%s:channel_layout=0x%" PRIx64,
    _inAudioCodecContext->sample_rate,
    av_get_sample_fmt_name(_inAudioCodecContext->sample_fmt),
    _inAudioCodecContext->channel_layout);

ret = avfilter_graph_create_filter(&_abufferFilterCtx, _abufferFilter, "abuffer", args, NULL, _filterGraph);
char *errorCode = new char[256];
av_strerror(ret, errorCode, 256);

/******************
VOLUME FILTER
*******************/
snprintf(args, sizeof(args),
    "%f",
    2.0f);
_volumeFilter = avfilter_get_by_name("volume");
ret = avfilter_graph_create_filter(&_volumeFilterCtx, _volumeFilter, "volume", args, NULL, _filterGraph);
char *errorCode = new char[256];
av_strerror(ret, errorCode, 256);

/******************
ABUFFERSINK FILTER
*******************/
// abuffersink must be the last filter used -- it gets data out of the filter graph
_abuffersinkFilter = avfilter_get_by_name("abuffersink");
ret = avfilter_graph_create_filter(&_abufferSinkFilterCtx, _abuffersinkFilter, "abuffersink", NULL, NULL, _filterGraph);

// Link the source buffer to the volume filter
// If I link this to the sink buffer and comment out the next line
// Audio sounds perfect
ret = avfilter_link(_abufferFilterCtx, 0, _volumeFilterCtx, 0);
// Link the volume filter to the sink buffer
ret = avfilter_link(_volumeFilterCtx, 0, _abufferSinkFilterCtx, 0);
ret = avfilter_graph_config(_filterGraph, NULL);

return ret;

Read frames from buffer从缓冲区读取帧

// Read a frame from the audio stream/file
ret = av_read_frame(_inFormatContext, &_packet);
int frameFinished = 0;
// Decode the resulting packet into a single frame for processing
int length = avcodec_decode_audio4(_inAudioCodecContext, _audioFrame, &frameFinished, &_packet);

if (frameFinished)
{
    // Insert the frame into the source filter
    ret = av_buffersrc_write_frame(_abufferFilterCtx, _audioFrame);
    while (true)
    {
        // Pull a frame from the filter graph
        ret = av_buffersink_get_frame(_abufferSinkFilterCtx, _audioFrame);

        // EOF or EAGAIN is expected when filtering frames, set the error to "0"
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
        {
            ret = 0;
            break;
        }
        if (ret < 0)
        {
            break;
        }
    }

    // This keeps going, doing some resampling and conversion based on codec output selection, but that isn't relevant to the issue

I figured this out.我想通了。 It was defaulting to "float" precision, so I had to add the following if the format was fixed:它默认为“浮点”精度,所以如果格式是固定的,我必须添加以下内容:

snprintf(args, sizeof(args),
    "volume=%f:precision=fixed",
    1.0f);
_volumeFilter = avfilter_get_by_name("volume");
ret = avfilter_graph_create_filter(&_volumeFilterCtx, _volumeFilter, "volume", args, NULL, _filterGraph);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM