📄 dvddump.cc
字号:
//// Copyright (c) 2003 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//------------------------------------------------------------------------------#include "DVDDump.h"#include "ifodump/IFOReader.h"#include "ifodump/NAVReader.h"#include "dvd/demux/Sector.h"#include "util/Log.h"#include <cstring>#include <cstdio>#include <libmpdvdkit/nav_read.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <byteswap.h>//------------------------------------------------------------------------------using dvd::demux::Sector;using dvd::demux::SECTOR_SIZE;using dvd::DVDDump;using ifodump::IFOReader;using ifodump::NAVReader;//------------------------------------------------------------------------------const char DVDDump::magic[4] = { 'D', '3', 'P', 'D' };//------------------------------------------------------------------------------bool DVDDump::isVersioned(FILE* f){ char buffer[sizeof(magic)]; fread(buffer, sizeof(buffer), 1, f); bool versioned = memcmp(buffer, magic, sizeof(magic))==0; if (!versioned) { fseek(f, 0, SEEK_SET); } return versioned;}//------------------------------------------------------------------------------//------------------------------------------------------------------------------//------------------------------------------------------------------------------void DVDDump::FileHandler::copy(pci_t& dest, const pci_t& src){ memcpy(&dest, &src, sizeof(pci_t)); dest.pci_gi.nv_pck_lbn = bswap_32(dest.pci_gi.nv_pck_lbn); dest.pci_gi.vobu_cat = bswap_16(dest.pci_gi.vobu_cat); dest.pci_gi.vobu_s_ptm = bswap_32(dest.pci_gi.vobu_s_ptm); dest.pci_gi.vobu_e_ptm = bswap_32(dest.pci_gi.vobu_e_ptm); dest.pci_gi.vobu_se_e_ptm = bswap_32(dest.pci_gi.vobu_se_e_ptm); for(size_t j = 0; j < 9; j++) { dest.nsml_agli.nsml_agl_dsta[j] = bswap_32(dest.nsml_agli.nsml_agl_dsta[j]); } dest.hli.hl_gi.hli_ss = bswap_16(dest.hli.hl_gi.hli_ss); dest.hli.hl_gi.hli_s_ptm = bswap_32(dest.hli.hl_gi.hli_s_ptm); dest.hli.hl_gi.hli_e_ptm = bswap_32(dest.hli.hl_gi.hli_e_ptm); dest.hli.hl_gi.btn_se_e_ptm = bswap_32(dest.hli.hl_gi.btn_se_e_ptm); /* pci hli btn_colit */ for(size_t j = 0; j < 3; j++) for(size_t k = 0; k < 2; k++) { dest.hli.btn_colit.btn_coli[j][k] = bswap_32(dest.hli.btn_colit.btn_coli[j][k]); }#if !defined(WORDS_BIGENDIAN) /* pci hli btni */ for(size_t j = 0; j < 36; j++) { char tmp[6], swap; memcpy(tmp, &(dest.hli.btnit[j]), 6); /* This is a B2N_24() */ swap = tmp[0]; tmp[0] = tmp[2]; tmp[2] = swap; /* This is a B2N_24() */ swap = tmp[3]; tmp[3] = tmp[5]; tmp[5] = swap; memcpy(&(dest.hli.btnit[j]), tmp, 6); }#endif }//------------------------------------------------------------------------------void DVDDump::FileHandler::copy(dsi_t& dest, const dsi_t& src){ navRead_DSI(&dest, reinterpret_cast<unsigned char*>(const_cast<dsi_t*>(&src)));}//------------------------------------------------------------------------------DVDDump::FileHandler::FileHandler(const navMap_t& navs) : navs(navs){}//------------------------------------------------------------------------------size_t DVDDump::FileHandler::getLength(){ // FIXME: we may need to make it meaningful return 0;}//------------------------------------------------------------------------------void DVDDump::FileHandler::readSectors(void* dest, size_t offset, size_t numSectors){ Log::verboseDebug("Reading %u sectors from %u\n", numSectors, offset); Sector* sectors = reinterpret_cast<Sector*>(dest); for(size_t i = 0; i<numSectors; ++i) { readSector(sectors + i, offset + i); }} //------------------------------------------------------------------------------void DVDDump::FileHandler::readSector(void* dest, size_t offset) const{ unsigned char* buffer = reinterpret_cast<unsigned char*>(dest); memset(buffer, 0, SECTOR_SIZE); buffer[0x026] = 0x00; buffer[0x027] = 0x00; buffer[0x028] = 0x01; buffer[0x029] = 0xbf; buffer[0x02a] = 0x03; buffer[0x02b] = 0xd4; buffer[0x02c] = 0x00; buffer[0x400] = 0x00; buffer[0x401] = 0x00; buffer[0x402] = 0x01; buffer[0x403] = 0xbf; buffer[0x404] = 0x03; buffer[0x405] = 0xfa; buffer[0x406] = 0x01; navMap_t::const_iterator i = navs.lower_bound(offset); if (i!=navs.end() && i->first==offset) { copy(*reinterpret_cast<pci_t*>(buffer + 0x02d), i->second.pci); copy(*reinterpret_cast<dsi_t*>(buffer + 0x407), i->second.dsi); }}//------------------------------------------------------------------------------//------------------------------------------------------------------------------bool DVDDump::isDumpFile(const char* path){ struct stat statBuffer; if (stat(path, &statBuffer)!=0) { Log::debug("%s does not exist.\n", path); return false; } bool isDump = S_ISREG(statBuffer.st_mode); if (isDump) { Log::debug("%s is a dump file.\n", path); } else { Log::debug("%s is not a dump file.\n", path); } return isDump;}//------------------------------------------------------------------------------DVDDump::DVDDump(const char* dumpFile) : opened(false){ for(size_t i = 0; i<sizeof(ifoInfos)/sizeof(ifoInfos[0]); ++i) { memset(&(ifoInfos[i].ifoHandle), 0, sizeof(ifoInfos[i].ifoHandle)); } FILE* dump = fopen(dumpFile, "rb"); if (dump==0) { Log::fatal("Cannot open dump file %s for reading!\n", dumpFile); abort(); } bool versioned = isVersioned(dump); IFOReader ifoReader(dump, versioned); unsigned version = ifoReader.getVersion(); if (version==0) Log::warning("dvd::DVDDump::DVDDump: dump is unversioned, may not work correctly!\n"); else Log::normal("dvd::DVDDump::DVDDump: dump is of version %u\n", version); NAVReader navReader(dump, version); readIFO(ifoReader, 0); readNAV(navReader, (size_t)0); size_t numVTs = ifoInfos[0].ifoHandle.vmgi_mat->vmg_nr_of_title_sets; for(size_t i = 1; i<=numVTs; ++i) { readIFO(ifoReader, i); readNAV(navReader, i); } fclose(dump);}//------------------------------------------------------------------------------bool DVDDump::hasDisk(){ return true;}//------------------------------------------------------------------------------bool DVDDump::isOpen() const{ return opened;} //------------------------------------------------------------------------------bool DVDDump::open(){ assert(!opened); return opened = true;}//------------------------------------------------------------------------------void DVDDump::getID(unsigned char* dest) const{ memset(dest, 0, 16);}//------------------------------------------------------------------------------const ifo_handle_t* DVDDump::getIFOHandle(unsigned titleNo) const{ return &(ifoInfos[titleNo].ifoHandle);} //------------------------------------------------------------------------------dvd::FileHandler* DVDDump::openFile(unsigned titleNo, bool isMenu) const{ Log::verboseDebug("dvd::DVDDump::openFile: titleNo=%u, isMenu: %d\n", titleNo, isMenu); const IFOInfo& ifoInfo = ifoInfos[titleNo]; return new FileHandler(isMenu ? ifoInfo.menuNAVs : ifoInfo.titleNAVs);}//------------------------------------------------------------------------------void DVDDump::close(){ assert(opened); opened = false;}//------------------------------------------------------------------------------void DVDDump::eject(){ assert(!opened);}//------------------------------------------------------------------------------void DVDDump::readIFO(IFOReader& reader, size_t ifoIndex){ ifo_handle_t& ifoHandle = ifoInfos[ifoIndex].ifoHandle; if (ifoIndex==0) { reader.readVMG(&ifoHandle); } else { reader.readVTS(&ifoHandle); }}//------------------------------------------------------------------------------void DVDDump::readNAV(NAVReader& reader, size_t ifoIndex){ IFOInfo& ifoInfo = ifoInfos[ifoIndex]; readNAV(reader, ifoInfo.menuNAVs, ifoInfo.ifoHandle.menu_vobu_admap); readNAV(reader, ifoInfo.titleNAVs, ifoInfo.ifoHandle.vts_vobu_admap);}//------------------------------------------------------------------------------void DVDDump::readNAV(ifodump::NAVReader& reader, navMap_t& dest, vobu_admap_t* vobuAddresses){ dest.clear(); uint8_t hasVOBUs; reader.read(hasVOBUs); if (hasVOBUs==0) { return; } assert(vobuAddresses!=0); size_t numVOBUs = vobuAddresses->last_byte / sizeof(uint32_t); for(size_t i = 0; i<numVOBUs; ++i) { size_t vobuSector = vobuAddresses->vobu_start_sectors[i]; reader.read(dest[vobuSector].pci); reader.read(dest[vobuSector].dsi); }}//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -