个人简介
个人主页:一二三o-0-O的博客
技术方向:C/C++客户端资深工程师(直播+音视频剪辑)
作者简介:数据结构算法与音视频领域创作者
系列专栏:ffmpeg入门
专栏目标:务实的掌握FFmpeg相关专业知识
如果对您有帮助的话,欢迎点赞收藏,关注不迷路
如果是刚刚开始学习音视频的伙伴,可以先看看音视频基 础专栏系列的内容,掌握音视频相关的一些基础理论。
音视频基础专栏系列
(一)【音视频基础】音频基础理论
(二)【音视频基础】视频基础理论
(三)【音视频基础】封装格式与编码数据
如果觉得理论学习枯燥的伙伴,可以先通过以下四篇文章使用ffmpeg实现一个播放器,可以获得些许成就感,为持续在音视频领域扎根打好兴趣基础。
ffmpeg专栏系列
(一)【ffmpeg】ffmpeg命令工具的使用
(二)【ffmpeg】视频解码器
(三)【ffmpeg】SDL视频显示
(四)【ffmpeg】ffmpeg+SDL实现播放器
本节主要阐述音频重采样。
本节代码在【ffmpeg】音频采集的基础上进行开发。
使用swr_alloc_set_opts分配采样上下文
SwrContext *swrCtx = swr_alloc_set_opts(NULL, // ctx
AV_CH_LAYOUT_STEREO,// 输出channel布局
AV_SAMPLE_FMT_FLT, // 输出的采样格式
44100, // 采样率
AV_CH_LAYOUT_STEREO,// 输入channel布局
AV_SAMPLE_FMT_S16, // 输入的采样格式
44100, // 输入的采样率
0,
NULL);
1.初始化重采样缓冲区
uint8_t **src_data {};
uint8_t **dst_data {};
2.使用av_samples_alloc_array_and_samples分配缓冲区
// 创建输入缓冲区
av_samples_alloc_array_and_samples(&srcData, // 输出缓冲区地址
&srcLineSize, // 缓冲区的大小
2, // 通道个数
22050, // 单通道采样个数
AV_SAMPLE_FMT_S16, // 采样格式
0);
1.将采集到的AVPacket音频包拷贝到输入缓冲区中
2.使用swr_convert进行重采样
// 进行内存拷贝
memcpy((void *)srcData[0], (void *)pkt.data, pkt.size);
// 重采样
swr_convert(swrCtx, // 重采样的上下文
dstData, // 输出结果缓冲区
22050, // 每个通道的采样数
(const uint8_t **)srcData, // 输入缓冲区
22050); // 输入单个通道的采样数
重点注意:
av_samples_alloc_array_and_samples的nb_samples参数
以及swr_convert的out_count与in_count两个参数表示的都是单通道的采样个数,切记是单通道的采样个数,而不是大小(字节)
计算规则:
因为我的音频采集设备每次采集到的AVPacket大小是88200个字节,采样大小是16位,即每采集一次是两个字节;所以一个Packet是采集了44100次,而一个通道就采集了22050次
【1】雷神博客
【2】ffmpeg官方文档
【3】李超:音视频基础+ffmpeg原理