📄 spuhandler.cc
字号:
//// 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//------------------------------------------------------------------------------#include "SPUHandler.h"#include "dvd/packet/PacketQueue.h"#include "dvd/packet/TimedDataBlockPacket.h"#include "dvd/packet/SPUPalettePacket.h"#include "dvd/packet/DemultiplexerParameterPacket.h"#include "dxr3/Video.h"//------------------------------------------------------------------------------using output::dxr3::SPUHandler;using output::dxr3::Timer;using dvd::packet::Packet;using dvd::packet::PacketQueue;using dvd::packet::TimedDataBlockPacket;using dvd::packet::SPUPalettePacket;using dvd::packet::DemultiplexerParameterPacket;using dxr3::Video;//------------------------------------------------------------------------------SPUHandler::SPUHandler(Timer& timer, PacketQueue& inputQueue, Video& videoDevice) : TimedStreamHandler("output::dxr3::SPUHandler", timer, inputQueue, videoDevice.getSPUStream()), videoDevice(videoDevice), forcedOnly(true), offset(0), pts(INVALID_PTS){}//------------------------------------------------------------------------------void SPUHandler::run(){ while(!shouldQuit()) { clearInterrupt(); Reference<Packet> packet = inputQueue.get(); if (!packet.isValid()) continue; Reference<TimedDataBlockPacket> dataPacket = TimedDataBlockPacket::convert(packet); if (dataPacket.isValid()) { processDataPacket(dataPacket); continue; } Reference<SPUPalettePacket> palettePacket = SPUPalettePacket::convert(packet); if (palettePacket.isValid()) { videoDevice.setSPUPalette(palettePacket->getPalette()); continue; } Reference<DemultiplexerParameterPacket> demultiplexerParameterPacket = DemultiplexerParameterPacket::convert(packet); if (demultiplexerParameterPacket.isValid()) { forcedOnly = demultiplexerParameterPacket->parameters.spuForcedOnly; continue; } } }//------------------------------------------------------------------------------void SPUHandler::highlightButton(int color, int contrast, size_t top, size_t bottom, size_t left, size_t right){ videoDevice.highlightButton(color, contrast, top, bottom, left, right);} //------------------------------------------------------------------------------void SPUHandler::clearButton(){ videoDevice.clearButton();}//------------------------------------------------------------------------------unsigned SPUHandler::read16(size_t offset) const{ unsigned value = buffer[offset]; value <<= 8; value |= buffer[offset+1]; return value;}//------------------------------------------------------------------------------size_t SPUHandler::copyIntoBuffer(const unsigned char*& data, size_t toCopy){ memcpy(buffer + offset, data, toCopy); offset += toCopy; data += toCopy; return toCopy;}//------------------------------------------------------------------------------bool SPUHandler::isForced() const{ size_t ctrlOffset = read16(2); // FIXME: constant do { size_t current = ctrlOffset+4; do { switch(buffer[current]) { // FIXME: do not use command constants case 0xff: current = 0; break; case 0x00: return true; break; case 0x01: case 0x02: ++current; break; case 0x03: case 0x04: current += 3; break; case 0x05: current += 7; break; case 0x06: current += 5; break; case 0x07: current += read16(current+1); ++current; break; default: assert(0); } } while(current>0); size_t nextOffset = read16(ctrlOffset+2); if (ctrlOffset==nextOffset) { break; } else { ctrlOffset = nextOffset; } } while(true); return false;}//------------------------------------------------------------------------------void SPUHandler::processDataPacket(Reference<TimedDataBlockPacket> packet){ const unsigned char* data = packet->getData(); size_t length = packet->getLength(); while(length>0) { if (offset==0) { assert(length>=2); length -= copyIntoBuffer(data, 2); if (pts==INVALID_PTS) pts = packet->getPTS(); } else { size_t toCopy = length; size_t spuLength = read16(0); if (spuLength<toCopy) toCopy = spuLength; length -= copyIntoBuffer(data, toCopy); if (offset >= spuLength) { if (!forcedOnly || isForced()) { write(buffer, spuLength, pts); } offset = 0; pts = INVALID_PTS; } } }}//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -