FFmpeg:如何编码最后一个音频帧?

标签 ffmpeg

考虑以下片段:(来自 https://ffmpeg.org/doxygen/trunk/encode_audio_8c-example.html )

for (i = 0; i < 200; i++) {
    /* make sure the frame is writable -- makes a copy if the encoder
     * kept a reference internally */
    ret = av_frame_make_writable(frame);
    if (ret < 0)
        exit(1);
    samples = (uint16_t*)frame->data[0];
    for (j = 0; j < c->frame_size; j++) {
        samples[2*j] = (int)(sin(t) * 10000);
        for (k = 1; k < c->channels; k++)
            samples[2*j + k] = samples[2*j];
        t += tincr;
    }
    encode(c, frame, pkt, f);
}
如果我正确理解了这个例子,生成的音频流正好包含 200 帧大小 c->frame_size它们被编码并保存到磁盘。
但是,如果我想对大小为 soundsize 的通用数据流进行编码,我会有一定数量的固定大小的帧c->frame_size ,即 size_t nframes = soundsize / c->frame_size; 加上最后一帧大小: size_t rem_lastframe = soundsize % c->frame_size;你能解释一下如何处理最后一帧吗? frame_size 似乎是由编解码器固定和选择的。

最佳答案

这就是 ffmpeg 所做的。

        if (src->nb_samples < avctx->frame_size) {
            ret = pad_last_frame(avctx, dst, src);
        ...
您可以使用 apad 过滤器或模仿 libavcodec 的功能
/**
 * Pad last frame with silence.
 */
static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src)
{
    int ret;

    frame->format         = src->format;
    frame->channel_layout = src->channel_layout;
    frame->channels       = src->channels;
    frame->nb_samples     = s->frame_size;
    ret = av_frame_get_buffer(frame, 0);
    if (ret < 0)
        goto fail;

    ret = av_frame_copy_props(frame, src);
    if (ret < 0)
        goto fail;

    if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0,
                               src->nb_samples, s->channels, s->sample_fmt)) < 0)
        goto fail;
    if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples,
                                      frame->nb_samples - src->nb_samples,
                                      s->channels, s->sample_fmt)) < 0)
        goto fail;

    return 0;

fail:
    av_frame_unref(frame);
    return ret;
}

关于FFmpeg:如何编码最后一个音频帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66738829/

相关文章:

php - 通过 PHP 运行 ffmpeg

audio - 使用 ffmpeg 对 mkv 进行缩减、色调映射、缩混和重新编码

python - 通过管道将 OpenCV 和 PyAudio 从 python 传输到 ffmpeg 流 youtube rtmp

php + ffmpeg 将标志添加到有错误的视频

ffmpeg - 将 Webrtc 轨道流转换为 Video 标签中的 URL (RTSP/UDP/RTP/Http)

ffmpeg - 树莓派 > CRTMPServer > JWplayer

ffmpeg 将 hls 转换为 rtsp 协议(protocol)

ffmpeg - 如何使用新的 Flascc 编译器编译 ffmpeg?

c++ - 'linesize alignment' 是什么意思?

ffmpeg - 使用 directshow 输入和 JPEG 图像序列输出为 FFmpeg 启用 QSV