File: mpeg2_parser.h

package info (click to toggle)
libyami 1.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,152 kB
  • sloc: cpp: 44,247; ansic: 1,255; makefile: 728; lisp: 479; sh: 21; python: 19
file content (354 lines) | stat: -rw-r--r-- 10,561 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*
 * Copyright 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This file contains an implementation of a Mpeg2 raw stream parser,
// as defined in ISO/IEC 13818-2
//
// parser is highly influenced on the way other parsers are written in
// this project in particular vp8_parser.
//
// The parser is built under the logic that the client will separate the
// input stream in chunks of information separated by start codes.
// Client can decide if partial start_code streams are permitted and owns
// the decision to parse partial information

#ifndef mpeg2_parser_h
#define mpeg2_parser_h

// local headers
#include "common/NonCopyable.h"
#include "bitReader.h"
#include "VideoCommonDefs.h"

// system headers
#include <stdio.h>
#include <string.h>

namespace YamiParser {
namespace MPEG2 {

    // See spec for definitions of values/fields.

    enum PictureCodingType {
        kIFrame = 1,
        kPFrame,
        kBFrame,
    };

    enum PictureStructure {
        kTopField = 1,
        kBottomField,
        kFramePicture,
    };

    enum StartCodeSize {
        kStartCodePrefixSize = 0,
        kStartCodeSize,
    };

    enum ExtensionIdentifierType {
        kSequence = 1,
        kSequenceDisplay,
        kQuantizationMatrix,
        kSequenceScalable = 5,
        kPictureDisplay = 7,
        kPictureCoding,
        kPictureSpatialScalable,
        kPictureTempralScalable,
    };

    enum StartCodeType {
        MPEG2_INVALID_START_CODE = -1,
        MPEG2_PICTURE_START_CODE = 0x00,
        MPEG2_SLICE_START_CODE_MIN,
        MPEG2_SLICE_START_CODE_MAX = 0xaf,
        MPEG2_RESERVED_CODE_0,
        MPEG2_RESERVED_CODE_1,
        MPEG2_USER_DATA_START_CODE,
        MPEG2_SEQUENCE_HEADER_CODE,
        MPEG2_SEQUENCE_ERROR_CODE,
        MPEG2_EXTENSION_START_CODE,
        MPEG2_RESERVED_CODE_2,
        MPEG2_SEQUENCE_END_CODE,
        MPEG2_GROUP_START_CODE,
    };

    enum SystemStartCodeType {
        MPEG2_PROGRAM_END_CODE = 0xb9,
        MPEG2_PACK_HEADER_CODE,
        MPEG2_SYSTEM_HEADER_CODE,
        MPEG2_PROGRAM_STREAM_MAP_CODE,
        MPEG2_PRIVATE_STREAM_CODE_1,
        MPEG2_PADDING_STREAM_CODE,
        MPEG2_PRIVATE_STREAM_CODE_2,
        MPEG2_AUDIO_PES_CODE_MIN = 0xc0,
        MPEG2_AUDIO_PES_CODE_MAX = 0xdf,
        MPEG2_VIDEO_PES_CODE_MIN = 0xe0,
        MPEG2_VIDEO_PES_CODE_MAX = 0xef,
        MPEG2_ECM_STREAM_CODE = 0xf0,
        MPEG2_EMM_STREAM_CODE,
        MPEG2_DSMCC_STREAM_CODE,
        MPEG2_13522_STREAM_CODE,
        MPEG2_H_222_TYPE_A_CODE,
        MPEG2_H_222_TYPE_B_CODE,
        MPEG2_H_222_TYPE_C_CODE,
        MPEG2_H_222_TYPE_D_CODE,
        MPEG2_H_222_TYPE_E_CODE,

    };

    enum ParserResult {
        MPEG2_PARSER_OK = 0,
        MPEG2_PARSER_BROKEN_DATA,
        MPEG2_PARSER_ERROR,
    };

    enum ProfileType {
        MPEG2_PROFILE_HIGH = 1,
        MPEG2_PROFILE_SPATIALLY_SCALABLE,
        MPEG2_PROFILE_SNR_SCALABLE,
        MPEG2_PROFILE_MAIN,
        MPEG2_PROFILE_SIMPLE,
    };

    enum LevelType {
        MPEG2_LEVEL_HIGH = 4,
        MPEG2_LEVEL_HIGH_1440 = 6,
        MPEG2_LEVEL_MAIN = 8,
        MPEG2_LEVEL_LOW = 10,
    };


    struct QuantMatrices {
        QuantMatrices();

        bool load_intra_quantiser_matrix;
        uint8_t intra_quantiser_matrix[64];
        bool load_non_intra_quantiser_matrix;
        uint8_t non_intra_quantiser_matrix[64];
        bool load_chroma_intra_quantiser_matrix;
        uint8_t chroma_intra_quantiser_matrix[64];
        bool load_chroma_non_intra_quantiser_matrix;
        uint8_t chroma_non_intra_quantiser_matrix[64];

    };

    // ISO/IEC spec section 6.2.2.1
    struct SeqHeader {
        SeqHeader();

        uint32_t horizontal_size_value;
        uint32_t vertical_size_value;
        uint32_t aspect_ratio_info;
        uint32_t frame_rate_code;
        uint32_t bit_rate_value;
        bool marker_bit;
        uint32_t vbv_buffer_size_value;
        bool constrained_params_flag;
        QuantMatrices quantizationMatrices;
    };

    // ISO/IEC spec section 6.2.2.3
    struct SeqExtension {
        SeqExtension();

