📄 video.cc
字号:
//// Copyright (c) 2002 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 "Video.h"#include "DXR3.h"#include "util/Util.h"#include "util/Log.h"#include <cassert>//------------------------------------------------------------------------------using dxr3::Video;//------------------------------------------------------------------------------inline void Video::executeCommand(int command){ dxr3.executeCommand(0, command, 0, 0xffff); // FIXME: register constants}//------------------------------------------------------------------------------inline void Video::setPlaying(){ if (!playing) { updateTiming(); playing = true; }}//------------------------------------------------------------------------------inline void Video::clearPlaying(){ playing = false;}//------------------------------------------------------------------------------void Video::initialize(unsigned deviceNumber){ stream.open(deviceNumber, O_RDWR|O_NONBLOCK, "mv"); stop(); int scrSpeed = 0x900; dxr3.dev.ioctl(EM8300_IOCTL_SCR_SETSPEED, &scrSpeed, "Error setting SCR speed to %04x", scrSpeed); setSCR(0); spuStream.open(deviceNumber, O_RDWR|O_NONBLOCK, "sp");}//------------------------------------------------------------------------------void Video::setStandard(videoStandard_t standard){ int videomode; switch(standard) { case PAL60: videomode = EM8300_VIDEOMODE_PAL60; break; case NTSC: videomode = EM8300_VIDEOMODE_NTSC; break; default: videomode = EM8300_VIDEOMODE_PAL; break; } dxr3.dev.ioctl(EM8300_IOCTL_SET_VIDEOMODE, &videomode, "Error settign video mode to %d", videomode);}//------------------------------------------------------------------------------videoStandard_t Video::getStandard(){ int videomode; dxr3.dev.ioctl(EM8300_IOCTL_GET_VIDEOMODE, &videomode, "Error retrieving video standard"); switch(videomode) { case EM8300_VIDEOMODE_PAL: return PAL; case EM8300_VIDEOMODE_PAL60: return PAL60; case EM8300_VIDEOMODE_NTSC: return NTSC; default: return PAL; }}//------------------------------------------------------------------------------void Video::setAspectRatio(aspectRatio_t aspectRatio){ int ar; switch(aspectRatio) { case AR_16_9: ar = EM8300_ASPECTRATIO_16_9; break; default: ar = EM8300_ASPECTRATIO_4_3; break; } dxr3.dev.ioctl(EM8300_IOCTL_SET_ASPECTRATIO, &ar, "Error setting aspect ratio to %d", ar);}//------------------------------------------------------------------------------aspectRatio_t Video::getAspectRatio(){ int ar; dxr3.dev.ioctl(EM8300_IOCTL_GET_ASPECTRATIO, &ar, "Error retrieving aspect ratio"); switch(ar) { case EM8300_ASPECTRATIO_4_3: return AR_4_3; case EM8300_ASPECTRATIO_16_9: return AR_16_9; default: return AR_16_9; }}//------------------------------------------------------------------------------void Video::play(){ executeCommand(MVCOMMAND_SYNC); setPlaying();}//------------------------------------------------------------------------------void Video::playIntra(){ executeCommand(MVCOMMAND_PLAYINTRA); setPlaying();}//------------------------------------------------------------------------------void Video::pause(){ executeCommand(MVCOMMAND_PAUSE); clearPlaying();}//------------------------------------------------------------------------------void Video::stop(){ executeCommand(MVCOMMAND_STOP); clearPlaying();}//------------------------------------------------------------------------------void Video::flush(){ assert(!playing); unsigned subDevice = EM8300_SUBDEVICE_VIDEO; dxr3.dev.ioctl(EM8300_IOCTL_FLUSH, &subDevice, "Error flusing video");}//------------------------------------------------------------------------------void Video::setSCR(pts_t scr){ assert(!playing); unsigned scrvalue = (unsigned)(scr>>1); dxr3.dev.ioctl(EM8300_IOCTL_SCR_SET, &scrvalue, "Error setting SCR to %u", scrvalue);}//------------------------------------------------------------------------------pts_t Video::getSCR(){ unsigned scrvalue; dxr3.dev.ioctl(EM8300_IOCTL_SCR_GET, &scrvalue, "Error retrieving SCR"); pts_t scr = scrvalue; scr <<= 1; if (playing) { millis_t nowMillis = Util::currentTimeMillis(); millis_t millisDiff = nowMillis - baseMillis; ptsdiff_t scrdiff = static_cast<ptsdiff_t>(millisDiff); scrdiff *= scrFrequency; scrdiff /= 1000000; pts_t shouldBeSCR = baseSCR + scrdiff; if (millisDiff==0) millisDiff = 1; Log::verboseDebug("dxr3::Video::getSCR: scr=0x%08llx, shouldBeSCR=0x%08llx, millisDiff=%llu, f=%llu\n", scr, shouldBeSCR, millisDiff, (scr-baseSCR)*1000000/millisDiff); if (scr > (shouldBeSCR+100000) ) { scr &= ~0x1ffff; Log::debug("dxr3::Video::getSCR: fixed SCR downward!\n"); } else if ( (scr+100000) < shouldBeSCR ) { scr += 0x20000; Log::debug("dxr3::Video::getSCR: fixed SCR upward!\n"); } scrdiff = scr - baseSCR; if ( (scr > (shouldBeSCR+2250) || (scr+2250) < shouldBeSCR) && millisDiff > 60000) { scrFrequency = scrdiff * 1000000 / millisDiff; Log::debug("dxr3::Video::getSCR: readjusted frequency to %u mHz\n", scrFrequency); } } return scr;}//------------------------------------------------------------------------------millis_t Video::getMillis(pts_t scr){ if (scr < baseSCR) { Log::debug("SCR: %llu, base: %llu\n", scr, baseSCR); return baseMillis; } else { getSCR(); // To force updating the frequency if needed millis_t millisDiff = scr - baseSCR; millisDiff *= 1000000; millisDiff /= scrFrequency; return baseMillis + millisDiff; }}//------------------------------------------------------------------------------void Video::setSPUPalette(palette_t palette){ spuStream.ioctl(EM8300_IOCTL_SPU_SETPALETTE, palette, "Error setting SPU palette");}//------------------------------------------------------------------------------void Video::highlightButton(int color, int contrast, int top, int bottom, int left, int right){ em8300_button_t button; button.color = color; button.contrast = contrast; button.top = top; button.bottom = bottom; button.left = left; button.right = right; spuStream.ioctl(EM8300_IOCTL_SPU_BUTTON, &button, "Error setting SPU button");}//------------------------------------------------------------------------------void Video::clearButton(){ spuStream.ioctl(EM8300_IOCTL_SPU_BUTTON, 0, "Error clearing SPU button");}//------------------------------------------------------------------------------void Video::getBCS(int& brightness, int& contrast, int& saturation){ em8300_bcs_t bcs; dxr3.dev.ioctl(EM8300_IOCTL_GETBCS, &bcs, "Error retrieving BCS"); brightness = bcs.brightness/10; contrast = bcs.contrast/10; saturation = bcs.saturation/10;}//------------------------------------------------------------------------------void Video::setBCS(int brightness, int contrast, int saturation){ em8300_bcs_t bcs; bcs.brightness = brightness*10; bcs.contrast = contrast*10; bcs.saturation = saturation*10; dxr3.dev.ioctl(EM8300_IOCTL_SETBCS, &bcs, "Error setting BCS");}//------------------------------------------------------------------------------void Video::updateTiming(){ baseSCR = getSCR(); baseMillis = Util::currentTimeMillis(); // Log::debug("dxr3::Video::updateTiming: Base SCR: %llu, base millis: %llu\n",// baseSCR, baseMillis);}//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -