[时间:2016-06] [状态:Open]

ASF,全称Advanced Systems Format,是由微软提出的开放封装格式标准。ASF是微软公司Windows Media的核心。这是一种包含音频、视频、图像、控制命令脚本、JPEG、二进制文件的数据格式。
目前常见遵循这种标准的数据封装格式化的后缀是.asf、.wma、.wmv。
详细介绍建议参考

  1. Overview of the ASF Format https://msdn.microsoft.com/en-us/library/windows/desktop/dd757562\v=vs.85).aspx
  2. Advanced Systems Format-wiki
  3. ASF-百度百科

学习ASF容器格式的目标

读完本文,你应该能够回答下面问题:

  1. ASF中数据是如何组织的?
  2. 该容器包含哪些编码格式的数据?这些数据是如何存储的?
  3. 该容器包含哪些元数据信息?包含哪些节目信息?
  4. 对于支持多节目的容器格式,如何找到对应的音频流、视频流、字幕流?
  5. 如何确定该容器的节目播放时长?
  6. 如何从该容器中提取音频、视频、字幕数据,并交给解码器解码,有时间戳否?
  7. 该容器是否支持seek?有哪些辅助信息?
  8. 是否支持直接流化?
  9. 哪里可以找到该容器格式最标准的文档资料?
  10. 有哪些可用的工具,方便分析容器格式异常或者错误?

1. ASF文件整体结构

ASF Object

ASF文件是有多个ASF Object构成,换个说法,ASF Object是ASF的最小组成单元。其结构如下:

Field Size(byte)
Object GUID 16
Object Size 8
Payload varies

ASF object 是16个字节的GUID代表这个Object的类型,Object的类型有很多种。8个字节的 Size 代表这个Object的大小(=24+负载长度),紧接着就是Object的内容(负载)。
所有ASF Object和结构都是以小端字节序存储的。

ASF文件顶层视图

ASF文件通常包含三类ASF Object: Header Object、Data Object和Index Object。

  • Header Object是必须位于ASF文件起始位置,一个ASF文件中有且仅有一个Header Object。
  • Data Object必须紧跟在Header Object之后,有且仅有一个。
  • Index Object是可选的,该对象主要提供了基于时间点的ASF随机访问机制(快速seek);如果Index Object存在必须是ASF文件最后一个Object。

实际结构类似下图:
==================
Header Object
------------------
Data Object
------------------

------------------
Index Object
===================

ASF文件的解析过程中可以忽略任何无法识别的ASF Object。所有新定义或添加的ASF Object必须位于Data Object之后,Index Object之前(即上面的Other Object)。

Header Object

Header Object以ASF_Header_Object GUID object开头,是唯一可以包含ASF Ojbect的顶层结构。它包含着一系列的ASF object,分别代表着不同类型的ASF object,由GUID区分;它们提供了关于ASF DATA 的一些解释信息,如音视频类型及详细信息等, Header Object通常包含如下类型的object:

  • File Properties Object:包含整个文件属性,如文件大小、时长等
  • Stream Properties Object:包含Stream特性,如音视频格式、类型、PID等
  • Header Extension Object:包含用于ASF后向兼容的机制
  • Content Description Object:包含内容目录信息
  • Script Command Object:包含用于回放时执行的脚本命令
  • Marker Object:Provides named jump points within a file
    一般情况, Header Object必须包含1个File Properties Object, 1个Header Extension Object, 和至少一个Stream Properties Object。
    并且Header Object中Object出现的顺序是不固定的。
    一类比较简单的Header Object构成如下(音视频Stream各一个):
========================
File Properties Object
------------------------
Header Extenstion Object
------------------------
Stream Properties Object
------------------------
Stream Properties Object
========================

Index Objects

Index Objects包含两种变体:Simple Index Object和Index Object。在ASF文件中Index Object可以有多个。
Simple Index Object包含视频流的基于时间的索引序列,其中索引之间的间隔是固定的,通常是1s。标准规定,对于ASF文件中的任意视频流必须有一个对应的Simple Index Object,而且顺序是必须以stream number出现。
Index Object指的是Index Object,Media Object Index Object和Timecode Index Object。Index Object类似Simple Index Object,保存固定时间间隔的索引序列,但可以包括非视频流;Media Object Index Object是逐帧的索引机制,支持逐帧seek。Timecode Index Object是基于时间码(timecode)的seek机制,主要针对有时间码的内容。
更具体的内容建议参考“ASF Specification” section 7.3。

