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

📄 spuhandler.cc

📁 Linux下比较早的基于命令行的DVD播放器
💻 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 "SPUHandler.h"#include "Timer.h"#include "dvd/packet/PacketQueue.h"#include "dvd/packet/TimedDataBlockPacket.h"#include "dvd/packet/SPUPalettePacket.h"#include "dvd/packet/DemultiplexerParameterPacket.h"#include "dvd/spu/ControlSequence.h"#include "sched/Scheduler.h"//------------------------------------------------------------------------------using output::SPUHandler;using output::Timer;using dvd::packet::PacketQueue;using dvd::packet::Packet;using dvd::packet::TimedDataBlockPacket;using dvd::packet::SPUPalettePacket;using dvd::packet::DemultiplexerParameterPacket;using dvd::spu::SPUBufferBitReader;using dvd::spu::SPU;using dvd::spu::ControlSequence;using sched::Scheduler;//------------------------------------------------------------------------------//------------------------------------------------------------------------------SPUHandler::DisplayController::DisplayController(SPUHandler& spuHandler) :    Schedulable("output::SPUHandler::DisplayController", defaultStackSize),    spuHandler(spuHandler),    forcedOnly(false),    hasControlSequences("output::SPUHandler::DisplayController",                        "hasControlSequences"){}        //------------------------------------------------------------------------------void SPUHandler::DisplayController::run(){    while(!shouldQuit()) {        clearInterrupt();                while(controlSequences.empty() && !isInterrupted()) {            Scheduler::wait(hasControlSequences);        }        for(controlSequences_t::iterator i = controlSequences.begin();            i!=controlSequences.end() && !isInterrupted();)        {            controlSequences_t::iterator current = i; ++i;            ControlSequence* controlSequence = *current;            controlSequences.erase(current);                        pts_t pts =                 controlSequence->getPTS() +                 spuHandler.timer.getPTSCompensation();            ControlSequence::displayCommand_t displayCommand =                 controlSequence->getDisplayCommand();            switch(displayCommand) {              case ControlSequence::FORCED_START:              case ControlSequence::START:              {                  if (forcedOnly && displayCommand!=ControlSequence::FORCED_START) break;                  if (!controlSequence->getPicture()->isValid()) break;                                        spuHandler.timer.sleepInterruptible(pts);                                        if (!isInterrupted()) {                      spuHandler.setPicture(*controlSequence);                  }              }              break;              case ControlSequence::STOP:                spuHandler.timer.sleepInterruptible(pts);                spuHandler.resetPicture();                break;              default:                break;            }                        delete controlSequence;        }    }}//------------------------------------------------------------------------------    void SPUHandler::DisplayController::reset(){    for(controlSequences_t::const_iterator i = controlSequences.begin();        i!=controlSequences.end(); ++i)    {        delete *i;    }    controlSequences.clear();    interrupt();}//------------------------------------------------------------------------------void SPUHandler::DisplayController::setForcedOnly(bool fo){    forcedOnly = fo;}//------------------------------------------------------------------------------    void SPUHandler::DisplayController::addSPU(SPU& spu){    spu.appendControlSequencesTo(controlSequences);    hasControlSequences.set();}//------------------------------------------------------------------------------//------------------------------------------------------------------------------SPUHandler::SPUHandler(PacketQueue& inputQueue, Timer& timer) :    Schedulable("output::SPUHandler", defaultStackSize, 2),    displayController(*this),    inputQueue(inputQueue),    timer(timer),    spuPTS(INVALID_PTS),    pictureForced(false),    pictureColor(0),    pictureContrast(0),    showButton(false),    buttonColor(0),    buttonContrast(0){}//------------------------------------------------------------------------------void SPUHandler::run(){    while(!shouldQuit()) {        clearInterrupt();        Reference<Packet> packet = inputQueue.get();                if (!packet.isValid()) continue;        Reference<TimedDataBlockPacket> dataPacket =             TimedDataBlockPacket::convert(packet);        if (dataPacket.isValid()) {            packet = 0;            processDataPacket(dataPacket);            continue;        }        Reference<SPUPalettePacket> palettePacket =             SPUPalettePacket::convert(packet);        if (palettePacket.isValid()) {            setPalette(palettePacket->getPalette());            continue;        }        Reference<DemultiplexerParameterPacket> demultiplexerParameterPacket =             DemultiplexerParameterPacket::convert(packet);        if (demultiplexerParameterPacket.isValid()) {            displayController.                setForcedOnly(demultiplexerParameterPacket->parameters.spuForcedOnly);            continue;        }    }}//------------------------------------------------------------------------------void SPUHandler::reset(){    displayController.reset();    spuPTS = INVALID_PTS;    picture = 0;    showButton = false;    spuBuffer.reset();    update();        interrupt();}//------------------------------------------------------------------------------void SPUHandler::setWideScreen(bool ws){    wideScreen = ws;}//------------------------------------------------------------------------------void SPUHandler::highlightButton(int color, int contrast,                                 size_t top, size_t bottom,                                 size_t left, size_t right){    Area newArea(left, right, top, bottom);    if (!showButton ||        !(buttonVisibleArea==newArea) ||        buttonColor!=color ||        buttonContrast!=contrast)    {        buttonVisibleArea = newArea;        buttonColor = color;        buttonContrast = contrast;        showButton = true;        update();    }}    //------------------------------------------------------------------------------void SPUHandler::clearButton(){    if (showButton) {        showButton = false;        update();    }}//------------------------------------------------------------------------------inline const Area& SPUHandler::getVisibleArea(displayEntity_t displayEntity)    const{    switch(displayEntity) {      case PICTURE:      default:        return pictureVisibleArea;        break;      case BUTTON:        return buttonVisibleArea;        break;    }}//------------------------------------------------------------------------------bool SPUHandler::isDisplayable(displayEntity_t displayEntity) const{    const Area& area = getVisibleArea(displayEntity);    return         picture.isValid() &&        (displayEntity==PICTURE || showButton) &&        area.getStartX() >= picture->getXOffset() &&        area.getStartY() >= picture->getYOffset();}//------------------------------------------------------------------------------const unsigned char* SPUHandler::getVisiblePictureData(displayEntity_t displayEntity,                      size_t& pictureWidth,                      size_t& startX, size_t& startY,                      size_t& width, size_t& height) const{    const Area& area = getVisibleArea(displayEntity);    pictureWidth = picture->getWidth();    startX = area.getStartX();    startY = area.getStartY();    width = area.getWidth();    height = area.getHeight();    if (wideScreen) {        startY *= 4;        startY /= 3;        startY -= 16;        height *= 4;        height /= 3;    }        return picture->getData() +         picture->getWidth() * (area.getStartY() - picture->getYOffset()) +         (area.getStartX() - picture->getXOffset());}//------------------------------------------------------------------------------void SPUHandler::processDataPacket(Reference<TimedDataBlockPacket>& packet){    const unsigned char* data = packet->getData();    size_t length = packet->getLength();    pts_t packetPTS = packet->getPTS() + timer.getPTSCompensation();        while(length>0 && !isInterrupted()) {        if (spuBuffer.isEmpty()) {            spuPTS = packetPTS;            packetPTS = INVALID_PTS;        }        size_t added = spuBuffer.add(data, length);                length -= added;        data   += added;        if (length==0) {            packet=0;        }        if (spuBuffer.isFull()) {            Scheduler::yield("output::sdl::SPUHandler::processDataPacket");                SPUBufferBitReader spuReader(spuBuffer);            spu.reset();            spu.decode(spuReader);            pts_t basePTS = spuPTS; spuPTS = INVALID_PTS;            if (basePTS==INVALID_PTS) {                basePTS = timer.getCurrentSCR();            }            spu.setPTS(basePTS);            displayController.addSPU(spu);            spuBuffer.reset();        }    }}//------------------------------------------------------------------------------void SPUHandler::setPicture(const ControlSequence& controlSequence){    picture = controlSequence.getPicture();    pictureForced =         controlSequence.getDisplayCommand()==ControlSequence::FORCED_START;    pictureColor = controlSequence.getColorIndex();    pictureContrast = controlSequence.getContrast();    pictureVisibleArea.reset();    picture->getVisibleArea(pictureVisibleArea);    update();}    //------------------------------------------------------------------------------void SPUHandler::resetPicture(){    picture = 0;    update();}//------------------------------------------------------------------------------void SPUHandler::update(){}//------------------------------------------------------------------------------//------------------------------------------------------------------------------// Local Variables:// mode: C++// c-basic-offset: 4// indent-tabs-mode: nil// End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -