📄 dsi.h
字号:
//// 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#ifndef DXR3PLAYER_DVD_DEMUX_DSI_H#define DXR3PLAYER_DVD_DEMUX_DSI_H//------------------------------------------------------------------------------#include "util/Log.h"#include <libmpdvdkit/nav_types.h>#include <cassert>//------------------------------------------------------------------------------namespace dvd { namespace demux {//------------------------------------------------------------------------------class Sector;//------------------------------------------------------------------------------/** * Wrapper around a DSI */class DSI{public: /** * Constants for the next/previous VOBU pointers. */ typedef enum timeOffset_t { TO_0_5 = 0, TO_1 = 1, TO_1_5 = 2, TO_2 = 3, TO_2_5 = 4, TO_3 = 5, TO_3_5 = 6, TO_4 = 7, TO_4_5 = 8, TO_5 = 9, TO_5_5 = 10, TO_6 = 11, TO_6_5 = 12, TO_7 = 13, TO_7_5 = 14, TO_10 = 15, TO_30 = 16, TO_60 = 17, TO_120 = 18 };private: /** * The low level structure. */ dsi_t dsi;public: /** * Construct the DSI from the bytes starting at the given address, * if not 0. */ explicit DSI(const unsigned char* d = 0); /** * Construct the DSI from the given DVD sector. */ explicit DSI(const Sector& sector); /** * Set the DSI from the given character array */ void set(const unsigned char* d); /** * Set the DSI from the given sector. */ void set(const Sector& sector); /** * Get the sector of this VOBU. */ size_t getSector() const; /** * Get the length of the VOBU this DSI belongs to. */ size_t getVOBULength() const; /** * Get the length until the end of the first reference block of * the VOBU this DSI belongs to. */ size_t getVOBUFirstRefLength() const; /** * Get the length until the end of the second reference block of * the VOBU this DSI belongs to. */ size_t getVOBUSecondRefLength() const; /** * Get the length until the end of the third reference block of * the VOBU this DSI belongs to. */ size_t getVOBUThirdRefLength() const; /** * Check if there is a next vobu. */ bool hasNextVOBU() const; /** * Get the offset of the next VOBU. Call only, if the offset is valid. */ size_t getNextVOBUOffset() const; /** * Get the sector number of the next VOBU. Call only, if the offset is valid. */ size_t getNextVOBUSector() const; /** * Check if there is a next vobu for the given angle (1..9) */ bool hasNextVOBU(unsigned angleNo) const; /** * Get the offset of the next VOBU for the given angle. * Call only, if the offset is valid. */ ssize_t getNextVOBUOffset(unsigned angleNo) const; /** * Get the sector number of the next VOBU for the given angle. * Call only, if the offset is valid. */ size_t getNextVOBUSector(unsigned angleNo) const; /** * Check if there is a next vobu for the given time offset */ bool hasNextVOBU(timeOffset_t timeOffset) const; /** * Get the offset of the next VOBU for the given time offset */ size_t getNextVOBUOffset(timeOffset_t timeOffset) const; /** * Get the sector of the next VOBU for the given time offset */ size_t getNextVOBUSector(timeOffset_t timeOffset) const; /** * Check if the next VOBU is immediately after this one. */ bool doesNextVOBUFollow() const; /** * Check if there is a previous vobu. */ bool hasPreviousVOBU() const; /** * Get the offset of the previous VOBU. Call only, if the offset is valid. */ size_t getPreviousVOBUOffset() const; /** * Get the sector number of the previous VOBU. Call only, if the offset is valid. */ size_t getPreviousVOBUSector() const; /** * Check if there is a previous vobu for the given time offset */ bool hasPreviousVOBU(timeOffset_t timeOffset) const; /** * Get the offset of the next VOBU for the given time offset */ size_t getPreviousVOBUOffset(timeOffset_t timeOffset) const; /** * Get the secotor of the next VOBU for the given time offset */ size_t getPreviousVOBUSector(timeOffset_t timeOffset) const; /** * Log some NAV information. */ void logNAV() const;};//------------------------------------------------------------------------------// Inline definitions//------------------------------------------------------------------------------inline DSI::DSI(const unsigned char* d){ if (d!=0) set(d);}//------------------------------------------------------------------------------inline DSI::DSI(const Sector& sector){ set(sector);}//------------------------------------------------------------------------------inline size_t DSI::getSector() const{ return dsi.dsi_gi.nv_pck_lbn;}//------------------------------------------------------------------------------inline size_t DSI::getVOBULength() const{ return (size_t)dsi.dsi_gi.vobu_ea;}//------------------------------------------------------------------------------inline size_t DSI::getVOBUFirstRefLength() const{ return (size_t)dsi.dsi_gi.vobu_1stref_ea;}//------------------------------------------------------------------------------inline size_t DSI::getVOBUSecondRefLength() const{ return (size_t)dsi.dsi_gi.vobu_2ndref_ea;}//------------------------------------------------------------------------------inline size_t DSI::getVOBUThirdRefLength() const{ return (size_t)dsi.dsi_gi.vobu_3rdref_ea;}//------------------------------------------------------------------------------inline bool DSI::hasNextVOBU() const{ return dsi.vobu_sri.next_vobu!=0x3fffffff && ((dsi.vobu_sri.next_vobu&0x80000000)!=0 || (dsi.vobu_sri.next_video==0xbfffffff)); // FIXME: should we check for bit 31?}//------------------------------------------------------------------------------inline size_t DSI::getNextVOBUOffset() const{ assert(hasNextVOBU()); return dsi.vobu_sri.next_vobu & 0x7fffffff;}//------------------------------------------------------------------------------inline size_t DSI::getNextVOBUSector() const{ return getSector() + getNextVOBUOffset();}//------------------------------------------------------------------------------inline bool DSI::hasNextVOBU(unsigned angleNo) const{ assert(angleNo>=1 && angleNo<=9); size_t offset = dsi.sml_agli.data[angleNo-1].address; return (dsi.sml_pbi.category&0x1000)==0x1000 && offset!=0 && offset!=0x7fffffff;}//------------------------------------------------------------------------------inline ssize_t DSI::getNextVOBUOffset(unsigned angleNo) const{ assert(hasNextVOBU(angleNo)); size_t offset = dsi.sml_agli.data[angleNo-1].address; if ( (offset&0x80000000)!=0 ) { return 0 - (offset&0x3fffffff); } else { return offset&0x3fffffff; } }//------------------------------------------------------------------------------inline size_t DSI::getNextVOBUSector(unsigned angleNo) const{ return getSector() + getNextVOBUOffset(angleNo);}//------------------------------------------------------------------------------inline bool DSI::hasNextVOBU(timeOffset_t timeOffset) const{ size_t index = 18 - static_cast<size_t>(timeOffset); assert(index<=18); return dsi.vobu_sri.fwda[index]!=0x3fffffff && (dsi.vobu_sri.fwda[index]&0x80000000)!=0;}//------------------------------------------------------------------------------inline size_t DSI::getNextVOBUOffset(timeOffset_t timeOffset) const{ assert(hasNextVOBU(timeOffset)); return dsi.vobu_sri.fwda[18-static_cast<size_t>(timeOffset)] & 0x3fffffff;}//------------------------------------------------------------------------------inline size_t DSI::getNextVOBUSector(timeOffset_t timeOffset) const{ return getSector() + getNextVOBUOffset(timeOffset);}//------------------------------------------------------------------------------inline bool DSI::hasPreviousVOBU() const{ return dsi.vobu_sri.prev_vobu!=0x3fffffff && ((dsi.vobu_sri.prev_vobu&0x80000000)!=0 || (dsi.vobu_sri.prev_video==0xbfffffff)); // FIXME: should we check for bit 31?}//------------------------------------------------------------------------------inline size_t DSI::getPreviousVOBUOffset() const{ assert(hasPreviousVOBU()); return dsi.vobu_sri.prev_vobu & 0x7fffffff;}//------------------------------------------------------------------------------inline size_t DSI::getPreviousVOBUSector() const{ assert(getSector() >= getPreviousVOBUOffset()); return getSector() - getPreviousVOBUOffset();}//------------------------------------------------------------------------------inline bool DSI::hasPreviousVOBU(timeOffset_t timeOffset) const{ size_t index = static_cast<size_t>(timeOffset); assert(index<=18); return dsi.vobu_sri.bwda[index]!=0x3fffffff && (dsi.vobu_sri.bwda[index]&0x80000000)!=0;}//------------------------------------------------------------------------------inline size_t DSI::getPreviousVOBUOffset(timeOffset_t timeOffset) const{ assert(hasPreviousVOBU(timeOffset)); return dsi.vobu_sri.bwda[static_cast<size_t>(timeOffset)] & 0x3fffffff;}//------------------------------------------------------------------------------inline size_t DSI::getPreviousVOBUSector(timeOffset_t timeOffset) const{ assert(getSector() >= getPreviousVOBUOffset(timeOffset)); return getSector() - getPreviousVOBUOffset(timeOffset);}//------------------------------------------------------------------------------} /* namespace dvd::demux */ } /* namespace dvd *///------------------------------------------------------------------------------#endif // DXR3PLAYER_DVD_DEMUX_DSI_H// Local variables:// mode: c++// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -