【问题标题】:FFMPEG C++ Volume FilterFFMPEG C++ 音量过滤器
【发布时间】:2020-05-18 23:20:12
【问题描述】:

在 C++ 代码中使用 FFMPEG 音频过滤器似乎有点麻烦。如果我只有“abuffer”和“abuffersink”过滤器,并从过滤器图中抓取音频帧,那听起来很完美。一旦我在图中添加了另一个过滤器(在这种情况下,它是一个“音量”过滤器),就会引入很多噪声。我不知道是什么原因造成的。

all 过滤器并非如此 - 例如,“aecho”可以正常工作。有什么想法吗?以下是相关代码:

过滤器创建

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 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

【问题讨论】:

    标签: c++ audio ffmpeg


    【解决方案1】:

    我想通了。它默认为“浮点”精度,所以如果格式是固定的,我必须添加以下内容:

    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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 2015-09-18
      • 1970-01-01
      • 1970-01-01
      • 2019-05-16
      • 2018-06-27
      • 2020-01-16
      相关资源
      最近更新 更多