//------------------------------------------------------------------------------
//
// 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