        uint32_t profile_and_level_indication;
        bool progressive_sequence;
        uint32_t chroma_format;
        uint32_t horizontal_size_extension;
        uint32_t vertical_size_extension;
        uint32_t bit_rate_extension;
        bool marker_bit;
        uint32_t vbv_buffer_size_extension;
        bool low_delay;
        uint32_t frame_rate_extension_n;
        uint32_t frame_rate_extension_d;
        //calclated value;
        uint32_t m_width;
        uint32_t m_height;
    };

    // ISO/IEC spec section 6.2.2.6 and 6.3.9
    struct GOPHeader {
        GOPHeader();

        bool drop_frame_flag;
        uint32_t time_code_hours;
        uint32_t time_code_minutes;
        bool marker_bit;
        uint32_t time_code_seconds;
        uint32_t time_code_pictures;
        bool closed_gop;
        bool broken_link;
    };

    // ISO/IEC spec section 6.2.3
    struct PictureHeader {
        PictureHeader();

        uint32_t temporal_reference;
        uint32_t picture_coding_type;
        uint32_t vbv_delay;
        bool full_pel_forward_vector;
        uint32_t forward_f_code;
        bool full_pel_backward_vector;
        uint32_t backward_f_code;
        bool extra_bit_picture;
    };

    // ISO/IEC spec section 6.2.3.1
    struct PictureCodingExtension {
        PictureCodingExtension();
        uint32_t getFCode();

        uint32_t f_code[2][2]; // forward_horizontal
        // forward_vertical
        // backward_horizontal
        // backward_vertical
        uint32_t intra_dc_precision;
        uint32_t picture_structure;
        bool top_field_first;
        bool frame_pred_frame_dct;
        bool concealment_motion_vectors;
        bool q_scale_type;
        bool intra_vlc_format;
        bool alternate_scan;
        bool repeat_first_field;
        bool chrome_420_type;
        bool progressive_frame;
        bool composite_display_flag;
        bool v_axis;
        uint32_t field_sequence;
        bool sub_carrier;
        uint32_t burst_amplitude;
        uint32_t sub_carrier_phase;
    };

    struct Slice {
        Slice();

        // helper variables
        const uint8_t* sliceData;
        uint64_t sliceDataSize;
        uint64_t sliceHeaderSize; // in bits
        uint32_t verticalPosition;
        uint32_t macroblockRow;
        uint32_t macroblockColumn;
        // spec variables
        uint32_t slice_vertical_position_extension;
        uint32_t priority_breakpoint;
        uint32_t quantiser_scale_code;
        bool intra_slice_flag;
        bool intra_slice;
        uint32_t reserved_bits;
        bool extra_bit_slice;
        uint32_t extra_information_slice;

        bool isFirstSlice()
        {
            return !macroblockRow && !macroblockColumn;
        }
    };

    class DecodeUnit {
    public:
        bool parse(const uint8_t* data, int32_t size);
        bool isSlice();

        const uint8_t* m_data;
        int32_t m_size;
        StartCodeType m_type;
    };

    // A parser for raw Mpeg2 streams as specified in ISO/IEC 13818-2.
    class Parser {
    public:
        Parser();
        ~Parser();

        // Try to parse exactly the information of interest in a Mpeg2 raw
        // stream
        // Client can seek for the next start code and then parse it as required

        // parseSequenceHeader will parse a SequenceHeader according to the spec
        // storing the information in the m_sequenceHdr structure and updating
        // the position to the last bit parsed. information will be returned
        bool parseSequenceHeader(const DecodeUnit&, SharedPtr<QuantMatrices>&);

        // parseSequenceExtension will parse a SequenceExtension according to
        // the
        // spec
        // storing the information in the sequence_extension structure and
        // updating
        // the position to the last bit parsed.
        bool parseSequenceExtension(BitReader&);

        // parseGOPHeader will parse a GOPHeader according to the spec storing
        // the information in the gop_header_ structure and updating the
        // position
        // to the last bit parsed.
        bool parseGOPHeader(const DecodeUnit&);

        // parsePictureHeader will parse a PictureHeader according to the spec
        // storing
        // the information in the m_pictureHeader_ structure and updating the
        // position
        // to the last bit parsed.
        bool parsePictureHeader(const DecodeUnit&);

        // parsePictureCodingExtension will parse a PictureHeader according to
        // the
        // spec storing the information in the picture_coding_extension_
        // structure
        // and updating the position to the last bit parsed.
        bool parsePictureCodingExtension(BitReader&);

        // parseQuantMatrixExtension will parse a Quant Matrix Extension ID
	// within a Extension Start Code and keep it on the quantization
	// Extension structure for later use
        bool parseQuantMatrixExtension(BitReader&, SharedPtr<QuantMatrices>&);

        // parseSlice will parse a Slice according to the spec storing the
        // information
        // in the Slice structure and updating the position to the last
        // bit parsed.
        bool parseSlice(Slice&, const DecodeUnit&);

        uint32_t getWidth();
        uint32_t getHeight();
        ProfileType getProfile();
        LevelType getLevel();

        SeqHeader m_sequenceHdr;
        SeqExtension m_sequenceExtension;
        GOPHeader m_GOPHeader;
        PictureHeader m_pictureHeader;
        PictureCodingExtension m_pictureCodingExtension;

    private:
        friend class MPEG2ParserTest;
        SharedPtr<QuantMatrices> m_quantMatrices;

        bool readQuantMatrix(bool& loadMatrix, uint8_t matrix[], BitReader&);
        bool calculateMBColumn(Slice&, BitReader&);

        DISALLOW_COPY_AND_ASSIGN(Parser);
    };

} // namespace MPEG2
} // namespace YamiParser

#endif // mpeg2_parser_h