14

我正在开发一个 mp4 容器解析器,但我正在疯狂地试图识别流的音频编解码器。我同时使用了 QtAtomViewer 和 AtomicParsley 但是当我找到原子时:

trak->mdia->minf->stbl->stsd

即使 mp4 文件有 mp3 流,我总是得到“mp4a”。

我应该寻找“.mp3”fourcc 吗?

我附加了两个不同的 mp4 结构: mp4 container with AAC audio stream

     Atom trak @ 716882 of size: 2960, ends @ 719842
     Atom tkhd @ 716890 of size: 92, ends @ 716982
     Atom mdia @ 716982 of size: 2860, ends @ 719842
         Atom mdhd @ 716990 of size: 32, ends @ 717022
         Atom hdlr @ 717022 of size: 33, ends @ 717055
         Atom minf @ 717055 of size: 2787, ends @ 719842
             Atom dinf @ 717063 of size: 36, ends @ 717099
                 Atom dref @ 717071 of size: 28, ends @ 717099
             Atom stbl @ 717099 of size: 2727, ends @ 719826
                 Atom stts @ 717107 of size: 24, ends @ 717131
                 Atom stsz @ 717131 of size: 1268, ends @ 718399
                 Atom stsc @ 718399 of size: 40, ends @ 718439
                 Atom stco @ 718439 of size: 32, ends @ 718471
                 Atom stss @ 718471 of size: 1264, ends @ 719735
                 Atom stsd @ 719735 of size: 91, ends @ 719826
                     Atom mp4a @ 719751 of size: 75, ends @ 719826
                         Atom esds @ 719787 of size: 39, ends @ 719826
             Atom smhd @ 719826 of size: 16, ends @ 719842

带有 mp3 音频流的 mp4 容器

Atom trak @ 1663835 of size: 4844, ends @ 1668679
     Atom tkhd @ 1663843 of size: 92, ends @ 1663935
     Atom mdia @ 1663935 of size: 4744, ends @ 1668679
         Atom mdhd @ 1663943 of size: 32, ends @ 1663975
         Atom hdlr @ 1663975 of size: 45, ends @ 1664020
         Atom minf @ 1664020 of size: 4659, ends @ 1668679
             Atom smhd @ 1664028 of size: 16, ends @ 1664044
             Atom dinf @ 1664044 of size: 36, ends @ 1664080
                 Atom dref @ 1664052 of size: 28, ends @ 1664080
             Atom stbl @ 1664080 of size: 4599, ends @ 1668679
                 Atom stsd @ 1664088 of size: 87, ends @ 1664175
                     Atom mp4a @ 1664104 of size: 71, ends @ 1664175
                         Atom esds @ 1664140 of size: 35, ends @ 1664175
                 Atom stts @ 1664175 of size: 24, ends @ 1664199
                 Atom stsc @ 1664199 of size: 28, ends @ 1664227
                 Atom stsz @ 1664227 of size: 2228, ends @ 1666455
                 Atom stco @ 1666455 of size: 2224, ends @ 1668679

谢谢 FE

更新:

我找到了解决问题的方法:通过查看 AtomicParsley 的代码,我发现可以获取有关流原子(mp4a)的编解码器信息,将第 11 个字节读入 esds(基本流描述)原子。

现在我正在以这种方式工作:

如果第 11 个字节的值为 0x40,我假设流是 AAC,否则如果我读取 0x69,我假设流是 MP3。

我不喜欢这些“经验”解决方案,所以我正在寻找更正确的方法,但我发现只有Understanding_AAC不完整。

有人知道我在哪里可以获得更详细的 MP4 容器规格吗?

4

3 回答 3

32

在“esds”原子中,有一些与确定编解码器相关的字段。esds atom 内容的第一个字节是objectTypeIndication(即解决方案中的第 11 个字节)。该字段应该指示使用的编解码器,但有几个条目被多个编解码器使用。MP4RA 有完整的编解码器值列表。以下是在这种情况下相关的一些内容:

  • 0x40 - MPEG-4 音频
  • 0x6B - MPEG-1 音频(MPEG-1 第 1、2 和 3 层)
  • 0x69 - MPEG-2 向后兼容音频(MPEG-2 第 1、2 和 3 层)
  • 0x67 - MPEG-2 AAC LC

0x6B0x69分别表示 MPEG-1 和 2 层 1、2 和 3。0x67表示 MPEG-2 AAC LC,但通常不用于支持0x0400x66而且0x68MPEG-2 AAC 配置文件也很少见)。0x40表示 MPEG-4 音频。MPEG-4 音频通常被认为是 AAC,但有一个完整的音频编解码器框架可以进入 MPEG-4 音频,包括 AAC、BSAC、ALS、CELP 和称为 MP3On4 的东西。MP3On4 是一种 MP3 变体,带有一些用于多声道的新标头信息。

