FFmpeg错误:frame_size (1024) was not respected for a non-last frame解决方法

在音视频变速滤镜代码运行时出现如下错误:

该错误是由于传给mp4的音频编码器时帧内的采样点数量不对引起的(没有浅蓝色字符串的行是自行输出的;采样点数量不对是因为用变速滤镜进行了重采样),mp4中的音频默认用aac编码,而aac编码一帧的采样点为1024,而这里每帧只传入819,因此引发了错误。若要解决,需要将输入的帧修正为1024个采样点的

解决的方法很多,以我的解决方法为例,将滤镜输出的帧先不输入编码器,而是将帧内采样点放入队列,若队列中的采样点超过1024则生成帧数组,依次输入编码器,没有引起以上错误且变速正常。

#include <vector>
#include <queue>
#include <iostream>
static std::vector<AVFrame*> addSamples(AVFrame *frame)
{
    static std::vector<std::queue<int8_t>> channel_samples;
    if(channel_samples.size() == 0)
    {
        channel_samples.insert(channel_samples.end(),
                     audio_encode_ctx->ch_layout.nb_channels, std::queue<int8_t>());
    }

    int data_size = av_get_bytes_per_sample(audio_encode_ctx->sample_fmt);

    for(int i = 0; i < frame->ch_layout.nb_channels; ++i)
    {
        for(int j = 0; j < frame->nb_samples; ++j)
        {
            for(int k = 0; k < data_size; ++k)
            {
                channel_samples[i].push(frame->data[i][j*data_size+k]);
            }
        }
    }

    std::vector<AVFrame*> res;
    while(channel_samples[0].size() >= audio_encode_ctx->frame_size * data_size)
    {
        AVFrame *cur = av_frame_alloc();
        cur->nb_samples = audio_encode_ctx->frame_size;//audio_encode_ctx为音频编码器
        cur->format = audio_encode_ctx->sample_fmt;
        cur->sample_rate = audio_encode_ctx->sample_rate;
        cur->ch_layout = frame->ch_layout;
        cur->channel_layout = frame->channel_layout;
        cur->time_base = frame->time_base;

        static int cur_index = -1;

        if(av_frame_get_buffer(cur, 0) < 0)
        {
            std::cerr << "Error: AVFrame could not get buffer.\n";
            av_frame_free(&cur);
            return res;
        }

        cur_index++;
//        cur->duration = frame->nb_samples*(frame->time_base.den/cur->sample_rate);
        cur->pts = cur->nb_samples * cur_index;//设置时间戳,aac帧的pts一般以1024为单位
        for(int i = 0; i < cur->ch_layout.nb_channels; ++i)
        {
            for(int j = 0; j < cur->nb_samples; ++j)
            {
                for(int k = 0; k < data_size; ++k)
                {
                    cur->data[i][j * data_size + k] = channel_samples[i].front();
                    channel_samples[i].pop();
                }
            }
        }
        res.push_back(cur);
//        std::cout << "new frame : " << cur->nb_samples << " samples.\n";
    }
    return res;
}

上述代码记得在输入编码器后将生成的帧用av_frame_free()释放空间。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值