【问题标题】:How to encode 3840 nb_samples to a codec that asks for 1024 using ffmpeg如何使用 ffmpeg 将 3840 nb_samples 编码为要求 1024 的编解码器
【发布时间】:2018-07-02 21:48:54
【问题描述】:

FFmpeg 在https://ffmpeg.org/doxygen/4.0/muxing_8c-example.html 上有一个示例复用代码

此代码逐帧生成视频和音频。我想做的是改变

ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
                                       c->sample_rate, nb_samples);

ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
                                       c->sample_rate, 3840);

这样它每个通道生成 3840 个样本,而不是 nb_samples(aac 编解码器)的默认值 1024 个样本。

我尝试合并来自https://ffmpeg.org/doxygen/4.0/transcode_aac_8c-example.html 的代码,其中有一个缓冲帧的示例。

当在第一次迭代中为 *q++ 分配一个新值时,在几帧之后生成音频样本时,我的结果程序崩溃了:

/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
 * 'nb_channels' channels. */
static AVFrame *get_audio_frame(OutputStream *ost)
{
    AVFrame *frame = ost->tmp_frame;
    int j, i, v;
    int16_t *q = (int16_t*)frame->data[0];
    /* check if we want to generate more frames */
    if (av_compare_ts(ost->next_pts, ost->enc->time_base,
                      STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
        return NULL;
    for (j = 0; j <frame->nb_samples; j++) {
        v = (int)(sin(ost->t) * 10000);
        for (i = 0; i < ost->enc->channels; i++)
            *q++ = v;
        ost->t     += ost->tincr;
        ost->tincr += ost->tincr2;
    }
    frame->pts = ost->next_pts;
    ost->next_pts  += frame->nb_samples;
    return frame;
}

也许我不明白编码背后的逻辑。

这是我想出的完整来源:

https://paste.ee/p/b07qf

我尝试完成此任务的原因是我有一个采集卡 sdk,它输出 2 通道 16 位原始 pcm 48000Hz,每个通道有 3840 个样本,我正在尝试将其输出编码为 aac。所以基本上,如果我让复用示例与 3840 nb_samples 一起工作,这将有助于我理解这个概念。

我已经看过How to encode resampled PCM-audio to AAC using ffmpeg-API when input pcm samples count not equal 1024,但该示例使用“encodeFrame”,ffmpeg 文档中的示例没有使用,或者我弄错了。

非常感谢任何帮助。

【问题讨论】:

  • AAC 编码器采用 1024 个样本的 MDCT 窗口。不支持 3840。
  • 我已经看到了一些对不受支持的 windows 样本使用缓冲的例子,我提供的链接有另一个例子。我认为它一次只发送 1024 个样本,直到它将一帧的所有样本发送到编码器,还是我弄错了?
  • 在我的计算中(这取决于一些假设)。 nb_samples 应该等于 48000 / 25 = 1920。 2 通道 16 位音频 (pcm_s16) 的 1920 个样本所需的缓冲区为 1920 x 2 x (16/8) = 7680 字节。
  • 好吧,我认为 nb_samples 应该等于 1920x2channels。你是对的,我从原始 pcm 得到的缓冲区正好是 7680 字节。我只想知道如何将 1920 个样本输入到 1024 个样本接受编解码器(例如 aac)。如果我尝试用我的数据填充 AVFrame,那么 nb_samples 将是 1920。当我将它发送到编码器时,它会抱怨 nb_sample 大小。
  • 我设法通过缓冲 1920 个样本并一次发送 1024 个样本来做到这一点。

标签: c++ c ffmpeg


【解决方案1】:

好的,这里是任何感兴趣的人的解决方案。

由于编解码器接受 1024 个样本,我们需要将 1920 个样本放入缓冲区并一次向编解码器提供 1024 个样本。

我从How to encode resampled PCM-audio to AAC using ffmpeg-API when input pcm samples count not equal 1024 获取了缓冲代码

【讨论】:

    猜你喜欢
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多