DVD-Videoのチャプターの話
とりあえず今すぐなんとかしたいならIfoEditあたりからいい感じにNeroっぽいtxtにしたりAppleっぽいxmlにしたりしても良い正直もうツール組んでまで使う用途ってそんなにないでしょうし……
IfoEdit – The solution to 1:1 DVD Copy
滅茶苦茶細かい情報出てくるのでオススメです。
が、ただこれだけいきなりみても全く面白くないのでIFOの仕様をちょっとだけ眺めてみようとかそういう話
IFO
まずIFOが何から始まるのかっていう話なんですけど、DVDあたりは本当に検索汚染がひどい……(基本的に怪しい有料ツールへの勧誘)
あ、勿論CSS等のコピーコントロールが掛かってない物の話ですよ!
おそらくenなWikipediaとか見た方が早いかな(Jaにはここまで書いてないので)
DVD-Video – Wikipedia
余談なんですけれどVTS_00_0.VOBってタイトルメニューって決まってたんですね初めて知りました
VOBに実際のMPEG2-VideoとかAC-3やPCMが入ってるんですけれど、それに対してそれ以外の再生に必要な情報が入ってる物がIFOみたいな感じだと思います(気になる人はもう少し深く追ってください)
簡単に言えばIFOを読めばいいわけです
読む
devill.tamachan / binaryeditorbz · GitLab
なんか怪しい資料が落ちてたのでIfoEditの結果とbzのHexと共に眺めながらなんかします。
ここにHeaderについて書いてあるので眺めます。
眺めるのはVTS_**_*.IFOです。VIDEO_TS.IFOではないです。
みれば分かるとおりVTS_**_*.IFOはDVDVIDEO-VTSなので右側を見ればいいのですがVMGはVIDEO_TS.IFOの方です。一応
真面目にParseしたいなら全部読む必要はありますが、今回はチャプターだけ読みたいので該当部分だけです。
最初に読まないといけないのはVTS_PTT_SRPTなのでPointerが書いてある0x00C8から4Byteみてみます。
0x00000001で、ついでにPGCIからVOBU_ADMAPまで眺めてみるといいのですが基本的には順番になってます(ここでいうポインターはどうやら順番らしい?
で、その辺で気になってくるのが真ん中にあるFileStructuresのVTSFilesだと思うのですが、おそらく該当空間がどのファイルについての情報を持っているかみたいな感じで良いと思います。今回欲しい情報はタイトルではない本編側の情報なのでVTS_**_*.VOBです。
ヘッダー後の1番目のブロックにあることがわかったので0x3D8から40b後の0x418の後からいい感じに始まるのをみてみましょう
ちょうど0x800ですね。手元のサンプルだと以下の通り
00 01 00 00 00 00 00 3F 00 00 00 0C 00 01 00 01
00 01 00 02 00 01 00 03 00 01 00 04 00 01 00 05
00 01 00 06 00 01 00 07 00 01 00 08 00 01 00 09
00 01 00 0A 00 01 00 0B 00 01 00 0C 00 01 00 0D
VTS IFO tables のVTS_PTT_SRPTのところ読んで貰ってる事を前提に
タイトルが0x0001 終端が0x800から3F飛んで0x83F、あってますね。
その後はPTTの開始位置が0x800オフセットで書かれているので省略
今回の場合だとタイトルが1つしかないけれど、そこそこの頻度で区切られてるみたいです(まあハンディカムの映像なので)
ともかく
| PCGN | PGN|
| — | –|
|01|01|
|01|02|
|略||
|01|0D|
みたいになってます。
とタイトルリストを手にしたところで、今度はチャプター情報が含まれているVTS_PGCIを実際に眺めてみます
2つ目のブロックなので0x800から0x800飛んで0x1000付近を眺めます。
そっからPCGNの数だけPCGがあるのでそっから順番におっていくことになります。
0x1000-1001がPCGNの数を示し(例えば一つしかなかったら0x0001)、0x1004-7がEndAddressのオフセット情報なので(今回は0x07fdなので加算して)0x17fd。ちなみに02-03はreservedなので無視。
1008-100bはPGC category、100c-fは0x1000からオフセットしたPGCのアドレスの記述。(今回だと0x10なので0x1010から)。PGCの数だけPCG categoryと共に繰り返されるので順番にみていけば最悪なんとかなります。
一つ目のPGCをみていくのですがここで頭の方でPGC全体の再生時間とCellの数が出てきました。
Program Chain (PGC) のplayback timeとNumber of Cellsのところですね。何枚かみた感じPGC自体はいくつか出てくると思うので、ここが全再生っぽいやつプログラムを選んでチャプター情報を拾い出せば得られやすいと思います。ここのCellの数が大事でこの分だけチャプターがあります。(今回は63個)こりゃひどい
次に該当PGCのcell playback information tableをみます。1つ目のPGCの始点から0xE8オフセットしたところに書いてあります。0x10F8から2Byteの部分です。
今回は0x010Aなので0x1010に足した値の0x111Aが1つ目のCell Playbackの始点になります。そこからCell Playback Timeが書いてあるのは0x4オフセットした先なので0x111Eから4Byteが時間になります。上位3バイトはそのままで最後の1バイトの下位6bitがフレーム数で上位2bitがフレームレートです。要するにミリ秒はフレームレートとフレーム数から計算から求めればOKです。
今回は00:00:14とD5なのでD5が
11010101なので30fpsで10101=21→0x15で15フレーム目となります。
Cell Playbackの長さは固定(24Bytes)なのでCell Playbackの最後までCellの数だけ繰り返して読んでいき、時間を時間を加算していけば出来上がり。どうせそんなに性能が追求されないと思うのでお好きな言語で。
もしどーしても大量にコピーフリーなDVD-Videoが大量にあって良い感じに再エンコードしたいとこんだけあるとめんどくせーよ!とかかそういう需要をAviSynthとかでよしなにしたい場合とかならまあ書いてみても良いんじゃないんですかね。
って思ったらクソ面倒だったので追記
DVDは基本的にドロップフレーム(NTSCだと30000/1001のインタレェ)なのでタイムコードからの変換をする時にフレームを30fpsと30000/1001fpsのズレ的に1分ごとに2f欠損させる必要があるっぽい
ここでちょっと詰まっててめんどくなって放置してたんですけれど、ドロップフレームであることを考慮した上で一回フレーム数に変換した後はそのままフレームレートで割ればOKな気がするんですよね。って思ったらさっきのページの参考文献に普通に書かれてました。
とまあ適当にぺちぺちしてたらなんかできた。CUEシートにしてぶち抜けるのが最大の利点です。
tana3n/IFOtoChap: Generating nero chapter files and CUE Sheets.
真面目にレイヤーブレークは弾く実装とかしてないのでそのうちなんとかしたいですね。多分やりませんが。
なんか結構時間空けてしまったので間違えてるような気がするけれど実際のIFOファイルとかがIfoEditあたりの方が確実に正しいと思われるのでそっちを優先することを推奨します。