''目次'' #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;