2 Copyright (c) 2005, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \brief MPEG2 VES parser interface
35 #include <KM_platform.h>
70 //------------------------------------------------------------------------------------------
73 // find the location in the buffer of the next VES packet, returns RESULT_FAIL
74 // if no start code is found
75 Result_t FindVESStartCode(const byte_t* buf, ui32_t buf_len, StartCode_t* sc, const byte_t** new_pos);
77 // return the extension code of an extension header
78 inline ExtCode_t ParseExtensionCode(const byte_t* buf)
81 return (ExtCode_t)(buf[4] >> 4);
85 class VESParserDelegate; // the delegate is declared later
86 const ui32_t VESHeaderBufSize = 1024*16; // should be larger than any expected header
88 // MPEG VES parser class - call Parse() as many times as you want with buffers
89 // of any size. State is maintained between calls. When complete headers are
90 // available for examination, the respective delegate method will be called.
91 // All other data is given to the delegate's Data() method.
95 Kumu::mem_ptr<h__StreamState> m_State;
96 VESParserDelegate* m_Delegate;
98 ui32_t m_HBufLen; // temp space for partial header contents
99 byte_t m_HBuf[VESHeaderBufSize];
103 ASDCP_NO_COPY_CONSTRUCT(VESParser);
109 void SetDelegate(VESParserDelegate*); // you must call this before Parse()
110 Result_t Parse(const byte_t*, ui32_t); // call repeatedly
111 void Reset(); // resets the internal state machine and counters, return to the top of the file
114 // Parser Event Delegate Interface
116 // Create a concrete subclass and give it to the parser by calling SetDelegate().
117 // The respective method will be called when a header of the named type is found.
118 // Handler methods should return RESULT_OK to continue processing or RESULT_FALSE
119 // to terminate parsing without signaling an error.
121 class VESParserDelegate
124 virtual ~VESParserDelegate() {}
127 virtual Result_t Picture(VESParser* Caller, const byte_t* header_buf, ui32_t header_len) = 0;
128 virtual Result_t Extension(VESParser*, const byte_t*, ui32_t) = 0;
129 virtual Result_t Sequence(VESParser*, const byte_t*, ui32_t) = 0;
130 virtual Result_t GOP(VESParser*, const byte_t*, ui32_t) = 0;
132 // this is not a header handler, it is a signal that actual picture data
133 // has started. All Slice data is reported via the Data() method.
134 virtual Result_t Slice(VESParser*, byte_t slice_id) = 0;
136 // Any data not given to the header handlers above is reported here
137 // This method may be called with a value of -1 or -2. This will happen
138 // when processing a start code that has one or two leading zeros
139 // in the preceding buffer
140 virtual Result_t Data(VESParser*, const byte_t*, i32_t) = 0;
144 //------------------------------------------------------------------------------------------
145 // VES header accessor objects
147 // For use within parser delegate methods. The constructor expects a pointer to a buffer
148 // containing two zero bytes, a one byte, a start code and some number of header bytes.
149 // They are not documented further as it is hoped that they are self-explanatory.
155 static i16_t FrameRateLUT[] = { 0, 24, 24, 25, 30, 30, 50, 60, 60};
156 static bool PulldownLUT[] = { false, true, false, false, true, false, false, true, false};
162 ASDCP_NO_COPY_CONSTRUCT(Sequence);
165 Sequence(const byte_t* p) { assert(p); m_p = p + 4; }
166 inline ui16_t HorizontalSize() { return (ui16_t)( ( m_p[0] << 4 ) | ( m_p[1] >> 4 ) ); }
167 inline ui16_t VerticalSize() { return (ui16_t)( ( ( m_p[1] & 0x0f ) << 8 ) | m_p[2] ); }
168 inline RateCode_t RateCode() { return (RateCode_t)( m_p[3] & 0x0f ); }
169 inline ui16_t FrameRate() { return FrameRateLUT[RateCode()]; }
170 inline bool Pulldown() { return PulldownLUT[RateCode()] != 0; }
171 inline i32_t BitRate() {
172 return ( ( (i32_t)m_p[4] << 10 ) + ( (i32_t)m_p[5] << 2 ) + ( m_p[6] >> 6 ) ) * 400;
175 Rational AspectRatio();
179 class SequenceEx // tension
182 ASDCP_NO_COPY_CONSTRUCT(SequenceEx);
185 SequenceEx(const byte_t* p)
188 assert(ParseExtensionCode(p) == EXT_SEQ);
192 inline ui16_t ProfileAndLevel() { return ( m_p[0] << 4) | ( m_p[1] >> 4 ); }
193 inline ui8_t ChromaFormat() { return ( m_p[1] >> 1 ) & 0x03; }
194 inline bool Progressive() { return ( ( m_p[1] >> 3 ) & 0x01 ) > 0; }
195 inline ui32_t HorizontalSizeExt() {
196 return ( ( m_p[1] & 0x01 ) << 13 ) | ( ( m_p[2] & 0x80 ) << 5 );
198 inline ui32_t VerticalSizeExt() { return ( m_p[2] & 0x60 ) << 7; }
199 inline ui32_t BitRateExt() {
200 return ( ( m_p[2] & 0x1f ) << 25 ) | ( ( m_p[3] & 0xfe ) << 17 );
203 inline bool LowDelay() { return ( m_p[5] & 0x80 ) > 0; }
210 ASDCP_NO_COPY_CONSTRUCT(GOP);
213 GOP(const byte_t* p) { assert(p); m_p = p + 4; }
214 inline bool Closed() { return ( ( m_p[3] ) >> 6 ) & 0x01; }
221 ASDCP_NO_COPY_CONSTRUCT(Picture);
224 Picture(const byte_t* p) { assert(p); m_p = p + 4; }
225 inline i16_t TemporalRef() {
226 return ( (i16_t)( m_p[0] << 2 ) ) | ( ( (i16_t)m_p[1] & 0x00c0 ) >> 6 );
229 inline FrameType_t FrameType() {
230 return (FrameType_t)( ( m_p[1] & 0x38 ) >> 3 );
234 } // namespace Accessor