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

时间:2016-05-11 09:55:01

标签: c++ audio ffmpeg mp3 resampling

我是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 以下是重新采样的代码(来自https://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 个答案:

答案 0 :(得分:0)

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

2)平面与非平面只是将样本保存在缓冲区中的一种方法(请检查:What is the difference between AV_SAMPLE_FMT_S16P and AV_SAMPLE_FMT_S16?)。您不应该错过飞机。

3)由于输出较短:提醒刷新解码器,重采样器,编码器。它们全部缓冲数据。当所有数据都馈送到处理器链(dre)时,您需要刷新每个组件并在下一阶段处理刷新的数据(刷新解码器->重采样->编码;刷新重采样器->编码;刷新编码器)。

您现在找到了解决问题的方法吗?我正在努力解决类似的问题。从S16-> FLTP转换时,出现ffmpeg错误:“处理器:psymodel.c:576:calc_energy:声明'el> = 0'失败。”