两种 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 把标签集中放一处,依赖容器统一管理。

相关推荐
Yang96111 小时前
鼎讯信通 RM-1000:助力风电信号覆盖与设备稳定运行
大数据·网络
SXJR1 小时前
langchain4j是如何保证tools或者funcation call不出错的
java·网络·数据库·ai·语言模型
Sagittarius_A*2 小时前
H3CSE 高性能园区网:NQA 网络质量分析详解
网络
m0_730801132 小时前
ospf实验作业
网络
郑洁文2 小时前
基于网络爬虫的XSS漏洞检测系统的设计与实现
网络·爬虫·网络安全·xss
饿了吃洗衣凝珠2 小时前
ospf笔记
网络·tcp/ip·智能路由器
上海云盾安全满满3 小时前
改善用户体验 从CDN网络加速开始
网络·ux
齐齐大魔王3 小时前
OpenSSL 原理
运维·网络·nginx·ssh·ssl
m0_730801133 小时前
ospf笔记
网络