inside webm

23
Inside of WebM 2015.06.06 イイイイイイイイイイ イイイイイイ @massie_g 1

Upload: mganeko

Post on 26-Jul-2015

102 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Inside WebM

Inside of WebM

2015.06.06インフォコム株式会社

がねこまさし@massie_g

1

Page 2: Inside WebM

WebM とは• Wikipedia より http://ja.wikipedia.org/wiki/WebM– 米 Google が開発している– オープンでロイヤリティフリーな– 動画コンテナフォーマット

• コーデック– 映像: VP8 / VP9– 音声: Vorbis

• コンテナ– Matroska のサブセット

Page 3: Inside WebM

Matroska• Wikipedia より  http://ja.wikipedia.org/wiki/Matroska

– ロシアの入れ子人形マトリョーシカにちなむ– オープンソース( GNU LGPL )で開発中– EBML ( Extensible Binary Meta Language )採用– http://www.matroska.org/technical/specs/index.html– こちらの記事からたどり着きました。ありがとうございます!

• Media Source Extensions を使ってみた (WebM 編 ) @othersight• http://qiita.com/tomoyukilabs/items/57ba8a982ab372611669

• EBML ( Extensible Binary Meta Language )– XML を基に作られた、拡張性に優れたデータ格納方式

• 要素のみ、属性なし、入れ子あり• ※ むしろ YAML と言った方が近いかも

– 対応していない機能 ( タグ ) は無視する– テキストではなくバイナリで表現

Page 4: Inside WebM

EMBL のイメージ<EBML>

<EBMLVersion>1</EBMLVersion><DocType>webm</DocType>

</EBML><Segment> …

<Info> … </Info><Tracks> … </Tracks><Cluster> … </Cluster><Cluster> … </Cluster>…

</Segment>

これがバイナリで格納されている

Page 5: Inside WebM

WebM のおおまかな構造

ヘッダー 部分

映像 / 音声 部分

おまけ 部分

Header

Meta Seek Info

Segment InfoTracks

(Chapters)

ClusterClusterCluster

Cluster

(Cue Data)(Attachment)

(Tagging)

Matroska 的

EBML

Segment

WebRTC 的

Page 6: Inside WebM

Header の主要要素EBML:[1A][45][DF][A3]... EBML 形式であることを示す

EBMLVersion:[42][86]… EBML のバージョン 1EBMLMaxIDLength:[42][F2]…ID( タグ ) の最大長 4EBMLMaxSizeLength:[42][F3]…

要素値のサイズを指定する数値の最大バイト数 8

DocType:[42][82]… ファイル形式” webm”DocTypeVersion:[42][87]… ファイル形式のバー

ジョン

Header

Page 7: Inside WebM

Header の主要要素EBML:[1A][45][DF][A3]... EBML 形式であることを示す

EBMLVersion:[42][86]… EBML のバージョン 1EBMLMaxIDLength:[42][F2]…ID( タグ ) の最大長 4EBMLMaxSizeLength:[42][F3]…

要素値のサイズを指定する数値の最大バイト数 8

DocType:[42][82]… ファイル形式” webm”DocTypeVersion:[42][87]… ファイル形式のバー

ジョン

Header

ファイル名が変更されて拡張子がなくても・先頭の 4 バイトが 0x1A, 0x45, 0xDF, 0xA3 であれば、高確率でWebM・さらに DocType の値を見れば、 WebM であることがほぼ確定

Page 8: Inside WebM

Segment Info の主要要素Info:[15][49][A9][66]

TimecodeScale:[2A][D7][B1]… トラックの時刻を示す単位を、ナノ秒で指

定 →1,000,000 ナノ秒 = 1 ミリ秒Duration:[44][89]… 映像 / 音声の長さ

TimecodeScale を単位として示す※ 不明(継続中)の場合は 0

Segment Info

Page 9: Inside WebM

Segment Info の主要要素Info:[15][49][A9][66]

TimecodeScale:[2A][D7][B1]… トラックの時刻を示す単位を、ナノ秒で指

定 →1,000,000 ナノ秒 = 1 ミリ秒Duration:[44][89]… 映像 / 音声の長さ

TimecodeScale を単位として示す※ 不明(継続中)の場合は 0

Segment Info

TimecodeScale で、この後登場する時刻、時間の単位を指定・仕様上ナノ秒単位でも指定できるので、光の動きも捉えられそうDuration では再生時間を指定・ MediaRecorder で録画したものでは、 0( ゼロ ) が指定

Page 10: Inside WebM

Tracks の主要要素Tracks:[16][54][AE][6B]… Video/Audio トラックのセット

TrackEntry:[AE]… トラックTrackNumber : [D7]CodecName:[25][86][88]TrackType:[83] … Video/AudioVideo:[E0]

PixelWidth:[B0]PixelHeight:[BA]FrameRate:[23][83][E3]

Audio:[E1]SamplingFrequency:[B5]Channels:[9F]

Tracks

Page 11: Inside WebM

Track についてTracks

・仕様上は、 Track は 127 個まで入れることが可能 ※今のところ、 Video が 1 つ、 Audio が 1 つ、というケースしか見たことがない・ TrackType は、 Video/Audio 以外にも字幕、ロゴなどが用意されている模様

Page 12: Inside WebM

Cluster の主要要素Cluster[1F][43][B6][75]… 実際の Video と Audio の断片を格納

Timecode:[E7] … その断片の開始時刻 (TimecodeScale の値単位 )

