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

📄 basicoutputprocessor.cc

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