LoginSignup
30
28

More than 1 year has passed since last update.

MP4のデータ構造

Last updated at Posted at 2019-08-17

mp4の構成要素

MP4ファイルはBoxとよばれる要素の木構造で構成されている。このBoxはMP4を構成する要素の中で最小単位であり、Atomと呼ばれる。子をもつBoxはContainer boxとも呼ばれる。ちなみにもともとQTFFの方でAtomと呼ばれていて、QTFFを元にMP4が作られたのでそのまま名残でMP4でもAtomと呼ばれているようです。

mp4のBoxは必ずftypeと呼ばれるものから始まり、それ以外のBoxの並び順は、VODで配信する場合はどのような並び順でもOK。だがLODで配信する場合は最初にメタデータを読み込んでから実際のデータを処理する必要があるので、先にmoovという、メタデータが記録されたBox(後述)をロードする必要がある。

Boxの基本構造

  • HeaderとData部分で構成される。
  • 先頭のオクテット(8Byte)がボックスを識別するためのHeaderになっている。
    • オクテットの中でも、最初の4ByteがBoxSize、最後の4ByteがそのType(BoxType)になる。
    • このBoxTypeの部分に、ftype, pdin, moovなどのBox固有のIDがASCII文字列で入る。
  • Data部については、HeaderのBoxSizeにBox全体のサイズが入っているのでHeaderの終わりからBoxSizeて定義されている位置までがBoxDataになる。
    • Headerのサイズは8ByteなのでBoxSize - 8Byte = DataSizeとなる。

ISO/IECでのBox構造定義

aligned(8) class Box (unsigned int(32) box type, 
                      optional unsigned int(8)[16] extended_type) {
    unsigned int(32) size;
    unsigned int(32) type = boxtype;
    if (size == 1) {
        unsigned int(64) largesize;
    } else if (size == 0) {
        // box extends to end of file
    }
    if (boxtype == 'uuid') {
        unsigned int(8)[16] usertype = extended_type;
    }
}

以下にmp4のBox一覧を列挙してみる。rootのBoxについてはこれで全部ですが、子要素のBoxは以下に記載しているもの以外にもたくさんあります。ちなみに、特にmoov内のstblがキモになってくる。

sample.mp4
  ├ ftyp
  ├ pdin
  ├ moov
  │   ├ mvhd
  │   ├ trak(movie)
  │   │   ├ tkhd
  │   │   ├ tref
  │   │   ├ edts
  │   │   |  └ elst
  │   │   └ mdia 
  │   │      ├ mdhd
  │   │      └ minf(Media Information Box)
  │   │         └ stbl
  │   │            └ stco
  │   ├ trak(audio)
  │   │   └ ...trak(movie)のchildrenと一緒
  │   ├ trak(hint)
  │   ├ mvex(extended box)
  │   └ ipmc(hint)
  ├ moof
  │   ├ mfhd
  │   └ traf
  ├ mfra
  ├ mdat
  ├ free(free space)
  ├ skip(free space)
  │   └ udta(user data)
  └ meta

以下にファイルのrootに配置されるボックスについて書いてみる。

ftype(File type)

ファイルがどのtypeに準拠しているかを表す。Boxの並び順としては一番最初に配置されている必要がある。

構造

aligned(8) class FileTypeBox
 extends Box(‘ftyp’) {
 unsigned int(32) major_brand;
 unsigned int(32) minor_version;
 unsigned int(32) compatible_brands[]; // to end of the box
} 

ftype一覧: http://www.ftyps.com/

minor_versionmajor_brandのマイナーバージョンを定義するみたいですが、ほぼ活用されないようなので全部0で埋めても問題ないケースが多いようです。
compatible_brandsは互換性があるmajor_brandを列挙できるみたいですが、こちらも必須ではないようで、空白でもいけるようです。

moov

moovボックスの中には動画のメタデータが定義されていて、その配下にtrak、mvhdボックスなどのボックスが入れ子になっている。
動画・音声のメディアデータをそれぞれ1trakとし、「movieのtrak」「audioのtrak」というように複数のtrakが同じ階層に配置される。
DRMを扱う場合は、複合の際に使うPSSHなどといったデータもこのボックスに格納される。

trakでは、動画・音声データがどのように配置されているかを記録していて、再生する際はこのtrakの情報を元にメディアデータをシークする。そのため、LODではmoovボックスが最初に読み込まれる必要がある。

そしてtrak配下のmdhdではトラックのメタデータや再生時間などを定義している。

mdat(Media data box)

メディアデータを格納するBoxで、動画・音声両方を格納できる。
mdatをデコードするには、moov -> trak -> mdia -> minf -> stbl配下のメタデータをパースする必要がある。このstbleを読み解くために、他の諸々のBox定義も理解しないといけなくてなかなか難しいらしい。

ユーザー定義Box

記事上部に記載したBox構造を見てみると、Boxではオプショナルでextended_typeというものが定義できる。

ユーザー定義のBoxを使うときはBoxTypeにはuuidを指定し、extended_typeではユーザが任意に作成した16Byteのuuidを格納する。するとBoxDataでは自由なデータを指定することができ、ユーザー定義Boxとして使うことができる。

Full Box

FullBoxの定義

aligned(8) class FullBox(unsigned int(32) boxtype, unsigned int(8) v, bit(24) f)
 extends Box(boxtype) {
 unsigned int(8) version = v;
 bit(24) flags = f;
} 

FullBoxとは、Boxを拡張してversionとflagフィールドをヘッダーに持てるようにしたもの。実際に扱われるのはFull Boxが多かったりする。

参考文献

30
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
28