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

📄 mpegparser.cc

📁 Linux下比较早的基于命令行的DVD播放器
💻 CC
📖 第 1 页 / 共 2 页
字号:
//// 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.// 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 "MPEGParser.h"#include "MPEGListener.h"#include "dvd/packet/PacketQueue.h"#include "dvd/packet/TimedDataBlockPacket.h"//------------------------------------------------------------------------------using mpeg::MPEGParser;using mpeg::SequenceHeader;using mpeg::PictureHeader;using dvd::packet::DataBlockPacket;using dvd::packet::TimedDataBlockPacket;using dvd::packet::PacketQueue;//------------------------------------------------------------------------------const SequenceHeader::aspectRatio_t MPEGParser::aspectRatios[16] = {    SequenceHeader::AR_UNKNOWN,    SequenceHeader::SAR_1_0,    SequenceHeader::DAR_3_4,    SequenceHeader::DAR_16_9,    SequenceHeader::DAR_1_221,    SequenceHeader::AR_UNKNOWN,    SequenceHeader::AR_UNKNOWN,    SequenceHeader::AR_UNKNOWN,       SequenceHeader::AR_UNKNOWN,    SequenceHeader::AR_UNKNOWN,    SequenceHeader::AR_UNKNOWN,    SequenceHeader::AR_UNKNOWN,        SequenceHeader::AR_UNKNOWN,    SequenceHeader::AR_UNKNOWN,    SequenceHeader::AR_UNKNOWN,    SequenceHeader::AR_UNKNOWN};//------------------------------------------------------------------------------const size_t MPEGParser::frameRateNs[16] = {    0, 24000, 24, 25,     30000, 30, 50, 60000,    60, 0, 0, 0,    0, 0, 0, 0};const size_t MPEGParser::frameRateDs[16] = {    0, 1001, 1, 1,    1001, 1, 1, 1001,    1, 0, 0, 0,    0, 0, 0, 0};//------------------------------------------------------------------------------const SequenceHeader::profile_t MPEGParser::profiles[8] = {    SequenceHeader::PROFILE_UNKOWN,    SequenceHeader::PROFILE_HIGH,    SequenceHeader::PROFILE_SPATIALLY_SCALABLE,    SequenceHeader::PROFILE_SNR_SCALABLE,    SequenceHeader::PROFILE_MAIN,    SequenceHeader::PROFILE_SIMPLE,    SequenceHeader::PROFILE_UNKOWN,    SequenceHeader::PROFILE_UNKOWN};const SequenceHeader::level_t MPEGParser::levels[16] = {    SequenceHeader::LEVEL_UNKNOWN,    SequenceHeader::LEVEL_UNKNOWN,    SequenceHeader::LEVEL_UNKNOWN,    SequenceHeader::LEVEL_UNKNOWN,        SequenceHeader::LEVEL_HIGH,    SequenceHeader::LEVEL_UNKNOWN,    SequenceHeader::LEVEL_HIGH_1440,    SequenceHeader::LEVEL_UNKNOWN,        SequenceHeader::LEVEL_MAIN,    SequenceHeader::LEVEL_UNKNOWN,    SequenceHeader::LEVEL_LOW,    SequenceHeader::LEVEL_UNKNOWN,        SequenceHeader::LEVEL_UNKNOWN,    SequenceHeader::LEVEL_UNKNOWN,    SequenceHeader::LEVEL_UNKNOWN,    SequenceHeader::LEVEL_UNKNOWN};//------------------------------------------------------------------------------const SequenceHeader::chromaFormat_t MPEGParser::chromaFormats[4] = {    SequenceHeader::CHROMA_UNKNOWN,    SequenceHeader::CHROMA_4_2_0,    SequenceHeader::CHROMA_4_2_2,    SequenceHeader::CHROMA_4_4_4};//------------------------------------------------------------------------------//------------------------------------------------------------------------------const PictureHeader::codingType_t MPEGParser::codingTypes[8] = {    PictureHeader::CODING_UNKNOWN,    PictureHeader::CODING_I,    PictureHeader::CODING_P,    PictureHeader::CODING_B,    PictureHeader::CODING_UNKNOWN,    PictureHeader::CODING_UNKNOWN,    PictureHeader::CODING_UNKNOWN,    PictureHeader::CODING_UNKNOWN};//------------------------------------------------------------------------------const PictureHeader::pictureStructure_t MPEGParser::pictureStructures[4] = {    PictureHeader::PICTURE_UNKNOWN,    PictureHeader::PICTURE_TOP,    PictureHeader::PICTURE_BOTTOM,    PictureHeader::PICTURE_FRAME};//------------------------------------------------------------------------------//------------------------------------------------------------------------------MPEGParser::MPEGParser(MPEGListener& listener) :    Schedulable("mpeg::MPEGParser"),    listener(listener),    data(0), dataLength(0),     currentByte(0), bitsLeft(0),    currentStartCode(0xff),    sliceBuffer(new unsigned char[sliceBufferSize]){}//------------------------------------------------------------------------------MPEGParser::~MPEGParser(){    delete[] sliceBuffer;}//------------------------------------------------------------------------------void MPEGParser::run(){    while(!shouldQuit()) {        clearInterrupt();                parse();    }}//------------------------------------------------------------------------------void MPEGParser::reset(){    currentPacket = 0;    dataLength = 0;    currentStartCode = 0xff;    interrupt();}//------------------------------------------------------------------------------void MPEGParser::nextPacket(){    currentPacket = 0; dataLength = 0;    currentPacket = getNextPacket();    if (currentPacket.isValid()) {                data = currentPacket->getData();        dataLength = currentPacket->getLength();        currentByte = 0;        bitsLeft = 8;        pts_t pts = INVALID_PTS;        Reference<TimedDataBlockPacket> timedPacket =             TimedDataBlockPacket::convert(currentPacket);        if (timedPacket.isValid()) {            pts = timedPacket->getPTS();        }        listener.ptsReceived(pts);    }}//------------------------------------------------------------------------------inline void MPEGParser::skipByte(){    if (bitsLeft<8) {        ++currentByte; bitsLeft = 8;    }}//------------------------------------------------------------------------------inline unsigned MPEGParser::readBits(size_t numBits){    unsigned result = 0;        while(numBits>0) {        if (currentByte<dataLength) {            size_t toRead = std::min(bitsLeft, numBits);            bitsLeft = (toRead<bitsLeft) ? (bitsLeft-toRead) : 0;                        result <<= toRead;            result |= (data[currentByte]>>bitsLeft) & ~(0xff<<toRead);                        if (bitsLeft==0) {                ++currentByte; bitsLeft = 8;            }            numBits -= toRead;        } else {            nextPacket();            if (isInterrupted()) return 0;        }    }        return result;}//------------------------------------------------------------------------------unsigned MPEGParser::readByte(){    skipByte();        if (currentByte<dataLength) {        return data[currentByte++];    }        nextPacket();    if (!isInterrupted()) {        return data[currentByte++];    }    return 0;}//------------------------------------------------------------------------------unsigned MPEGParser::nextStartCode(){    size_t matchLength = 0;    while(!isInterrupted() && matchLength<3) {        unsigned b = readByte();        if (b==0) {            if (matchLength<2) ++matchLength;        } else if (b==1 && matchLength==2) {            ++matchLength;        } else {            matchLength = 0;        }    }    currentStartCode = readByte();    return currentStartCode;}//------------------------------------------------------------------------------void MPEGParser::parse(){    dataLength = 0;    currentStartCode = 0xff;    nextStartCode();    while(!isInterrupted()) {        while(!isInterrupted() && currentStartCode!=STARTCODE_SEQUENCE_HEADER) {            nextStartCode();        }                if (!isInterrupted() && currentStartCode==STARTCODE_SEQUENCE_HEADER) {            if (!parseSequenceHeader()) continue;                        while(!isInterrupted() && currentStartCode!=STARTCODE_SEQUENCE_END) {                parseExtensionAndUserData(0);                if (!isInterrupted()) do {                    if (currentStartCode==STARTCODE_GROUP_START) {                        parseGOPHeader();                        parseExtensionAndUserData(1);                    }                    if (currentStartCode==STARTCODE_PICTURE) {                        parsePictureHeader();                        parseExtensionAndUserData(2);                        parsePictureData();                    }                } while((currentStartCode==STARTCODE_PICTURE ||                          currentStartCode==STARTCODE_GROUP_START) &&                        !isInterrupted());                                if (!isInterrupted()) {                    if (!parseSequenceHeader()) break;                }            }            if (!isInterrupted() && currentStartCode==STARTCODE_SEQUENCE_END) {                listener.endSequence();            }        }    }}//------------------------------------------------------------------------------bool MPEGParser::parseSequenceHeader(){//     Log::debug("mpeg::MPEGParser::parseSequenceHeader\n");    if (currentStartCode!=STARTCODE_SEQUENCE_HEADER) {//         Log::debug("mpeg::MPEGParser::parseSequenceHeader: sequence header not found, start code=0x%02x\n",//                    currentStartCode);        return false;    }    sequenceHeader.horizontalSize = readBits(12);    sequenceHeader.verticalSize = readBits(12);    sequenceHeader.aspectRatio = aspectRatios[readBits(4)];    size_t frameRateIndex = readBits(4);    sequenceHeader.frameRateN = frameRateNs[frameRateIndex];    sequenceHeader.frameRateD = frameRateDs[frameRateIndex];    sequenceHeader.bitRate = readBits(18);    readBits(1);      // marker_bit    sequenceHeader.vbvBufferSize = readBits(10);    readBits(1);      // constraind_parameters_flag    sequenceHeader.quantMatrix.loadIntraQMX = readBits(1)==1;    if (sequenceHeader.quantMatrix.loadIntraQMX) {        for(size_t i = 0; i<sizeof(sequenceHeader.quantMatrix.intraQMX); ++i) {            sequenceHeader.quantMatrix.intraQMX[i] = readBits(8);        }    }    sequenceHeader.quantMatrix.loadNonIntraQMX = readBits(1)==1;    if (sequenceHeader.quantMatrix.loadNonIntraQMX) {        for(size_t i = 0; i<sizeof(sequenceHeader.quantMatrix.nonIntraQMX); ++i) {            sequenceHeader.quantMatrix.nonIntraQMX[i] = readBits(8);        }    }    sequenceHeader.quantMatrix.loadChromaIntraQMX = false;    sequenceHeader.quantMatrix.loadChromaNonIntraQMX = false;    if (nextStartCode()!=STARTCODE_EXTENSION) {        Log::debug("mpeg::MPEGParser::readSequenceHeader: Sequence header not followed by sequence extension\n");        return false;    }    if (readBits(4)!=EXTENSION_SEQUENCE) {        Log::debug("mpeg::MPEGParser::readSequenceHeader: Sequence header followed by extension other than a sequence extension\n");        return false;    }    sequenceHeader.profileAndLevelEscape = readBits(1)==1;    sequenceHeader.profile = profiles[readBits(3)];    sequenceHeader.level = levels[readBits(4)];    sequenceHeader.progressive = readBits(1)==1;    sequenceHeader.chromaFormat = chromaFormats[readBits(2)];    sequenceHeader.horizontalSize |= readBits(2)<<12;    sequenceHeader.verticalSize |= readBits(2)<<12;    sequenceHeader.bitRate |= readBits(12)<<18;    readBits(1);      // marker bit    sequenceHeader.vbvBufferSize |= readBits(8) << 10;    sequenceHeader.lowDelay = readBits(1)==1;    sequenceHeader.frameRateN *= readBits(2)+1;    sequenceHeader.frameRateD *= readBits(5)+1;    if (!isInterrupted()) {        listener.sequence(sequenceHeader);    }    nextStartCode();        return !isInterrupted();}//------------------------------------------------------------------------------void MPEGParser::parseExtensionAndUserData(unsigned i){//     Log::debug("mpeg::MPEGParser::parseExtensionAndUserData\n");    while(!isInterrupted() &&          (currentStartCode==STARTCODE_EXTENSION ||            currentStartCode==STARTCODE_USER_DATA))    {

⌨️ 快捷键说明

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