2. 如何解析ASF Data Object?

Data Object(GUID:ASF_Data_Object)是由多个Data Packet构成。这些Data Packet是按照发送时间顺序排列的,并且可以来自多个不同的stream。
Data Object包含64位的Total Data Packets字段,用于说明当前文件包含的Data Packet数目。
Data Packet通常是等长的,长度固定(具体长度在File Properties Object中的Data Packet Size字段)。
一个Data Packet中可以包含一个或多个Payload。

Data Packet结构

ASF Data Packet的结构如下图:

============================Error Correction Data
----------------------------    Payload Parsing Info
----------------------------Playload Data
----------------------------    Padding Data
============================
or
============================Error Correction Data
----------------------------    Opaque Data----------------------------    Padding Data
============================

其中Error Correction Data和Padding Data都是可选的,不一定每一个Data Packet都存在这些数据。
由于Error Correction Data是可选的,如何区分ASF Data Packet开始位置是Error Correction Data还是Payload Parsing Info呢?主要区分在于Data Packet中第一个字节的最高位是否的值(Error Correction Present),如果为1,则是Error Correction Data,否则是Playload Parsing Info。不管是那种数据,其中都存储了数据长度,可以按照ASF Specification中的section 5.2解析。
其中Error Correction Data中有一个字段Opaque Data Present,表示当前Data Packet结构是第二种,负载中有Opaque Data。

Payload Parsing & data解析

Payload Parsing Info段的长度不是固定的,需要按照其实际字段含义解析。其中需要特别关注的是Multiple Payloads Present、Padding Length、Send Time字段。在解析Payload data时会参考这些字段。
一个Playload Data可以包含一个或多个Payload,需要根据Multiple Payloads Present的值判断,如果该值为1,表示包含多个Payload。

Payload结构

ASF中定义Payload如下:

Field name Filed Type Size(bits)
Stream Number BYTE 8
Media Object Number BYTE/WORD/DWORD 0/8/16/32
Offset Into Media Object BYTE/WORD/DWORD 0/8/16/32
Relicated Data Length BYTE/WORD/DWORD 0/8/16/32
Replicated Data BYTE varies
Payload Data BYTE varies

其中Stream Number的最高位表示是否是关键帧(key frame),这也就限制了ASF最大能支持128个Stream Media。
另外,如果Replicated Data Length长度为1,表示payload是压缩格式的,具体建议参考ASF Specification的section 5.2.3。
Replicated Data中包含一个DWORD用于标识Payload长度,紧跟一个DWORD表示时间戳信息(以毫秒为单位),其他数据是附加的media sample信息。

对于Multiple Payloads Present为0的情况,可以直接通过Payload的结构解析出负载数据信息。

多个Payload数据解析

理解单个Payload解析之后,多Payload解析是参考Payload Data第一个字节的信息来解析的。其定义如下:

Filed name Field type Size(bits)
Playload Flags BYTE 8
==Number of Payloads - 6(LSDB)
==Payload Length Type - 2
Payloads - varies

这里的Payload的定义包含了Payload Length字段,定义结构如下:

Field name Filed Type Size(bits)
Stream Number BYTE 8
Media Object Number BYTE/WORD/DWORD 0/8/16/32
Offset Into Media Object BYTE/WORD/DWORD 0/8/16/32
Relicated Data Length BYTE/WORD/DWORD 0/8/16/32
Replicated Data BYTE varies
Payload Length BYTE/WORD/DWORD 8/16/32
Payload Data BYTE varies

填充字节主要为了保证ASF Data Packet的定长,通常填充0数据。

3. 如何解析ASF MetaData?

