一个AAC+的痛苦问题,请问各位老师。

AgedBOY 2008-05-08 09:19:30
我这个问题其实说来并不复杂:

1,现有一台网络接收器。接收器不是自己做的,因此不太了解技术细节。只知道它能够接收到发射器发来的AAC+编码的音频数据包。一包大约有40ms左右音频。是48K,16Bits,AAC+的。
2,我做了Source Filter,从接收器的USB驱动程序里将那传说中的AAC+数据包一笔一笔收上来,并在Capture Pin上直接往下游推出。
3,从网上找了FFDShow、CoreAAC等几个支持AAC/AAC+的Decoder,连接上以后跑起来。都无法解码,FFDShow在Output里显示“Wrong channel number”、“Bitstream exceeds...”(具体英文记不清了)。

如果我怀疑收上来的数据有错,那么我就应该把收到的数据保存为AAC文件,用暴风影音什么的播一下。可据说AAC不像MP3那么简单。MP3是直接写进文件就可以形成MP3文件了,可是AAC号称不行。

但是提供接收器和底层程序的人一口咬定收到的数据没有错!那么各位老师可否帮我想想,根据前面描述,假如数据真是对的,那还可能是什么原因造成AAC Decoder无法解码呢?
...全文
2039 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qxwitkey168 2012-03-22
  • 打赏
  • 举报
回复
请问老师:有没有查看AAC文件里装载的内容的软件?
tudou_nuaa 2009-04-23
  • 打赏
  • 举报
回复
http://bbs.lmtw.com/dispbbs.asp?boardid=20&id=132846
关于AAC文档在这个帖子里面可以下载
另外流媒体论坛里面有些关于 AAC 的东西可以参考一下。
tudou_nuaa 2008-05-15
  • 打赏
  • 举报
回复
Table 5 – Syntax of adts_frame()
Syntax No. of bits Mnemonic
adts_frame()
{
adts_fixed_header();
adts_variable_header();
if (number_of_raw_data_blocks_in_frame == 0) {
adts_error_check();
raw_data_block();
}
else {
adts_header_error_check();
for (i = 0; i <= number_of_raw_data_blocks_in_frame; i++) {
raw_data_block();
adts_raw_data_block_error_check();
}
}
}

Table 8 – Syntax of adts_fixed_header()
Syntax No. of bits Mnemonic
adts_fixed_header()
{
syncword; 12 bslbf
ID; 1 bslbf
layer; 2 uimsbf
protection_absent; 1 bslbf
profile; 2 uimsbf
sampling_frequency_index; 4 uimsbf
private_bit; 1 bslbf
channel_configuration; 3 uimsbf
original/copy; 1 bslbf
home; 1 bslbf
}

Table 9 – Syntax of adts_variable_header()
Syntax No. of bits Mnemonic
adts_variable_header()
{
copyright_identification_bit; 1 bslbf
copyright_identification_start; 1 bslbf
frame_length; 13 bslbf
adts_buffer_fullness; 11 bslbf
number_of_raw_data_blocks_in_frame; 2 uimsfb
}

上面这是这7个字节的解释, 我这有AAC的一份标准文档, 也是找了好久才找到的,你可以加我的MSN :tudou_nuaa@hotmail.com
传给你

最前面的0xFF 0xF1 前面12个bit是同步字,用来标示一帧数据的开始。

AgedBOY 2008-05-15
  • 打赏
  • 举报
回复
zhangchaoyszq:WAVE_FORMAT_AAC就是你说的0xFF,至于扩展字节,看下面:

tudou_nuaa:

你回答的太强了。在发这个帖子不久,我从网上看到有个人说,说在output pin的格式“WAVEFORMATEX”后面扩展5个字节,并且添上“0x13 0x10 0x56 0xe5 0x98”。我加上后,大部分AAC decoder filter就都可以解码了。

我想,这和你说的给收到的AAC帧加个帧头是同样的道理。只不过如果通过在“WAVEFORMATEX”后面追加帧头,则肯定是decoder收到后,保存下来,自己给加到AAC帧上了。

但是我获知的是5个字节,你提到的是7个字节。

我想这个好理解(猜测的理解):差那两个字节,刚好是“有效长度 FF F1”。由于我是在pin连接时,通过扩展“WAVEFORMATEX”传给decoder的。所以当然不需要“有效长度”字段。后面,当decoder收到一个LATM帧时,会自己先做一个有效长度字段,再把有效长度、ADTS头,以及LATM包Merge在一起,送进decode库里面去(比如著名的FAAD2等)。这样解释,则5字节和7字节的差异刚好可以解释。

我猜的应该没错。那么如果pin连接时,我不扩展那5字节,则以后在stream跑起来时,自己加上那7字节,想必也是可以的了。

只是你的AdtsHead那段代码的注释看不太明白。我需要知道那5字节都是啥。我自己看看你说的“ISO/IEC 13818-7:2003 (MPEG-2 AAC, Second Edition)”吧!实在太谢谢你了!
tudou_nuaa 2008-05-14
  • 打赏
  • 举报
