1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// An abstract parser for MPEG video streams
19// C++ header
20
21#ifndef _MPEG_VIDEO_STREAM_PARSER_HH
22#define _MPEG_VIDEO_STREAM_PARSER_HH
23
24#ifndef _STREAM_PARSER_HH
25#include "StreamParser.hh"
26#endif
27#ifndef _MPEG_VIDEO_STREAM_FRAMER_HH
28#include "MPEGVideoStreamFramer.hh"
29#endif
30
31////////// MPEGVideoStreamParser definition //////////
32
33class MPEGVideoStreamParser: public StreamParser {
34public:
35 MPEGVideoStreamParser(MPEGVideoStreamFramer* usingSource,
36 FramedSource* inputSource);
37 virtual ~MPEGVideoStreamParser();
38
39public:
40 void registerReadInterest(unsigned char* to, unsigned maxSize);
41
42 virtual unsigned parse() = 0;
43 // returns the size of the frame that was acquired, or 0 if none was
44 // The number of truncated bytes (if any) is given by:
45 unsigned numTruncatedBytes() const { return fNumTruncatedBytes; }
46
47protected:
48 void setParseState() {
49 fSavedTo = fTo;
50 fSavedNumTruncatedBytes = fNumTruncatedBytes;
51 saveParserState();
52 }
53
54 // Record "byte" in the current output frame:
55 void saveByte(u_int8_t byte) {
56 if (fTo >= fLimit) { // there's no space left
57 ++fNumTruncatedBytes;
58 return;
59 }
60
61 *fTo++ = byte;
62 }
63
64 void save4Bytes(u_int32_t word) {
65 if (fTo+4 > fLimit) { // there's no space left
66 fNumTruncatedBytes += 4;
67 return;
68 }
69
70 *fTo++ = word>>24; *fTo++ = word>>16; *fTo++ = word>>8; *fTo++ = word;
71 }
72
73 // Save data until we see a sync word (0x000001xx):
74 void saveToNextCode(u_int32_t& curWord) {
75 saveByte(curWord>>24);
76 curWord = (curWord<<8)|get1Byte();
77 while ((curWord&0xFFFFFF00) != 0x00000100) {
78 if ((unsigned)(curWord&0xFF) > 1) {
79 // a sync word definitely doesn't begin anywhere in "curWord"
80 save4Bytes(curWord);
81 curWord = get4Bytes();
82 } else {
83 // a sync word might begin in "curWord", although not at its start
84 saveByte(curWord>>24);
85 unsigned char newByte = get1Byte();
86 curWord = (curWord<<8)|newByte;
87 }
88 }
89 }
90
91 // Skip data until we see a sync word (0x000001xx):
92 void skipToNextCode(u_int32_t& curWord) {
93 curWord = (curWord<<8)|get1Byte();
94 while ((curWord&0xFFFFFF00) != 0x00000100) {
95 if ((unsigned)(curWord&0xFF) > 1) {
96 // a sync word definitely doesn't begin anywhere in "curWord"
97 curWord = get4Bytes();
98 } else {
99 // a sync word might begin in "curWord", although not at its start
100 unsigned char newByte = get1Byte();
101 curWord = (curWord<<8)|newByte;
102 }
103 }
104 }
105
106protected:
107 MPEGVideoStreamFramer* fUsingSource;
108
109 // state of the frame that's currently being read:
110 unsigned char* fStartOfFrame;
111 unsigned char* fTo;
112 unsigned char* fLimit;
113 unsigned fNumTruncatedBytes;
114 unsigned curFrameSize() { return fTo - fStartOfFrame; }
115 unsigned char* fSavedTo;
116 unsigned fSavedNumTruncatedBytes;
117
118private: // redefined virtual functions
119 virtual void restoreSavedParserState();
120};
121
122#endif
123