ASF中有五种Object用于存储Metadata,每个Metadata属性存储的顺序按照下面规则选择:

  • Content Description Object:可用于存储长度小于65535字节、与Stream无关、与语言无关的属性值,包括:Title, Author, Copyright, Description, and Rating
  • Content Branding Object:可用于存储与Stream无关、与语言无关的以下属性值:Banner Image Type, Banner Image Data, Banner Image URL, and Copyright URL
  • Extended Content Description Object:可用于存储任意命名的属性值,该属性值需要是下列类型的一种,并且长度小于65535,与Stream无关、与语言无关:WCHAR strings, BYTE arrays, Boolean values, DWORDs, QWORDs, or WORDs
  • Metadata Object:可用于存储与语言无关的任意名称的属性。允许数据按照Extended Content Description Object格式存储。属性可以用于描述特定stream,但长度必须不超过65535字节。
  • Metadata Library Object:可用于存储任意名称的属性。允许数据按照Extended Content Description Object格式或者GUID数据类型存储。属性可以用于描述特定stream,并支持指定特定语言,并且其长度可以超过65535字节(DWORD)。

至于这五种Object如何解析,建议参考ASF Specification的相关内容。

4. ASF中的节目选择

ASF文件中用StreamID唯一的标识一个stream(音频或者视频,当然也支持其他数据,比如字幕、脚本命令等,目前不需要关心这个,按照传统的音视频处理即可,后续需要可以自己按照标准处理下),这些信息可以在Header Object中的Stream Properties Object找到。比如说音频的声道数、采样率、量化位数、编码方式,视频的编码宽高、编码方式、量化位数。
如果ASF文件中只有一个音频或者一个视频,这是很容易选择,但是如果存在多个音频、视频文件该如何选择呢?
ASF中提供了Bitrate Mutual Exclusion Object、Advanced Mutual Exclusion Object、Group Mutual Exclusion Object,用于说明不能同时播放的视频流。
Stream Prioritization Object用于给出流播放的优先级。
stream选择在流媒体推流,及带宽变化时用的比较多,正常播放文件的话,通常默认选择最大分辨率、最大码率的视频,最大采样率、最多声道数的音频。
具体选择策略建议参考ASF Specification的section 7.2。

5. ASF如何实现seek?

第一部分介绍了ASF中提供的四种不同的Index Object。对于文件,比较常见的是Simple Index Object。多数seek操作时可以通过这个对象实现的。
Simple Index Object中存储的是按照固定时间间隔seek point。先了解下Simple Index Object的结构:

Field name Field type Size (bits)
Object ID GUID 128
Object Size QWORD 64
File ID GUID 128
Index Entry Time Interval QWORD 64
Maximum Packet Count DWORD 32
Index Entries Count DWORD 32
Index Entries See below varies

其中Index Entry Time Interval表示相邻seek point之间的时间间隔,单位是100纳秒。最常用的是10000000,表示1s。
Maximum Packet Count中存储的是Index Entries中最大的Packet数目。
Index Entries的定义如下:

Field name Field type Size (bits)
Packet Number DWORD 32
Packet Count WORD 16

其中Packet Number指的是与当前时间有关的Data Packet的编号。对于视频stream,该域总是指向具当前时间最近的关键帧所在的Data packet.
Packet Count表示在当前时间间隔内需要发送的Data Packet数目。

举个例子,下面数据是一个wmv文件的Simple Index Object的二进制数据:

0000: 90 08 00 33 B1 E5 CF 11-89 F4 00 A0 C9 03 49 CB
0010: CE 00 00 00 00 00 00 00-B6 FA 97 93 D3 CB E3 4B
0020: 81 D0 F0 6B 24 96 98 A2-80 96 98 00 00 00 00 00
0030: 0F 00 00 00 19 00 00 00-01 00 00 00 01 00 01 00
0040: 00 00 01 00 01 00 00 00-01 00 01 00 00 00 01 00
0050: 38 00 00 00 08 00 38 00-00 00 08 00 38 00 00 00
0060: 08 00 77 01 00 00 0A 00-77 01 00 00 0A 00 77 01
0070: 00 00 0A 00 B2 02 00 00-0D 00 B2 02 00 00 0D 00
0080: B2 02 00 00 0D 00 E8 03-00 00 07 00 E8 03 00 00
0090: 07 00 E8 03 00 00 07 00-26 05 00 00 08 00 26 05
00A0: 00 00 08 00 26 05 00 00-08 00 66 06 00 00 0F 00
00B0: 66 06 00 00 0F 00 66 06-00 00 0F 00 69 07 00 00
00C0: 0A 00 69 07 00 00 0A 00-69 07 00 00 0A 00      

