⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvddump.cc

📁 Linux下比较早的基于命令行的DVD播放器
💻 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 + -