SimpleBlock : [A3] …Video か Audio の断片。複数※SimpleBlock の中身は、 EBML 形式ではない

Cluster

Page 13: Inside WebM

Cluster の主要要素Cluster[1F][43][B6][75]… 実際の Video と Audio の断片を格納

Timecode:[E7] … その断片の開始時刻 (TimecodeScale の値単位 )

SimpleBlock : [A3] …Video か Audio の断片。複数※SimpleBlock の中身は、 EBML 形式ではない

Cluster

・実際の映像 (Video) と音声 (Audio) のデータは Cluster に含まれる・一つの WebM ファイルには複数の Cluster が含まれる

Page 14: Inside WebM

WebM/Matroska/EBMLバイナリのレイアウト

Page 15: Inside WebM

EBML

EBMLVersion

“webm”

Segment

1

Tracks

CodecName

“VP8”

DOCType

Page 16: Inside WebM

タグ /Element のバイナリ表現

• 3 つのパートでタグ /Element は構成される

ID DataSize Data

1 ~ 4 バイト 1 ~ 8 バイト 0 ~ 0x00FFFFFFFFFFFFFE バイト      ペタバイト級まで

可変長 可変長

可変長

実際のデータだけでなく、 ID も DataSize も可変長厄介なヤツ。マジ勘弁…

Page 17: Inside WebM

ID 部のバイナリ表現1 バイト目 (2 進 )

1xxx-xxxx

01xx-xxxx xxxx-xxxx

001x-xxxx xxxx-xxxx xxxx-xxxx

0001-xxxx xxxx-xxxx xxxx-xxxx xxxx-xxxx

0x80 ~ 0xFF

0x40 ~ 0x7F

1 バイト目 (16 進 )

0x20 ~ 0x3F

0x10 ~ 0x1F

※ 先頭ビットも、 ID の値に含める

Page 18: Inside WebM

DataSize 部のバイナリ表現

xxxx-xxxxxxxx-xxxx xxxx-xxxxxxxx-xxxx xxxx-xxxx xxxx-xxxxxxxx-xxxx0000-0001

xxxx-xxxxxxxx-xxxx xxxx-xxxxxxxx-xxxx xxxx-xxxx xxxx-xxxx0000-001x

xxxx-xxxxxxxx-xxxx xxxx-xxxxxxxx-xxxx xxxx-xxxx0000-01xx

xxxx-xxxxxxxx-xxxx xxxx-xxxxxxxx-xxxx0000-1xxx

xxxx-xxxxxxxx-xxxx xxxx-xxxx0001-xxxx

xxxx-xxxxxxxx-xxxx001x-xxxx

xxxx-xxxx01xx-xxxx

1xxx-xxxx

1 バイト目 (2 進 )

7bits

14bits

21bits

28bits

35bits

42bits

49bits

56bits

値は Big Endian の Unsigned Integer※ 先頭ビットは、 DataSize の値に含めない※ すべてのビットが 1 の値は予約済(多分)

Page 19: Inside WebM

Data 部分• DataSize で指定されたバイト数• タグ (ID) の種類によって、さまざま型– 整数: unsigned int, signed int (Big Endian)– 文字列 : ASCII string, UTF-8 string– 実数: float (Big Endian)– 日付 : date (Big Endian)– バイナリ : binary– 他の複数のタグ: master

• タグの入れ子の構造• 型を識別するルールは無い …みたい– タグの値と型を対応付ける辞書を持つしかなさそう– http://www.matroska.org/technical/specs/index.html

Page 20: Inside WebM

20

http://www.matroska.org/technical/specs/index.html より

ID 型

Page 21: Inside WebM

解析例 (1) EBMLVersion

• 16 進表記: 42 86 81 01• ID の最初のバイトの 2 進表記: 0100 0010– → ID は 2 バイトの [42][86]– 一覧表から、 EBMLVersion と判明

• DataSize の最初のバイトの 2 進表記: 1000 0001– → DataSize は 1 バイト– サイズは 0000 0001 = 1 バイト

• Data は 1 バイト。先ほどの一覧表から、型は Unsigend Int– → 値は 1

• 結果:  EBMLVersion = 1

Page 22: Inside WebM

解析例 (2) DocType

• 16 進表記: 42 86 84 77 65 62 6D• ID の最初のバイトの 2 進表記: 0100 0010– → ID は 2 バイトの [42][84]– 一覧表から、 DocType と判明

• DataSize の最初のバイトの 2 進表記: 1000 1000– → DataSize は 1 バイト。サイズは 0000 1000 = 4 バイ

ト• Data は 4 バイト。先ほどの一覧表から、型は ASCII string– 77 65 62 6D →  値は "webm"

• 結果:  DocType = "webm"

Page 23: Inside WebM

WebM のパース• 先頭から 1 バイトづつパースしていけば、タグの内容を

解析可能• とくに興味が無いタグや、理解できないタグが出現した

場合– データー長はルールに従って算出可能 → スキップすることが可

• ※ もちろんライブラリもあります– libebml http://dl.matroska.org/downloads/libebml/– libmatroska http://dl.matroska.org/downloads/libmatroska/– yamka https://sourceforge.net/projects/yamka/※ 使ってはいません。詳細不明

• Node.js のサンプルコードを書いてみました– https://gist.github.com/mganeko/9ceee931ac5dde298e81– メモリ上に一括して読み込む、しょぼい実装ですが…