如何将小端24位PCM音频样本转为适配RFC7310的大端apt-X RTP格式
24位PCM样本转apt-X RTP网络字节序打包实现
问题背景
需要按照RFC 7310第5.5节的apt-X RTP格式要求,将音频样本以网络字节序填充到RTP数据报缓冲区(缓冲区前12字节为已配置好的大端RTP头,从偏移12处开始填充音频数据):
- 当前内存中的音频样本为24位紧凑小端有符号PCM(spcm24-le),单样本内存布局:
[最低有效字节(LSB)][中间字节(MB)][最高有效字节(MSB)] - 额外场景:麦克风输入为Intel平台的
std::uint32_t数组,将每个元素右移8位即可得到spcm24-le格式的样本,需要同步处理该场景 - 疑问:应该用
std::reverse配合memcpy实现,还是依赖特殊字节序库?需要基于std::endian、std::reverse或std::byteswap的C++实现示例
解决方案
网络字节序为大端序,而当前24位样本是小端紧凑布局,因此每个样本需要反转字节顺序(从LSB→MB→MSB转为MSB→MB→LSB)。由于C++标准库没有专门的24位字节交换函数,std::reverse是最直接且符合标准的实现方式,无需额外第三方库。
场景1:直接处理spcm24-le缓冲区
假设输入缓冲区src_spcm24_le是存储spcm24-le样本的字节数组,目标RTP缓冲区rtp_buffer已分配足够空间,前12字节为RTP头:
#include <algorithm> #include <cstring> #include <bit> // 用于std::endian(C++20及以上) // 确认当前平台是小端(Intel平台默认满足) static_assert(std::endian::native == std::endian::little, "This code requires little-endian platform"); void pack_spcm24_le_to_rtp(const uint8_t* src_spcm24_le, size_t sample_count, uint8_t* rtp_buffer) { uint8_t* audio_dst = rtp_buffer + 12; // 跳过12字节RTP头 for (size_t i = 0; i < sample_count; ++i) { // 定位当前样本的字节范围 const uint8_t* src_sample = src_spcm24_le + i * 3; uint8_t* dst_sample = audio_dst + i * 3; // 反转字节顺序,转为网络大端序 std::reverse_copy(src_sample, src_sample + 3, dst_sample); } }
场景2:从std::uint32_t麦克风输入转换并打包
麦克风输入的std::uint32_t数组每个元素是32位无符号值,右移8位后得到24位有符号样本的小端紧凑布局:
#include <algorithm> #include <cstring> #include <bit> static_assert(std::endian::native == std::endian::little, "This code requires little-endian platform"); void pack_mic_input_to_rtp(const uint32_t* mic_input, size_t sample_count, uint8_t* rtp_buffer) { uint8_t* audio_dst = rtp_buffer + 12; for (size_t i = 0; i < sample_count; ++i) { // 右移8位提取24位样本的小端字节 uint32_t shifted_sample = mic_input[i] >> 8; uint8_t src_sample[3]; std::memcpy(src_sample, &shifted_sample, 3); // 反转字节顺序转为网络大端序,写入RTP缓冲区 uint8_t* dst_sample = audio_dst + i * 3; std::reverse_copy(src_sample, src_sample + 3, dst_sample); } }
说明
- 若使用C++20之前的标准,可移除
std::endian的静态断言,直接基于Intel平台小端的前提编写代码 std::reverse_copy是标准库函数,性能可靠,无需额外依赖- 每个样本的字节反转是严格匹配RFC 7310要求的网络字节序布局的核心操作
内容的提问来源于stack exchange,提问作者johnco3
相关产品推荐
相关产品推荐

