1. EBML(Extensible Binary Meta Language)
参考:http://blog.csdn.net/LBO4031/article/details/7591945
http://www.matroska.org/technical/specs/rfc/index.html
mkv是建立在EBML语言基础上的,因此要了解mkv需要先了解EBML语言。
1. EBML元素(EBML elements):
每个EBML文档就是一系列EBML元素的集合。每个EBML基本元素由ID+DATA_SIZE+DATA构成,即:
typedef struct EBML{
vint ID; // EBML-ID
vint size; // size of element
char[size] data;// data
};
数据可以是实际的值(VALUE),也可以是另一个EBML元素集合(数据的实际意义由ID指示)。
ID和size都是vint,也即可变长度整数类型,这种类型的定义参考下面。
2. 值的数据类型:
(所有数据都采用大端模式存储)
a. 变长的无符号整型(vint):
这种类型的长度(所占字节数)为: length = 1 + 整数前缀0bit的个数(number_of_leading_zero_bits),比如,有一段数据: 1A 45 DF A3 A3 42 86...
其中, 1A的二进制为: 00011010,按上面规则,前面有3个0,因此length=1+3=4,因此此整数占4个字节,为: 0x1A45DFA3。
b. 有符号/无符号整型:
采用2的补码的符号表示,size为0-8字节,0字节表示该整数值为0。
c. float型:
采用IEEE float,size为0,4,8或者10字节。0字节表示该float值为0.0。
d string型:
PADDING = 0x00 (结束标识符)
STRING = *BYTE*PADDING (即一个字符串由N个字节的数据和N个结束标识符构成,*表示0-N个)
字符串采用UTF-8编码,注意可以有0个字符串结束标识符,字符串长度也可以是0。
e date型:
有符号8字节整数,以ns表示距离新千年开始的时间(2001-01-01 00:00:00 UTC)
f binary型:
二进制型,即没有在EBML层中解释得数据。
2-1. EBML元素解析示例:
任然以1A 45 DF A3 A3 42 86...为例子:
由2.a中已知,第一个vint整数,即ID为0x1A45DFA3。接下来的数为A3,其二进制表示为:10100011, 即length=1+0=1, 因此此整数占1个字节,为A3,其表示的数字为00100011,即0x23=35,因此,size=35;data为从42开始的35个字节。
(注意,在计算ID时,我们不需要把ID所表示的具体数字算出来;但是在计算size时,我们需要把size所表示的具体数字算出来,即把最高位从1改为0,然后计算值)。
3. 语义解释:
有了上面的知识,我们能够把数据从结构上解析为一个个的EBML元素,但无法知道这些元素表示的是什么意思(即语义解释),语义解释由文档类型定义给出。即:
每个元素都有几个在文档类型定义中定义的属性,这些属性是: name, parent, ID, cardinality, value restricitions, deafult value, value type, child order.
a. name(名字):
NAME = [A-Za-z_]1*[A-Za-z_0-9]
name是一个元素的标识符,而且与元素ID一一对应。只有字幕、数字和下划线可以用于name,且不可以数字开头,不区分大小写。
b. value type(值类型):
只通过EBML数据所给的信息无法得知是否值(data)的类型,因此在EBML的DTD(文档类型定义,参见第5部分)中给出元素值的类型 。除2中给出的数据类型以外,一个元素
还可以是"container"类型,这表示这个元素的内容是更多的元素。
c ID:
每个元素必须有一个ID。
d default value(默认值):
每个非容器元素可以被分配一个默认值。在这种情况下,如果未显式指定这种元素的值,那么将采用这个默认值。
e parent:
在层次结构中放置元素,我们需要知道元素的关系信息。在EBML DTD中这由元素的父元素属性(也可能没有这个属性)表示。有两种表示方法:
可运行的父元素的详细列表,或可运行的潜入深度的一般定义。
PARENTS = NAME / (NAME "," PARENTS)