FFMpeg:从AV_SAMPLE_FMT_S16到AV_SAMPLE_FMT_FLTP的重新采样将比特率除以2

FFMpeg: Resampling from AV_SAMPLE_FMT_S16 to AV_SAMPLE_FMT_FLTP divides bitrate by 2

本文关键字:SAMPLE AV FMT 采样 比特率 S16 FLTP FFMpeg 新采样      更新时间:2023-10-16

我对FFMpeg非常陌生,目前正在尝试将音频数据从PCM AV_SAMPLE_FMT_S16格式转换为Mp3 AV_SAMPLE_FMT_FLTP格式。

为此,我使用来自FFMpeg 的AudioResampleContext

            av_opt_set_int( audioResampleCtx, "in_sample_fmt",     m_aplayer->aCodecCtx->sample_fmt, 0);
            av_opt_set_int( audioResampleCtx, "in_sample_rate",    m_aplayer->aCodecCtx->sample_rate, 0);
            av_opt_set_int( audioResampleCtx, "in_channels",       m_aplayer->aCodecCtx->channels,0);
            av_opt_set_int( audioResampleCtx, "out_channel_layout", audioCodecCtx->channel_layout, 0);
            av_opt_set_int( audioResampleCtx, "out_sample_fmt",     audioCodecCtx->sample_fmt, 0);
            av_opt_set_int( audioResampleCtx, "out_sample_rate",    audioCodecCtx->sample_rate, 0);
            av_opt_set_int( audioResampleCtx, "out_channels",       audioCodecCtx->channels, 0);

转换效果很好,因为我可以听我的mp3文件,但问题是我的原始文件长60秒,输出的mp3文件只有34秒。我能听到它被加速了,就像有什么东西加速了声音一样。当用FFMpeg查找信息时,我发现比特率刚刚从128kbps上升到64kbps。

编辑:为了完成更多信息,我想用mp3编解码器压缩一些原始音频数据,并使用output.mp3输出格式。原始音频数据采样格式为AV_sample_FMT_S16,mp3编解码器支持的采样格式为FLTP(或S16P)。因此,我正在进行从AV_sample_FMT_S16到AV_sample_FMT_FLTP的示例格式转换,但它缺少一半的数据。

有人能帮我吗?我知道我错过了一些非常简单的东西,但我就是不知道是什么。

编辑:2以下是执行重新采样的代码(即将fromhttps://github.com/martin-steghoefer/debian-karlyriceditor/blob/master/src/ffmpegvideoencoder.cpp)。音频源不是AVFrame,而是一个字节数组:

    // Resample the input into the audioSampleBuffer until we proceed the whole decoded data
    if ( (err = avresample_convert( audioResampleCtx,
                                    NULL,
                                    0,
                                    0,
                                    audioFrame->data,
                                    0,
                                    audioFrame->nb_samples )) < 0 )
    {
        qWarning( "Error resampling decoded audio: %d", err );
        return -1;
    }
    if( avresample_available( audioResampleCtx ) >= audioFrame->nb_samples )
    {
        // Read a frame audio data from the resample fifo
        if ( avresample_read( audioResampleCtx, audioFrame->data, audioFrame->nb_samples ) != audioFrame->nb_samples )
        {
            qWarning( "Error reading resampled audio: %d", err );
            return -1;
        }
        //Init packet, do the encoding and write data to file

谢谢你的帮助!

1)如果音频播放速度快,则采样率可能不正确。检查重采样器的输入采样率是否与解码器中的相同。AND输出采样率与编码器中使用的采样率相同。

2) 平面与非平面只是将样本保存在缓冲区中的一种方式(检查:AV_SAMPLE_FMT_S16P和AV_SAMPLE_FMT_S16之间有什么区别?)。你不应该错过飞机。

3) 由于输出较短:提醒刷新解码器、重采样器、编码器。所有这些都缓冲数据。当所有数据被馈送到处理器链(d-r-e)时,您需要刷新每个组件,并在下一阶段处理刷新的数据(刷新解码器->重采样->编码;刷新重采样器->编码;清除编码器)。

你现在找到解决问题的方法了吗?我正在为类似的问题而挣扎。当从S16->FLTP转换时,我得到一个ffmpeg错误:"处理器:psymodel.c:576:calc_energy:Assertion`el>=0'失败。"