遵循:BY-SA

署名-相同方式共享 4.0协议

作者:谭东

时间:2016年10月28日

环境:Windows 7

ADTS是Audio Data Transport Stream的简称。

是AAC音频文件常见的传输格式。

有的时候当你编码AAC裸流的时候,会遇到写出来的AAC文件并不能在PC和手机上播放,很大的可能就是AAC文件的每一帧里缺少了ADTS头信息文件的包装拼接。只需要加入头文件ADTS即可。一个AAC原始数据块长度是可变的,对原始帧加上ADTS头进行ADTS的封装,就形成了ADTS帧。

下面分析下ADTS头文件结构和信息:

AAC音频文件的每一帧由ADTS Header和AAC Audio Data组成。

大家可以用AAC Audio ES Viewer工具来查看AAC的ADTS Header。

每一帧的ADTS的头文件都包含了音频的采样率,声道,帧长度等信息,这样解码器才能解析读取。

一般情况下ADTS的头信息都是7个字节,分为2部分:

adts_fixed_header();

adts_variable_header();

先来看:adts_fixed_header();

syncword :总是0xFFF, 代表一个ADTS帧的开始, 用于同步.
解码器可通过0xFFF确定每个ADTS的开始位置.
因为它的存在,解码可以在这个流中任何位置开始, 即可以在任意帧解码。
ID:MPEG Version: 0 for MPEG-4,1 for MPEG-2
Layer:always: ‘00’
protection_absent:Warning, set to 1 if there is no CRC and 0 if there is CRC
profile:表示使用哪个级别的AAC,如01 Low Complexity(LC) – AAC LC
profile的值等于 Audio Object Type的值减1.
profile = MPEG-4 Audio Object Type - 1

sampling_frequency_index:采样率的下标

channel_configuration:声道数,比如2表示立体声双声道

接下来看下adts_variable_header();

aac_frame_length:一个ADTS帧的长度包括ADTS头和AAC原始流。frame length, this value must include 7 or 9 bytes of header length:
aac_frame_length = (protection_absent == 1 ? 7 : 9) + size(AACFrame)

protection_absent=0时, header length=9bytes
protection_absent=1时, header length=7bytes
adts_buffer_fullness:0x7FF 说明是码率可变的码流。
number_of_raw_data_blocks_in_frame:表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧。
所以说number_of_raw_data_blocks_in_frame == 0 表示说ADTS帧中有一个AAC数据块。
(一个AAC原始帧包含一段时间内1024个采样及相关数据)

两个头文件就讲到这里。

这里给出JAVA和Android里的给AAC添加ADTS头文件的部分方法代码,针对ByteBuffer。


```java/*** 添加ADTS头** @param packet* @param packetLen*/private void addADTStoPacket(byte[] packet, int packetLen) {int profile = 2; // AAC LCint freqIdx = 4; // 44.1KHzint chanCfg = 2; // CPE// fill in ADTS datapacket[0] = (byte) 0xFF;packet[1] = (byte) 0xF9;packet[2] = (byte) (((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));packet[3] = (byte) (((chanCfg & 3) << 6) + (packetLen >> 11));packet[4] = (byte) ((packetLen & 0x7FF) >> 3);packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);packet[6] = (byte) 0xFC;}

这里是调用:(可根据自己需求,这里的AudioBufFrame是我们自己项目里的类,其实就是个ByteBuffer封装的类)AudioBufFrame audioBufFrame = (AudioBufFrame) o;int outBufferSize = audioBufFrame.buf.limit() + 7;byte[] aacBytes = new byte[outBufferSize];try {if (!write) {fout = new FileOutputStream(MyConfiguration.VIDEO_PATH + "/audio.aac");write = true;}addADTStoPacket(aacBytes, outBufferSize);audioBufFrame.buf.get(aacBytes, 7, audioBufFrame.buf.limit());fout.write(aacBytes);} catch (IOException e) {e.printStackTrace();}`在这里插入代码片`下面是FFMPEG参考的C的添加ADTS头文件代码,供大家参考。```cpp
int ff_adts_write_frame_header(ADTSContext *ctx,  uint8_t *buf, int size, int pce_size)
{  PutBitContext pb;  init_put_bits(&pb, buf, ADTS_HEADER_SIZE);  /* adts_fixed_header */  put_bits(&pb, 12, 0xfff);   /* syncword */  put_bits(&pb, 1, 0);        /* ID */  put_bits(&pb, 2, 0);        /* layer */  put_bits(&pb, 1, 1);        /* protection_absent */  put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */  put_bits(&pb, 4, ctx->sample_rate_index);  put_bits(&pb, 1, 0);        /* private_bit */  put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */  put_bits(&pb, 1, 0);        /* original_copy */  put_bits(&pb, 1, 0);        /* home */  /* adts_variable_header */  put_bits(&pb, 1, 0);        /* copyright_identification_bit */  put_bits(&pb, 1, 0);        /* copyright_identification_start */  put_bits(&pb, 13, ADTS_HEADER_SIZE + size + pce_size); /* aac_frame_length */  put_bits(&pb, 11, 0x7ff);   /* adts_buffer_fullness */  put_bits(&pb, 2, 0);        /* number_of_raw_data_blocks_in_frame */  flush_put_bits(&pb);  return 0;
}

