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

📄 videohandler.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 "VideoHandler.h"#include "SPUHandler.h"#include "output/SystemTimer.h"#include "dvd/packet/PacketQueue.h"#include "dvd/packet/TimedDataBlockPacket.h"#include "dvd/packet/DataBlockTypes.h"#include "util/Reference.h"#include "util/Util.h"#include "util/Config.h"#include "unichrome/Unichrome.h"#include "unichrome/Mode.h"#include <cstring>//------------------------------------------------------------------------------using output::unichrome::VideoHandler;using output::SystemTimer;using dvd::packet::PacketQueue;using dvd::packet::TimedDataBlockPacket;using dvd::packet::DataBlockPacket;using dvd::packet::DataBlockTypes;using unichrome::Mode;using sched::Scheduler;using mpeg::SequenceHeader;using mpeg::PictureHeader;using mpeg::GOPHeader;using mpeg::QuantMatrix;using unichrome::Unichrome;using unichrome::MPEGDecoder;//------------------------------------------------------------------------------inline ptsdiff_t VideoHandler::getFrameLength() const{    return (videoAttributes.standard==PAL) ? 3600 : 3003;}//------------------------------------------------------------------------------inline ptsdiff_t VideoHandler::getTolerance() const{    return playIntra ? Util::ptsFrequency : getFrameLength()/2;}//------------------------------------------------------------------------------//------------------------------------------------------------------------------VideoHandler::VideoHandler(PacketQueue& inputQueue, SystemTimer& timer,                           SPUHandler& spuHandler, Unichrome& videoDevice) :    MPEGParser( (MPEGListener&)*this ),    inputQueue(inputQueue),    videoDevice(videoDevice),    timer(timer),    spuHandler(spuHandler),    basePTS(0),    numFields(0),    fieldCompensation(0),    playIntra(false),    nextOnlyIFrame(true){}//------------------------------------------------------------------------------void VideoHandler::run(){    Mode mode(videoAttributes.standard);    videoDevice.setMode(mode);    clearOSD();    videoDevice.setAspectRatio(videoAttributes.aspectRatio);    spuHandler.setWideScreen(videoAttributes.aspectRatio==AR_16_9);        while(!shouldQuit()) {        clearInterrupt();                waitHWFlipFinished(false);                parse();    }    waitHWFlipFinished(false);            videoDevice.stop();}//------------------------------------------------------------------------------Reference<DataBlockPacket> VideoHandler::getNextPacket(){    Reference<TimedDataBlockPacket> packet;                while(!isInterrupted() && !packet.isValid())  {        packet = TimedDataBlockPacket::convert(inputQueue.get(Util::currentTimeMillis()+100));                if (!packet.isValid() && !isInterrupted()) {            drawCurrentFrame(false);        }    }    return packet;}//------------------------------------------------------------------------------void VideoHandler::printStatus() const{    //Log::debug("  brightness: %u\n", brightness/2);}//------------------------------------------------------------------------------void VideoHandler::setPlayIntra(bool x){    playIntra = x;    videoDevice.getMPEGDecoder().setPlayIntra(x);}//------------------------------------------------------------------------------void VideoHandler::reset(){    flush();        videoDevice.getMPEGDecoder().reset();    nextOnlyIFrame = true;        MPEGParser::reset();}//------------------------------------------------------------------------------void VideoHandler::flush(){    basePTS = 0;    numFields = 0;    fieldCompensation = 0;    videoDevice.getMPEGDecoder().flush();}//------------------------------------------------------------------------------bool VideoHandler::isDifferent(const VideoAttributes& attributes) const{    return         attributes.standard!=videoAttributes.standard ||        attributes.aspectRatio!=videoAttributes.aspectRatio;}//------------------------------------------------------------------------------void VideoHandler::setAttributes(const VideoAttributes& attributes){    if (attributes.standard!=videoAttributes.standard) {        Mode mode(attributes.standard);        videoDevice.setMode(mode);        clearOSD();    }    if (attributes.aspectRatio!=videoAttributes.aspectRatio) {        videoDevice.setAspectRatio(attributes.aspectRatio);        spuHandler.setWideScreen(attributes.aspectRatio==AR_16_9);    }    videoAttributes = attributes;}    //------------------------------------------------------------------------------unsigned VideoHandler::increaseBrightness(){    return 50;}//------------------------------------------------------------------------------unsigned VideoHandler::decreaseBrightness(){    return 50;}//------------------------------------------------------------------------------unsigned VideoHandler::increaseContrast(){    return 50;}//------------------------------------------------------------------------------unsigned VideoHandler::decreaseContrast(){    return 50;}//------------------------------------------------------------------------------unsigned VideoHandler::increaseSaturation(){    return 50;}//------------------------------------------------------------------------------unsigned VideoHandler::decreaseSaturation(){    return 50;}//------------------------------------------------------------------------------void VideoHandler::ptsReceived(pts_t pts){    videoDevice.getMPEGDecoder().setPTS(pts);}//------------------------------------------------------------------------------void VideoHandler::sequence(const SequenceHeader& header){    videoDevice.getMPEGDecoder().startSequence(header);}//------------------------------------------------------------------------------void VideoHandler::quantMatrix(const QuantMatrix& quantMatrix){    videoDevice.getMPEGDecoder().setQuantMatrix(quantMatrix);}//------------------------------------------------------------------------------void VideoHandler::groupOfPictures(const GOPHeader& /*header*/){}//------------------------------------------------------------------------------void VideoHandler::picture(const PictureHeader& header){    videoDevice.getMPEGDecoder().startPicture(header);}//------------------------------------------------------------------------------void VideoHandler::slice(const unsigned char* data, size_t length){    videoDevice.getMPEGDecoder().addSlice(data, length);}//------------------------------------------------------------------------------void VideoHandler::endPicture(){    MPEGDecoder& mpegDecoder = videoDevice.getMPEGDecoder();    if (!mpegDecoder.isDisplayable()) return;    const MPEGDecoder::PictureInfo& displayInfo =         mpegDecoder.getDisplayInfo();    bool isIFrame = displayInfo.codingType==PictureHeader::CODING_I;    if ((playIntra || nextOnlyIFrame) && !isIFrame) return;    nextOnlyIFrame = false;    timeFrame(displayInfo.pts);    if (isInterrupted()) return;    drawCurrentFrame();    if (isInterrupted()) return;        numFields += displayInfo.numFields;}//------------------------------------------------------------------------------void VideoHandler::endSequence(){    videoDevice.getMPEGDecoder().endSequence();    endPicture();}//------------------------------------------------------------------------------void VideoHandler::clearOSD(){    size_t width, height;    videoDevice.getOutputSize(width, height);    videoDevice.setForeground(0xff000000);    videoDevice.fillRectangle(0, 0, width, height);    videoDevice.flush();}//------------------------------------------------------------------------------void VideoHandler::drawCurrentFrame(bool updateFieldCompensation){    MPEGDecoder& mpegDecoder = videoDevice.getMPEGDecoder();    if (!mpegDecoder.isDisplayable()) return;    waitHWFlipFinished(updateFieldCompensation && numFields>0);    if (isInterrupted()) return;    mpegDecoder.displayPicture();        if (videoDevice.usingHWFlipping()) {        // Even if displayPicture() was interrupted, we need to        // initiate a HW flip so that the buffer index (nextV1Buffer)        // remains consitent with what is displayed!        if (updateFieldCompensation) {            videoDevice.startHWFlip(numFields, fieldCompensation);        } else {            videoDevice.startHWFlip(0, 0);        }    }}//------------------------------------------------------------------------------pts_t VideoHandler::getFramePTS(pts_t pts){    const ptsdiff_t frameLength = getFrameLength();        pts_t framePTS = basePTS + numFields * frameLength / 2;    if (pts!=INVALID_PTS) {        pts_t picturePTS = pts + timer.getPTSCompensation();        if (framePTS!=picturePTS || playIntra) {            if (!playIntra) {                Log::debug("output::unichrome::VideoHandler::getFramePTS: framePTS=%llu, picturePTS=%llu, basePTS=%llu, numFields=%u\n",                           framePTS, picturePTS,                           basePTS, numFields);            }                        framePTS = picturePTS;            basePTS = picturePTS;            numFields = 0;            fieldCompensation = 0;        }    } else if (playIntra) {        basePTS = framePTS;        numFields = 0;        fieldCompensation = 0;    }    return framePTS;}//------------------------------------------------------------------------------void VideoHandler::timeFrame(pts_t pts){    pts_t framePTS = getFramePTS(pts);        if (!videoDevice.usingHWFlipping() || numFields==0) {        pts_t currentSCR = timer.getCurrentSCR();        if (framePTS<currentSCR) {            if ( (framePTS+getTolerance()) < currentSCR )             {                ptsdiff_t diff = currentSCR - framePTS;                timer.advancePTSCompensation(diff);                basePTS += diff;                Log::debug("output::unichrome::VideoHandler::timeFrame: advanced PTS compensation by: %lld\n",                           diff);            }        } else {            if (videoDevice.usingHWFlipping()) {                if (framePTS>=900) framePTS -= 900;                else framePTS = 0;            }            timer.sleepInterruptible(framePTS);        }    }}//------------------------------------------------------------------------------void VideoHandler::waitHWFlipFinished(bool updateFieldCompensation){    if (!videoDevice.usingHWFlipping()) return;    size_t fieldNumber;    millis_t flipTime = videoDevice.waitHWFlipFinished(fieldNumber);    if (!updateFieldCompensation || flipTime==INVALID_MILLIS ||        isInterrupted())     {        return;    }    const ptsdiff_t frameLength = getFrameLength();    const ptsdiff_t tolerance = getTolerance();    pts_t fieldPTS = basePTS + fieldNumber * frameLength / 2;    pts_t flipPTS = timer.getPTS(flipTime);    if ( (fieldPTS+tolerance) < flipPTS ) {        ssize_t diff = (flipPTS - fieldPTS) * 2 / frameLength;                        Log::debug("output::unichrome::VideoHandler::waitHWFlipFinished: skipping %d fields (fieldPTS=%llu, flipPTS=%llu)\n",                   diff, fieldPTS, flipPTS);                        fieldCompensation -= diff;    } else if ( fieldPTS > (flipPTS + tolerance) ) {        ssize_t diff = (fieldPTS - flipPTS) * 2 / frameLength;                        Log::debug("output::unichrome::VideoHandler::waitHWFlipFinished: inserting a delay of %d fields (fieldPTS=%llu, flipPTS=%llu)\n",                   diff, fieldPTS, flipPTS);                fieldCompensation += diff;    }}//------------------------------------------------------------------------------//------------------------------------------------------------------------------

⌨️ 快捷键说明

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