【问题标题】:FFmpeg: how to encode last audio frame?FFmpeg:如何编码最后一个音频帧?
【发布时间】:2021-03-22 13:23:03
【问题描述】:

考虑以下sn-p:(来自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-&gt;frame_size 的帧,这些帧经过编码并保存到磁盘。 但是,如果我想编码大小为soundsize 的通用数据流,我将有一定数量的固定大小的帧c-&gt;frame_size,即size_t nframes = soundsize / c-&gt;frame_size;加上最后一帧大小: size_t rem_lastframe = soundsize % c-&gt;frame_size;

你能解释一下如何处理最后一帧吗? frame_size 似乎是由编解码器固定和选择的。

【问题讨论】:

    标签: ffmpeg


    【解决方案1】:

    这就是 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-07-14
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 2016-02-26
      • 2018-03-16
      • 2015-05-21
      • 2021-04-12
      • 2013-12-26
      相关资源
      最近更新 更多