FFmpeg --17-重采样器设计

本文详细介绍了音频重采样器在iOS开发中的基本概念、参数设置、API使用以及流程,包括AVAudioFifo和AVSampleFormat在音频格式调整中的作用。

基本概念

重采样器设计原理:

  1. 支持重采样参数的设置
  2. 支持不同形式的源输入,如frame ,int**
    data
  3. 支持不同形式的输出,如frame, int ** ou
  4. 支持pts (显示时间戳)
  5. 支持获取指定采样点数
  6. 支持flush

流程

读取采样点----> SwrContext------> AVAudioFifo----> 输出修改后采样点

若不需要调整音频格式,需调整采样点,直接将输入数据存储到AVAudioFifo

api

// 重采样的参数
typedef struct audio_resampler_params; 
// 封装的重采样器
typedef struct audio_resample;

/**
 * @brief 分配重采样器
 * @param resampler_params 重采样的设置参数
 * @return 成功返回重采样器;失败返回NULL
 */
audio_resampler_t *audio_resampler_alloc(const audio_resampler_params_t resampler_params);


void audio_resampler_free(audio_resampler_t *resampler);

/**
 * @brief 发送要进行重采样的帧
 * @param resampler
 * @param frame
 * @return 这次重采样后得到的采样点数
 */
int audio_resampler_send_frame(audio_resampler_t *resampler, AVFrame *frame);


/**
 * @brief 获取重采样后的数据
 * @param resampler
 * @param nb_samples    我们需要读取多少采样数量: 如果nb_samples>0,只有audio fifo>=nb_samples才能获取到数据;nb_samples=0,有多少就给多少
 * @return 如果获取到采样点数则非NULL
 */
AVFrame *audio_resampler_receive_frame(audio_resampler_t *resampler, int nb_samples);

code

// 重采样的参数
typedef struct audio_resampler_params {
    // 输入参数
    enum AVSampleFormat src_sample_fmt;
    int src_sample_rate;
    uint64_t src_channel_layout;
    // 输出参数
    enum AVSampleFormat dst_sample_fmt;
    int dst_sample_rate;
    uint64_t dst_channel_layout;
}audio_resampler_params_t;


// 封装的重采样器
typedef struct audio_resampler {
    struct SwrContext *swr_ctx;     // 重采样的核心
    audio_resampler_params_t resampler_params;  // 重采样的设置参数
    int is_fifo_only;       // 不需要进行重采样,只需要缓存到 audio_fifo
    int is_flushed;         // flush的时候使用
    AVAudioFifo *audio_fifo;    // 采样点的缓存
    int64_t start_pts;          // 起始pts
    int64_t cur_pts;            // 当前pts

    uint8_t **resampled_data;   // 用来缓存重采样后的数据
    int resampled_data_size;    // 重采样后的采样数
    int src_channels;           // 输入的通道数
    int dst_channels;           // 输出通道数
    int64_t total_resampled_num;    // 统计总共的重采样点数,目前只是统计
}audio_resampler_t;

int main()
{
	//重采样
	 do {
        /* generate synthetic audio */
        // 生成输入源
        fill_samples((double *)src_data[0], src_nb_samples, src_nb_channels, src_rate, &t);

        int ret_size = audio_resampler_send_frame2(resampler, src_data, src_nb_samples, in_pts);
        in_pts += src_nb_samples;
        ret_size = audio_resampler_receive_frame2(resampler, dst_data, dst_nb_samples, &out_pts);

        if(ret_size > 0) {
            dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
                                                     ret_size, dst_sample_fmt, 1);
            if (dst_bufsize < 0) {
                fprintf(stderr, "Could not get sample buffer size\n");
                goto end;
            }
            printf("t:%f in:%d out:%d, out_pts:%"PRId64"\n", t, src_nb_samples, ret_size, out_pts);
            fwrite(dst_data[0], 1, dst_bufsize, dst_file);
        } else {
            printf("can't get %d samples, ret_size:%d, cur_size:%d\n", dst_nb_samples, ret_size,
                   audio_resampler_get_fifo_size(resampler));
        }
    } while (t < 10);  // 调整t观察内存使用情况
    // ... 
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八月的雨季997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值