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
32 #ifndef _ASDCP_MPEG_H_
33 #define _ASDCP_MPEG_H_
35 #include <AS_DCP_system.h>
68 //------------------------------------------------------------------------------------------
71 // find the location in the buffer of the next VES packet, returns RESULT_FAIL
72 // if no start code is found
73 Result_t FindVESStartCode(const byte_t* buf, ui32_t buf_len, StartCode_t* sc, const byte_t** new_pos);
75 // return the extension code of an extension header
76 inline ExtCode_t ParseExtensionCode(const byte_t* buf)
79 return (ExtCode_t)(buf[4] >> 4);
83 class VESParserDelegate; // the delegate is declared later
84 const ui32_t VESHeaderBufSize = 1024; // should be larger than any expected header
86 // MPEG VES parser class - call Parse() as many times as you want with buffers
87 // of any size. State is maintained between calls. When complete headers are
88 // available for examination, the respective delegate method will be called.
89 // All other data is given to the delegate's Data() method.
93 mem_ptr<h__StreamState> m_State;
94 VESParserDelegate* m_Delegate;
96 ui32_t m_HBufLen; // temp space for partial header contents
97 byte_t m_HBuf[VESHeaderBufSize];
101 ASDCP_NO_COPY_CONSTRUCT(VESParser);
107 void SetDelegate(VESParserDelegate*); // you must call this before Parse()
108 Result_t Parse(const byte_t*, ui32_t); // call repeatedly
109 void Reset(); // resets the internal state machine and counters
112 // Parser Event Delegate Interface
114 // Create a concrete subclass and give it to the parser by calling SetDelegate().
115 // The respective method will be called when a header of the named type is found.
116 // Handler methods should return RESULT_OK to continue processing or RESULT_FALSE
117 // to stop without error.
119 class VESParserDelegate
122 virtual ~VESParserDelegate() {}
125 virtual Result_t Picture(VESParser*, const byte_t*, ui32_t) = 0;
126 virtual Result_t Extension(VESParser*, const byte_t*, ui32_t) = 0;
127 virtual Result_t Sequence(VESParser*, const byte_t*, ui32_t) = 0;
128 virtual Result_t GOP(VESParser*, const byte_t*, ui32_t) = 0;
130 // this is not a header handler, it is a signal that actual picture data
131 // has started. All Slice data is reported via the Data() method.
132 virtual Result_t Slice(VESParser*) = 0;
134 // Any data not given to the header handlers above is reported here
135 virtual Result_t Data(VESParser*, const byte_t*, ui32_t) = 0;
139 //------------------------------------------------------------------------------------------
140 // VES header accessor objects
142 // For use within parser delegate methods. The constructor expects a pointer to a buffer
143 // containing two zero bytes, a one byte, a start code and some number of header bytes.
144 // They are not documented further as they should be self-explanatory.
148 static i16_t FrameRateLUT[] = { 0, 24, 24, 25, 30, 30, 50, 60, 60};
149 static bool PulldownLUT[] = { false, true, false, false, true, false, false, true, false};
155 ASDCP_NO_COPY_CONSTRUCT(Sequence);
158 Sequence(const byte_t* p) { assert(p); m_p = p + 4; }
159 inline ui16_t HorizontalSize() { return (ui16_t)( ( m_p[0] << 4 ) | ( m_p[1] >> 4 ) ); }
160 inline ui16_t VerticalSize() { return (ui16_t)( ( ( m_p[1] & 0x0f ) << 8 ) | m_p[2] ); }
161 inline RateCode_t RateCode() { return (RateCode_t)( m_p[3] & 0x0f ); }
162 inline ui16_t FrameRate() { return FrameRateLUT[RateCode()]; }
163 inline bool Pulldown() { return PulldownLUT[RateCode()] != 0; }
164 inline i32_t BitRate() {
165 return ( ( (i32_t)m_p[4] << 10 ) + ( (i32_t)m_p[5] << 2 ) + ( m_p[6] >> 6 ) ) * 400;
168 Rational AspectRatio();
175 ASDCP_NO_COPY_CONSTRUCT(SequenceEx);
178 SequenceEx(const byte_t* p)
181 assert(ParseExtensionCode(p) == EXT_SEQ);
185 inline ui16_t ProfileAndLevel() { return ( m_p[0] << 4) | ( m_p[1] >> 4 ); }
186 inline ui8_t ChromaFormat() { return ( m_p[1] >> 1 ) & 0x03; }
187 inline bool Progressive() { return ( ( m_p[1] >> 3 ) & 0x01 ) > 0; }
188 inline ui32_t HorizontalSizeExt() {
189 return ( ( m_p[1] & 0x01 ) << 13 ) | ( ( m_p[2] & 0x80 ) << 5 );
191 inline ui32_t VerticalSizeExt() { return ( m_p[2] & 0x60 ) << 7; }
192 inline ui32_t BitRateExt() {
193 return ( ( m_p[2] & 0x1f ) << 25 ) | ( ( m_p[3] & 0xfe ) << 17 );
196 inline bool LowDelay() { return ( m_p[5] & 0x80 ) > 0; }
203 ASDCP_NO_COPY_CONSTRUCT(GOP);
206 GOP(const byte_t* p) { assert(p); m_p = p + 4; }
207 inline bool Closed() { return ( ( m_p[3] ) >> 6 ) & 0x01; }
214 ASDCP_NO_COPY_CONSTRUCT(Picture);
217 Picture(const byte_t* p) { assert(p); m_p = p + 4; }
218 inline i16_t TemporalRef() {
219 return ( (i16_t)( m_p[0] << 2 ) ) | ( ( (i16_t)m_p[1] & 0x00c0 ) >> 6 );
222 inline FrameType_t FrameType() {
223 return (FrameType_t)( ( m_p[1] & 0x38 ) >> 3 );
227 } // namespace Accessor
233 #endif // ASDCP_MPEG_H_