一覧 検索 最終更新 改名 | ヘルプ | 最終更新のRSS |

HDDレコーダーのHDDの中をみる のバックアップソース(No.5)

''目次''
#contents

#br

* RD-X4 HDDの中を見る [#p462eab7]

『「高速ダビング」の処理速度を考えると、DVD-RAMのデータと同様な形式でHDDに記録されているのでは?』という予測を立ててみた。
この予測通りなら、packデータの連続性を補完することが出来れば、最低限ではあるものの、「見られるデータ」が取得できることになる。

そこで、

** HDDの中身を見る前に、RD-X4で記録したDVD-RAMのデータを見ると、 [#rcf06d0d]

2048バイトごとに、pack_headerが現れる = packは2048バイト固定
MPEG_program_end_codeは存在しない
タイトルのsystem_clock_referenceは常に0から始まる
ただし、タイトルではなくチャプタを高速ダビングしたときのsystem_clock_referenceは0から始まらない → オリジナルのsystem_clock_referenceが引き継がれている
system_headerは、45045/90000秒ごとに現れる
同一タイトルと思われる範囲のデータで、system_headerを含むpackからある程度の長さのデータを抜き出して、拡張子mpgのファイル化して再生を試みると再生できる
となっていた。

つまり、この予測を確認するためには

2048バイトごとに、「00 00 01 BA」のバイト列が出現する
という事が確認できれば良いということになる。
ということで、「00 00 01 BA」のバイト列を探すプログラムを作成し、実行してみたが、無かった。

暗号化でもしているのかと思い、100GB目くらいの辺りのデータを見ると、

 00 00 BA 01 ....

というデータが2048バイトごとに現れている。
要するに、 2バイト単位でバイトスワップしている ということらしい。
まぁ、CPUと、IDEコントローラの間のバイトオーダが異なっている事から、PCで見たときにスワップして見えるとかなのでしょう。

ということで、バイトスワップを考慮してHDDを再度チェックすると、先頭から0x000FA110 * 0x800バイト目から始まっていることがわかった。

また、たいていのファイルシステムは、複数のセクタを一まとめにしたクラスタという単位でファイルアクセスをするので、RD-X4でも、同じようにクラスタ的な概念があるか検証してみる。
これには、system_clock_referenceが0のpackの位置をチェックしていけばよい。
そこでチェックしたところ、16 * 2048バイト単位であるらしいことがわかった。

ここまでわかったことを実証するために、DVD-RAMで行った、「同一タイトルと思われる範囲のデータで、system_headerを含むpackからある程度の長さのデータを抜き出して、拡張子mpgのファイル化して再生を試みる」を実施したところ、無事再生に成功。

一番最低のレベルではあるものの、データの抜き出しに一応成功。

** まとめ [#za6435ed]

HDDのデータは奇数バイトと偶数バイトが逆になっている
MPEG-2 Program Streamのデータは、HDDの先頭から0x000FA110 * 0x800バイト目の位置以降に記録されている
MPEG-2 Program Streamのデータは、32KB(16*2048バイト)単位で記録されている

* HDDの中を見る(UDF編) [#j4f7617a]

UDFの基礎を踏まえて、RD-X4のHDDを見る。
なお、IDE HDDのセクタ長は512バイトであるが、ここでは、ファイルシステムの設定どおり、セクタ長を2048バイトとして記述していく。

256セクタ目までは、

 セクタ  識別子
 0〜15  未使用
 16  Beginning Extended Area Descriptor
 17  Volume Structure Descriptor(NSR03 Descriptor)
 18  Terminating Extended Area Descriptor
 19〜31  未使用
 32  Primary Volume Descriptor
 33  Implementation Use Volume Descriptor
 34  Partition Descriptor
 35  Logivcal Volume Descriptor
 36  Unallocated Space Descriptor
 37  Terminating Descriptor
 38〜47  未使用
 48  Logical Volume Integrity Descriptor
 49  Terminating Descriptor
 50〜255  未使用
 256  Anchor Volume Descriptor Pointer

の様になっている。

Partition Descriptorには、

 Partition Starting Location 0x110
 Partition Length 0x0746944a

の値が記録されている。
これらは、論理セクタの配置で、

論理セクタ(0)は、物理セクタ0x110から始まる
論理セクタは、0x0746944a(122065994)セクタある
という意味になる。

このセクタ数に関しては、Logical Volume Integrity Descriptorでも、

Size Table 0x0746944a

と同じ値が指定されている。

また、Anchor Volume Descriptor Pointerは、

Main Volume Descriptor Sequence Extent 0x20セクタ
Reserve Volume Descriptor Sequence Extent 0x07469570セクタ

と、Volume Descriptor Sequenceの開始位置を指定しているらしい。

と言う事は、0x0746944aなどの値と、Allocation情報を変える事で、500GBなどの容量にする事が出来るのか?


論理セクタ0に相当する、物理セクタ0x110は、

 08 03 03 00 C9 00 00 00  B8 FB 08 00 00 00 00 00
 45 69 74 00 29 8D 0E 00  00 00 00 00 00 00 00 00

と、0x0308というtag値となっていて、一見、ゴミのようにも見えるのだが、Descriptor Tagの

TagChecksum
TagLocation
の各値がそれらしいものになっている。

論理セクタ466以降は、

セクタ 識別子

 466(0x1d2) File Set Descriptor
 467(0x1d3) Terminating Descriptor
 468(0x1d4) File Entry
 469(0x1d5) File Identifier Descriptor

の様なDescriptorが記述されている。

File Set Descriptor
ルートディレクトリを格納している識別子の位置情報などの、ファイル構造が定義されている

 0000  00 01 03 00 2C 00 00 00  76 EE F0 01 D2 01 00 00
 0010  1C 12 D7 07 01 15 10 32  18 56 5A 00 03 00 03 00
 0020  01 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00
 ・・・・・・・・・
 0190  00 08 00 00 D4 01 00 00  00 00 00 00 00 00 00 00
 01A0  00 2A 4F 53 54 41 20 55  44 46 20 43 6F 6D 70 6C
 01B0  69 61 6E 74 00 00 00 00  00 02 00 00 00 00 00 00

0x190(400)バイト目(long_ad)の、Root Directory ICBの値が、「セクタ0x1d4から0x800バイト」と記述されているので、ルートディレクトリのFile Entryが論理セクタ0x1d4にある(はず)

File Entry
ディレクトリの属性情報で、Extended Attribute Header Descriptorをパラメータとして持つことが出来る

 0000  05 01 03 00 35 00 00 00  AF 5B 4C 01 D4 01 00 00
 0010  00 00 00 00 04 00 00 00  01 00 00 04 D4 01 00 00
 0020  00 00 20 00 FF FF FF FF  FF FF FF FF D6 5A 00 00
 ・・・・・・・・・
 0090  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00
 00A0  00 00 00 00 00 00 00 00  A4 00 00 00 08 00 00 00
 00B0  06 01 03 00 71 00 00 00  C9 C1 08 00 D4 01 00 00
 00C0  38 00 00 00 FF FF FF FF  05 00 00 00 01 00 00 00
 ・・・・・・・・・
 0140  65 00 00 00 00 00 00 00  00 02 00 00 00 00 00 00
 0150  60 05 00 00 48 01 00 00  D5 01 00 00 00 00 00 00

0xa8(168)バイト目は、Length of Extended Attribute(0xa4バイト)
0xac(172)バイト目は、Length of Allocation Descriptor(0x08バイト)
0xb0(176)バイト目からは、Extended Attribute領域で、Extended Attribute Header Descriptorが0xa4(164)バイト配置されている
0x154(340)バイト目からは、Allocation Descriptor(short_ad)で、このディレクトリに対するFile Identifier Descriptorの論理セクタ位置が指定されている(→ 論理セクタ0x01d5にFile Identifier Descriptorが存在する)

File Identifier Descriptor
ディレクトリや、ファイルの名前、開始位置などの情報が配列状に格納されている

 0000  01 01 03 00 F1 00 00 00  53 AB 18 00 D5 01 00 00
 0010  01 00 0A 00 00 08 00 00  D4 01 00 00 00 00 00 00
 0020  00 00 00 00 00 00 00 00  01 01 03 00 E3 00 00 00
 0030  A0 48 20 00 D5 01 00 00  01 00 02 09 00 08 00 00
 0040  E0 01 00 00 00 00 00 00  12 00 00 00 00 00 08 54
 0050  53 5F 4D 41 4E 47 52 00  01 01 03 00 C1 00 00 00
 0060  A3 23 20 00 D5 01 00 00  01 00 02 09 00 08 00 00
 ・・・・・・・・・
 0120  08 4C 20 00 D5 01 00 00  01 00 02 09 00 08 00 00
 0130  20 52 04 00 00 00 00 00  21 00 00 00 00 00 08 54
 0140  53 5F 50 46 44 41 54 00  00 00 00 00 00 00 00 00

0x00バイト目は、最初のFile Identifier Descriptor
0x12(18)バイト目は、File Characteristicsで、b1:ディレクトリ、b2:親ディレクトリ情報となり、この場合、0x0aなので、親ディレクトリの情報を格納しているFile Identifier Descriptorとなる
0x14(18)バイト目は、ICBの位置(long_ad)で、この場合のICBは、File Entryで、論理セクタ0x1d4からの0x800バイトとなっている
0x28(40)バイト目は、二番目のFile Identifier Descriptor
0x3a(58)バイト目は、File Characteristicsで、0x02なので、ディレクトリエントリとなる
0x3c(60)バイト目は、ICBの位置(long_ad)で、この場合、論理セクタ0x1e0からの0x800バイトとなっている
0x4e(78)バイト目は、ディレクトリ名で、"TS_MANGR"となる
0x58(88)バイト目は、三番目のFile Identifier Descriptor
……

TS_MANGRディレクトリのFile Entry(論理セクタ0x1e0)を見ると、

 0000  05 01 03 00 7C 00 00 00  FE 47 4C 01 E0 01 00 00
 0010  00 00 00 00 04 00 00 00  01 00 00 04 00 00 00 00
 0020  00 00 00 00 FF FF FF FF  FF FF FF FF D6 5A 00 00
 ・・・・・・・・・
 0090  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00
 00A0  12 00 00 00 00 00 00 00  A4 00 00 00 08 00 00 00
 00B0  06 01 03 00 7D 00 00 00  C9 C1 08 00 E0 01 00 00
 00C0  38 00 00 00 FF FF FF FF  05 00 00 00 01 00 00 00
 ・・・・・・・・・
 0140  65 00 00 00 00 00 00 00  00 02 00 00 00 00 00 00
 0150  60 05 00 00 C0 01 00 00  F0 01 00 00 00 00 00 00

実は、0x1d4と大差なく、Allocation Descriptor(short_ad)の値が、0x1f0となっている(→ 論理セクタ0x01f0にFile Identifier Descriptorが存在する)

TS_MANGRディレクトリのFile Identifier Descriptor(論理セクタ0x1f0)を見ると、

 0000  01 01 03 00 0C 00 00 00  53 AB 18 00 F0 01 00 00
 0010  01 00 0A 00 00 08 00 00  D4 01 00 00 00 00 00 00
 0020  00 00 00 00 00 00 00 00  01 01 03 00 9B 00 00 00
 0030  EB 9A 20 00 F0 01 00 00  01 00 00 09 00 08 00 00
 0040  60 02 00 00 00 00 00 00  16 00 00 00 00 00 08 54
 0050  53 47 49 2E 49 46 4F 00  01 01 03 00 55 00 00 00
 0060  F4 47 24 00 F0 01 00 00  01 00 00 0D 00 08 00 00
 ・・・・・・・・・
 0190  58 00 00 00 F2 4C 24 00  F0 01 00 00 01 00 00 0D
 01A0  00 08 00 00 30 AA 04 00  00 00 00 00 28 00 00 00
 01B0  00 00 08 52 53 56 44 45  54 41 49 2E 49 46 4F 00
 01C0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

0x00バイト目は、最初のFile Identifier Descriptor
0x12(18)バイト目は、0x0aなので、親ディレクトリの情報を格納しているFile Identifier Descriptorとなる
0x14(18)バイト目は、ICBの位置(long_ad)で、この場合、子ディレクトリなので、値が入っていない
0x28(40)バイト目は、二番目のFile Identifier Descriptor
0x3a(58)バイト目は、File Characteristicsで、0x00なので、ファイルとなる
0x3c(60)バイト目は、ICBの位置(long_ad)で、この場合、論理セクタ0x260からの0x800バイトとなっている
0x4e(78)バイト目は、ファイル名で、"SGI.IFO"となる
0x58(88)バイト目は、三番目のFile Identifier Descriptor
……

** SGI.IFOファイルのFile Entry(論理セクタ0x260)を見ると、 [#ma64afb9]

 0000  05 01 03 00 F1 00 00 00  91 A8 4C 01 60 02 00 00
 0010  00 00 00 00 04 00 00 00  01 00 00 05 00 00 00 00
 0020  00 00 00 00 FF FF FF FF  FF FF FF FF D6 5A 00 00
 ・・・・・・・・・
 0090  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00
 00A0  16 00 00 00 00 00 00 00  A4 00 00 00 08 00 00 00
 00B0  06 01 03 00 FE 00 00 00  C9 C1 08 00 60 02 00 00
 00C0  38 00 00 00 FF FF FF FF  05 00 00 00 01 00 00 00
 ・・・・・・・・・
 0140  65 00 00 00 00 00 00 00  00 02 00 00 00 00 00 00
 0150  60 05 00 00 00 08 00 00  70 02 00 00 00 00 00 00

今までのFile Entryと大差なく、Allocation Descriptorのpointer値が、0x270となっている(→ 論理セクタ0x0270にSGI.IFOのデータが存在する)

** ディレクトリ構造 [#x5ce4c8a]

上記の様な手順で、ディレクトリツリーを辿った結果、

ルート
TS_MANGR
■TSGI.IFO
■TTLUTLTY.IFO
■TTDETAIL.IFO
■DISC.IFO
■DISCNO2.IFO
■TMPMENU.DAT
■USRMENU.DAT
■RSVDETAI.IFO
TS_THMNL
■THMNL_SM.DAT
■THMNL_LR.DAT
TS_LOG
■RECLOG2.IFO
TS_LBRRY
■LIBRARY2.IFO
■LIBDETAI.IFO
TS_HDDAV
■TMAPDATA.IFO
■TS_HDDMV.DAT
■TS_HDDMG.BUP
■TS_HDDMG.IFO
TS_PFDAT
■TS_PFTHD.DAT
■TS_PFTDV.DAT

という結果となった。

MPEG-2 PSデータと直接関係するファイルを、DVD-RAMのファイルと対比させると

DVD-RAM  RD-X4 HDD
VR_MOVIE.VRO  \TS_HDDAV\TS_HDDMV.DAT
VR_MANGR.IFO  \TS_HDDAV\TS_HDDMG.IFO

ということになる。

** TS_HDDMV.DAT [#u6e5419b]

このファイルが、MPEG-2 PSデータそのものとなる。

このファイルのFile Entry(論理セクタ0x455c0)を見てみると

 0000  05 01 03 00 9C 00 00 00  1C 6B EC 07 C0 55 04 00
 0010  00 00 00 00 04 00 00 00  01 00 00 F9 00 00 00 00
 0020  00 00 10 00 FF FF FF FF  FF FF FF FF D6 5A 00 00
 ・・・・・・・・・
 0090  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00
 00A0  24 00 00 00 00 00 00 00  A4 00 00 00 A8 06 00 00
 00B0  06 01 03 00 B5 00 00 00  C9 C1 08 00 C0 55 04 00
 00C0  38 00 00 00 FF FF FF FF  05 00 00 00 01 00 00 00
 ・・・・・・・・・
 0140  65 00 00 00 00 00 00 00  00 02 00 00 00 00 00 00
 0150  60 05 00 00 00 58 89 02  00 A0 0F 00 00 00 6D 40
 0160  30 F1 0F 00 00 80 FF 7F  D0 FE 0F 00 00 80 FF 7F
 0170  C0 FE 17 00 00 80 FF 7F  B0 FE 1F 00 00 80 FF 7F
 0180  A0 FE 27 00 00 80 FF 7F  90 FE 2F 00 00 80 FF 7F
 ・・・・・・・・・
 07E0  E0 F1 87 06 00 80 FF 7F  D0 F1 8F 06 00 80 FF 7F
 07F0  C0 F1 97 06 00 08 00 C0  E0 55 04 00 00 00 00 00

0xac(172)バイト目は、Length of Allocation Descriptor(0x6a8バイト)と大きな値と なっている
0x154(340)バイト目は、最初のファイルの位置と長さ(0x0fa000から、記録済み    0x02895800バイト)の指定
0x15c(348)バイト目は、二番目のファイルの位置と長さ(0x0ff130から、未記録 0x006d0000バイト)の指定
0x164(356)バイト目は、三番目のファイルの位置と長さ(0x0ffed0から、未記録0x3fff8000バイト)の指定
0x7ec(2028)バイト目は、0x0697f1c0から、未記録0x3fff8000バイト)の指定
0x7f4(2036)バイト目は、0x0455e0から、次のAllocation情報が0x800バイト続く

さらに、論理セクタ0x455e0(Alloocation Extent Descriptor)を見てみると

 0000  02 01 03 00 09 00 00 00  D1 F1 08 00 E0 55 04 00
 0010  00 00 00 00 B0 00 00 00  00 80 FF 7F B0 F1 9F 06
 0020  00 80 FF 7F A0 F1 A7 06  00 80 FF 7F 90 F1 AF 06
 0030  00 80 FF 7F 80 F1 B7 06  00 80 FF 7F 70 F1 BF 06
 0040  00 80 FF 7F 60 F1 C7 06  00 80 FF 7F 50 F1 CF 06
 ・・・・・・・・・
 00B0  00 80 FF 7F 80 F0 37 07  00 80 1E 75 70 F0 3F 07
 00C0  00 28 00 40 2B F1 0F 00  00 00 00 00 00 00 00 00

0x14(20)バイト目は、Length of Allocation Descriptor(0xb0バイト)
0x18(24)バイト目は、このタグでの最初のファイルの位置と長さ(0x069ff1b0から、未記録0x3fff8000バイト)の指定
0x24(36)バイト目は、次のファイルの位置と長さ(0x06a7f1a0から、未記録0x3fff8000バイト)の指定
0xbc(188)バイト目は、最後のファイルの位置と長さ(0x0ff12bから、未記録0x2800バイト)の指定

これらを整理すると

開始セクタは、論理セクタの0x0fa000で、論理セクタは、物理セクタ0x110から始まっているので、物理セクタ0x0fa110となる
ファイルのAllocationは、
 開始セクタ番号 長さ(バイト数) 長さ(セクタ数)  次のセクタ番号
 最初のshort_ad  0x000fa000  0x2895800  0x512b  0x000ff12b
 二番目のshort_ad  0x000ff130  0x06d0000  0x0da0  0x000ffed0
 三番目のshort_ad  0x000ffed0  0x3fff8000  0x7fff0  0x0017fec0
 四番目のshort_ad  0x0017fec0  0x3fff8000  0x7fff0  0x001ffeb0
 最後のshort_ad  0x000ff12b  0x2800  0x0005  0x000ff130

となり、

順番は前後しているものの、全てのセクタがAllocation管理下にあることが分る。
未使用領域の16セクタ未満のセクタは、最後に未使用領域としてリンクされる


ということで、\TS_HDDAV\TS_HDDMV.DATを抜き出して、使用領域が16セクタ未満のブロック位置や、pack_headerのsystem_clock_referenceが大きく外れるところで区切ってあげれば、(ほぼ、タイトル通りの内容を)パソコンで再生する事は出来る。

* DVD-RAMのIFOファイル [#uc4fa0af]

タイトルとクリップの紐付け情報が記録されていると思われるIFOファイルの構造を調べてみるために、DVD-RAMのIFOファイル(VR_MANGR.IFO)を見る。
この構造は、DVD-VR(DVD Video Recording Format)仕様のものだと思われる。しかし、DVD-VRの仕様書を見つける事が出来なかったので、地道に色々なデータを書き込んで検証する事に…。

とりあえず、色々な形式のIFOファイルの資料を見ていると、IFOファイルの内部は、複数のデータブロックの寄せ集めらしい事が分った。
また、これらのデータブロックに対するアドレス指定が、ヘッダの中に記述されているらしい事も。

と言う事で、以下のブロックがあると思われる(当然のことながら正式名称は不明)

ヘッダ
プレイリスト
クリップリスト
不明1
タイトルリスト
ベンダ情報

※これらのブロック中の数値はBig Endian

** ヘッダ [#ba222e39]

 位置  長さ  内容 
 0000   0C   識別子('DVD_RTR_VMG0')
 000C   04   このIFOファイルの終端位置(= ファイル長 - 1)
 0010   04   「プレイリスト」ブロックの終端位置(ここまでが、本来のIFOブロックなのか?)
 006C   04   ディスク番号?
 00A2   3D   ディスクタイトル
 0100   04   「クリップリスト」ブロックの開始位置
 0104   04   「不明1」ブロックの開始位置
 0130   04   「タイトルリスト」ブロックの開始位置
 0164   04   「ベンダ情報」ブロックの開始位置

** プレイリスト [#m2e598a4]

ヘッダ中に、このブロックの開始位置を示す数値は見当たらず、ファイルの先頭から0x200の位置から始まる。
したがって、このブロックは、ヘッダの一部と解釈するほうが正しいのかも。

 位置  長さ  内容 
 0000   04   有効フラグ? (1: プレイリストあり、0: プレイリストなし)
 0004   04   このブロックの長さ相対的な終端位置(= ブロック長 - 1)

プレイリストが存在しない場合、「00 00 00 00 00 00 00 07」の8バイトのバイト列となる。

** クリップリスト [#bc83cd60]

 位置  長さ  内容 
 0000   04   フラグ?(0x00000101)
 0004   04   このブロックの長さ相対的な終端位置(= ブロック長 - 1)
 0008   3C   不明なデータ列
 0044   02   クリップ数
 0046   04 * クリップ数   クリップ情報への相対位置配列

** クリップ情報 [#ebfb6869]

 位置  長さ  内容 
 0000   02   0固定?(世界時、地方時識別フラグ?)
 0002   05   日時情報(*)
 0007   02   音声モード
 0009   06   再生開始タイムスタンプ(*SCR)
 000F   06   再生終了タイムスタンプ(*SCR)
 001D   04   ストリームのセクタ位置
 0021   ??   不明


※日時情報は、5バイトの値を、b39-b26:年 b25-b22:月 b21-b17:日 b18-b12:時 b11-b06:分 b05-b00:秒として表現したもの
※SCRは、0x00からの4バイト整数値 * 300 + 0x04からの2バイト整数値で表される27MHzのタイムスタンプ


** 不明1 [#eda91276]

ヘッダの0x0104で指し示されたアドレスからのデータが、「00 00 00 00 00 00 00 07」となっているので、プレイリストブロックの先頭8バイトと同じ構造と思われる。

 位置  長さ  内容 
 0000   04   有効フラグ? (0: 無効)
 0004   04   このブロックの長さ相対的な終端位置(= ブロック長 - 1)

** タイトルリスト [#h9b1d3df]

 位置  長さ  内容 
 0000   02   タイトル数
 0002   02   クリップ数
 0004   8E * タイトル数   タイトルの情報 * タイトル数
 0004 + 8E * タイトル数   4 * クリップ数   タイトルクリップ情報への相対位置配列

** タイトル情報 [#y698d180]

 位置  長さ  内容 
 0000   04   このタイトルに含まれるクリップ数
 0004   40   記録日時や、ビットレートなどの情報
 0044   40   タイトル名(シフトJIS)
 0084   04   タイトルサムネイルのフレームが含まれるクリップ番号
 0088   08   タイトルサムネイルのフレームのタイムスタンプ

** タイトルクリップ情報 [#k5207dc7]

この情報は、クリップリストのクリップ情報とは異なる

 位置  長さ  内容 
 0000   04   クリップ番号(1〜)
 0004   02   このクリップに含まれるチャプタ数
 0006   06   再生開始タイムスタンプ(*SCR)
 000C   06   再生終了タイムスタンプ(*SCR)
 0012   any   チャプタ情報の配列

** チャプタ情報 [#v507e955]

 位置  長さ  内容 
 0000   01   チャプタ情報文字列の長さ(未定義の場合0)
 0001   06   チャプタ位置のタイムスタンプ(*SCR)
 0007   チャプタ情報文字列の長さ   チャプタタイトル
 0007 + チャプタ情報文字列の長さ   チャプタ情報文字列の長さ   チャプタの詳細

ということらしい。

* MPEG-2 Program Stream [#p505f35e]

概要については、MPEG-2解説@Pioneerが詳しい。

以下、MPEG-2の規格を見ていくと…

** MPEG-2 Program Streamは、 [#jb5ca092]

 MPEG2_program_stream() {
 do {
   pack()
 } while (nextbits()==pack_start_code)
   MPEG_program_end_code                   // 32 bslbf
 }

と、1個以上のpackが連続したもので、最後に、MPEG_Program_end_codeが付く。
※MPEG_program_end_codeは、0x000001B9

** packは、 [#zcba2ec1]

 pack() {
   pack_header()
   while (nextbits()==pack_start_code) {
     PES_packet()
   }
 }

と、pack_headerから始まり、0個以上のPES_packetが連続するデータ。
※pack_start_codeは、0x000001BA

** pack_headerは、 [#k905be39]

 pack_header() {
   pack_start_code                       // 32 bslbf
   '01'                                  //  2 bslbf
   system_clock_reference_base[32..30]   //  3 bslbf
   marker_bit                            //  1 bslbf
   system_clock_reference_base[29..15]   // 15 bslbf
   marker_bit                            //  1 bslbf
   system_clock_reference_base[14..0]    // 15 bslbf
   marker_bit                            //  1 bslbf
   system_clock_reference_extension      //  9 uimsbf
   marker_bit                            //  1 bslbf
   program_mux_rate                      // 22 uimsbf
   marker_bit                            //  1 bslbf
   marker_bit                            //  1 bslbf
   Reserved                              //  5 bslbf
   pack_staffing_length                  //  3 uimsbf
   for(i=0;i<pack_staffing_length;i++) {
     stuffing_byte                     //  8 bslbf
   }
   for(nextbits()==system_header_start_code) {
     system_header()
   }
 }

と、system_clock_referenceと、program_mux_rateの情報を持ち、オプションとして、system_headerを持つ。
※system_clock_reference_baseは、90kHz
※system_clock_reference_extenstionは、0〜299
※system_header_start_codeは、0x000001BB

* UDF(Universal Disk Format) [#n62b6a37]

一番最低のレベルではあるものの、データの抜き出しに一応成功したとはいえ、タイトル単位で抜き出せない事には意味が無い。
そのためには、UDF(Universal Disk Format)を勉強することに…

UDF(Universal Disk Format)は、ファイルシステムの一種で、DVD-RAMの標準フォーマットとしても採用されている。
OSTA(Optical Storage Technology Association)を中心に規格化されている。

また、UDFは、ECMA-167を参照しているらしい。
というか、本質的な部分は、ECMA-167で定義されている。
※ECMA(European Computer Manufacturer Association: 欧州電子計算機工業会)

2007年2月末時点では、

UDF 2.6
ECMA-167 3rd Edition
が最新らしい。

とりあえず、

Volume and Boot Blockから始まり、Volume Structureが続く
Volume and Boot Blockは、Volume Structure Descriptorから始まり、StandardIdentifierの値によってDescriptorの意味を示す(ECMA-167 Part2)
Volume Structureは、Descriptor Tagから始まり、TagIdentifierの値によってDescriptorの意味を示す(ECMA-167 Part3)
Descriptorデータはバイト単位で記録され、ワードデータの場合、Little Endianで記録される(ECMA-167 Part1 7.1)
DVDメディアのセクタ長は2048バイト
セクタ番号は、0から始める
くらいは、理解していないと話しにならない模様。

※packが2048バイト固定だったのは、ここから来ている??

Volume and Boot Block

 [volume recognition sequence] {
   <CD-ROM Volume Descriptor Set> 0+1
   [Extended Area] {
       <Beginning Extended Area Descriptor> 1+
       { <Volume Structure Descriptor> | <Boot Descriptor> } n+
       <Terminating Extended Area Descriptor> 1+
     } 0+
 }

** Volume Structure Descriptorは、2048バイト長のデータで、以下の構造となっている [#g54d2faf]

 struct {
   Uint8  StructureType;
   byte   StandardIdentifier[5];
   Uint8  StructureVersion;
   byte   StructureData[2041];
 };


** StandardIdentifierの値は、以下の通り [#r67aaac6]

 "BEA01"  Beginning Extended Area Descriptor
 "TEA01"  Terminating Extended Area Descriptor
 "BOOT2"  Boot Descriptor
 "CD001"  Volume Structure Descriptor
 "CDW02"  Volume Structure Descriptor
 "NSR02"  Volume Structure Descriptor(NSR Descriptor)
 "NSR03"  Volume Structure Descriptor(NSR Descriptor)

 Volume Structure

** Descriptor Tagは16バイト長のデータで、以下の構造となっている [#l55108df]

 struct tag {
   Uint16 TagIdentifier;
   Uint16 DescriptorVersion;
   byte   TagChecksum;
   byte   Reserved;
   Uint16 TagSerialNumber;
   Uint16 DescriptorCRC;
   Uint16 DescriptorCRCLength;
   Uint32 TagLocation;
 };

Descriptorの意味は、TagIdentifierで区別される、具体的な値はUDFのドキュメントには記載されておらず、ECMA-167を参照する必要がある
TagChecksumは、tagの0〜3、5〜15バイト目の各値を加算した値の下位8bit
16バイト目以降の有効データ長は、DescriptorCRCLengthと一致する
TagLocationには自身のセクタ値を記録する。つまり、複数のディスクを使用している環境でもセクタの配置を追いかける事が可能


** TagIdentifierの値は、以下の通り [#m3ceec2a]

  1  Primary Volume Descriptor
  2  Anchor Volume Descriptor Pointer
  3  Volume Descriptor Pointer
  4  Implementation Use Volume Descriptor
  5  Partition Descriptor
  6  Logivcal Volume Descriptor
  7  Unallocated Space Descriptor
  8  Terminating Descriptor
  9  Logical Volume Integrity Descriptor
 256  File Set Descriptor
 257  File Identifier Descriptor ※
 258  Allocation Extent Descriptor
 259  Indirect Entry
 260  Terminal Entry
 261  File Entry
 262  Extended Attribute Header Descriptor ※
 263  Unallocated Space Entry
 264  Space Bitmap Descriptor
 265  Partition Integrity Entry
 266  Extended File Entry

※ File Identifier Descriptorと、Extended Attribute Header Descriptorは、セクタの先頭以外の場所に配置可能 → 他のDescriptorのデータ的な使われ方が可能

Volume Descriptorは、

Primary Volume Descriptor
Implementation Use Volume Descriptor
Partition Descriptor
Logivcal Volume Descriptor
Unallocated Space Descriptor
Terminating Descriptor
の順で配置される。

さらに、

その他のDescriptor
Anchor Volume Descriptor Pointer
論理セクタ0
と続くらしい。

Allocation descriptors
あるデータが配置されている位置、長さを指定するための記述子で、

Short Allocation Descriptor (short_ad)
Long Allocation Descriptor (short_ad)
Extended Allocation Descriptor (ext_ad)
の三種類がある。

short_ad

 struct long_ad {
   Uint32 ExtentLength;
   Uint32 ExtentPoint;
 };

ExtentLengthは、
下位30bitは、データの長さを表す
上位2ビットは、Allocation状態を表す
■0: Extent recorded and allocatted(記録済みで確保済み)
■1: Extent not recorded but allocatted(未記録だが確保済み)
■2: Extent not recorded and not allocatted(未記録で未確保)
■3: The extent is the next extent of allocation dcescriptor(次のAllocation descriptorsの位置)
ExtentPointは、(一般に)論理セクタ番号を示す

long_ad
short_adが自パーティションに対して位置、長さを指定するのに対し、long_adは、他のパーティションの位置、長さを指定出来ると言う事らしい。
ExtentLengthの意味は、short_adと同じ。

 struct lb_ad {
   Uint32 LogicalBlockNumber;
   Uint16 PartitionReferenceNumber;
 };

 struct long_ad {
   Uint32 ExtentLength;
   lb_ad  ExtentLocation;
   byte   ImplementationUse[6];
 };

ext_ad
こんなのも定義されている。

 struct ext_ad {
   Uint32 ExtentLength;
   Uint32 RecordedLength;
   Uint32 InformationLength;
   lb_ad  ExtentLocation;
   byte   ImplementationUse[2];

(HTML conversion costs 0.009 sec.)