两种 AAC 码流封装详解:Raw(ASC) vs ADTS

两种 AAC 码流封装详解:Raw(ASC) vs ADTS

一、核心概念

AAC(Advanced Audio Coding)是一种音频压缩编码格式。同样的 AAC 编码数据,在"打包传输"时有两种不同的封装方式,区别在于配置信息(采样率、声道数、profile 等)放在哪里


二、Raw / ASC(裸流)方式

1. 什么是 Raw AAC

复制代码
┌─────────┐ ┌─────────┐ ┌─────────┐
│ AAC帧1  │ │ AAC帧2  │ │ AAC帧3  │  ← 只有纯音频数据
└─────────┘ └─────────┘ └─────────┘
  • 每一帧只有纯压缩音频数据,没有任何头部信息
  • 帧与帧之间没有同步标记
  • 码流本身无法自我描述(不知道采样率、声道数等)

2. 什么是 ASC(AudioSpecificConfig)

配置信息被单独抽出来,存放在一个叫 ASC 的数据结构里:

复制代码
ASC(通常 2 字节,也可能更长):
┌──────────────┬──────────────┬──────────────┐
│ Object Type  │ Sample Rate  │ Channel      │
│ (profile)    │ Index        │ Config       │
│ 5 bits       │ 4 bits       │ 4 bits       │
└──────────────┴──────────────┴──────────────┘

ASC 示例 (常见的 0x12 0x10):

复制代码
0x12 0x10 = 0001 0010 0001 0000
            ┌───┐┌──┐┌───┐
            00010 0100 0010 ...
            AAC LC  44.1kHz  立体声

3. ASC 存放在哪里?

ASC 作为 extradata (额外数据),由容器格式单独提供:

容器 ASC 存放位置
MP4/MOV esds box 中
FLV AAC sequence header(首个音频 tag)
MKV CodecPrivate 字段

4. 数据流向示意

复制代码
        ┌─────────────────┐
        │  容器(MP4/FLV)  │
        └─────────────────┘
           │            │
     extradata      raw帧数据
     (ASC配置)     (无头纯数据)
           │            │
           └────┬───────┘
                ▼
            解码器需要两者结合才能解码

三、ADTS 方式

1. 什么是 ADTS

ADTS = Audio Data Transport Stream(音频数据传输流)

每一帧前面都加一个同步头,配置信息内嵌:

复制代码
┌──────────┬─────────┐ ┌──────────┬─────────┐
│ADTS头(7/9)│ AAC数据 │ │ADTS头(7/9)│ AAC数据 │
└──────────┴─────────┘ └──────────┴─────────┘
   每一帧都自带头部信息

2. ADTS 头结构(7 字节 = 56 bits)

复制代码
固定头部(fixed header):
┌─────────────┬───────┬──────────┬─────────┐
│ Syncword    │ ...   │ profile  │ sf_index│
│ 0xFFF       │       │ 2 bits   │ 4 bits  │
│ (12 bits)   │       │          │         │
└─────────────┴───────┴──────────┴─────────┘
       ↑                  ↑          ↑
   同步标记            profile    采样率索引
                                      
┌──────────┬──────────────┐
│ channel  │ frame_length │
│ config   │ (13 bits)    │
│ 3 bits   │              │
└──────────┴──────────────┘
       ↑           ↑
    声道数    本帧总长度

关键字段说明:

字段 作用
Syncword (0xFFF) 同步字,用于在码流中定位帧的起始
profile AAC 规格(LC/Main/SSR)
sampling_freq_index 采样率索引(如 4=44.1kHz)
channel_config 声道配置
frame_length 整帧长度(含头),用于找到下一帧

注:如果不带 CRC 校验是 7 字节 ,带 CRC 校验是 9 字节

3. ADTS 的特点:自描述

复制代码
┌──────────────────────────────┐
│         ADTS 码流             │
│  每帧头里都包含完整配置信息   │
│  ┌────────────────────────┐  │
│  │ 采样率 ✓ 声道 ✓        │  │
│  │ profile ✓ 帧长度 ✓     │  │
│  └────────────────────────┘  │
└──────────────────────────────┘
        ↓
   不需要任何外部 extradata
   解码器读头部即可解码

四、两者对比总表