解析之后的数据如下:

Simple Index Object (206 bytes)
Property Value
File Position 16235016 ( 0xF7BA08 )
Object ID 33000890-E5B1-11CF-89F4-00A0C90349CB
Object Size 206 ( 0xCE )
MMS ID 9397FAB6-CBD3-4BE3-81D0-F06B249698A2
Interval 00:01.000
Max. Packets in Entry 15
Index Entries
Entry Seek Time Packet SCR Packet Number Packet Count
0 00:00.000 00:00.000 1 1
1 00:01.000 00:00.000 1 1
2 00:02.000 00:00.000 1 1
3 00:03.000 00:00.000 1 1
4 00:04.000 00:00.651 56 8
5 00:05.000 00:00.651 56 8
6 00:06.000 00:00.651 56 8
7 00:07.000 00:03.683 375 10
8 00:08.000 00:03.683 375 10
9 00:09.000 00:03.683 375 10
10 00:10.000 00:06.657 690 13
11 00:11.000 00:06.657 690 13
12 00:12.000 00:06.657 690 13
13 00:13.000 00:09.611 1000 7
14 00:14.000 00:09.611 1000 7
15 00:15.000 00:09.611 1000 7
16 00:16.000 00:12.624 1318 8
17 00:17.000 00:12.624 1318 8
18 00:18.000 00:12.624 1318 8
19 00:19.000 00:15.644 1638 15
20 00:20.000 00:15.644 1638 15
21 00:21.000 00:15.644 1638 15
22 00:22.000 00:18.541 1897 10
23 00:23.000 00:18.541 1897 10
24 00:24.000 00:18.541 1897 10

这样我们就可以通过这张表查到需要seek到的时间点对应的Data Packet的索引号,然后通过ASF Data Packet的定长逻辑跳转到指定位置。(注意其他三种Index Object给出的是相对第一个ASF Data Packet的偏移位置)
上面表格中的Packet SCR是Packet Send Time。

6. 其他

读到这里,相信对ASF文件格式有一定的了解了,那么剩下的就回答下没有覆盖的问题。

  • 如何确定该容器的节目播放时长?
    在Header Object中的File Properties Object中有一个字段Duration,可以通过这个直接读出节目时长(有时候不准确,这就是文件生成方的责任了)。

  • 哪里可以找到该容器格式最标准的文档资料?
    通常在微软的官网上是可以下载到ASF标准文档的,但是不行的话可以谷歌(百度基本找不到)。
    我现在参考的是“Advanced Systems Format (ASF) Specification Revision 01.20.05 Microsoft Corporation June 2010”

  • 有哪些可用的工具,方便分析容器格式异常或者错误?
    比较经典的分析ASF、wmv、wma文件的工具是ASFViewer,也是微软提供的码流辅助分析工具,当然你也可以使用开源的demuxer分析(比如ffmpeg asf_demuxer)。

小结

本文主要是参考:

  1. “Advanced Systems Format (ASF) Specification Revision 01.20.05 Microsoft Corporation June 2010”
  2. 【多媒体封装格式详解】---ASF(WMV/WMA)

这里主要整理我对于ASF文件格式一些疑惑的地方。算是基本上可以解析了。了解了基本的文件结构,清楚了如何选择音频、视频,时间戳信息、seek索引文件的使用。

多媒体文件格式之ASF相关推荐

  1. 多媒体文件格式全解说(上)--音视频

    视频: mp4/m4v/3gp/mpg.flv/f4v/swf.avi.gif.wmv.rmvb.mov.mts/m2t.webm/ogg/mkv MP4格式是最常见的一种视频文件格式,它现在所使用的 ...

  2. 常见多媒体文件格式及视音频编解码总结

    首先要分清楚媒体文件和编码的区别:文件是既包括视频又包括音频.甚至还带有脚本的一个集合,也可以叫容器:文件当中的视频和音频的压缩算法才是具体的编码. 常见的音视频文件格式(容器): MPG:MPEG编 ...

  3. 多媒体文件格式之MKV

    [时间:2016-07] [状态:Open] MKV是一种开源的多媒体封装格式,是Matroska中应用比较多的格式之一.常见的后缀格式是.mkv(视频,包括音频和字幕)..mka(纯音频)..mks ...

  4. 多媒体文件格式之RMVB

    [时间:2016-07] [状态:Open] RM/RMVB是Real公司私有的封装格式,常见的后缀形式是rm.ra.rmvb. 通常封装的都是real转悠的编码格式,比如音频中的sipro.cook ...

  5. 多媒体文件格式之MP4

    [时间:2016-06] [状态:Open] 学习多媒体容器格式的目的 主要是为了回答以下问题: 该容器中数据是如何组织的? 该容器包含哪些编码格式的数据?这些数据是如何存储的? 该容器包含哪些元数据 ...

  6. 【音视频基础】多媒体文件格式

    转载自原文地址:https://www.cnblogs.com/batsing/p/5135508.html 视频: mp4/m4v/3gp/mpg.flv/f4v/swf.avi.gif.wmv.r ...

  7. 多媒体文件格式之TS

    TS流是MPEG-2标准中定义一种用于直播的码流结构,具有很好的容错能力.所有跟TS相关的标准可以从ISO/IEC_13818-1中找到. 通常TS流的后缀是.ts..mpg或者.mpeg,多数播放器 ...

  8. 多媒体文件格式(五):PCM / WAV 格式

    一.名词解析 PCM(Pulse Code Modulation)也被称为脉码编码调制,PCM中的声音数据没有被压缩,它是由模拟信号经过采样.量化.编码转换成的标准的数字音频数据.采样转换方式参考下图 ...

  9. 常用多媒体文件格式压缩标准解析学习---图像表示与声音基本

    多媒体数据表示理论 前言 图像是一类非常重要的多媒体数据,人类获取的信息70%来自视觉系统,所以在所有的多媒体数据中,图像提供的信息最多!但是,在图像数字化之后的数据量是非常大的,由于存储介质和传输的 ...

最新文章

  1. linux之pid文件
  2. Fikker 站长缓存无法缓存用 IIS 做 Web 服务器的 PHP 页面的解决方法
  3. 工作流技术杂谈 --- 2008
  4. Fabric 代码发布
  5. python 决策树 math库 c45算法
  6. 5-4日 socket套接字
  7. 手动创建Github pull request
  8. sysbench 1.0.6 mysql_Sysbench 测试mysql数据库性能(version:sysbench-1.1.0)
  9. 在TextView中实时显示数据
  10. java阻塞锁_java – 阻止锁与非阻塞锁
  11. 轻量级的 JavaScript 弹出框脚本:TinyBox
  12. Andrew Ng机器学习公开课笔记 -- Logistic Regression
  13. Linux开机启动过程(5):内核解压
  14. 海思Hi3796MV200最新官方SDK
  15. python字符串输入小圆点_第6章 多序列比对
  16. 转载:破解DR.COM实现共享上网方法大搜罗(抱歉,直接转载
  17. 耐磨钢球磨耗计算方法
  18. 【flask高级】结合源码解决flask经典报错:Working outside of application context
  19. Mysql的分组函数
  20. 万豪国际集团旗舰酒店品牌正式入驻中国东北地区

热门文章

  1. 21. VUE 的 V-model 指令(双向绑定input)【主要绑定表单】
  2. linux没有应用程序,Ninite为Linux安装多个应用程序没有任何麻烦 | MOS86
  3. 安卓怎样查看网站服务器地址,怎样查看安卓APP服务器地址
  4. 【校招VIP】“推推”Java项目课程:产品原型:产品需求要点分析
  5. AI丨亚马逊将联合美国国家科学基金会为AI公平性研究拨款1000万美元
  6. FillMemory()、ZeroMemory(),fillchar()
  7. 爬虫CNVD构建漏洞库
  8. Linux系统移植:NXP 官板 uboot 移植
  9. 给09年考博上海交大安泰经济、金融考生一些建议!【zz】
  10. java javac命令用法_javac命令的用法介绍