[时间: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
File Position
Object ID
Object Size
MMS ID
Interval
Max. Packets in Entry
Index Entries
Entry
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

这样我们就可以通过这张表查到需要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 格式

    在互联网常见的格式中,跨平台最好的应该就属MP4文件了.因为MP4文件既可以在PC平台的Flashplayer中播放,又可以在移动平台的Android.iOS等平台中进行播放,而且使用系统默认的播放器 ...

  2. 多媒体文件格式分析 MP3文件结构及编解码流程

    多媒体文件格式分析 http://blog.csdn.net/taniya001/article/details/7962864 多媒体文件格式分析 MP3文件结构及编解码流程 http://www. ...

  3. 多媒体文件格式之MKV

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

  4. 多媒体文件格式之AVI

    [时间:2016-07] [状态:Open] AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchange File Format的缩写)文件 ...

  5. 多媒体文件格式之RMVB

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

  6. 多媒体文件格式之FLV

    [时间:2016-07] [状态:Open] FLV是一个相对简单的多媒体格式,仅支持单节目,也就是说每个FLV只能至多一个音频.至多一个视频.FLV(Flash Video)是Adobe的一个免费开 ...

  7. 多媒体文件格式之MP4

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

  8. 多媒体文件格式(二):FLV 格式

    在网络的直播与点播场景中,FLV也是一种常见的格式,FLV是Adobe发布的一种可以作为直播也可以作为点播的封装格式,其封装格式非常简单,均以FLVTAG的形式存在,并且每一个TAG都是独立存在的,接 ...

  9. 多媒体文件格式(四):TS 格式

    一.TS 格式标准介绍 TS是一种音视频封装格式,全称为MPEG2-TS.其中TS即"Transport Stream"的缩写. 先简要介绍一下什么是MPEG2-TS: DVD的音 ...

随机推荐

  1. JSONObject.parseObject(jsonStr);和JSONObject.fromObject(jsonStr);

    虽然都是返回JSONObject,但是 JSONObject.parseObject(jsonStr);这个方法需要导入import com.alibaba.fastjson.JSONObject; ...

  2. iOS 性能调优

    1.内存空间的划分: 我们知道,一个进程占用的内存空间,包含5种不同的数据区:(1)BSS段:通常是存放未初始化的全局变量:(2)数据段:通常是存放已初始化的全局变量.(3)代码段:通常是存放程序执行 ...

  3. 业务、架构、技术,我们应该关注什么 Java和.Net的优势劣势简单看法 市场经济决定,商业之道即是软件之道,市场的需求决定着软件技术的发展 利益决定着选择应用新技术

    业务.架构.技术,我们应该关注什么 一个企业存在的必然和前提就是获取企业生成的利润,怎么样合法合理取得利润呢,企业怎么样生存下去呢,很简单,为客户提供等值的产品与服务,客户支付你相应的报酬. 我们是从 ...

  4. 【脚下生根】之深度探索安卓OpenGL投影矩阵

    世界变化真快,前段时间windows开发技术热还在如火如荼,web技术就开始来势汹汹,正当web呈现欣欣向荣之际,安卓小机器人,咬过一口的苹果,winPhone开发平台又如闪电般划破了混沌的web世界 ...

  5. Android 获取包名,版本信息

    Android 获取包名,版本信息及VersionName名称     <span style="font-size: 14px;">private String ge ...

  6. Spring Cloud问题分析

    基于Spring Cloud框架开发时,经常会碰到各种开发问题,那么碰到这些问题时如何去解决呢?下面描述基于Spring Cloud问题定位的基本思路,大概可以分为如下几步: 排查配置问题 环境问题 ...

  7. Java中Map相关的快速查找算法与唯一性(转载)

    原文地址:http://blog.csdn.net/chuyuqing/article/details/19629229 在对<Set和hashCode()>的一篇原创文章写完后,由于对自 ...

  8. Mac PATH你所需要了解的

    关于Mac环境变量你需要知道: 0.何为环境变量? 1.如何查看环境变量? 2.如何配置环境变量? 3.如何重置环境变量? 0.环境变量: 所谓环境变量,$PATH,应用于Linux,OS X,Uni ...

  9. appium简明教程(11)——使用resource id定位(仅支持安卓4.3以上系统)

    上一节乙醇带大家了解了appium的定位策略.实际上appium的控件定位方式是完全遵守webdriver的mobile扩展协议的. 这一节将分享一下如何使用resource id来定位android ...

  10. C++中没有finally,那么应该在哪里关闭资源?

    这是一篇有趣的帖子 原文链接: http://bbs.csdn.net/topics/90070457 楼主: C++中没有finally,那么应该在哪里关闭资源? C++的try{}catch(){ ...