————————————————
版权声明:本文为CSDN博主「范特西_jay」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jay100500/article/details/52955232

AAC的ADTS头文件信息介绍相关推荐

  1. landsat8 编辑头文件信息

    不想把之前学过的知识丢掉,简单记录一下提醒自己. landsat8 没有完整头文件的时候只能一次打开一个文件,打开后便需要编辑头文件信息,在进行辐射定标和大气校正. 然后把信息填进去,把几个波段进行l ...

  2. java获得U盘根目录、读取图片视频头文件信息、获取视频时长

    1.获得U盘根目录,例如我们取名U盘名称为"测试U盘",一般插入U盘后,在系统的H盘 /** * 得到系统U盘根目录 */ public String findURootPath( ...

  3. C++11中头文件type_traits介绍

    C++11中的头文件type_traits定义了一系列模板类,在编译期获得某一参数.某一变量.某一个类等等类型信息,主要做静态检查. 此头文件包含三部分: (1).Helper类:帮助创建编译时常量的 ...

  4. Spring:applicationContext.xml的头文件信息

    文章目录 Spring介绍 1.内核 2.提供服务 3.特性 4.体系结构 xml头文件代码展示 Spring介绍 分层的JavaSE/EE,应用full-stack(全栈)轻量级开源框架. 1.内核 ...

  5. C++/C++11中头文件sstream介绍

    C++使用标准库类来处理面向流的输入和输出:(1).iostream处理控制台IO:(2).fstream处理命名文件IO:(3).stringstream完成内存string的IO. 类fstrea ...

  6. OpenFOAM 雾化模型头文件信息摘录

    1.BlobsSheetAtomization(空心喷雾) Description     Primary Breakup Model for pressure swirl atomizers. Ac ...

  7. 关于intrins.h头文件的介绍,做流水灯时候更方便

    先来个示例..循环左移..体现在开发板上是流水灯(从左到右) #include <reg52.h> #include<intrins.h> #define uchar unsi ...

  8. date字段 http 头文件_http头文件信息

    状态码 Response 消息中的第一行叫做状态行,由 HTTP 协议版本号, 状态码, 状态消息 三部分组成. 状态码用来告诉 HTTP 客户端 ,HTTP 服务器是否产生了预期的 Response ...

  9. c++ memory 头文件详细介绍

    类 指针特征 pointer_traits (C++11) 提供关于指针式类型的信息 (类模板) 垃圾收集器支持 pointer_safety (C++11) 列出指针安全模式 (枚举) 分配器 al ...

最新文章

  1. 关于Fast Terrain Rendering Using Geometrical MipMapp
  2. .Net CLR 中的同步机制(一): 互斥体
  3. MySQL Connector/ODBC 5.2.2 发布
  4. onBlur()事件连续触发问题。
  5. Java教程:影响MySQL性能的配置参数
  6. wxWidgets:wxConfigPathChanger类用法
  7. DevC++怎么更改背景颜色
  8. 数十种TensorFlow实现案例汇集:代码+笔记
  9. 大数据先行 传统金融转型需从体制上创新
  10. IE 11打开之后一直提示“恢复非正常关闭的网页”,让后IE就卡死
  11. python爬取豆瓣电影排行榜_爬取豆瓣电影排名的代码以及思路
  12. 题解报告:hdu 2030 汉字统计
  13. Artistic Style Dev CPP 运算符 前后空格
  14. idea打包jar的多种方式
  15. PVE7.2 显示CPU温度和频率
  16. android设备如何挂载sdcard(有些设备是自动挂载的)
  17. 烤仔TVのCCW | 带宽不可能三角(下)
  18. 钒酸钠的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  19. arcengine双击属性表内的一行,定位到该要素,并添加到选择集
  20. 装X与务实并存!iPad越狱必装插件汇总

热门文章

  1. Spark 算子之distinct使用
  2. 值得收藏【Markdown】皇额娘级教你玩转vscode插件: Markdown All in One
  3. 密码验证:8-20位必须包含大写字母,小写字母,数字组合,特殊字符
  4. 类似于微信发语音Demo
  5. 2022DASCTF Apr X FATE 防疫挑战赛
  6. java中OOD_还在傻傻分不清?3分钟快速认识Java中的OOA、OOD、OOP
  7. 如何增加 yota3 的 墨水屏应用?
  8. Tengine(一)
  9. jquery 滚轮插件 jquery.mousewheel.js
  10. 研究fastdds v2.8.0 2之 Domain 模块 4