📄 basicoutputprocessor.cc
字号:
//// Copyright (c) 2005 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 "BasicOutputProcessor.h"#include "AudioHandler.h"#include "OSDHandler.h"#include "Timer.h"#include "dvd/packet/DataBlockTypes.h"#include "dvd/packet/PCIPacket.h"#include "dvd/packet/AVAttributesPacket.h"#include "dvd/packet/StillPacket.h"#include "dvd/packet/SPUPalettePacket.h"#include "dvd/packet/PlayModePacket.h"#include "dvd/packet/DemultiplexerParameterPacket.h"#include "input/InputListener.h"//------------------------------------------------------------------------------using output::BasicOutputProcessor;using output::OutputProcessor;using output::OSDHandler;using input::InputListener;using dvd::packet::PacketQueue;using dvd::packet::Packet;using dvd::packet::DataBlockTypes;using dvd::packet::DataBlockType;using dvd::packet::DataBlockPacket;using dvd::packet::TimedDataBlockPacket;using dvd::packet::PCIPacket;using dvd::packet::AVAttributesPacket;using dvd::packet::StillPacket;using dvd::packet::TimedCommandPacket;using dvd::packet::SPUPalettePacket;using dvd::packet::PlayModePacket;using dvd::packet::DemultiplexerParameterPacket;using dvd::demux::PCI;using dvd::vm::ProcessorCommandQueue;using dvd::vm::State;using dvd::DVD;using dvd::PGC;using sched::Scheduler;//------------------------------------------------------------------------------BasicOutputProcessor::BasicOutputProcessor(const char* name, PacketQueue& inputQueue, Timer& timer, AudioHandler& audioHandler, DVD& dvd, ProcessorCommandQueue& processorCommandQueue, StateTracker::ButtonHandler& buttonHandler, OSDHandler& osdHandler, bool invalidatePTS) : OutputProcessor(name), lastVOBUEnd(INVALID_PTS), ptsOffset(0), audioOffset(0), inputQueue(inputQueue), timer(timer), encodedAudioQueue("output::BasicOutputProcessor::encodedAudioQueue", 16), audioProcessor(encodedAudioQueue, audioQueue), audioQueue("output::BasicOutputProcessor::audioQueue", 16), audioHandler(audioHandler), spuQueue("output::BasicOutputProcessor::spuQueue", 16), videoQueue("output::BasicOutputProcessor::videoQueue", 512), stateQueue("output::BasicOutputProcessor::stateQueue", 8), stateTracker(timer, stateQueue, buttonHandler, osdHandler, processorCommandQueue, dvd), osdHandler(osdHandler), playMode(FORWARD), invalidatePTS(invalidatePTS){}//------------------------------------------------------------------------------void BasicOutputProcessor::run(){ while(!shouldQuit()) { clearInterrupt(); Reference<Packet> packet = inputQueue.get(); if (packet.isValid()) { packet->processOn(*this); } if (isInterrupted()) { audioHandler.waitStop(); timer.reset(); lastVOBUEnd = INVALID_PTS; } } encodedAudioQueue.reset(); videoQueue.reset(); spuQueue.reset();}//------------------------------------------------------------------------------void BasicOutputProcessor::printStatus() const{ Log::debug(" inputQueue: size=%u\n", inputQueue.getSize());// inputQueue.printValues(); Log::debug(" encodedAudioQueue: size=%u\n", encodedAudioQueue.getSize());// encodedAudioQueue.printValues(); Log::debug(" audioQueue: size=%u\n", audioQueue.getSize());// audioQueue.printValues(); Log::debug(" videoQueue: size=%u\n", videoQueue.getSize());// videoQueue.printValues(); Log::debug(" spuQueue: size=%u\n", spuQueue.getSize());// spuQueue.printValues(); Log::debug(" stateQueue: size=%u\n", stateQueue.getSize());// stateQueue.printValues(); Log::debug(" AC-3 volume: %u\n", audioProcessor.getVolume());}//------------------------------------------------------------------------------void BasicOutputProcessor::reset(playMode_t newPlayMode, bool hasDVD){ encodedAudioQueue.reset(); audioQueue.reset(); audioProcessor.reset(); videoQueue.reset(); spuQueue.reset(); stateQueue.reset(); if (playMode!=newPlayMode) { osdHandler.setPlayMode(newPlayMode); playMode = newPlayMode; } if (!hasDVD) { osdHandler.disableDVDInfo(); } interrupt();}//------------------------------------------------------------------------------unsigned BasicOutputProcessor::volumeReset(){ unsigned volume = audioProcessor.volumeReset(); osdHandler.updateVolume(volume); return volume;}//------------------------------------------------------------------------------unsigned BasicOutputProcessor::volumeUp(){ unsigned volume = audioProcessor.volumeUp(); osdHandler.updateVolume(volume); return volume;}//------------------------------------------------------------------------------unsigned BasicOutputProcessor::volumeDown(){ unsigned volume = audioProcessor.volumeDown(); osdHandler.updateVolume(volume); return volume;}//------------------------------------------------------------------------------bool BasicOutputProcessor::toggleAudio(){ bool audioEnabled = audioProcessor.toggleAudio(); osdHandler.updateVolume(audioEnabled ? audioProcessor.getVolume() : 0); return audioEnabled;}//------------------------------------------------------------------------------OutputProcessor::processorChange_t BasicOutputProcessor::handleOperation(InputListener::operation_t operation, State& processorState){ return stateTracker.handleOperation(operation, processorState);}//------------------------------------------------------------------------------const State& BasicOutputProcessor::getVMState(){ return stateTracker.getVMState();}//------------------------------------------------------------------------------OSDHandler& BasicOutputProcessor::getOSDHandler(){ return osdHandler;}//------------------------------------------------------------------------------void BasicOutputProcessor::processPacket(Reference<DataBlockPacket> packet){// Log::debug("output::BasicOutputProcessor: data block packet arrived\n"); if (!packet->isOfType(DataBlockTypes::pci)) { Log::debug("output::BasicOutputProcessor: unhandled data block packet.\n"); return; } Reference<PCI> pci = new PCI(packet->getData()); pts_t startPresentation = pci->getStartPresentation(); pts_t endPresentation = pci->getEndPresentation(); if (playMode!=FORWARD) { // FIXME: constant endPresentation = startPresentation + 7200; } if (lastVOBUEnd==INVALID_PTS) { ptsOffset = 45000; if (audioOffset<0) { ptsOffset -= audioOffset; } ptsOffset -= startPresentation; startPlaybackSequence(); } else { ptsOffset += lastVOBUEnd; ptsOffset -= startPresentation; } lastVOBUEnd = endPresentation;// Log::debug("output::BasicOutputProcessor: PCI from %llu to %llu, ptsOffset=%lld\n",// startPresentation, endPresentation, ptsOffset); stateQueue.put(new PCIPacket(pci, startPresentation + ptsOffset));}//------------------------------------------------------------------------------void BasicOutputProcessor::processPacket(Reference<TimedDataBlockPacket> packet){// Log::debug("output::UnichromeOutputProcessor:: timed data block packet (@%p) of type %s arrived @ %llu\n", // packet.get(), packet->getType().name, packet->getPTS()); PacketQueue* queue = findQueue(packet->getType()); if (queue==0) { Log::verboseDebug("output::BasicOutputProcessor: unhandled timed data block packet.\n"); return; } if (playMode==FORWARD || !invalidatePTS) { packet->advancePTS(ptsOffset); if (queue==&encodedAudioQueue) { packet->advancePTS(audioOffset); } } else { packet->invalidatePTS(); } queue->put(packet);}//------------------------------------------------------------------------------void BasicOutputProcessor::processPacket(Reference<AVAttributesPacket> packet){ const AVAttributes& attributes = packet->getAttributes(); bool different = isDifferent(attributes); avAttributes = attributes; if (!different) return; Log::debug("output::BasicOutputProcessor: changing A/V attributes\n"); waitCurrentVOBUEnd(); updateAVAttributes(); Scheduler::sleep("output::BasicOutputProcessor::processAVAttributesPacket", Util::currentTimeMillis() + 250);}//------------------------------------------------------------------------------void BasicOutputProcessor::processPacket(Reference<StillPacket> packet){ Log::debug("output::BasicOutputProcessor: still time packet arrived with %u seconds\n", packet->stillTime); waitCurrentVOBUEnd(); unsigned stillTime = packet->stillTime; if (stillTime==PGC::infiniteStillTime) { Scheduler::sleepInterruptible("output::BasicOutputProcessor::processStillPacket(infinite)"); } else { Scheduler::sleepInterruptible("output::BasicOutputProcessor::processStillPacket", Util::currentTimeMillis() + stillTime*1000); }}//------------------------------------------------------------------------------void BasicOutputProcessor::processPacket(Reference<TimedCommandPacket> packet){ packet->advancePTS(ptsOffset); stateQueue.put(packet);}//------------------------------------------------------------------------------void BasicOutputProcessor::processPacket(Reference<SPUPalettePacket> packet){ spuQueue.put(packet);}//------------------------------------------------------------------------------void BasicOutputProcessor::processPacket(Reference<PlayModePacket> packet){ if (playMode==packet->getPlayMode()) { return; } waitCurrentVOBUEnd(); playMode = packet->getPlayMode(); osdHandler.setPlayMode(playMode);}//------------------------------------------------------------------------------void BasicOutputProcessor::processPacket(Reference<DemultiplexerParameterPacket> packet){ // FIXME: maybe we need an SPUForcedOnly packet or something spuQueue.put(packet); // FIXME: maybe we need an DisplayFormat packet or something stateQueue.put(packet);}//------------------------------------------------------------------------------PacketQueue* BasicOutputProcessor::findQueue(const DataBlockType& dataBlockType){ if (dataBlockType==DataBlockTypes::ac3Audio || dataBlockType==DataBlockTypes::lpcmAudio || dataBlockType==DataBlockTypes::mpegAudio || dataBlockType==DataBlockTypes::dtsAudio) { return &encodedAudioQueue; } else if (dataBlockType==DataBlockTypes::video) { return &videoQueue; } else if (dataBlockType==DataBlockTypes::spu) { return &spuQueue; } else { return 0; }}//------------------------------------------------------------------------------void BasicOutputProcessor::waitCurrentVOBUEnd(){ audioHandler.flush(); if (lastVOBUEnd!=INVALID_PTS) { timer.sleep(lastVOBUEnd + ptsOffset + 9000); // FIXME: remove constant } audioHandler.waitStop(); processCurrentVOBUEnd(); timer.reset(); lastVOBUEnd = INVALID_PTS;}//------------------------------------------------------------------------------void BasicOutputProcessor::processCurrentVOBUEnd(){}//------------------------------------------------------------------------------//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -