| /********** |
| This library is free software; you can redistribute it and/or modify it under |
| the terms of the GNU Lesser General Public License as published by the |
| Free Software Foundation; either version 2.1 of the License, or (at your |
| option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) |
| |
| This library 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 Lesser General Public License for |
| more details. |
| |
| You should have received a copy of the GNU Lesser General Public License |
| along with this library; if not, write to the Free Software Foundation, Inc., |
| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| **********/ |
| // "liveMedia" |
| // Copyright (c) 1996-2015 Live Networks, Inc. All rights reserved. |
| // An abstract parser for MPEG video streams |
| // Implementation |
| |
| #include "MPEGVideoStreamParser.hh" |
| |
| MPEGVideoStreamParser |
| ::MPEGVideoStreamParser(MPEGVideoStreamFramer* usingSource, |
| FramedSource* inputSource) |
| : StreamParser(inputSource, FramedSource::handleClosure, usingSource, |
| &MPEGVideoStreamFramer::continueReadProcessing, usingSource), |
| fUsingSource(usingSource) { |
| } |
| |
| MPEGVideoStreamParser::~MPEGVideoStreamParser() { |
| } |
| |
| void MPEGVideoStreamParser::restoreSavedParserState() { |
| StreamParser::restoreSavedParserState(); |
| fTo = fSavedTo; |
| fNumTruncatedBytes = fSavedNumTruncatedBytes; |
| } |
| |
| void MPEGVideoStreamParser::registerReadInterest(unsigned char* to, |
| unsigned maxSize) { |
| fStartOfFrame = fTo = fSavedTo = to; |
| fLimit = to + maxSize; |
| fNumTruncatedBytes = fSavedNumTruncatedBytes = 0; |
| } |
| |
| void MPEGVideoStreamParser::setParseState() { |
| fSavedTo = fTo; |
| fSavedNumTruncatedBytes = fNumTruncatedBytes; |
| saveParserState(); |
| } |
| |
| void MPEGVideoStreamParser::saveByte(u_int8_t byte) { |
| if (fTo >= fLimit) { // there's no space left |
| ++fNumTruncatedBytes; |
| return; |
| } |
| |
| *fTo++ = byte; |
| } |
| |
| void MPEGVideoStreamParser::save4Bytes(u_int32_t word) { |
| if (fTo+4 > fLimit) { // there's no space left |
| fNumTruncatedBytes += 4; |
| return; |
| } |
| |
| *fTo++ = word>>24; *fTo++ = word>>16; *fTo++ = word>>8; *fTo++ = word; |
| } |
| |
| void MPEGVideoStreamParser::saveToNextCode(u_int32_t& curWord) { |
| saveByte(curWord>>24); |
| curWord = (curWord<<8)|get1Byte(); |
| while ((curWord&0xFFFFFF00) != 0x00000100) { |
| if ((unsigned)(curWord&0xFF) > 1) { |
| // a sync word definitely doesn't begin anywhere in "curWord" |
| save4Bytes(curWord); |
| curWord = get4Bytes(); |
| } else { |
| // a sync word might begin in "curWord", although not at its start |
| saveByte(curWord>>24); |
| unsigned char newByte = get1Byte(); |
| curWord = (curWord<<8)|newByte; |
| } |
| } |
| } |
| |
| void MPEGVideoStreamParser::skipToNextCode(u_int32_t& curWord) { |
| curWord = (curWord<<8)|get1Byte(); |
| while ((curWord&0xFFFFFF00) != 0x00000100) { |
| if ((unsigned)(curWord&0xFF) > 1) { |
| // a sync word definitely doesn't begin anywhere in "curWord" |
| curWord = get4Bytes(); |
| } else { |
| // a sync word might begin in "curWord", although not at its start |
| unsigned char newByte = get1Byte(); |
| curWord = (curWord<<8)|newByte; |
| } |
| } |
| } |
| |
| unsigned MPEGVideoStreamParser::curFrameSize() { |
| return fTo - fStartOfFrame; |
| } |
| |
| unsigned MPEGVideoStreamParser::numTruncatedBytes() const { |
| return fNumTruncatedBytes; |
| } |