« 吉里吉里Java に組み込むプラグイン | メイン | 動画再生でサーバーエラーが出る場合の対処 »

2012年09月19日

Misc.:: Matroska のファイル構造

    

MKV ( Matroska ) のファイルフォーマットは、Matroska のページに載っている。
WebM もコンテナは Matroska 。
Matroska を扱うライブラリとして、libmatroska があるんだけど、LGPL 。

基本構造
Matroska の基本構造は、よくある ID + size でチャンクを構成すると言うもの。
XML のように入れ子構造にはなっているが、基本はチャンク構造と同じ。
ただ、ID も サイズも可変長になっているのでその辺り少し取り扱いに注意がいる。
ID は1~4バイト。
MSB から 4ビットの範囲でどこにビットが立っているかで ID 長が決定される。
つまり、以下のような形。

2進数バイト長
1xxx xxxx1バイト
01xx xxxx xxxx xxxx2バイト
001x xxxx xxxx xxxx xxxx xxxx3バイト
0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx4バイト

ID は、長さを表すビット部分も含んだ形で ID となっている。
つまり、ID の値を見れば長さがわかる。

サイズも同様にどこにビットが立っているかで長さが決まる。
サイズの場合は8バイトまで許容されている。

2進数バイト長
1xxx xxxx1バイト
01xx xxxx xxxx xxxx2バイト
001x xxxx xxxx xxxx xxxx xxxx3バイト
0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx4バイト
0000 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx5バイト
0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx6バイト
0000 001x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx7バイト
0000 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx8バイト

サイズは ID と異なり、MSB から最初に1が立っているところまでは無視して、残りで長さを表す。
仮想コードで書くのなら、以下のような形。

u8 v = firstByte;
u8 len = 0;
for( int i = 0; i < 8; i++ ) {
  if( (v & (0x80>>i)) != 0 ) {
    len = i+1;
    break;
  }
}
u8 mask = (0x80 >> (len-1));
mask -= 1;
u64 ret = v & mask;
for( int i = 0; i < (len-1); i++ ) {
  v = stream.readByte();
  ret <<= 8;
  ret |= (((u64)v)&0xff);
}

サイズは、ID と サイズ部分の長さを含まない。
つまり、サイズを読み込んだ後、そのサイズ分シークすれば次のチャンク ( Element ) に飛べる。

ここまでの情報があれば、後は上述の Matroska のファイルフォーマットのページを見て、それぞれの値や入れ子構造を見てデータを読み込める。
入れ子の深さを表す Level と、複数格納されている可能性があるかどうかの Multiple 、必須かどうかの Mandatory、後は Element Type の integer や string などに注意して表を見ればだいたい問題ない。



投稿者 Takenori : 2012年09月19日 18:25




comments powered by Disqus
Total : Today : Yesterday : なかのひと