Blame codecparsers/mpeg2_parser.h

Packit 1244b8
/*
Packit 1244b8
 * Copyright 2016 Intel Corporation
Packit 1244b8
 *
Packit 1244b8
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1244b8
 * you may not use this file except in compliance with the License.
Packit 1244b8
 * You may obtain a copy of the License at
Packit 1244b8
 *
Packit 1244b8
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1244b8
 *
Packit 1244b8
 * Unless required by applicable law or agreed to in writing, software
Packit 1244b8
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1244b8
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1244b8
 * See the License for the specific language governing permissions and
Packit 1244b8
 * limitations under the License.
Packit 1244b8
 */
Packit 1244b8
Packit 1244b8
// This file contains an implementation of a Mpeg2 raw stream parser,
Packit 1244b8
// as defined in ISO/IEC 13818-2
Packit 1244b8
//
Packit 1244b8
// parser is highly influenced on the way other parsers are written in
Packit 1244b8
// this project in particular vp8_parser.
Packit 1244b8
//
Packit 1244b8
// The parser is built under the logic that the client will separate the
Packit 1244b8
// input stream in chunks of information separated by start codes.
Packit 1244b8
// Client can decide if partial start_code streams are permitted and owns
Packit 1244b8
// the decision to parse partial information
Packit 1244b8
Packit 1244b8
#ifndef mpeg2_parser_h
Packit 1244b8
#define mpeg2_parser_h
Packit 1244b8
Packit 1244b8
// local headers
Packit 1244b8
#include "common/NonCopyable.h"
Packit 1244b8
#include "bitReader.h"
Packit 1244b8
#include "VideoCommonDefs.h"
Packit 1244b8
Packit 1244b8
// system headers
Packit 1244b8
#include <stdio.h>
Packit 1244b8
#include <string.h>
Packit 1244b8
Packit 1244b8
namespace YamiParser {
Packit 1244b8
namespace MPEG2 {
Packit 1244b8
Packit 1244b8
    // See spec for definitions of values/fields.
Packit 1244b8
Packit 1244b8
    enum PictureCodingType {
Packit 1244b8
        kIFrame = 1,
Packit 1244b8
        kPFrame,
Packit 1244b8
        kBFrame,
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    enum StartCodeSize {
Packit 1244b8
        kStartCodePrefixSize = 0,
Packit 1244b8
        kStartCodeSize,
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    enum ExtensionIdentifierType {
Packit 1244b8
        kSequence = 1,
Packit 1244b8
        kSequenceDisplay,
Packit 1244b8
        kQuantizationMatrix,
Packit 1244b8
        kSequenceScalable = 5,
Packit 1244b8
        kPictureDisplay = 7,
Packit 1244b8
        kPictureCoding,
Packit 1244b8
        kPictureSpatialScalable,
Packit 1244b8
        kPictureTempralScalable,
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    enum StartCodeType {
Packit 1244b8
        MPEG2_INVALID_START_CODE = -1,
Packit 1244b8
        MPEG2_PICTURE_START_CODE = 0x00,
Packit 1244b8
        MPEG2_SLICE_START_CODE_MIN,
Packit 1244b8
        MPEG2_SLICE_START_CODE_MAX = 0xaf,
Packit 1244b8
        MPEG2_RESERVED_CODE_0,
Packit 1244b8
        MPEG2_RESERVED_CODE_1,
Packit 1244b8
        MPEG2_USER_DATA_START_CODE,
Packit 1244b8
        MPEG2_SEQUENCE_HEADER_CODE,
Packit 1244b8
        MPEG2_SEQUENCE_ERROR_CODE,
Packit 1244b8
        MPEG2_EXTENSION_START_CODE,
Packit 1244b8
        MPEG2_RESERVED_CODE_2,
Packit 1244b8
        MPEG2_SEQUENCE_END_CODE,
Packit 1244b8
        MPEG2_GROUP_START_CODE,
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    enum SystemStartCodeType {
Packit 1244b8
        MPEG2_PROGRAM_END_CODE = 0xb9,
Packit 1244b8
        MPEG2_PACK_HEADER_CODE,
Packit 1244b8
        MPEG2_SYSTEM_HEADER_CODE,
Packit 1244b8
        MPEG2_PROGRAM_STREAM_MAP_CODE,
Packit 1244b8
        MPEG2_PRIVATE_STREAM_CODE_1,
Packit 1244b8
        MPEG2_PADDING_STREAM_CODE,
Packit 1244b8
        MPEG2_PRIVATE_STREAM_CODE_2,
Packit 1244b8
        MPEG2_AUDIO_PES_CODE_MIN = 0xc0,
Packit 1244b8
        MPEG2_AUDIO_PES_CODE_MAX = 0xdf,
Packit 1244b8
        MPEG2_VIDEO_PES_CODE_MIN = 0xe0,
Packit 1244b8
        MPEG2_VIDEO_PES_CODE_MAX = 0xef,
Packit 1244b8
        MPEG2_ECM_STREAM_CODE = 0xf0,
Packit 1244b8
        MPEG2_EMM_STREAM_CODE,
Packit 1244b8
        MPEG2_DSMCC_STREAM_CODE,
Packit 1244b8
        MPEG2_13522_STREAM_CODE,
Packit 1244b8
        MPEG2_H_222_TYPE_A_CODE,
Packit 1244b8
        MPEG2_H_222_TYPE_B_CODE,
Packit 1244b8
        MPEG2_H_222_TYPE_C_CODE,
Packit 1244b8
        MPEG2_H_222_TYPE_D_CODE,
Packit 1244b8
        MPEG2_H_222_TYPE_E_CODE,
Packit 1244b8
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    enum ParserResult {
Packit 1244b8
        MPEG2_PARSER_OK = 0,
Packit 1244b8
        MPEG2_PARSER_BROKEN_DATA,
Packit 1244b8
        MPEG2_PARSER_ERROR,
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    enum ProfileType {
Packit 1244b8
        MPEG2_PROFILE_HIGH = 1,
Packit 1244b8
        MPEG2_PROFILE_SPATIALLY_SCALABLE,
Packit 1244b8
        MPEG2_PROFILE_SNR_SCALABLE,
Packit 1244b8
        MPEG2_PROFILE_MAIN,
Packit 1244b8
        MPEG2_PROFILE_SIMPLE,
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    enum LevelType {
Packit 1244b8
        MPEG2_LEVEL_HIGH = 4,
Packit 1244b8
        MPEG2_LEVEL_HIGH_1440 = 6,
Packit 1244b8
        MPEG2_LEVEL_MAIN = 8,
Packit 1244b8
        MPEG2_LEVEL_LOW = 10,
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    struct StreamHeader {
Packit 1244b8
        StreamHeader();
Packit 1244b8
Packit 1244b8
        const uint8_t* data;
Packit 1244b8
        off_t streamSize;
Packit 1244b8
        const uint8_t* nalData;
Packit 1244b8
        int32_t nalSize;
Packit 1244b8
        uint64_t time_stamp;
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    struct QuantMatrices {
Packit 1244b8
        QuantMatrices();
Packit 1244b8
Packit 1244b8
        bool load_intra_quantiser_matrix;
Packit 1244b8
        uint8_t intra_quantiser_matrix[64];
Packit 1244b8
        bool load_non_intra_quantiser_matrix;
Packit 1244b8
        uint8_t non_intra_quantiser_matrix[64];
Packit 1244b8
        bool load_chroma_intra_quantiser_matrix;
Packit 1244b8
        uint8_t chroma_intra_quantiser_matrix[64];
Packit 1244b8
        bool load_chroma_non_intra_quantiser_matrix;
Packit 1244b8
        uint8_t chroma_non_intra_quantiser_matrix[64];
Packit 1244b8
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    // ISO/IEC spec section 6.2.2.1
Packit 1244b8
    struct SeqHeader {
Packit 1244b8
        SeqHeader();
Packit 1244b8
Packit 1244b8
        uint32_t horizontal_size_value;
Packit 1244b8
        uint32_t vertical_size_value;
Packit 1244b8
        uint32_t aspect_ratio_info;
Packit 1244b8
        uint32_t frame_rate_code;
Packit 1244b8
        uint32_t bit_rate_value;
Packit 1244b8
        bool marker_bit;
Packit 1244b8
        uint32_t vbv_buffer_size_value;
Packit 1244b8
        bool constrained_params_flag;
Packit 1244b8
        QuantMatrices quantizationMatrices;
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    // ISO/IEC spec section 6.2.2.3
Packit 1244b8
    struct SeqExtension {
Packit 1244b8
        SeqExtension();
Packit 1244b8
Packit 1244b8
        uint32_t extension_start_code_identifier;
Packit 1244b8
        uint32_t profile_and_level_indication;
Packit 1244b8
        bool progressive_sequence;
Packit 1244b8
        uint32_t chroma_format;
Packit 1244b8
        uint32_t horizontal_size_extension;
Packit 1244b8
        uint32_t vertical_size_extension;
Packit 1244b8
        uint32_t bit_rate_extension;
Packit 1244b8
        bool marker_bit;
Packit 1244b8
        uint32_t vbv_buffer_size_extension;
Packit 1244b8
        bool low_delay;
Packit 1244b8
        uint32_t frame_rate_extension_n;
Packit 1244b8
        uint32_t frame_rate_extension_d;
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    // ISO/IEC spec section 6.2.2.6 and 6.3.9
Packit 1244b8
    struct GOPHeader {
Packit 1244b8
        GOPHeader();
Packit 1244b8
Packit 1244b8
        bool drop_frame_flag;
Packit 1244b8
        uint32_t time_code_hours;
Packit 1244b8
        uint32_t time_code_minutes;
Packit 1244b8
        bool marker_bit;
Packit 1244b8
        uint32_t time_code_seconds;
Packit 1244b8
        uint32_t time_code_pictures;
Packit 1244b8
        bool closed_gop;
Packit 1244b8
        bool broken_link;
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    // ISO/IEC spec section 6.2.3
Packit 1244b8
    struct PictureHeader {
Packit 1244b8
        PictureHeader();
Packit 1244b8
Packit 1244b8
        uint32_t temporal_reference;
Packit 1244b8
        uint32_t picture_coding_type;
Packit 1244b8
        uint32_t vbv_delay;
Packit 1244b8
        bool full_pel_forward_vector;
Packit 1244b8
        uint32_t forward_f_code;
Packit 1244b8
        bool full_pel_backward_vector;
Packit 1244b8
        uint32_t backward_f_code;
Packit 1244b8
        bool extra_bit_picture;
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    // ISO/IEC spec section 6.2.3.1
Packit 1244b8
    struct PictureCodingExtension {
Packit 1244b8
        PictureCodingExtension();
Packit 1244b8
Packit 1244b8
        uint32_t extension_start_code_identifier;
Packit 1244b8
        uint32_t f_code[2][2]; // forward_horizontal
Packit 1244b8
        // forward_vertical
Packit 1244b8
        // backward_horizontal
Packit 1244b8
        // backward_vertical
Packit 1244b8
        uint32_t intra_dc_precision;
Packit 1244b8
        uint32_t picture_structure;
Packit 1244b8
        bool top_field_first;
Packit 1244b8
        bool frame_pred_frame_dct;
Packit 1244b8
        bool concealment_motion_vectors;
Packit 1244b8
        bool q_scale_type;
Packit 1244b8
        bool intra_vlc_format;
Packit 1244b8
        bool alternate_scan;
Packit 1244b8
        bool repeat_first_field;
Packit 1244b8
        bool chrome_420_type;
Packit 1244b8
        bool progressive_frame;
Packit 1244b8
        bool composite_display_flag;
Packit 1244b8
        bool v_axis;
Packit 1244b8
        uint32_t field_sequence;
Packit 1244b8
        bool sub_carrier;
Packit 1244b8
        uint32_t burst_amplitude;
Packit 1244b8
        uint32_t sub_carrier_phase;
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    // ISO/IEC spec section 6.2.3.2
Packit 1244b8
    struct QuantMatrixExtension {
Packit 1244b8
        QuantMatrixExtension();
Packit 1244b8
Packit 1244b8
        uint32_t extension_start_code_identifier;
Packit 1244b8
        QuantMatrices quantizationMatrices;
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    struct Slice {
Packit 1244b8
        Slice();
Packit 1244b8
Packit 1244b8
        // helper variables
Packit 1244b8
        const uint8_t* sliceData;
Packit 1244b8
        uint64_t sliceDataSize;
Packit 1244b8
        uint64_t sliceHeaderSize; // in bits
Packit 1244b8
        uint32_t verticalPosition;
Packit 1244b8
        uint32_t macroblockRow;
Packit 1244b8
        uint32_t macroblockColumn;
Packit 1244b8
        // spec variables
Packit 1244b8
        uint32_t slice_vertical_position_extension;
Packit 1244b8
        uint32_t priority_breakpoint;
Packit 1244b8
        uint32_t quantiser_scale_code;
Packit 1244b8
        bool intra_slice_flag;
Packit 1244b8
        bool intra_slice;
Packit 1244b8
        uint32_t reserved_bits;
Packit 1244b8
        bool extra_bit_slice;
Packit 1244b8
        uint32_t extra_information_slice;
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
    // A parser for raw Mpeg2 streams as specified in ISO/IEC 13818-2.
Packit 1244b8
    class Parser {
Packit 1244b8
    public:
Packit 1244b8
        Parser();
Packit 1244b8
        ~Parser();
Packit 1244b8
Packit 1244b8
        // Try to parse exactly the information of interest in a Mpeg2 raw
Packit 1244b8
        // stream
Packit 1244b8
        // Client can seek for the next start code and then parse it as required
Packit 1244b8
Packit 1244b8
        // parseSequenceHeader will parse a SequenceHeader according to the spec
Packit 1244b8
        // storing the information in the m_sequenceHdr structure and updating
Packit 1244b8
        // the position to the last bit parsed. information will be returned
Packit 1244b8
        bool parseSequenceHeader(const StreamHeader* shdr);
Packit 1244b8
Packit 1244b8
        // parseSequenceExtension will parse a SequenceExtension according to
Packit 1244b8
        // the
Packit 1244b8
        // spec
Packit 1244b8
        // storing the information in the sequence_extension structure and
Packit 1244b8
        // updating
Packit 1244b8
        // the position to the last bit parsed.
Packit 1244b8
        bool parseSequenceExtension(const StreamHeader* shdr);
Packit 1244b8
Packit 1244b8
        // parseGOPHeader will parse a GOPHeader according to the spec storing
Packit 1244b8
        // the information in the gop_header_ structure and updating the
Packit 1244b8
        // position
Packit 1244b8
        // to the last bit parsed.
Packit 1244b8
        bool parseGOPHeader(const StreamHeader* shdr);
Packit 1244b8
Packit 1244b8
        // parsePictureHeader will parse a PictureHeader according to the spec
Packit 1244b8
        // storing
Packit 1244b8
        // the information in the m_pictureHeader_ structure and updating the
Packit 1244b8
        // position
Packit 1244b8
        // to the last bit parsed.
Packit 1244b8
        bool parsePictureHeader(const StreamHeader* shdr);
Packit 1244b8
Packit 1244b8
        // parsePictureCodingExtension will parse a PictureHeader according to
Packit 1244b8
        // the
Packit 1244b8
        // spec storing the information in the picture_coding_extension_
Packit 1244b8
        // structure
Packit 1244b8
        // and updating the position to the last bit parsed.
Packit 1244b8
        bool parsePictureCodingExtension(const StreamHeader* shdr);
Packit 1244b8
Packit 1244b8
        // parseQuantMatrixExtension will parse a Quant Matrix Extension ID
Packit 1244b8
	// within a Extension Start Code and keep it on the quantization
Packit 1244b8
	// Extension structure for later use
Packit 1244b8
        bool parseQuantMatrixExtension(const StreamHeader* shdr);
Packit 1244b8
Packit 1244b8
        // parseSlice will parse a Slice according to the spec storing the
Packit 1244b8
        // information
Packit 1244b8
        // in the Slice structure and updating the position to the last
Packit 1244b8
        // bit parsed.
Packit 1244b8
        bool parseSlice(const StreamHeader* shdr);
Packit 1244b8
Packit 1244b8
        // nextStartCodeNew will update with next start code and return true if one
Packit 1244b8
        // is found,
Packit 1244b8
        bool nextStartCode(const StreamHeader* shdr, StartCodeType& start_code);
Packit 1244b8
Packit 1244b8
Packit 1244b8
        const SeqHeader* getSequenceHeader() { return &m_sequenceHdr; }
Packit 1244b8
        const SeqExtension* getSequenceExtension()
Packit 1244b8
        {
Packit 1244b8
            return &m_sequenceExtension;
Packit 1244b8
        }
Packit 1244b8
        const GOPHeader* getGOPHeader() { return &m_GOPHeader; }
Packit 1244b8
        const PictureHeader* getPictureHeader() { return &m_pictureHeader; }
Packit 1244b8
        const PictureCodingExtension* getPictureCodingExtension()
Packit 1244b8
        {
Packit 1244b8
            return &m_pictureCodingExtension;
Packit 1244b8
        }
Packit 1244b8
        const QuantMatrixExtension* getQuantMatrixExtension()
Packit 1244b8
        {
Packit 1244b8
            return &m_quantMatrixExtension;
Packit 1244b8
        }
Packit 1244b8
        const Slice* getMPEG2Slice() { return &m_slice; }
Packit 1244b8
Packit 1244b8
    private:
Packit 1244b8
        friend class MPEG2ParserTest;
Packit 1244b8
Packit 1244b8
        bool readQuantMatrixOrDefault(bool& loadMatrix, uint8_t matrix[],
Packit 1244b8
                                      const uint8_t defaultMatrix[]);
Packit 1244b8
Packit 1244b8
        bool readQuantMatrix(bool& loadMatrix, uint8_t matrix[]);
Packit 1244b8
        bool calculateMBColumn();
Packit 1244b8
Packit 1244b8
        // bitReader functions
Packit 1244b8
Packit 1244b8
        inline void bitReaderInit(const BitReader* bitReader)
Packit 1244b8
        {
Packit 1244b8
            m_bitReader = const_cast<BitReader*>(bitReader);
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        inline void bitReaderDeInit() { m_bitReader = NULL; }
Packit 1244b8
Packit 1244b8
        inline bool bitReaderSkipBits(uint32_t num_bits) const
Packit 1244b8
        {
Packit 1244b8
            return m_bitReader->skip(num_bits);
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        inline bool bitReaderReadBits(uint32_t num_bits, uint32_t* out) const
Packit 1244b8
        {
Packit 1244b8
            return m_bitReader->readT(*out, num_bits);
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        inline bool bitReaderPeekBits(uint32_t num_bits, uint32_t* out) const
Packit 1244b8
        {
Packit 1244b8
            return m_bitReader->peek(*out, num_bits);
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        inline bool bitReaderPeekBool(bool* out) const
Packit 1244b8
        {
Packit 1244b8
            return m_bitReader->peek(*out, 1);
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        inline bool bitReaderReadMarker(bool value) const
Packit 1244b8
        {
Packit 1244b8
            bool readMarker, ret;
Packit 1244b8
            // read 1 bit marker
Packit 1244b8
            ret = m_bitReader->readT(readMarker);
Packit 1244b8
            return ret && readMarker == value;
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        inline bool bitReaderReadFlag(bool* flag) const
Packit 1244b8
        {
Packit 1244b8
            return m_bitReader->readT(*flag);
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        inline uint64_t bitReaderCurrentPosition() const
Packit 1244b8
        {
Packit 1244b8
            return m_bitReader->getPos();
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        inline bool bitReaderIsByteAligned() const
Packit 1244b8
        {
Packit 1244b8
            return !(m_bitReader->getPos() % 8);
Packit 1244b8
        }
Packit 1244b8
Packit 1244b8
        BitReader* m_bitReader;
Packit 1244b8
Packit 1244b8
        SeqHeader m_sequenceHdr;
Packit 1244b8
        SeqExtension m_sequenceExtension;
Packit 1244b8
        GOPHeader m_GOPHeader;
Packit 1244b8
        PictureHeader m_pictureHeader;
Packit 1244b8
        PictureCodingExtension m_pictureCodingExtension;
Packit 1244b8
        QuantMatrixExtension m_quantMatrixExtension;
Packit 1244b8
        Slice m_slice;
Packit 1244b8
Packit 1244b8
        DISALLOW_COPY_AND_ASSIGN(Parser);
Packit 1244b8
    };
Packit 1244b8
Packit 1244b8
} // namespace MPEG2
Packit 1244b8
} // namespace YamiParser
Packit 1244b8
Packit 1244b8
#endif // mpeg2_parser_h