Невозможно передать параметры в секундах в звуковой фильтр FFMpeg. - PullRequest
0 голосов
/ 18 октября 2019

Я пытаюсь использовать неадекватный фильтр FFmpeg, и он не работает должным образом. Я не могу передать параметры запуска и длительности в секундах. С этой строкой:

afilter=afade=t=out:st=1:d=0:curve=par

мой фильтр исчезает с самого первого кадра. Поэтому у меня нет звука ни в первом, ни в любом другом кадре. Но если я установлю магическое число 208 в качестве времени начала затухания:

afilter=afade=t=out:st=208:d=0:curve=par

, оно начнет работать через 1 секунду (RMS превращается в бесконечность при затухании):

...
Frame=0.501 Samples=23543 RMS=-35.186275
Frame=0.535 Samples=25014 RMS=-37.393734
Frame=0.568 Samples=26486 RMS=-40.655666
Frame=0.602 Samples=27957 RMS=-38.321899
Frame=0.635 Samples=29429 RMS=-41.370567
Frame=0.669 Samples=30900 RMS=-39.316444
Frame=0.702 Samples=32372 RMS=-27.994545
Frame=0.735 Samples=33843 RMS=-23.577181
Frame=0.769 Samples=35315 RMS=-22.933538
Frame=0.802 Samples=36786 RMS=-25.900106
Frame=0.836 Samples=38258 RMS=-26.836918
Frame=0.869 Samples=39729 RMS=-29.685308
Frame=0.902 Samples=41201 RMS=-32.493404
Frame=0.936 Samples=42672 RMS=-32.552109
Frame=0.969 Samples=44144 RMS=-42.384045
Frame=1.003 Samples=45615 RMS=-inf
Frame=1.036 Samples=47087 RMS=-inf
Frame=1.070 Samples=48558 RMS=-inf
Frame=1.103 Samples=50029 RMS=-inf
Frame=1.136 Samples=51501 RMS=-inf
Frame=1.170 Samples=52972 RMS=-inf
Frame=1.203 Samples=54444 RMS=-inf
Frame=1.237 Samples=55915 RMS=-inf
Frame=1.270 Samples=57387 RMS=-inf
Frame=1.304 Samples=58858 RMS=-inf
Frame=1.337 Samples=60330 RMS=-inf
Frame=1.370 Samples=61801 RMS=-inf
Frame=1.404 Samples=63273 RMS=-inf
Frame=1.437 Samples=64744 RMS=-inf
Frame=1.471 Samples=66216 RMS=-inf
Frame=1.504 Samples=67687 RMS=-inf

Похоже, мне нужно умножить время запуска в секундах на этот странный коэффициент 208 (я нашел это значение экспериментально для частоты дискретизации 44100 Гц). То же самое с параметром длительности. Чтобы установить длительность N секунд, я должен передать N * 208 в качестве параметра. Для других частот выборки этот коэффициент изменяется.

Так что, возможно, что-то не так с моей инициализацией графа фильтра?

Это мой код для инициализации графа фильтра (почти скопированный из некоторого примера):

int _InitFilterGraph(const char *_pszFilterDesc, AVFrame* _pFrame, AVRational* _pTimeBase)
{
    const AVFilter *pBufferSrc = avfilter_get_by_name( "abuffer" );
    const AVFilter *pBufferSink = avfilter_get_by_name( "abuffersink" );
    AVFilterInOut *pOutputs = avfilter_inout_alloc();
    AVFilterInOut *pInputs = avfilter_inout_alloc();

    AVSampleFormat out_sample_fmts[] = { (AVSampleFormat)_pFrame->format, (AVSampleFormat)-1 };
    int64_t out_channel_layouts[] = { (int64_t)_pFrame->channel_layout, -1 };
    int out_sample_rates[] = { _pFrame->sample_rate, -1 };

    m_pFilterGraph = avfilter_graph_alloc();

    // Buffer audio source: the decoded frames from the decoder will be inserted here.
    char args[512] = {};
    snprintf( args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%llx",
        _pTimeBase->num, _pTimeBase->den,
        _pFrame->sample_rate, av_get_sample_fmt_name( (AVSampleFormat)_pFrame->format ),
        _pFrame->channel_layout );

    int nRet = avfilter_graph_create_filter( &m_pBufferSrcCtx, pBufferSrc, "in",
        args, NULL, m_pFilterGraph );
    if( nRet < 0 ) goto final;

    // Buffer audio sink: to terminate the filter chain.
    AVABufferSinkParams *pBufferSinkParams = av_abuffersink_params_alloc();
    pBufferSinkParams->all_channel_counts = _pFrame->channels;

    nRet = avfilter_graph_create_filter( &m_pBufferSinkCtx, pBufferSink, "out",
        NULL, pBufferSinkParams, m_pFilterGraph );
    av_free( pBufferSinkParams );
    if( nRet < 0 ) goto final;

    nRet = av_opt_set_int_list( m_pBufferSinkCtx, "sample_fmts", out_sample_fmts, -1,
        AV_OPT_SEARCH_CHILDREN );
    if( nRet < 0 ) goto final;

    nRet = av_opt_set_int_list( m_pBufferSinkCtx, "channel_layouts", out_channel_layouts, -1,
        AV_OPT_SEARCH_CHILDREN );
    if( nRet < 0 ) goto final;

    nRet = av_opt_set_int_list( m_pBufferSinkCtx, "sample_rates", out_sample_rates, -1,
        AV_OPT_SEARCH_CHILDREN );
    if( nRet < 0 ) goto final;

    // Endpoints for the filter graph.
    pOutputs->name          = av_strdup( "in" );
    pOutputs->filter_ctx    = m_pBufferSrcCtx;
    pOutputs->pad_idx       = 0;
    pOutputs->next          = NULL;

    pInputs->name           = av_strdup( "out" );
    pInputs->filter_ctx     = m_pBufferSinkCtx;
    pInputs->pad_idx        = 0;
    pInputs->next           = NULL;

    nRet = avfilter_graph_parse_ptr( m_pFilterGraph, _pszFilterDesc, &pInputs, &pOutputs, NULL );
    if( nRet < 0 ) goto final;

    nRet = avfilter_graph_config( m_pFilterGraph, NULL );

final:
    avfilter_inout_free( &pInputs );
    avfilter_inout_free( &pOutputs );

    return nRet;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...