我们可以通过查看AudioSpecificConfig. 这是解码器的全局标头,存在于“esds”原子内容的第 13 字节。在开头AudioSpecificConfig有一个 5-bit AudioObjectType。可以在多媒体 wiki 上找到完整列表(在“MPEG-4 音频”文章下的帖子中链接:http ://wiki.multimedia.cx/index.php?title=MPEG-4_Audio但这里是有用的价值:

  • 00 - 空
  • 01 - AAC Main(MPEG-2 中已弃用的 AAC 配置文件)
  • 02 - AAC LC 或向后兼容的 HE-AAC(大多数现实世界的 AAC 都属于这些情况之一)
  • 03 - AAC 可扩展采样率(很少使用)
  • 03 - AAC LTP(AAC Main 的替代品,很少使用)
  • 05 - HE-AAC 明确发出信号(非向后兼容)
  • 22 - ER BSAC(韩国广播编解码器)
  • 23 - 低延迟 AAC
  • 29 - HE-AACv2 明确发出信号(在一份草案中,这是 MP3On4)
  • 31 - ESCAPE(再读 6 位,加 32)
  • 32 - MP3on4 第 1 层
  • 33 - MP3on4 第 2 层
  • 34 - MP3on4 第 3 层

如果您不担心“MP3On4”mp3 变体或其他奇怪的 MPEG-4 音频编解码器,那么只需使用objectTypeIndication.

在 MPEG 规范中,这些细节分布在 14496-1、-12、-14 和 -3 中。其中只有 14496-12 是免费提供的:http ://standards.iso.org/ittf/PubliclyAvailableStandards/index.html

于 2011-01-10T05:54:43.327 回答
6

esds atom [1] 的格式定义为:

Size 32-bit
Type 32-bit 'esds'
Version: 8-bit, zero.
Flags: 24-bit field, zero.
Elementary Stream Descriptor

基本流描述符在相关的 MPEG4 文档 [2] 中定义。

查看 MP4A 文件中的典型 ESDS:

00000033 65736473 00000000 03808080  
22000100 04808080 14401500 00000001
FC170001 FC170580 80800212 08068080
800102

解释为

00000033 65736473 = ISO Atom "esds" of length 0x33
00000000 = Version/Flags field (0), meaning tagged Elementary Stream Descriptor follows
03808080 = TAG(3) = Object Descriptor ([2])
22       = length of this OD (which includes the next 2 tags)
  0001   = ES_ID = 1
      00 = flags etc = 0
04808080 = TAG(4) = ES Descriptor ([2]) embedded in above OD
14       = length of this ESD
  40     = MPEG4 Audio (see table for valid types here)
    15   = stream type(6bits)=5 audio, flags(2bits)=1
000000   = 24bit buffer size
0001FC17 = max bitrate (130,071 bps)
0001FC17 = avg bitrate
05808080 = TAG(5) = ASC ([2],[3]) embedded in above OD
02       = length
1208     = ASC (AOT=2 AAC-LC, freq=4 => 44100 Hz, chan=1 => single channel, flen0 => 1024 samples)
06808080 = TAG(6)
01       = length
02       = data

参考:

于 2019-02-21T09:07:26.133 回答
2

Andy Henson 的答案中的字段拆分是错误的,“0x80”字节不是标签的一部分,而是长度的一部分并形成 Varint32 长度。

00000033 65736473 = ISO Atom "esds" of length 0x33
00000000 = Version/Flags field (0), meaning tagged Elementary Stream Descriptor follows
03       = TAG(3) = Object Descriptor ([2])
80808022 = length = 34 [4] of this OD (which includes the next 3 tags)
  0001   = ES_ID = 1
      00 = flags etc = 0
04       = TAG(4) = ES Descriptor ([2]) embedded in above OD
80808014 = length of this ESD
  40     = MPEG4 Audio (see table for valid types here)
    15   = stream type(6bits)=5 audio, flags(2bits)=1
000000   = 24bit buffer size
0001FC17 = max bitrate (130,071 bps)
0001FC17 = avg bitrate
05       = TAG(5) = ASC ([2],[3]) embedded in above OD
80808002 = length
1208     = ASC (AOT=2 AAC-LC, freq=4 => 44100 Hz, chan=1 => single channel, flen0 => 1024 samples)
06       = TAG(6)
80808001 = length
02       = data

长度编码记录在 MPEG-4 系统 (ISO 14496-1) 的附件 E.1 中

于 2020-04-11T14:48:31.860 回答