视音频数据处理入门:AAC音频码流解析
=====================================================
视音频数据处理入门系列文章:
=====================================================
本文继续上一篇文章的内容,介绍一个音频码流处理程序。音频码流在视频播放器中的位置例如以下所看到的。
本文中的程序是一个AAC码流解析程序。该程序能够从AAC码流中分析得到它的基本单元ADTS frame。而且能够简单解析ADTS frame首部的字段。
通过改动该程序能够实现不同的AAC码流处理功能。
原理
AAC原始码流(又称为“裸流”)是由一个一个的ADTS frame组成的。
他们的结构例如以下图所看到的。
当中每一个ADTS frame之间通过syncword(同步字)进行分隔。同步字为0xFFF(二进制“111111111111”)。AAC码流解析的步骤就是首先从码流中搜索0x0FFF,分离出ADTS frame。然后再分析ADTS frame的首部各个字段。本文的程序即实现了上述的两个步骤。
代码
整个程序位于simplest_aac_parser()函数中,例如以下所看到的。
/**
* 最简单的视音频数据处理演示样例
* Simplest MediaData Test
*
* 雷霄骅 Lei Xiaohua
* leixiaohua1020@126.com
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
*
* 本项目包括例如以下几种视音频測试演示样例:
* (1)像素数据处理程序。包括RGB和YUV像素格式处理的函数。
* (2)音频採样数据处理程序。包括PCM音频採样格式处理的函数。
* (3)H.264码流分析程序。能够分离并解析NALU。
* (4)AAC码流分析程序。能够分离并解析ADTS帧。
* (5)FLV封装格式分析程序。能够将FLV中的MP3音频码流分离出来。
* (6)UDP-RTP协议分析程序。能够将分析UDP/RTP/MPEG-TS数据包。
*
* This project contains following samples to handling multimedia data:
* (1) Video pixel data handling program. It contains several examples to handle RGB and YUV data.
* (2) Audio sample data handling program. It contains several examples to handle PCM data.
* (3) H.264 stream analysis program. It can parse H.264 bitstream and analysis NALU of stream.
* (4) AAC stream analysis program. It can parse AAC bitstream and analysis ADTS frame of stream.
* (5) FLV format analysis program. It can analysis FLV file and extract MP3 audio stream.
* (6) UDP-RTP protocol analysis program. It can analysis UDP/RTP/MPEG-TS Packet.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int getADTSframe(unsigned char* buffer, int buf_size, unsigned char* data ,int* data_size){
int size = 0; if(!buffer || !data || !data_size ){
return -1;
} while(1){
if(buf_size < 7 ){
return -1;
}
//Sync words
if((buffer[0] == 0xff) && ((buffer[1] & 0xf0) == 0xf0) ){
size |= ((buffer[3] & 0x03) <<11); //high 2 bit
size |= buffer[4]<<3; //middle 8 bit
size |= ((buffer[5] & 0xe0)>>5); //low 3bit
break;
}
--buf_size;
++buffer;
} if(buf_size < size){
return 1;
} memcpy(data, buffer, size);
*data_size = size; return 0;
} int simplest_aac_parser(char *url)
{
int data_size = 0;
int size = 0;
int cnt=0;
int offset=0; //FILE *myout=fopen("output_log.txt","wb+");
FILE *myout=stdout; unsigned char *aacframe=(unsigned char *)malloc(1024*5);
unsigned char *aacbuffer=(unsigned char *)malloc(1024*1024); FILE *ifile = fopen(url, "rb");
if(!ifile){
printf("Open file error");
return -1;
} printf("-----+- ADTS Frame Table -+------+\n");
printf(" NUM | Profile | Frequency| Size |\n");
printf("-----+---------+----------+------+\n"); while(!feof(ifile)){
data_size = fread(aacbuffer+offset, 1, 1024*1024-offset, ifile);
unsigned char* input_data = aacbuffer; while(1)
{
int ret=getADTSframe(input_data, data_size, aacframe, &size);
if(ret==-1){
break;
}else if(ret==1){
memcpy(aacbuffer,input_data,data_size);
offset=data_size;
break;
} char profile_str[10]={0};
char frequence_str[10]={0}; unsigned char profile=aacframe[2]&0xC0;
profile=profile>>6;
switch(profile){
case 0: sprintf(profile_str,"Main");break;
case 1: sprintf(profile_str,"LC");break;
case 2: sprintf(profile_str,"SSR");break;
default:sprintf(profile_str,"unknown");break;
} unsigned char sampling_frequency_index=aacframe[2]&0x3C;
sampling_frequency_index=sampling_frequency_index>>2;
switch(sampling_frequency_index){
case 0: sprintf(frequence_str,"96000Hz");break;
case 1: sprintf(frequence_str,"88200Hz");break;
case 2: sprintf(frequence_str,"64000Hz");break;
case 3: sprintf(frequence_str,"48000Hz");break;
case 4: sprintf(frequence_str,"44100Hz");break;
case 5: sprintf(frequence_str,"32000Hz");break;
case 6: sprintf(frequence_str,"24000Hz");break;
case 7: sprintf(frequence_str,"22050Hz");break;
case 8: sprintf(frequence_str,"16000Hz");break;
case 9: sprintf(frequence_str,"12000Hz");break;
case 10: sprintf(frequence_str,"11025Hz");break;
case 11: sprintf(frequence_str,"8000Hz");break;
default:sprintf(frequence_str,"unknown");break;
} fprintf(myout,"%5d| %8s| %8s| %5d|\n",cnt,profile_str ,frequence_str,size);
data_size -= size;
input_data += size;
cnt++;
} }
fclose(ifile);
free(aacbuffer);
free(aacframe); return 0;
}
上文中的函数调用方法例如以下所看到的。
simplest_aac_parser("nocturne.aac");
结果
本程序的输入为一个AAC原始码流(裸流)的文件路径,输出为该码流中ADTS frame的统计数据。例如以下图所看到的。
下载
Simplest mediadata test
项目主页
SourceForge:https://sourceforge.net/projects/simplest-mediadata-test/
Github:https://github.com/leixiaohua1020/simplest_mediadata_test
开源中国:http://git.oschina.net/leixiaohua1020/simplest_mediadata_test
CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/9422409
本项目包括例如以下几种视音频数据解析演示样例:
(1)像素数据处理程序。包括RGB和YUV像素格式处理的函数。
(2)音频採样数据处理程序。包括PCM音频採样格式处理的函数。
(3)H.264码流分析程序。
能够分离并解析NALU。
(4)AAC码流分析程序。
能够分离并解析ADTS帧。
(5)FLV封装格式分析程序。能够将FLV中的MP3音频码流分离出来。
(6)UDP-RTP协议分析程序。能够将分析UDP/RTP/MPEG-TS数据包。
雷霄骅 (Lei Xiaohua)
leixiaohua1020@126.com
http://blog.csdn.net/leixiaohua1020
视音频数据处理入门:AAC音频码流解析的更多相关文章
- 视音频数据处理入门:FLV封装格式解析
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- 视音频数据处理入门:H.264视频码流解析
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- 视音频数据处理入门:UDP-RTP协议解析
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- 视音频数据处理入门:PCM音频采样数据处理
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- 视音频数据处理入门:RGB、YUV像素数据处理
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- [转载] 视音频数据处理入门:RGB、YUV像素数据处理
===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...
- 视音频数据处理入门:RGB、YUV像素数据处理【转】
转自:http://blog.csdn.net/leixiaohua1020/article/details/50534150 ==================================== ...
- 【雷神源码解析】无基础看懂AAC码流解析,看不懂你打我
一 前言 最近在尝试学习一些视频相关的知识,随便一搜才知道原来国内有雷神这么一个真正神级的人物存在,尤其是在这里(传送门)看到他的感言更是对他膜拜不已,雷神这种无私奉献的精神应当被我辈发扬光大.那写这 ...
- 大华NVR设备接分别入宇视摄像机Onvif和RTSP主子码流的方案说明
需求提要 1.各个内网现场有多种网络摄像机IPC和网络硬盘录像机NVR设备: 2.需要将这些设备统一接入到云端中心平台,进行统一的视频直播和录像回放管理: 3.由于目前IPC设备都属于高清设备,主码流 ...
随机推荐
- 安装oracle11g时遇到INS-13001环境不满足最低要求
在安装oracle11g,点击setup.exe之后,弹出了如下提示框: 解决方法: 首先,打开你解压后的database文件夹,找到stage,然后cvu,找到cvu_prereq.xml文件,用记 ...
- SpringBoot前端给后端传list
前端JS "]; var params = { taskList: taskList }; $.ajax({ type: "PUT", dataType: "j ...
- python的random模块(生成验证码)
python的random模块(生成验证码) random模块常用方法 random.random() #生成0到1之间的随机数,没有参数,float类型 random.randint(1, 3) # ...
- centos6.8 yum安装mysql 5.6 (完整)
一.检查系统是否安装其他版本的MYSQL数据 #yum list installed | grep mysql #yum -y remove mysql-libs.x86_64 二.安装及配置 # w ...
- Redis实现的分布式锁和分布式限流
随着现在分布式越来越普遍,分布式锁也十分常用,我的上一篇文章解释了使用zookeeper实现分布式锁(传送门),本次咱们说一下如何用Redis实现分布式锁和分布限流. Redis有个事务锁,就是如下的 ...
- N=NP?
#include<stdio.h> ],b[]; int len(char a[]) { ; while(a[i]!='\0') ++i; return i; } int who(char ...
- html/css实现阴影蒙版覆盖原网页并显示浮框的功能
在提供用户修改资料/密码等功能的时候,往往希望给用户这样的使用体验,在不跳转,不弹框的情况下完成对这些功能的操作. 这可以通过一种效果来实现,在同一页面下阴影覆盖整个当前网页并使得原网页中元素无法使用 ...
- windows安全配置
比较重要的 1. 更改默认administrator用户名,密码复杂些 2. 开启防火墙(设置入站规则,入站出站默认全部阻止) 3. 杀毒软件 4. 删除默认共享(net share C$ /del) ...
- 爬虫scrapy的使用
1.常用命令
- webstorm显示行号,结构预览
1,代码结构浏览menu>view>file structure popupwindwows>tool windws >structure (alt+7)代码结构当JS代码量很 ...