对比项 Raw / ASC ADTS
每帧是否有头 ❌ 无 ✅ 有(7/9字节)
同步字 ❌ 无 ✅ 0xFFF
配置信息位置 外部 extradata(ASC) 内嵌每帧头
是否自描述 ❌ 否 ✅ 是
依赖容器 ✅ 需要容器提供ASC ❌ 可独立存在
额外开销 小(仅一次ASC) 大(每帧+7/9字节)
典型应用 MP4、FLV、MKV .aac文件、直播流、TS流

五、应用场景与选择

Raw/ASC 适用场景

  • 存储到容器(MP4/FLV):容器已能提供配置,再加 ADTS 头是冗余浪费
  • 追求最小体积

ADTS 适用场景

  • 裸 .aac 文件:双击即可播放(自描述)
  • 直播流 / 广播流:接收端可能中途加入,每帧自带配置可立即解码
  • MPEG-TS 流:电视广播等

六、实战:相互转换

ASC → ADTS(封装时添加头部)

从 ASC 解析出 profile、采样率、声道,构造 ADTS 头:

c 复制代码
// 伪代码:构造 ADTS 7字节头
void make_adts_header(uint8_t *header, int frame_len,
                      int profile, int sf_index, int channels) {
    int total = frame_len + 7;
    
    header[0] = 0xFF;                          // syncword 高8位
    header[1] = 0xF1;                           // syncword低4位+MPEG4+无CRC
    header[2] = ((profile - 1) << 6)            // profile
              | (sf_index << 2)                 // 采样率索引
              | (channels >> 2);                // 声道高位
    header[3] = ((channels & 3) << 6)           // 声道低位
              | (total >> 11);                  // 帧长高位
    header[4] = (total >> 3) & 0xFF;            // 帧长中间
    header[5] = ((total & 7) << 5) | 0x1F;      // 帧长低位
    header[6] = 0xFC;
}

FFmpeg 中的转换

bash 复制代码
# 提取裸AAC(带ADTS)从MP4 → 自动加ADTS头
ffmpeg -i input.mp4 -c:a copy output.aac

# 内部使用 bitstream filter:
# aac_adtstoasc : ADTS → ASC(去头)
# 用于将 .aac 封装进 MP4 时
ffmpeg -i input.aac -c:a copy -bsf:a aac_adtstoasc output.mp4

关键过滤器 aac_adtstoasc:把 ADTS 流转成 ASC(去掉每帧头,提取配置生成extradata),常用于 .aac → .mp4。


七、记忆要点总结

复制代码
Raw/ASC  =  纯数据 + 配置另放(靠容器)→ 省空间,但不能独立
ADTS     =  数据 + 每帧带头(自描述)  → 能独立,但有冗余

一句话理解:

ADTS 就是给每个裸 AAC 帧"贴标签",让它脱离容器也能被识别;而 Raw/ASC 把标签集中放一处,依赖容器统一管理。

相关推荐
黑桃小柒711 小时前
小,最终显示为TCP WINDOW FULL,TCP ZeroWindow。 仔细分析了下LWIP源码,还以为是内存管理出了问题,跟 ...
网络·网络协议·tcp/ip
网络研究院12 小时前
LastPass 发布紧急安全预警:针对主密码的活跃网络钓鱼攻击正在进行中
网络·安全·黑客·攻击·漏洞·风险·钓鱼
向夏威夷 梦断明暄14 小时前
【高效管理token成本】OpenClaw精细化分库管理memory以减少token成本的方案的可行性研究
网络
酷可达拉斯16 小时前
Linux操作系统-免密登录远程操作系统
linux·运维·服务器·网络·云计算
aixingkong92117 小时前
AI超节点Scale Up域总线各层优化设计
linux·服务器·网络
瓦学妹20 小时前
为什么您的AI总是显示“不支持的区域”?如何解决?
大数据·网络·人工智能
优化Henry20 小时前
5G站点软件错误告警与资源激活超时两类典型告警分析与处理
网络·笔记·学习·5g·信息与通信
coward9120 小时前
千兆以太网卡(Ethernet)驱动初始化完成,但是无法udhcpc获取ip
服务器·网络·嵌入式硬件·tcp/ip
逸Y 仙X21 小时前
跨语言RPC框架Thrift实战
网络·网络协议·rpc·thrift
软件技术员1 天前
SSL.com 证书:免费单域名 90 天证书
网络·网络协议·ssl