回复
很有可能你接受下来的数据是通过RTP协议传输的LATM格式打包的 mp4 aac+数据
你不妨试试给你的数据加上一个ADTS的数据头 7个字节的头

framlen = LatmLen + 7;

AdtsHead[0] = 0xff;
AdtsHead[1] = 0xf1;
AdtsHead[2] = (0x01<<6)|(0x06<<2); //2400 sample rate
AdtsHead[3] = 0x80|(framlen>>11); //双声道? a=rtpmap:97 mpeg4generic/44100/2
AdtsHead[4] = ((framlen&0x7FF)>>3)&0xff;
AdtsHead[5] = ((framlen&0x07)<<5|0x1f);
AdtsHead[6] = 0xfc;

latmlen 为latm封装音频数据的长度 再加上7个字节的 ADTS 头信息 就是framlen 这些东西在AAC的标准
ISO/IEC 13818-7:2003 (MPEG-2 AAC, Second Edition)里面有提到

另外需要注意的是我接收下来的latm数据包的头几个字节不是用来放音频数据的,而是用来放当前latm包的有效长度的,从开头的第一个字节来取, 如果是0xff则连下一个字节一起都表示有效长度,以此类推,直到找到不是0xff的,表示有效长度的最后一个字节,一般都是一个字节就可以表示的一包数据长度,少数有两个字节表示的。

所以取音频数据的时候需要把前面表示有效长度的字节给剔除掉。
tudou_nuaa 2008-05-14
  • 打赏
  • 举报
回复
很有可能你接受下来的数据是通过RTP协议传输的LATM格式打包的 mp4 aac+数据
你不妨试试给你的数据加上一个ADTS的数据头 7个字节的头

framlen = LatmLen + 7;

AdtsHead[0] = 0xff;
AdtsHead[1] = 0xf1;
AdtsHead[2] = (0x01<<6)|(0x06<<2); //2400 sample rate
AdtsHead[3] = 0x80|(framlen>>11); //双声道? a=rtpmap:97 mpeg4generic/44100/2
AdtsHead[4] = ((framlen&0x7FF)>>3)&0xff;
AdtsHead[5] = ((framlen&0x07)<<5|0x1f);
AdtsHead[6] = 0xfc;

latmlen 为latm封装音频数据的长度 再加上7个字节的 ADTS 头信息 就是framlen 这些东西在AAC的标准
ISO/IEC 13818-7:2003 (MPEG-2 AAC, Second Edition)里面有提到

另外需要注意的是我接收下来的latm数据包的头几个字节不是用来放音频数据的,而是用来放当前latm包的有效长度的,从开头的第一个字节来取, 如果是0xff则连下一个字节一起都表示有效长度,以此类推,直到找到不是0xff的,表示有效长度的最后一个字节,一般都是一个字节就可以表示的一包数据长度,少数有两个字节表示的。

所以取音频数据的时候需要把前面表示有效长度的字节给剔除掉。
zhangchaoyszq 2008-05-13
  • 打赏
  • 举报
回复
目前我做的项目也与AAC有关:请问你这个pwf->wFormatTag = WAVE_FORMAT_AAC这个值你定义的是多少呀?
如果AAC格式数据应该等于:pwf->wFormatTag = 0xFF;至于那两个扩展的字节是:0x12和0x90
asddg67 2008-05-09
  • 打赏
  • 举报
回复
AAC的音频文件可以用千千静听播放..你播一下就知道文件的数据到底对不对了
asddg67 2008-05-09
  • 打赏
  • 举报
回复
可以使用开源的FAAD的AAC解码库,将解码完的数据使用DirectSound或者系统的API播放即可...
AgedBOY 2008-05-08
  • 打赏
  • 举报
回复
哦对,我这还有个疑惑的地方:

我的Output Pin的格式信息里,Format虽然是FORMAT_WaveFormarEx,但是Fotmat Buffer实际上要比WAVEFORMATEX大两个字节,多出的两个字节里写了两个数。

这两个数的含义我不知道,因为这么做是从网上查到的!网上那资料只给了数,没告诉含义。而如果没这两个数,decoder都会拒绝连接的。

那数是这样的:

WAVEFORMATAAC* pwf = (WAVEFORMATAAC*)g_StaticAudioFormat.pbFormat;
pwf->nChannels = 2;
pwf->nSamplesPerSec = 48000;
pwf->wBitsPerSample = 16;
pwf->nBlockAlign = pwf->nChannels * pwf->wBitsPerSample / 8;
pwf->nAvgBytesPerSec = pwf->nSamplesPerSec * pwf->nBlockAlign;
pwf->wFormatTag = WAVE_FORMAT_AAC;
pwf->cbSize = 2;
// 网上就提供了这两个可选的数值,但哪个都不行。
// pwf->wExtraData = 0x900a;
pwf->wExtraData = 0x9011;

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