//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // // The use and distribution terms for this software are covered by the // Microsoft Limited Public License (Ms-LPL) // which can be found in the file MS-LPL.txt at the root of this distribution. // By using this software in any fashion, you are agreeing to be bound by // the terms of this license. // // The software is licensed “as-is.” // // You must not remove this notice, or any other, from this software. // // // // Demux code for Windows CE // //------------------------------------------------------------------------- //====================================================================== // Demux code for Windows CE //====================================================================== /*++ Module Name: mp2const.h Abstract: This module contains MPEG2-specific constants, macros, etc... The MPEG parsing macros are in parsemac.h. It is included in precomp.h so there's no reason to include it explicitely. Revision History: 23-Jul-1999 created 17-Apr-2000 added PCR & PTS max delta Notes: XXXX really ought to have some macros that check a header or integrity by looking at bit patterns that must exist, such the '10' which follow the 1st three fields in a PES header; might then have a registry switch which has the demux operate in "paranoid" mode. --*/ #ifndef __mp2demux_mp2const_h #define __mp2demux_mp2const_h // transport stream - related // macro // MPEG-2 systems specification: // section_length is the bytes remaining AFTER the section_length field; // since all PSI has section_length at the same offset, we can add 3 bytes // to section_length and obtain the real PSI section length #define COMPLETE_SECTION_LENGTH(sl) ((sl) + 3) // ---------------------------------------------------------------------------- // general constants // transport #define DISTINCT_PID_COUNT (1 << 13) #define MAX_PID_VALUE (DISTINCT_PID_COUNT - 1) #define TS_PACKET_SIZE 188 #define TS_PACKET_SYNC_BYTE 0x47 #define TS_SIMPLE_PACKET_HEADER_SIZE 4 #define TS_NULL_PID 0x1fff #define PCR_BIT_COUNT 48 #define PCR_PID_NOT_DEFINED_FOR_PROGRAM 0x1fff // program #define DISTINCT_STREAM_ID_COUNT (1 << 8) #define MAX_STREAM_ID_VALUE (DISTINCT_STREAM_ID_COUNT - 1) #define ATSC_BITRATE 19200000 // MPEG-2 PSI constants #define PAT_MAX_SECTION_LENGTH_FIELD_VALUE 0x3fd #define PMT_MAX_SECTION_LENGTH_FIELD_VALUE 0x3fd #define CAT_MAX_SECTION_LENGTH_FIELD_VALUE 0x3fd #define PRIVATE_MAX_SECTION_LENGTH_FIELD_VALUE 0x3fd #define PURE_PRIVATE_MAX_SECTION_LENGTH_FIELD_VALUE 0xffd #define PSI_PAT_PID 0 #define PSI_MAX_SECTION_LENGTH_NUMBER PURE_PRIVATE_MAX_SECTION_LENGTH_FIELD_VALUE #define PSI_MAX_SECTION_LENGTH COMPLETE_SECTION_LENGTH (PSI_MAX_SECTION_LENGTH_NUMBER) #define PSI_NON_VERSIONED_HEADER_SIZE 3 #define PSI_VERSIONED_HEADER_SIZE 8 // max size rounded to the next highest transport packet boundary #define PSI_MAX_SECTION_LENGTH_ROUNDED (TS_PACKET_SIZE * DIV_ROUND_UP_MAYBE (PSI_MAX_SECTION_LENGTH, TS_PACKET_SIZE)) // see table 2-26, MPEG-2 systems spec #define PAT_TABLE_ID 0x00 #define CAT_TABLE_ID 0x01 #define PMT_TABLE_ID 0x02 #define FORBIDDEN_TABLE_ID 0xff // internal parser types #define MPEG2_MEDIA_ELEMENTARY_STREAM 0 #define MPEG2_MEDIA_PES_STREAM 1 #define MPEG2_MEDIA_TRANSPORT_PSI_PAT 2 #define MPEG2_MEDIA_TRANSPORT_PSI_CAT 3 #define MPEG2_MEDIA_TRANSPORT_PSI_PMT 4 #define MPEG2_MEDIA_TRANSPORT_PSI_PRIVATE_PURE 5 #define MPEG2_MEDIA_TRANSPORT_PSI_PRIVATE_NOT_PURE 6 #define MPEG2_MEDIA_TRANSPORT_PCR 7 #define MPEG2_MEDIA_TRANSPORT_PACKET 8 #define MPEG2_MEDIA_TRANSPORT_PSI 9 #define MPEG2_MEDIA_TRANSPORT_PAYLOAD 10 #define MPEG2_MEDIA_PROGRAM_STREAM_MAP 11 #define MPEG2_MEDIA_PROGRAM_SCR 12 #define MPEG2_MEDIA_PROGRAM_DIRECTORY_PES_PACKET 13 #define MPEG2_MEDIA_PROGRAM_PACK_HEADER 14 #define MPEG2_MEDIA_PROGRAM_SYSTEM_HEADER 15 #define MPEG2_MEDIA_PROGRAM_ANALOGCOPYPROTECTION 16 #define MPEG2_DEFAULT_VIDEO_STREAM 0x10000000 #define MPEG2_DEFAULT_AUDIO_STREAM 0x20000000 // max program stream PES packet length #define MAX_PS_PES_PACKET_LENGTH 0x10000 // start codes, etc... #define START_CODE_PREFIX 0x000001 #define MPEG2_PACK_START_CODE 0xBA #define MPEG2_SYSTEM_HEADER_START_CODE 0xBB #define PS_PMT_START_CODE 0XBC #define PS_DIRECTORY_START_CODE 0XFF #define PROGRAM_END_CODE 0xB9 #define MPEG2_SEQUENCE_HEADER_START_CODE 0xB3 #define MPEG2_EXTENSION_START_CODE 0xB5 #define MPEG2_SEQUENCE_HEADER_LENGTH 10 // start_code_prefix + prefix // 00 00 01 #define START_CODE_PREFIX_LENGTH 3 // xx #define PREFIX_LENGTH 1 // 00 00 01 xx #define START_CODE_LENGTH (START_CODE_PREFIX_LENGTH + PREFIX_LENGTH) // fields: [pack_start_code, pack_stuffing_length] #define PACK_HEADER_CORE_LEN 14 // fields: [pack_start_code, marker_bit (4th)] #define PACK_HEADER_SCR_LEN 10 // pack payload i.e. PES packet, PS_PMT packet, etc... have this core header // length #define PACK_PAYLOAD_HEADER_LEN 6 // ---------------------------------------------------------------------------- // PES packet - related #define PES_START_CODE_PREFIX START_CODE_PREFIX // all PES headers start with these values #define PES_COMMON_HEADER_FIELD_LEN (3 + 1 + 2) // tier1 req headers are packet_start_code_prefix -> PES_header_data_length // see MPEG2 systems spec, p. 30 for field widths #define PES_TIER1_REQ_HEADER_FIELD_LEN (PES_COMMON_HEADER_FIELD_LEN + 1 + 1 + 1) // largest size 188 evenly divisible size <= 64K #define PES_DEFAULT_BUFFER_SIZE_REQUEST 65424 // offset into PES header of last byte of PES_packet_length field #define PES_PACKET_LENGTH_LAST_BYTE_OFFSET 6 // tier_1 + all optional fields #define MAX_PES_HEADER_LEN (PES_TIER1_REQ_HEADER_FIELD_LEN + 210) // PES stream id (table 2-18, MPEG2 Systems Specification, H.222.0) #define STREAM_ID_MIN 0xBA #define STREAM_ID_MAX 0xFF #define STREAM_ID_PROGRAM_STREAM_MAP 0xBC #define STREAM_ID_PRIVATE_STREAM_1 0xBD #define STREAM_ID_PADDING_STREAM 0xBE #define STREAM_ID_PRIVATE_STREAM_2 0xBF #define STREAM_ID_AUDIO_STREAM_MIN 0xC0 #define STREAM_ID_AUDIO_STREAM_MAX 0xDF #define STREAM_ID_VIDEO_STREAM_MIN 0xE0 #define STREAM_ID_VIDEO_STREAM_MAX 0xEF #define STREAM_ID_ECM 0xF0 #define STREAM_ID_EMM 0xF1 #define STREAM_ID_DSMCC_STREAM 0xF2 #define STREAM_ID_IEC_13522 0xF3 #define STREAM_ID_H_222_1_TYPE_A 0xF4 #define STREAM_ID_H_222_1_TYPE_B 0xF5 #define STREAM_ID_H_222_1_TYPE_C 0xF6 #define STREAM_ID_H_222_1_TYPE_D 0xF7 #define STREAM_ID_H_222_1_TYPE_E 0xF8 #define STREAM_ID_ANCILLARY 0xF9 #define STREAM_ID_RESERVED_DATA_MIN 0xFA #define STREAM_ID_RESERVED_DATA_MAX 0xFE #define STREAM_ID_PROGRAM_STREAM_DIRECTORY 0xFF // ---------------------------------------------------------------------------- // analog copy protection stream_id #define STREAM_ID_ANALOGCOPYPROTECTION STREAM_ID_PRIVATE_STREAM_2 #define SUBSTREAM_ID_ANALOGCOPYPROTECTION (0) #define ANALOGCOPYPROTECTION_WORD_OFFSET (PES_COMMON_HEADER_FIELD_LEN + 1 + 4) #define MIN_VALID_ANALOGCOPYPROTECTION_PES_PACKET_LENGTH (ANALOGCOPYPROTECTION_WORD_OFFSET + 2) // --------------------------------------------------------------------------- // timing constants // PCRs are in adaptation fields ==> transport streams // H.222.0, D.0.2 "Audio and Video Presentation Synchronization", pp. 95 #define MAX_INTRA_PTS_INTERVAL_MILLIS 700 // H.222.0, D.0.3 "System Time Clock recovery in the decoder", pp. 96 #define MAX_INTRA_PCR_INTERVAL_MILLIS 100 #define MAX_PCR_RATE (MILLISECONDS_PER_SECOND / MAX_INTRA_PCR_INTERVAL_MILLIS) // SCRs are in pack headers ==> program streams // H.222.0, D.0.2 "Audio and Video Presentation Synchronization", pp. 95 #define MAX_INTRA_SCR_INTERVAL_MILLIS 700 // SCRs are held in a 48 bit counter #ifndef UNDER_CE #define MAX_SCR_VALUE ((1 << 48) - 1) #else // !UNDER_CE // not sure how this ever worked on the desktop codebase but on // CE this value ends up being 0xffffffffffffffff instead of 0x0000ffffffffffff // make sure everything knows that this is a 64 bit number #define MAX_SCR_VALUE (LONGLONG)((((LONGLONG)1 << 48) - (LONGLONG)1)) #endif // !UNDER_CE // // H.222.0, 2.4.2.1 places the following restraint on rate of change of the // system clock : // // rate of change of system_clock_frequency <= 75 x 10^-3 Hz/s // // since we use QPCs to expose a clock (that in turn is subordinated to PCRs), the // above constraint must be enforced against the QPC frequency on the local // host, over time // // our subordinating schema is to compute a scaling value (slope) over time, which // we multiply against a QPC value to skew the value appropriately (greater, // or less, depending on the PCR-QPC relationship) // // thus, given QPC(f) as being the QPC frequency (Hz/s) on the local host, // and N(i) being a current "skewing" value that changes over time as we // subordinate to the PCRs, our maximum allowable rate of change is computed as // follows [QPC(f) changes from host to host, but is constant on a single // host]: // // [i : seconds] // // abs (N(i) * QPC(f) - N(i+1) * QPC(f)) <= 0.075 // or // abs (N(i) - N(i+1)) * QPC(f) <= 0.075 // or // abs (N(i) - N(i+1)) <= 0.075 / QPC(f) // // we can then use the above formula, coupled with the maximum rate of // arrival of PCRs, to compute a maximum "clock step" with which to // correct our scaling value: // // [k : PCRs] // // PCR_rate = MILLISECONDS_PER_SECOND / MAX_INTRA_PCR_INTERVAL_MILLIS // // abs (N(k) - N(k+1)) <= (0.075 / QPC(f)) / PCR_rate // or // abs (N(k) - N(k+1)) <= 0.075 / (QPC(f) * PCR_rate) // // macro yields a double value that is the maximum rate change, from // pcr to pcr; mult is a registry supplied value that defaults to 1, // but can be increased to increase the rate of closure between what we // are observing and what we are using to subordinate with #define MAX_SLOPE_STEP_VALUE(qpc_freq,mult) ( (double) (((0.075) * (double) (mult)) / (double (qpc_freq) * double (MAX_PCR_RATE))) ) // this is a multiplier that is used in the allowable error bracket, which // is a multiplier, within which we allow the clock to "jitter" i.e. drift // up and down without triggering a correction #define ACCEPTABLE_CLOCK_JITTER_MULTIPLIER 10.0 // macro yields the max correction threshold frame size; #define MAX_ALLOWABLE_ERROR_BRACKET(max_clock_step) ((max_clock_step) * ACCEPTABLE_CLOCK_JITTER_MULTIPLIER) // macro yields the correction frame size degradation; current frame // size degrades when no corrections are made; #define ERROR_BRACKET_GRANULARITY 1000.0 #define ERROR_BRACKET_DEGRADATION(max_clock_step) (MAX_ALLOWABLE_ERROR_BRACKET(max_clock_step) / ERROR_BRACKET_GRANULARITY) #endif // __mp2demux_mp2const_h