📄 unichrome.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, but now handles other// hardware as well. These files contain a (mostly) user-space driver // for the Unichrome board found on Via's EPIA motherboards.//// The information for implementing this driver has been gathered// from the following sources://// - The DirectFB Unichrome driver// Copyright (c) 2003 Andreas Robinson, All rights reserved.//// - Andreas Robinson's MPEG-2 decoder for the Unichrome board.// Copyright (c) 2003 Andreas Robinson, All rights reserved.//// - Via's Unichrome Framebuffer driver// Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.// Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.// 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 "Unichrome.h"#include "ModeInfoTemplate.h"#include "MemoryBlock.h"#include "TVEncoder.h"#include "Register.h"#include "Constant.h"#include "sched/Scheduler.h"#include "sched/Thread.h"#include "util/Util.h"#include "util/Log.h"#include "unichrome/kernel/uchelper.h"#include <algorithm>//------------------------------------------------------------------------------using unichrome::IO;using unichrome::MemoryBlock;using unichrome::ModeInfoTemplate;using unichrome::Mode;using unichrome::MPEGDecoder;using unichrome::Unichrome;using sched::Scheduler;using sched::Thread;using std::min;using std::max;//------------------------------------------------------------------------------namespace {IO::RegisterPart<0x00, 0, 7, IO::RegisterPart<0x36, 3, 3> > IGA1Horizontal_total;IO::RegisterPart<0x01, 0, 7> IGA1Horizontal_addressable;IO::RegisterPart<0x02, 0, 7> IGA1Horizontal_blankStart;IO::RegisterPart<0x03, 0, 4, IO::RegisterPart<0x05, 7, 7, IO::RegisterPart<0x33, 5, 5> > > IGA1Horizontal_blankEnd;IO::RegisterPart<0x04, 0, 7, IO::RegisterPart<0x33, 4, 4> > IGA1Horizontal_synchStart;IO::RegisterPart<0x05, 0, 4> IGA1Horizontal_synchEnd;IO::RegisterPart<0x06, 0, 7, IO::RegisterPart<0x07, 0, 0, IO::RegisterPart<0x07, 5, 5, IO::RegisterPart<0x35, 0, 0 > > > > IGA1Vertical_total;IO::RegisterPart<0x12, 0, 7, IO::RegisterPart<0x07, 1, 1, IO::RegisterPart<0x07, 6, 6, IO::RegisterPart<0x35, 2, 2 > > > > IGA1Vertical_addressable;IO::RegisterPart<0x15, 0, 7, IO::RegisterPart<0x07, 3, 3, IO::RegisterPart<0x09, 5, 5, IO::RegisterPart<0x35, 3, 3 > > > > IGA1Vertical_blankStart;IO::RegisterPart<0x16, 0, 7> IGA1Vertical_blankEnd;IO::RegisterPart<0x10, 0, 7, IO::RegisterPart<0x07, 2, 2, IO::RegisterPart<0x07, 7, 7, IO::RegisterPart<0x35, 1, 1 > > > > IGA1Vertical_synchStart;IO::RegisterPart<0x11, 0, 3> IGA1Vertical_synchEnd;IO::RegisterPart<0x13, 0, 7, IO::RegisterPart<0x35, 5, 7> > IGA1Other_offset;IO::RegisterPart<0x1c, 0, 7, IO::RegisterPart<0x1d, 0, 1> > IGA1Other_fetchCount;/** * Mode info structure. */class ModeInfo : public ModeInfoTemplate<ModeInfo> {public: /** * The number of sequencer registers. */ static const size_t numSequencerRegisters = 4; /** * The offset of sequencer register. */ static const size_t sequencerRegisterOffset = 1; /** * The number of attribute registers. */ static const size_t numAttributeRegisters = 20; /** * The number of graphics registers. */ static const size_t numGraphicsRegisters = 9; /** * The array of mode infos. This must be defined for each * different mode info. */ static ModeInfo modeInfos[]; /** * Find the mode info for the given mode. */ static ModeInfo* find(const Mode& mode, size_t& index); /** * Get the mode info with the given index. */ static ModeInfo& get(size_t index); /** * The width of the mode. */ size_t width; /** * The height of the mode. */ size_t height; /** * The bit depth of the mode. */ size_t bpp; /** * The VCLK value. */ size_t vclk; /** * The sequence registers. */ const uint8_t* sequenceRegisters; /** * The miscallenous reigster. */ uint8_t miscRegister; /** * The horizontal CRT settings. */ const Unichrome::CRTSettings& horizontalCRT; /** * The vertical CRT settings. */ const Unichrome::CRTSettings& verticalCRT; /** * The attribute registers. */ const uint8_t* attributeRegisters; /** * The graphics registers. */ const uint8_t* graphicsRegisters; /** * Extended mode register. */ uint8_t extModeRegister; /** * Construct a ModeInfo structure with the given parameters. */ ModeInfo(const Mode& mode, size_t width, size_t height, size_t bpp, size_t vclk, const uint8_t* sequenceRegisters, uint8_t miscRegister, const Unichrome::CRTSettings& horizontalCRT, const Unichrome::CRTSettings& verticalCRT, const uint8_t* attributeRegisters, const uint8_t* graphicsRegisters, uint8_t extModeRegister); };inline ModeInfo::ModeInfo(const Mode& mode, size_t width, size_t height, size_t bpp, size_t vclk, const uint8_t* sequenceRegisters, uint8_t miscRegister, const Unichrome::CRTSettings& horizontalCRT, const Unichrome::CRTSettings& verticalCRT, const uint8_t* attributeRegisters, const uint8_t* graphicsRegisters, uint8_t extModeRegister) : ModeInfoTemplate<ModeInfo>(mode), width(width), height(height), bpp(bpp), vclk(vclk), sequenceRegisters(sequenceRegisters), miscRegister(miscRegister), horizontalCRT(horizontalCRT), verticalCRT(verticalCRT), attributeRegisters(attributeRegisters), graphicsRegisters(graphicsRegisters), extModeRegister(extModeRegister){}//------------------------------------------------------------------------------uint8_t palSequenceRegisters[ModeInfo::numSequencerRegisters] = { 0x01, 0x0f, 0x03, 0x0e};Unichrome::CRTSettings palHorizontalCRT = { 864, 720, 720, 864, 760, 840};Unichrome::CRTSettings palVerticalCRT = { 625, 576, 576, 625, 577, 580};uint8_t palAttributeRegisters[ModeInfo::numAttributeRegisters] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x41, 0x00, 0x0f, 0x00 };uint8_t palGraphicsRegisters[ModeInfo::numGraphicsRegisters] = { 0x00, 0x00, 0x00, 0x00, 0x99, 0x40, 0x05, 0x0f, 0xff};Unichrome::CRTSettings ntscHorizontalCRT = { 800, 720, 720, 800, 760, 800};Unichrome::CRTSettings ntscVerticalCRT = { 525, 480, 480, 525, 480, 483};//------------------------------------------------------------------------------ModeInfo ModeInfo::modeInfos[] = { ModeInfo(Mode(PAL), 720, 576, 32, 0x471c, palSequenceRegisters, 0x4f, palHorizontalCRT, palVerticalCRT, palAttributeRegisters, palGraphicsRegisters, 0xae), ModeInfo(Mode(NTSC), 720, 480, 32, 0x471c, palSequenceRegisters, 0x4f, ntscHorizontalCRT, ntscVerticalCRT, palAttributeRegisters, palGraphicsRegisters, 0xae)};//------------------------------------------------------------------------------ModeInfo* ModeInfo::find(const Mode& mode, size_t& index){ return ModeInfoTemplate<ModeInfo>::find(mode, modeInfos, sizeof(modeInfos)/sizeof(ModeInfo), index);}//------------------------------------------------------------------------------ModeInfo& ModeInfo::get(size_t index){ return modeInfos[index];}//------------------------------------------------------------------------------} /* anonymous namespace *///------------------------------------------------------------------------------//------------------------------------------------------------------------------Unichrome::FlipperThread* Unichrome::FlipperThread::create(){ int fd = open("/dev/uchelper", O_RDONLY); if (fd>=0) { Log::debug("unichrome::Unichrome::FlipperThread::create: helper device driver found, using HW flipping\n"); return new FlipperThread(fd); } else { Log::debug("unichrome::Unichrome::FlipperThread::create: cannot open helper device file\n"); return 0; }}//------------------------------------------------------------------------------Unichrome::FlipperThread::FlipperThread(int uchelperFD) : Thread("unichrome::Unichrome::FlipperThread"), uchelperFD(uchelperFD){}//------------------------------------------------------------------------------void Unichrome::FlipperThread::startFlip(size_t fieldNo, ssize_t compensation, size_t offset){ fieldNumber = fieldNo; fieldCompensation = compensation; bufferOffset = offset; flipTime = INVALID_MILLIS; asyncTrigger();}//------------------------------------------------------------------------------millis_t Unichrome::FlipperThread::finishFlip(size_t& fieldNo){ finishTrigger(); fieldNo = fieldNumber; return flipTime;}//------------------------------------------------------------------------------void Unichrome::FlipperThread::perform(){ ssize_t realFieldNumber = fieldNumber + fieldCompensation; if (realFieldNumber<0) realFieldNumber = 0; flip_param_t flip_param = { (unsigned)bufferOffset, (unsigned)realFieldNumber, 0 }; POSIX::ioctl(uchelperFD, UCHELPER_CTL_FLIP, &flip_param, "output::unichrome::Unichrome::FlipperThread::perform failed"); if (flip_param.displayed) { flipTime = Util::currentTimeMillis(); }}//------------------------------------------------------------------------------//------------------------------------------------------------------------------bool Unichrome::wait(IO& io, bool (*checkFn)(IO& io), const char* name, size_t busyCycles, size_t sleepCycles, millis_t sleepLength){ for(size_t i = 0; i<busyCycles; ++i) { if (!checkFn(io)) return true; if (i==0) Log::verboseDebug("unichrome::Unichrome::wait(%s): busy\n", name); } for(size_t i = 0; i<sleepCycles && !Scheduler::isInterrupted(); ++i) { if (!checkFn(io)) return true; if (i>0) { Log::debug("unichrome::Unichrome::wait(%s): extended waiting (%u of %u)\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -