📄 statetracker.cc
字号:
// Copyright (c) 2004 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 "StateTracker.h"#include "Timer.h"#include "OSDHandler.h"#include "output/osd/DVDPosition.h"#include "dvd/packet/PacketQueue.h"#include "dvd/packet/TimedCommandPacket.h"#include "dvd/packet/DemultiplexerParameterPacket.h"#include "dvd/vm/ProcessorCommandQueue.h"#include "util/Config.h"//------------------------------------------------------------------------------using output::StateTracker;using output::OutputProcessor;using output::osd::DVDPosition;using dvd::packet::Packet;using dvd::packet::TimedCommandPacket;using dvd::packet::DemultiplexerParameterPacket;using dvd::vm::State;using dvd::vm::Position;using dvd::demux::PCI;using dvd::demux::HighlightInformation;using dvd::demux::GeneralHighlightInformation;using dvd::demux::ButtonInformation;using dvd::demux::ButtonColourTable;using dvd::PGCInfo;using dvd::IFO;using dvd::PGC;using dvd::VideoStreamAttributes;using input::InputListener;using sched::Scheduler;//------------------------------------------------------------------------------void StateTracker::run(){ while(!shouldQuit()) { clearInterrupt(); Reference<Packet> pack = inputQueue.get(); Reference<TimedCommandPacket> timedCommandPacket = TimedCommandPacket::convert(pack); if (timedCommandPacket.isValid()) { pts_t pts = timedCommandPacket->getPTS() + timer.getPTSCompensation(); pts_t currentSCR = timer.getCurrentSCR(); // Log::debug("output::StateTracker::run: pts=%llu + %lld, currentSCR=%llu\n",// timedCommandPacket->getPTS(), timer.getPTSCompensation(), currentSCR); if ( (pts+22500) < currentSCR ) { // FIXME: constant // FIXME: use a common routine for compensating ptsdiff_t diff = currentSCR - pts; timer.advancePTSCompensation(diff); pts += diff; Log::debug("output::StateTracker::run: advanced PTS compensation by: %lld\n", diff); } if ( pts > (currentSCR+4500)) { // FIXME: remove constant timer.sleepInterruptible(pts); } if (!isInterrupted()) {// Log::debug("output::StateTracker::run: executing command packet of %llu at %llu\n",// pts, timer.getCurrentSCR()); timedCommandPacket->execute(*this); } } Reference<DemultiplexerParameterPacket> demuxParameterPacket = DemultiplexerParameterPacket::convert(pack); if (demuxParameterPacket.isValid()) { nextDisplayFormat = demuxParameterPacket->parameters.displayFormat; audioStreamNumber = demuxParameterPacket->parameters.audioStreamNumber; if (demuxParameterPacket->parameters.spuForcedOnly) { spuStreamNumber = 0xff; } else { spuStreamNumber = demuxParameterPacket->parameters.spuStreamNumber; } } if (isInterrupted()) { previousPCI = 0; currentPCI = 0; } }}//------------------------------------------------------------------------------void StateTracker::printStatus() const{ const Position& position = processor.getPosition(); Log::debug(" VTS: %u (%sin menu), PGC: %u, cell: %u\n", position.getVTSNumber(), (position.isInMenu() ? "" : "not "), position.getPGCNumber(), position.getCellNumber());}//------------------------------------------------------------------------------void StateTracker::reset(){ hideButtons = false; buttonHandler.clearButton(); interrupt();}//------------------------------------------------------------------------------OutputProcessor::processorChange_t StateTracker::handleOperation(InputListener::operation_t operation, State& processorState){ if (!processor.getPosition().isValid()) return OutputProcessor::NONE; OutputProcessor::processorChange_t change = OutputProcessor::NONE; processorState = processor.getState(); switch(operation) { case InputListener::UP: case InputListener::DOWN: case InputListener::LEFT: case InputListener::RIGHT: case InputListener::ACTIVATE: change = handleButton(operation); break; case InputListener::MENU_TITLE: case InputListener::MENU_ROOT: case InputListener::MENU_ROOT_FORCED: case InputListener::MENU_SUBPICTURE: case InputListener::MENU_AUDIO: case InputListener::MENU_ANGLE: case InputListener::MENU_PART: change = handleMenu(operation); break; case InputListener::NEXT_CHAPTER: change = processor.nextProgram() ? OutputProcessor::STATE : OutputProcessor::NONE; if (processor.getPosition().atExit()) { processor.setState(processorState); change = OutputProcessor::NONE; } break; case InputListener::PREVIOUS_CHAPTER: if (hasCellElapsed(Config::get().repeatProgramThreshold)) { change = processor.previousProgram() ? OutputProcessor::STATE : OutputProcessor::NONE; } else { change = processor.repeatProgram() ? OutputProcessor::BRANCH : OutputProcessor::NONE; } break; case InputListener::CHANGE_ANGLE: change = processor.nextAngle() ? OutputProcessor::STATE : OutputProcessor::NONE; break; case InputListener::NEXT_AUDIO_STREAM: case InputListener::PREVIOUS_AUDIO_STREAM: change = processor.nextAudioStream(operation==InputListener::PREVIOUS_AUDIO_STREAM) ? OutputProcessor::STATE : OutputProcessor::NONE; break; case InputListener::NEXT_SPU_STREAM: case InputListener::PREVIOUS_SPU_STREAM: change = processor.nextSPUStream(operation==InputListener::PREVIOUS_SPU_STREAM) ? OutputProcessor::STATE : OutputProcessor::NONE; break; default: Log::debug("output::StateTracker::handleOperation: unhandled operation: %d\n", operation); } if (processor.getPosition().atExit()) { return OutputProcessor::QUIT; } else if (change==OutputProcessor::STATE) { processorState.updateEssential(processor.getState()); if (processorCommandQueue.updateStates(processorState)) { processorState.updateNonEssential(processor.getState()); } else { change = OutputProcessor::BRANCH; processorState = processor.getState(); } } else if (change==OutputProcessor::BRANCH) { processorState = processor.getState(); } return change;}//------------------------------------------------------------------------------const State& StateTracker::getVMState() const{ return processor.getState();}//------------------------------------------------------------------------------void StateTracker::setPCI(Reference<PCI> pci){ if (currentPCI.isValid()) previousPCI = currentPCI; else previousPCI = pci; currentPCI = pci; currentDisplayFormat = nextDisplayFormat;}//------------------------------------------------------------------------------void StateTracker::updateProcessor(size_t commandID){ processorCommandQueue.setState(processor, commandID); if (processor.getPosition().atExit()) { Log::debug("output::StateTracker::updateProcessor: quitting\n"); Scheduler::get().quit(); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -