//------------------------------------------------------------------------------
//
// 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:
parsemac.h
Abstract:
This module contains macros that are used to parse the various
headers
Revision History:
13-Jul-1999 created
--*/
#ifndef __mp2demux_parsemac_h
#define __mp2demux_parsemac_h
// Remove our dependency on ws2_32.dll by implementing our own
// little-endian <--> big-endian byte swapping. The MPEG-2
// systems spec is all big-endian, so we need these macros
// when we don't run on big-endian architectures e.g. x86.
#ifndef BIG_ENDIAN
// we're little-endian and need to swap bytes around
#define NTOH_LL(ll) \
( (((ll) & 0xFF00000000000000) >> 56) | \
(((ll) & 0x00FF000000000000) >> 40) | \
(((ll) & 0x0000FF0000000000) >> 24) | \
(((ll) & 0x000000FF00000000) >> 8) | \
(((ll) & 0x00000000FF000000) << 8) | \
(((ll) & 0x0000000000FF0000) << 24) | \
(((ll) & 0x000000000000FF00) << 40) | \
(((ll) & 0x00000000000000FF) << 56) )
#define NTOH_L(l) \
( (((l) & 0xFF000000) >> 24) | \
(((l) & 0x00FF0000) >> 8) | \
(((l) & 0x0000FF00) << 8) | \
(((l) & 0x000000FF) << 24) )
#define NTOH_S(s) \
( (((s) & 0xFF00) >> 8) | \
(((s) & 0x00FF) << 8) )
#else // BIG_ENDIAN
// we're already big-endian, so we do nothing
#define NTOH_LL(ll) (ll)
#define NTOH_L(l) (l)
#define NTOH_S(s) (s)
#endif // BIG_ENDIAN
// swapping from host back to network order is the same
#define HTON_LL(ll) NTOH_LL(ll)
#define HTON_L(l) NTOH_L(l)
#define HTON_S(s) NTOH_S(s)
// define or undef this to parse with methods vs. macros
#ifdef PARSE_WITH_MACROS
#pragma message("parsing with MACROS")
// i 0-based
#define BIT_VALUE(v,b) ((v & (0x00 | (1 << b))) >> b)
#define BYTE_OFFSET(pb,i) (& BYTE_VALUE((pb),i))
#define BYTE_VALUE(pb,i) (((BYTE *) (pb))[i])
#define WORD_VALUE(pb,i) (* (UNALIGNED WORD *) BYTE_OFFSET((pb),i))
#define DWORD_VALUE(pb,i) (* (UNALIGNED DWORD *) BYTE_OFFSET((pb),i))
#define ULONGLONG_VALUE(pb,i) (* (UNALIGNED ULONGLONG *) BYTE_OFFSET((pb),i))
// ---------------------------------------------------------------------------
// ===========================================================================
// beginning of transport - related parsing
// ===========================================================================
// ---------------------------------------------------------------------------
// all macros have either "_BIT" or "_VALUE" appended. These indicate whether
// the value of interest is a bit or a value. A bit value is always shifted
// so 1 means it's on, and 0 means it's off. A value consists of a > 1 bits
// of data.
// all macros assume pb points to the beginning of the transport packet
// i.e. points to the sync byte --> * pb = 0x47
// in order of appearance in header
#define SYNC_BYTE_VALUE(pb) (BYTE_VALUE((pb),0))
#define TRANSPORT_ERROR_INDICATOR_BIT(pb) ((NTOH_S(WORD_VALUE(pb,1)) & 0x00008000) >> 15)
#define PAYLOAD_UNIT_START_INDICATOR_BIT(pb) ((NTOH_S(WORD_VALUE(pb,1)) & 0x00004000) >> 14)
#define TRANSPORT_PRIORITY_BIT(pb) ((NTOH_S(WORD_VALUE(pb,1)) & 0x00002000) >> 13)
#define PID_VALUE(pb) (NTOH_S(WORD_VALUE(pb,1)) & 0x00001fff)
#define TRANSPORT_SCRAMBLING_CONTROL_VALUE(pb) ((BYTE_VALUE((pb),3) & 0x000000c0) >> 6)
#define ADAPTATION_FIELD_CONTROL_VALUE(pb) ((BYTE_VALUE((pb),3) & 0x00000030) >> 4)
#define CONTINUITY_COUNTER_VALUE(pb) (BYTE_VALUE((pb),3) & 0x0000000f)
// --------------------------------------------------------------------------------------
// adaptation field parsing macros
// pb points to adaptation field
#define ADAPTATION_FIELD_LENGTH_VALUE(pb) (BYTE_VALUE((pb),0))
#define DISCONTINUITY_INDICATOR_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000080) >> 7)
#define RANDOM_ACCESS_INDICATOR_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000040) >> 6)
#define ELEMENTARY_STREAM_PRIORITY_INDICATOR_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000020) >> 5)
#define PCR_FLAG_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000010) >> 4)
#define OPCR_FLAG_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000008) >> 3)
#define SPLICING_POINT_FLAG_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000004) >> 2)
#define TRANSPORT_PRIVATE_DATA_FLAG_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000002) >> 1)
#define ADAPTATION_FIELD_EXTENSION_FLAG_BIT(pb) (BYTE_VALUE((pb),1) & 0x00000001)
// pb points to PCR_BASE block
#define PCR_BASE_VALUE(pb) (NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 31)
#define PCR_EXT_VALUE(pb) ((DWORD) (NTOH_LL(ULONGLONG_VALUE(pb,0)) & 0x00000000000001ff))
// pb points to OPCR_BASE block
#define OPCR_BASE_VALUE(pb) PCR_BASE_VALUE(pb)
#define OPCR_EXT_VALUE(pb) PCR_EXT_VALUE(pb)
// pb points to splice_countdown block
#define SPLICE_COUNTDOWN_VALUE(pb) BYTE_VALUE(pb,0)
// pb points to transport_private_data_length
#define TRANSPORT_PRIVATE_DATA_LENGTH_VALUE(pb) BYTE_VALUE(pb,0)
// pb points to adaptation_field_extension_length
#define ADAPTATION_FIELD_EXTENSION_LENGTH_VALUE(pb) BYTE_VALUE(pb,0)
// XXXX: we ignore the field extensions for now
// ---------------------------------------------------------------------------
// PSI generic information (except for pure private sections)
// pb points to first byte of section (TS packet payload +
// pointer_field offset)
#define PSI_TABLE_ID_VALUE(pb) (BYTE_VALUE((pb),0))
#define PSI_SECTION_SYNTAX_INDICATOR_BIT(pb) ((BYTE_VALUE((pb),1) & 0x80) >> 7)
#define PSI_SECTION_LENGTH_VALUE(pb) (NTOH_S(WORD_VALUE(pb,1)) & 0x0fff)
#define PSI_VERSION_NUMBER_VALUE(pb) ((BYTE_VALUE((pb),5) >> 1) & 0x1f)
#define PSI_CURRENT_NEXT_INDICATOR_BIT(pb) (BYTE_VALUE((pb),5) & 0x01)
#define PSI_SECTION_NUMBER_VALUE(pb) (BYTE_VALUE((pb),6))
#define PSI_LAST_SECTION_NUMBER_VALUE(pb) (BYTE_VALUE((pb),7))
// ---------------------------------------------------------------------------
// Program Association Table (PAT) macros
// pb points to the first byte of section
#define PAT_TABLE_ID_VALUE(pb) PSI_TABLE_ID_VALUE(pb)
#define PAT_SECTION_SYNTAX_INDICATOR_BIT(pb) PSI_SECTION_SYNTAX_INDICATOR(pb)
#define PAT_SECTION_LENGTH_VALUE(pb) PSI_SECTION_LENGTH_VALUE(pb)
#define PAT_TRANSPORT_STREAM_ID_VALUE(pb) (NTOH_S(WORD_VALUE(pb,3)))
#define PAT_VERSION_NUMBER_VALUE(pb) PSI_VERSION_NUMBER_VALUE(pb)
#define PAT_CURRENT_NEXT_INDICATOR_BIT(pb) PSI_CURRENT_NEXT_INDICATOR_BIT(pb)
#define PAT_SECTION_NUMBER_VALUE(pb) PSI_SECTION_NUMBER_VALUE(pb)
#define PAT_LAST_SECTION_NUMBER_VALUE(pb) PSI_LAST_SECTION_NUMBER_VALUE(pb)
// PAT program descriptor parsing macros
// pointer to the nth program descriptor in the section; n is 0-based; does
// NO range checking on the validity of n; offsets past the header (8 bytes)
// then into the program descriptors
#define PAT_PROGRAM_DESCRIPTOR(pbPAT,n) ((((BYTE *) (pbPAT)) + 8) + ((n) * 4))
// nth program descriptor field extractions
#define PAT_PROGRAM_DESCRIPTOR_PROGRAM_NUMBER_VALUE(pbPAT,n) (NTOH_S (WORD_VALUE(PAT_PROGRAM_DESCRIPTOR(pbPAT,n),0)))
#define PAT_PROGRAM_DESCRIPTOR_PID_VALUE(pbPAT,n) (NTOH_S (WORD_VALUE(PAT_PROGRAM_DESCRIPTOR(pbPAT,n),2)) & 0x1fff)
#define PAT_PROGRAM_DESCRIPTOR_IS_PROGRAM(pbPAT,n) (PAT_PROGRAM_DESCRIPTOR_PROGRAM_NUMBER_VALUE(pbPAT,n) != 0x0000)
#define PAT_PROGRAM_DESCRIPTOR_IS_NETWORK(pbPAT,n) (PAT_PROGRAM_DESCRIPTOR_IS_PROGRAM(pbPAT,n) == FALSE)
#define PAT_PROGRAM_DESCRIPTOR_PROGRAM_PID_VALUE(pbPAT,n) PAT_PROGRAM_DESCRIPTOR_PID_VALUE(pbPAT,n)
#define PAT_PROGRAM_DESCRIPTOR_NETWORK_PID_VALUE(pbPAT,n) PAT_PROGRAM_DESCRIPTOR_PID_VALUE(pbPAT,n)
// ---------------------------------------------------------------------------
// Program Map Table (PMT) macros
// pb points to the first byte of section
#define PMT_TABLE_ID_VALUE(pb) BYTE_VALUE(pb,0)
#define PMT_SECTION_SYNTAX_INDICATOR_BIT(pb) PSI_SECTION_SYNTAX_INDICATOR(pb)
#define PMT_SECTION_LENGTH_VALUE(pb) PSI_SECTION_LENGTH_VALUE(pb)
#define PMT_PROGRAM_NUMBER_VALUE(pb) NTOH_S(WORD_VALUE(pb,3))
#define PMT_VERSION_NUMBER_VALUE(pb) PSI_VERSION_NUMBER_VALUE(pb)
#define PMT_CURRENT_NEXT_INDICATOR_BIT(pb) PSI_CURRENT_NEXT_INDICATOR_BIT(pb)
#define PMT_SECTION_NUMBER(pb) PSI_SECTION_NUMBER_VALUE(pb)
#define PMT_LAST_SECTION_NUMBER(pb) PSI_LAST_SECTION_NUMBER_VALUE(pb)
#define PMT_PCR_PID_VALUE(pb) (NTOH_S(WORD_VALUE(pb,8)) & 0x1fff)
#define PMT_PROGRAM_INFO_LENGTH_VALUE(pb) (NTOH_S(WORD_VALUE(pb,10)) & 0x0fff)
// pb points to the stream record block (stream_type, etc...)
#define PMT_STREAM_RECORD_STREAM_TYPE_VALUE(pb) BYTE_VALUE(pb,0)
#define PMT_STREAM_RECORD_ELEMENTARY_PID(pb) (NTOH_S(WORD_VALUE(pb,1)) & 0x1fff)
#define PMT_STREAM_RECORD_ES_INFO_LENGTH(pb) (NTOH_S(WORD_VALUE(pb,3)) & 0x0fff)
// ---------------------------------------------------------------------------
// Private section
// pb points to the TS packet payload ! (first byte of section)
#define PRIVATE_SECTION_SYNTAX_INDICATOR_BIT(pb) PSI_SECTION_SYNTAX_INDICATOR(pb)
// ===========================================================================
// pb points to prefix i.e. pb = { 0x00, 0x00, 0x01, ....}
#define START_CODE_PREFIX_VALUE(pb) (NTOH_L(DWORD_VALUE(pb,0)) >> 8)
#define START_CODE_VALUE(pb) (BYTE_VALUE(pb,3))
#define PACKET_LENGTH_VALUE(pb) (NTOH_S(WORD_VALUE(pb,4)))
// ----------------------------------------------------------------------------
// pack header parsing
// pb points to pack_start_code
#define PACK_START_CODE_VALUE(pb) NTOH_L(DWORD_VALUE(pb,0))
#define PACK_HEADER_SCR_BASE(pb) (((NTOH_LL(ULONGLONG_VALUE(pb,1)) & 0x000000000003FFF8) >> 3) | \
((NTOH_LL(ULONGLONG_VALUE(pb,1)) & 0x00000003FFF80000) >> 4) | \
((NTOH_LL(ULONGLONG_VALUE(pb,1)) & 0x0000003800000000) >> 5))
#define PACK_HEADER_SCR_EXT(pb) ((NTOH_LL(ULONGLONG_VALUE(pb,2)) & 0x00000000000003FE) >> 1)
#define PACK_PROGRAM_MUX_RATE(pb) (((NTOH_L(DWORD_VALUE(pb,10)) >> 8) & 0xFFFFFC0) >> 2)
#define PACK_STUFFING_LENGTH(pb) (BYTE_VALUE(pb,13) & 0x03)
// ===========================================================================
// ---------------------------------------------------------------------------
// ===========================================================================
// PES - related parsing
// ===========================================================================
// ---------------------------------------------------------------------------
#define PES_PACKET_START_CODE_PREFIX_VALUE(pb) START_CODE_PREFIX_VALUE(pb)
#define PES_STREAM_ID_VALUE(pb) START_CODE_VALUE(pb)
#define PES_PACKET_LENGTH_VALUE(pb) PACKET_LENGTH_VALUE(pb)
// pb points to TIER_1 header
#define PES_SCRAMBLING_CONTROL_VALUE(pb) ((BYTE_VALUE(pb,0) & 0x30) >> 4)
#define PES_PRIORITY_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,0),3)
#define PES_DATA_ALIGNMENT_INDICATOR_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,0),2)
#define PES_COPYRIGHT_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,0),1)
#define PES_ORIGINAL_OR_COPY_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,0),0)
#define PES_PTS_DTS_FLAGS_VALUE(pb) ((BYTE_VALUE(pb,1) & 0xc0) >> 6)
#define PES_ESCR_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,1),5)
#define PES_ES_RATE_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,1),4)
#define PES_DSM_TRICK_MODE_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,1),3)
#define PES_ADDITIONAL_COPY_INFO_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,1),2)
#define PES_CRC_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,1),1)
#define PES_EXTENSION_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,1),0)
#define PES_PES_HEADER_DATA_LENGTH_VALUE(pb) BYTE_VALUE(pb,2)
// pb points to the PTS field
#define PES_PTS_VALUE(pb) ((((NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 24) & 0x000000000000FFFE) >> 1) | \
(((NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 24) & 0x00000000FFFE0000) >> 2) | \
(((NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 24) & 0x0000000E00000000) >> 3))
#define PES_DTS_VALUE(pb) PES_PTS_VALUE(pb)
// ============================================================================
// analog copy protection parsing
// pb points to PES header
// ============================================================================
#define PES_ACP_SUBSTREAM_ID(pb) BYTE_VALUE(pb,PES_COMMON_HEADER_FIELD_LEN)
#define PES_ACP_BITS(pb) ((NTOH_S (WORD_VALUE(pb,ANALOGCOPYPROTECTION_WORD_OFFSET))) >> 14)
#else // else we're parsing with functions
#pragma message("parsing with FUNCTIONS")
// ---------------------------------------------------------------------------
// all functions ..
// returns the bit value; i is 0-based
_inline BYTE BIT_VALUE (BYTE b, int i)
{
BYTE m = -1 ;
m = 0x00 | (1 << i) ;
b &= m ;
b >>= i ;
return b ;
// #define BIT_VALUE(v,b) ((v & (0x00 | (1 << i))) >> i)
}
_inline BYTE * BYTE_OFFSET (BYTE * pb, int i)
{
return & (((BYTE *) pb) [i]) ;
// (& BYTE_VALUE((pb),i))
}
_inline BYTE BYTE_VALUE (BYTE * pb, int i)
{
BYTE b = -1 ;
b = * (BYTE *) BYTE_OFFSET (pb, i) ;
return b ;
// (((BYTE *) (pb))[i])
}
_inline WORD WORD_VALUE (BYTE * pb, int i)
{
WORD w = -1 ;
w = * (WORD *) BYTE_OFFSET (pb, i) ;
return w ;
// #define WORD_VALUE(pb,i) (* (WORD *) BYTE_OFFSET((pb),i))
}
_inline DWORD DWORD_VALUE (BYTE * pb, int i)
{
DWORD dw = -1 ;
dw = * (DWORD *) BYTE_OFFSET (pb, i) ;
return dw ;
// #define DWORD_VALUE(pb,i) (* (DWORD *) BYTE_OFFSET((pb),i))
}
_inline ULONGLONG ULONGLONG_VALUE (BYTE * pb,int i)
{
ULONGLONG ull = -1 ;
ull = * (ULONGLONG *) BYTE_OFFSET (pb, i) ;
return ull ;
// #define ULONGLONG_VALUE(pb,i) (* (ULONGLONG *) BYTE_OFFSET((pb),i))
}
// ---------------------------------------------------------------------------
// ===========================================================================
// beginning of transport - related parsing
// ===========================================================================
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// transport header parsing
// pb points to sync_byte
// ---------------------------------------------------------------------------
// retrieves the continuity_counter value
_inline DWORD CONTINUITY_COUNTER_VALUE(BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE((pb),3) ;
dw &= 0x0000000f ;
return dw ;
// (BYTE_VALUE((pb),3) & 0x0000000f)
}
// payload_unit_start_indicator bit
_inline BOOL PAYLOAD_UNIT_START_INDICATOR_BIT(BYTE * pb)
{
WORD w = -1 ;
BOOL f ;
w = WORD_VALUE (pb, 1) ;
w = NTOH_S (w) ;
w &= 0x00004000 ;
w >>= 14 ;
f = w != 0 ;
return f ;
// #define PAYLOAD_UNIT_START_INDICATOR_BIT(pb) ((NTOH_S((* ((WORD *) BYTE_OFFSET((pb),1)))) & 0x00004000) >> 14)
}
// retrieves the PID value
_inline DWORD PID_VALUE(BYTE * pb)
{
WORD w = -1 ;
w = WORD_VALUE (pb, 1) ;
w = NTOH_S (w) ;
w &= 0x00001fff ;
return w ;
// (NTOH_S((* ((WORD *) BYTE_OFFSET((pb),1)))) & 0x00001fff)
}
// retrieves the pointer_field value
_inline DWORD POINTER_FIELD_VALUE(BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 4) ;
return dw ;
}
// transport_error_indicator bit
_inline BOOL TRANSPORT_ERROR_INDICATOR_BIT(BYTE * pb)
{
BOOL f ;
WORD w = -1 ;
w = WORD_VALUE (pb, 1) ;
w = NTOH_S (w) ;
w &= 0x00008000 ;
w >>= 15 ;
f = w != 0 ;
return f ;
// ((NTOH_S((* ((WORD *) BYTE_OFFSET((pb),1)))) & 0x00008000) >> 15)
}
// retrieves the transport_scrambling_control value
_inline DWORD TRANSPORT_SCRAMBLING_CONTROL_VALUE(BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 3) ;
dw &= 0x000000c0 ;
dw >>= 6 ;
return dw ;
//((BYTE_VALUE((pb),3) & 0x000000c0) >> 6)
}
// ---------------------------------------------------------------------------
// adaptation field parsing
// ---------------------------------------------------------------------------
// pb points to start of adaptation field
// retrieves the adaptation_field_length value
_inline DWORD ADAPTATION_FIELD_LENGTH_VALUE(BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 0) ;
return dw ;
// (BYTE_VALUE((pb),0))
}
// retrieves the discontinuity_indicator bit
_inline BOOL DISCONTINUITY_INDICATOR_BIT(BYTE * pb)
{
DWORD dw = -1 ;
BOOL f ;
dw = BYTE_VALUE((pb),1) ;
dw &= 0x00000080 ;
dw >>= 7 ;
f = dw != 0 ;
return f ;
// ((BYTE_VALUE((pb),1) & 0x00000080) >> 7)
}
// retrieves the random_access_indicator bit
_inline BOOL RANDOM_ACCESS_INDICATOR_BIT(BYTE * pb)
{
BOOL f ;
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 1) ;
dw &= 0x00000040 ;
dw >>= 6 ;
f = dw != 0 ;
return f ;
// ((BYTE_VALUE((pb),1) & 0x00000040) >> 6)
}
// retrieves the elementary_stream_priority_indicator bit
_inline BOOL ELEMENTARY_STREAM_PRIORITY_INDICATOR_BIT(BYTE * pb)
{
DWORD dw = -1 ;
BOOL f ;
dw = BYTE_VALUE((pb),1) ;
dw &= 0x00000020 ;
dw >>= 5 ;
f = dw != 0 ;
return f ;
// ((BYTE_VALUE((pb),1) & 0x00000020) >> 5)
}
// retrieves the PCR_flag bit
_inline BOOL PCR_FLAG_BIT(BYTE * pb)
{
DWORD dw = -1 ;
BOOL f ;
dw = BYTE_VALUE (pb, 1) ;
dw &= 0x00000010 ;
dw >>= 4 ;
f = dw != 0 ;
return f ;
// #define PCR_FLAG_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000010) >> 4)
}
// retrieves the OPCR_flag bit
_inline BOOL OPCR_FLAG_BIT(BYTE * pb)
{
DWORD dw = -1 ;
BOOL f ;
dw = BYTE_VALUE((pb),1) ;
dw &= 0x00000008 ;
dw >>= 3 ;
f = dw != 0 ;
return f ;
// #define OPCR_FLAG_BIT(pb) ((BYTE_VALUE((pb),1) & 0x00000008) >> 3)
}
// retrieves the splicing_point_flag bit
_inline BOOL SPLICING_POINT_FLAG_BIT(BYTE * pb)
{
DWORD dw = -1 ;
BOOL f ;
dw = BYTE_VALUE(pb,1) ;
dw &= 0x00000004 ;
dw >>= 2 ;
f = dw != 0 ;
return f ;
// ((BYTE_VALUE((pb),1) & 0x00000004) >> 2)
}
// retrieves the adaptation_field_control value
// retrieves the transport_private_data_flag bit
_inline BOOL TRANSPORT_PRIVATE_DATA_FLAG_BIT(BYTE * pb)
{
BOOL f ;
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 1) ;
dw &= 0x00000002 ;
dw >>= 1 ;
f = dw != 0 ;
return f ;
// ((BYTE_VALUE((pb),1) & 0x00000002) >> 1)
}
// retrieves the adaptation_field_extension_flag bit
_inline BOOL ADAPTATION_FIELD_EXTENSION_FLAG_BIT(BYTE * pb)
{
BOOL f ;
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 1) ;
dw &= 0x00000001 ;
f = dw != 0 ;
return f ;
// (BYTE_VALUE((pb),1) & 0x00000001)
}
_inline DWORD ADAPTATION_FIELD_CONTROL_VALUE(BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 3) ;
dw &= 0x00000030 ;
dw >>= 4 ;
return dw ;
// ((BYTE_VALUE((pb),3) & 0x00000030) >> 4)
}
// retrieves the sync_byte value
_inline DWORD SYNC_BYTE_VALUE(BYTE * pb)
{
DWORD dw ;
dw = BYTE_VALUE (pb, 0) ;
return dw ;
// (BYTE_VALUE((pb),0))
}
// transport_priority bit
_inline BOOL TRANSPORT_PRIORITY_BIT(BYTE * pb)
{
BOOL f ;
WORD w = -1 ;
w = WORD_VALUE (pb, 1) ;
w = NTOH_S (w) ;
w &= 0x00002000 ;
w >>= 13 ;
f = w != 0 ;
return f ;
// ((NTOH_S((* ((WORD *) BYTE_OFFSET((pb),1)))) & 0x00002000) >> 13)
}
// retrieves the PCR_base value (ULONGLONG)
// pb points to byte that follows adaptation_field_extension_flag
_inline ULONGLONG PCR_BASE_VALUE (BYTE * pb)
{
ULONGLONG ull = -1 ;
ull = ULONGLONG_VALUE (pb, 0) ;
ull = NTOH_LL (ull) ;
ull >>= 31 ;
return ull ;
// #define PCR_BASE_VALUE(pb) (NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 31)
}
// retrieves the PCR_ext value (DWORD)
// pb points to byte that follows adaptation_field_extension_flag
_inline DWORD PCR_EXT_VALUE (BYTE * pb)
{
ULONGLONG ull = -1 ;
DWORD dw = -1 ;
ull = ULONGLONG_VALUE (pb, 0) ;
ull = NTOH_LL (ull) ;
ull >>= 16 ;
ull &= (ULONGLONG) 0x00000000000001ff ;
dw = (DWORD) ull ;
return dw ;
// #define PCR_EXT_VALUE(pb) ((NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 16) & 0x00000000000001ff)
}
// pb points to first byte of the OPCR field
_inline ULONGLONG OPCR_BASE_VALUE (BYTE * pb)
{
ULONGLONG ull = -1 ;
ull = PCR_BASE_VALUE (pb) ;
return ull ;
// #define OPCR_BASE_VALUE(pb) PCR_BASE_VALUE(pb)
}
// retrieves the PCR_ext value (DWORD)
// pb points to first byte of the OPCR field
_inline DWORD OPCR_EXT_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = PCR_EXT_VALUE (pb) ;
return dw ;
// #define OPCR_EXT_VALUE(pb) PCR_EXT_VALUE(pb)
}
// retrieves the splice_countdown value (DWORD)
// pb points to it
_inline BYTE SPLICE_COUNTDOWN_VALUE (BYTE * pb)
{
BYTE b = -1 ;
b = BYTE_VALUE (pb, 0) ;
return b ;
// #define SPLICE_COUNTDOWN_VALUE(pb) BYTE_VALUE(pb,0)
}
// pb points to it
_inline DWORD TRANSPORT_PRIVATE_DATA_LENGTH_VALUE (BYTE * pb)
{
BYTE b = -1 ;
b = BYTE_VALUE (pb, 0) ;
return b ;
// #define TRANSPORT_PRIVATE_DATA_LENGTH_VALUE(pb) BYTE_VALUE(pb,0)
}
// retrieves the adaptation_field_extension_length value
// pb points to it
_inline DWORD ADAPTATION_FIELD_EXTENSION_LENGTH_VALUE (BYTE * pb)
{
BYTE b = -1 ;
b = BYTE_VALUE (pb, 0) ;
return b ;
// #define ADAPTATION_FIELD_EXTENSION_LENGTH_VALUE(pb) BYTE_VALUE(pb,0)
}
// ---------------------------------------------------------------------------
// PSI generic information (except for pure private sections)
// pb points to first byte of section (TS packet payload + pointer_field)
// ---------------------------------------------------------------------------
_inline DWORD PSI_TABLE_ID_VALUE(BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 0) ;
return dw ;
// #define PSI_TABLE_ID_VALUE(pb) (BYTE_VALUE((pb),0))
}
_inline BOOL PSI_SECTION_SYNTAX_INDICATOR_BIT (BYTE * pb)
{
BOOL f ;
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 1) ;
dw &= 0x80 ;
dw >>= 7 ;
f = dw != 0 ;
return f ;
// #define PSI_SECTION_SYNTAX_INDICATOR_BIT (pb) ((BYTE_VALUE((pb),1) & 0x80) >> 7)
}
_inline WORD PSI_SECTION_LENGTH_VALUE (BYTE * pb)
{
WORD w = -1 ;
w = WORD_VALUE (pb, 1) ;
w = NTOH_S (w) ;
w &= 0x0fff ;
return w ;
// #define PSI_SECTION_LENGTH_VALUE(pb) (NTOH_S(* ((WORD *) BYTE_OFFSET((pb),1))) & 0x0fff)
}
_inline DWORD PSI_VERSION_NUMBER_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 5) ;
dw >>= 1 ;
dw &= 0x1f ;
return dw ;
// #define PSI_VERSION_NUMBER_VALUE(pb) ((BYTE_VALUE((pb),5) >> 1) & 0x1f)
}
_inline BOOL PSI_CURRENT_NEXT_INDICATOR_BIT (BYTE * pb)
{
BOOL f ;
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 5) ;
dw &= 0x01 ;
f = dw != 1 ;
return f ;
// #define PSI_CURRENT_NEXT_INDICATOR_BIT (pb) (BYTE_VALUE((pb),5) & 0x01)
}
_inline DWORD PSI_SECTION_NUMBER_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 6) ;
return dw ;
// #define PSI_SECTION_NUMBER_VALUE(pb) (BYTE_VALUE((pb),6))
}
_inline DWORD PSI_LAST_SECTION_NUMBER_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = BYTE_VALUE (pb, 7) ;
return dw ;
// #define PSI_LAST_SECTION_NUMBER_VALUE(pb) (BYTE_VALUE((pb),7))
}
// ---------------------------------------------------------------------------
// PAT parsing follows
// pb points to beginning of section
// ---------------------------------------------------------------------------
_inline DWORD PAT_TABLE_ID_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = PSI_TABLE_ID_VALUE (pb) ;
return dw ;
// #define PAT_TABLE_ID_VALUE(pb) PSI_TABLE_ID_VALUE(pb)
}
_inline BOOL PAT_SECTION_SYNTAX_INDICATOR_BIT (BYTE * pb)
{
BOOL f ;
f = PSI_SECTION_SYNTAX_INDICATOR_BIT (pb) ;
return f ;
// #define PAT_SECTION_SYNTAX_INDICATOR_BIT(pb) PSI_SECTION_SYNTAX_INDICATOR_BIT(pb)
}
_inline WORD PAT_SECTION_LENGTH_VALUE (BYTE * pb)
{
WORD w = -1 ;
w = PSI_SECTION_LENGTH_VALUE (pb) ;
return w ;
// #define PAT_SECTION_LENGTH_VALUE(pb) PSI_SECTION_LENGTH_VALUE(pb)
}
_inline DWORD PAT_TRANSPORT_STREAM_ID_VALUE (BYTE * pb)
{
WORD w = -1 ;
w = WORD_VALUE (pb, 3) ;
w = NTOH_S (w) ;
return w ;
// #define PAT_TRANSPORT_STREAM_ID_VALUE(pb) NTOH_S(* ((WORD *) BYTE_OFFSET((pb),3)))
}
_inline DWORD PAT_VERSION_NUMBER_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = PSI_VERSION_NUMBER_VALUE (pb) ;
return dw ;
// #define PAT_VERSION_NUMBER_VALUE(pb) PSI_VERSION_NUMBER_VALUE(pb)
}
_inline BOOL PAT_CURRENT_NEXT_INDICATOR_BIT (BYTE * pb)
{
BOOL f ;
f = PSI_CURRENT_NEXT_INDICATOR_BIT (pb) ;
return f ;
// #define PAT_CURRENT_NEXT_INDICATOR_BIT(pb) PSI_CURRENT_NEXT_INDICATOR(pb)
}
_inline DWORD PAT_SECTION_NUMBER_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = PSI_SECTION_NUMBER_VALUE (pb) ;
return dw ;
// #define PAT_SECTION_NUMBER_VALUE(pb) PSI_SECTION_NUMBER_VALUE(pb)
}
_inline DWORD PAT_LAST_SECTION_NUMBER_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = PSI_LAST_SECTION_NUMBER_VALUE (pb) ;
return dw ;
// #define PAT_LAST_SECTION_NUMBER_VALUE(pb) PSI_LAST_SECTION_NUMBER_VALUE(pb)
}
_inline BYTE * PAT_PROGRAM_DESCRIPTOR (BYTE * pbPAT, DWORD n)
{
pbPAT += 8 ; // beyond the header
pbPAT += (n * 4) ; // and to the program
return pbPAT ;
// #define PAT_PROGRAM_DESCRIPTOR(pbPAT,n) ((((BYTE *) (pbPAT)) + 8) + ((n) * 4))
}
_inline WORD PAT_PROGRAM_DESCRIPTOR_PROGRAM_NUMBER_VALUE (BYTE * pbPAT, DWORD n)
{
BYTE * pb ; // program descriptor
WORD w ;
pb = PAT_PROGRAM_DESCRIPTOR (pbPAT, n) ;
w = WORD_VALUE (pb, 0) ;
w = NTOH_S (w) ;
return w ;
// #define PAT_PROGRAM_DESCRIPTOR_PROGRAM_NUMBER_VALUE(pbPAT,n) (NTOH_S (WORD_VALUE(PAT_PROGRAM_DESCRIPTOR(pbPAT,n))))
}
_inline WORD PAT_PROGRAM_DESCRIPTOR_PID_VALUE (BYTE * pbPAT, DWORD n)
{
BYTE * pb ; // program descriptor
WORD w ;
pb = PAT_PROGRAM_DESCRIPTOR(pbPAT,n) ;
w = WORD_VALUE (pb, 2) ;
w = NTOH_S (w) ;
w &= 0x1fff ;
return w ;
// #define PAT_PROGRAM_DESCRIPTOR_PID_VALUE(pbPAT,n) (NTOH_S (WORD_VALUE(PAT_PROGRAM_DESCRIPTOR(pbPAT,n) + 2)) & 0x1fff)
}
_inline BOOL PAT_PROGRAM_DESCRIPTOR_IS_PROGRAM (BYTE * pbPAT, DWORD n)
{
WORD w ;
BOOL f ;
w = PAT_PROGRAM_DESCRIPTOR_PROGRAM_NUMBER_VALUE (pbPAT,n) ;
f = w != 0x0000 ;
return f ;
// #define PAT_PROGRAM_DESCRIPTOR_IS_PROGRAM(pbPAT,n) (PAT_PROGRAM_DESCRIPTOR_PROGRAM_NUMBER_VALUE(pbPAT,n) != 0x0000)
}
__inline BOOL PAT_PROGRAM_DESCRIPTOR_IS_NETWORK (BYTE * pbPAT, DWORD n)
{
BOOL f ;
f = PAT_PROGRAM_DESCRIPTOR_IS_PROGRAM (pbPAT, n) ;
f = f == FALSE ;
return f ;
// #define PAT_PROGRAM_DESCRIPTOR_IS_NETWORK(pbPAT,n) (PAT_PROGRAM_DESCRIPTOR_IS_PROGRAM(pbPAT,n) == FALSE)
}
_inline WORD PAT_PROGRAM_DESCRIPTOR_PROGRAM_PID_VALUE (BYTE * pbPAT, DWORD n)
{
WORD w ;
w = PAT_PROGRAM_DESCRIPTOR_PID_VALUE (pbPAT, n) ;
return w ;
// #define PAT_PROGRAM_DESCRIPTOR_PROGRAM_PID_VALUE(pbPAT,n) PAT_PROGRAM_DESCRIPTOR_PID_VALUE(pbPAT,n)
}
_inline WORD PAT_PROGRAM_DESCRIPTOR_NETWORK_PID_VALUE (BYTE * pbPAT, DWORD n)
{
WORD w ;
w = PAT_PROGRAM_DESCRIPTOR_PID_VALUE (pbPAT, n) ;
return w ;
// #define PAT_PROGRAM_DESCRIPTOR_NETWORK_PID_VALUE(pbPAT,n) PAT_PROGRAM_DESCRIPTOR_PID_VALUE(pbPAT,n)
}
// ---------------------------------------------------------------------------
// PMT parsing follows
// ---------------------------------------------------------------------------
// pb points to the beginning of the section
_inline BYTE PMT_TABLE_ID_VALUE (BYTE * pb)
{
BYTE b ;
b = BYTE_VALUE (pb,0) ;
return b ;
// #define PMT_TABLE_ID_VALUE(pb) BYTE_VALUE(pb,0)
}
_inline BOOL PMT_SECTION_SYNTAX_INDICATOR_BIT (BYTE * pb)
{
BOOL f ;
f = PSI_SECTION_SYNTAX_INDICATOR_BIT(pb) ;
return f ;
//#define PMT_SECTION_SYNTAX_INDICATOR_BIT(pb) PSI_SECTION_SYNTAX_INDICATOR_BIT(pb)
}
_inline WORD PMT_SECTION_LENGTH_VALUE (BYTE * pb)
{
WORD w ;
w = PSI_SECTION_LENGTH_VALUE (pb) ;
return w ;
// #define PMT_SECTION_LENGTH_VALUE(pb) PSI_SECTION_LENGTH_VALUE(pb)
}
_inline WORD PMT_PROGRAM_NUMBER_VALUE (BYTE * pb)
{
WORD w ;
w = WORD_VALUE (pb, 3) ;
w = NTOH_S (w) ;
return w ;
// #define PMT_PROGRAM_NUMBER_VALUE(pb) NTOH_S(WORD_VALUE(pb,3))
}
_inline DWORD PMT_VERSION_NUMBER_VALUE (BYTE * pb)
{
DWORD dw ;
dw = PSI_VERSION_NUMBER_VALUE (pb) ;
return dw ;
// #define PMT_VERSION_NUMBER_VALUE(pb) PSI_VERSION_NUMBER_VALUE(pb)
}
_inline BOOL PMT_CURRENT_NEXT_INDICATOR_BIT (BYTE * pb)
{
BOOL f ;
f = PSI_CURRENT_NEXT_INDICATOR_BIT (pb) ;
return f ;
// #define PMT_CURRENT_NEXT_INDICATOR_BIT(pb) PSI_CURRENT_NEXT_INDICATOR_BIT(pb)
}
_inline DWORD PMT_SECTION_NUMBER (BYTE * pb)
{
DWORD dw ;
dw = PSI_SECTION_NUMBER_VALUE (pb) ;
return dw ;
// #define PMT_SECTION_NUMBER(pb) PSI_SECTION_NUMBER_VALUE(pb)
}
_inline DWORD PMT_LAST_SECTION_NUMBER (BYTE * pb)
{
DWORD dw ;
dw = PSI_LAST_SECTION_NUMBER_VALUE (pb) ;
return dw ;
// #define PMT_LAST_SECTION_NUMBER(pb) PSI_LAST_SECTION_NUMBER_VALUE(pb)
}
_inline WORD PMT_PCR_PID_VALUE (BYTE * pb)
{
WORD w ;
w = WORD_VALUE (pb, 8) ;
w = NTOH_S (w) ;
w &= 0x1fff ;
return w ;
// #define PMT_PCR_PID_VALUE(pb) (NTOH_S(WORD_VALUE(pb,8)) & 0x1fff)
}
_inline WORD PMT_PROGRAM_INFO_LENGTH_VALUE (BYTE * pb)
{
WORD w ;
w = WORD_VALUE (pb, 10) ;
w = NTOH_S (w) ;
w &= 0x0fff ;
return w ;
// #define PMT_PROGRAM_INFO_LENGTH_VALUE(pb) (NTOH_S(WORD_VALUE(pb,10)) & 0x0fff)
}
// pb points to the stream record block (stream_type, etc...)
_inline BYTE PMT_STREAM_RECORD_STREAM_TYPE_VALUE (BYTE * pb)
{
BYTE b ;
b = BYTE_VALUE (pb, 0) ;
return b ;
// #define PMT_STREAM_RECORD_STREAM_TYPE_VALUE(pb) BYTE_VALUE(pb,0)
}
_inline WORD PMT_STREAM_RECORD_ELEMENTARY_PID (BYTE * pb)
{
WORD w ;
w = WORD_VALUE (pb, 1) ;
w = NTOH_S (w) ;
w &= 0x1fff ;
return w ;
// #define PMT_STREAM_RECORD_ELEMENTARY_PID(pb) (NTOH_S(WORD_VALUE(pb,1)) & 0x1fff)
}
_inline WORD PMT_STREAM_RECORD_ES_INFO_LENGTH (BYTE * pb)
{
WORD w ;
w = WORD_VALUE (pb, 3) ;
w = NTOH_S (w) ;
w &= 0x0fff ;
return w ;
// #define PMT_STREAM_RECORD_ES_INFO_LENGTH(pb) (NTOH_S(WORD_VALUE(pb,3)) & 0x0fff)
}
// ---------------------------------------------------------------------------
// Private parsing follows
// pb points to beginning of section
// ---------------------------------------------------------------------------
_inline BOOL PRIVATE_SECTION_SYNTAX_INDICATOR_BIT (BYTE * pb)
{
BOOL f ;
f = PSI_SECTION_SYNTAX_INDICATOR_BIT (pb) ;
return f ;
// #define PRIVATE_SECTION_SYNTAX_INDICATOR_BIT(pb) PSI_SECTION_SYNTAX_INDICATOR(pb)
}
// ---------------------------------------------------------------------------
// ===========================================================================
// end of transport - related parsing
// ===========================================================================
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ===========================================================================
// beginning of PES - related parsing
// ===========================================================================
// ---------------------------------------------------------------------------
_inline DWORD START_CODE_PREFIX_VALUE (BYTE * pb)
{
DWORD dw = -1 ;
dw = DWORD_VALUE (pb,0) ;
dw = NTOH_L (dw) ;
dw >>= 8 ;
return dw ;
// #define START_CODE_PREFIX_VALUE(pb) (NTOH_L(DWORD_VALUE(pb,0)) >> 8)
}
_inline BYTE START_CODE_VALUE (BYTE * pb)
{
BYTE b = -1 ;
b = BYTE_VALUE (pb,3) ;
return b ;
// #define START_CODE_VALUE (BYTE_VALUE(pb,3))
}
_inline WORD PACKET_LENGTH_VALUE (BYTE * pb)
{
WORD w = -1 ;
w = WORD_VALUE (pb, 4) ;
w = NTOH_S (w) ;
return w ;
// #define PACKET_LENGTH_VALUE(pb) (NTOH_S(WORD_VALUE(pb,4)))
}
// ---------------------------------------------------------------------------
// pack header core parsing macros
// ---------------------------------------------------------------------------
_inline DWORD PACK_START_CODE_VALUE (BYTE * pb)
{
DWORD dw ;
dw = DWORD_VALUE (pb, 0) ;
dw = NTOH_L (dw) ;
return dw ;
// #define PACK_START_CODE_VALUE(pb) NTOH_L(DWORD_VALUE(pb, 0))
}
_inline ULONGLONG PACK_HEADER_SCR_BASE (BYTE * pb)
{
ULONGLONG scr ;
ULONGLONG ull ;
ull = ULONGLONG_VALUE (pb,1) ;
ull = NTOH_LL (ull) ;
//ull >>= 24 ;
scr = (0x000000000003FFF8 & ull) >> 3 ;
scr |= (0x00000003FFF80000 & ull) >> 4 ;
scr |= (0x0380000000000000 & ull) >> 5 ;
return scr ;
//#define PACK_HEADER_SCR_BASE(pb) (((NTOH_LL(ULONGLONG_VALUE(pb,1)) & 0x000000000003FFF8) >> 3) | \
// ((NTOH_LL(ULONGLONG_VALUE(pb,1)) & 0x00000003FFF80000) >> 4) | \
// ((NTOH_LL(ULONGLONG_VALUE(pb,1)) & 0x0380000000000000) >> 5))
}
_inline ULONGLONG PACK_HEADER_SCR_EXT (BYTE * pb)
{
ULONGLONG ull ;
ULONGLONG scr_ext ;
ull = ULONGLONG_VALUE(pb,4) ;
ull = NTOH_LL (ull) ;
ull >>= 16 ;
scr_ext = (ull & 0x00000000000003FE) ;
scr_ext >>= 1 ;
return scr_ext ;
// #define PACK_HEADER_SCR_EXT(pb) (((NTOH_LL(ULONGLONG_VALUE(pb,4)) >> 16) & 0x00000000000003FE) >> 1)
}
_inline DWORD PACK_PROGRAM_MUX_RATE (BYTE * pb)
{
DWORD dw ;
dw = DWORD_VALUE(pb,10) ;
dw = NTOH_L (dw) ;
dw >>= 8 ;
dw &= 0xFFFFFC0 ;
dw >>= 2 ;
return dw ;
// #define PACK_PROGRAM_MUX_RATE(pb) (((NTOH_L(DWORD_VALUE(pb,10)) >> 8) & 0xFFFFFC0) >> 2)
}
_inline BYTE PACK_STUFFING_LENGTH (BYTE * pb)
{
BYTE b ;
b = BYTE_VALUE (pb, 13) ;
b &= 0x03 ;
return b ;
// #define PACK_STUFFING_LENGTH(pb) (BYTE_VALUE(pb,13) & 0x03)
}
// ---------------------------------------------------------------------------
// common PES header parsing
// pb points to the first byte in the PES header
// ---------------------------------------------------------------------------
_inline DWORD PES_PACKET_START_CODE_PREFIX_VALUE (BYTE * pb)
{
return START_CODE_PREFIX_VALUE (pb) ;
// #define PES_PACKET_START_CODE_PREFIX_VALUE(pb) START_CODE_PREFIX_VALUE(pb)
}
_inline BYTE PES_STREAM_ID_VALUE (BYTE * pb)
{
return START_CODE_VALUE (pb) ;
// #define PES_STREAM_ID_VALUE(pb) START_CODE_VALUE(pb)
}
_inline WORD PES_PACKET_LENGTH_VALUE (BYTE * pb)
{
return PACKET_LENGTH_VALUE (pb) ;
// #define PES_PACKET_LENGTH_VALUE(pb) PACKET_LENGTH_VALUE(pb)
}
// ---------------------------------------------------------------------------
// tier1 header components (tier1: MPEG2 systems spec, first
// conditional (p. 30)
// pb points to first byte in PES header
// ---------------------------------------------------------------------------
_inline BYTE PES_SCRAMBLING_CONTROL_VALUE (BYTE * pb)
{
BYTE b = -1 ;
b = BYTE_VALUE (pb,6) ;
b &= 0x30 ;
b >>= 4 ;
return b ;
// #define PES_SCRAMBLING_CONTROL_VALUE(pb) ((BYTE_VALUE(pb,6) & 0x30) >> 4)
}
_inline BOOL PES_PRIORITY_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,6) ;
b = BIT_VALUE (b,3) ;
f = b != 0 ;
return f ;
// #define PES_PRIORITY_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,6),3)
}
_inline BOOL PES_DATA_ALIGNMENT_INDICATOR_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,6) ;
b = BIT_VALUE (b,2) ;
f = b != 0 ;
return f ;
// #define PES_PRIORITY_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,6),2)
}
_inline BOOL PES_COPYRIGHT_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,6) ;
b = BIT_VALUE (b,1) ;
f = b != 0 ;
return f ;
// #define PES_PRIORITY_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,6),1)
}
_inline BOOL PES_ORIGINAL_OR_COPY_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,6) ;
b = BIT_VALUE (b,0) ;
f = b != 0 ;
return f ;
// #define PES_PRIORITY_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,6),0)
}
_inline BYTE PES_PTS_DTS_FLAGS_VALUE (BYTE * pb)
{
BYTE b = -1 ;
b = BYTE_VALUE (pb,7) ;
b &= 0xc0 ;
b >>= 6 ;
return b ;
// #define PES_PTS_DTS_FLAGS_VALUE(pb) ((BYTE_VALUE(pb,7) & 0xc0) >> 6)
}
_inline BOOL PES_ESCR_FLAG_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,7) ;
b = BIT_VALUE (b,5) ;
f = b != 0 ;
return f ;
// #define PES_ESCR_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,7),5)
}
_inline BOOL PES_ES_RATE_FLAG_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,7) ;
b = BIT_VALUE (b,4) ;
f = b != 0 ;
return f ;
// #define PES_ES_RATE_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,7),4)
}
_inline BOOL PES_DSM_TRICK_MODE_FLAG_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,7) ;
b = BIT_VALUE (b,3) ;
f = b != 0 ;
return f ;
// #define PES_DSM_TRICK_MODE_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,7),3)
}
_inline BOOL PES_ADDITIONAL_COPY_INFO_FLAG_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,7) ;
b = BIT_VALUE (b,2) ;
f = b != 0 ;
return f ;
// #define PES_ADDITIONAL_COPY_INFO_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,7),2)
}
_inline BOOL PES_CRC_FLAG_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,7) ;
b = BIT_VALUE (b,1) ;
f = b != 0 ;
return f ;
// #define PES_CRC_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,7),1)
}
_inline BOOL PES_EXTENSION_FLAG_BIT (BYTE * pb)
{
BYTE b = -1 ;
BOOL f ;
b = BYTE_VALUE (pb,7) ;
b = BIT_VALUE (b,0) ;
f = b != 0 ;
return f ;
// #define PES_EXTENSION_FLAG_BIT(pb) BIT_VALUE(BYTE_VALUE(pb,7),0)
}
_inline BYTE PES_PES_HEADER_DATA_LENGTH_VALUE (BYTE * pb)
{
BYTE b = -1 ;
b = BYTE_VALUE (pb,8) ;
return b ;
// #define PES_PES_HEADER_DATA_LENGTH_VALUE(pb) BYTE_VALUE(pb,8)
}
// pb points to it
_inline ULONGLONG PES_PTS_VALUE (BYTE * pb)
{
ULONGLONG pts ;
ULONGLONG ull ;
ull = ULONGLONG_VALUE (pb,0) ;
ull = NTOH_LL (ull) ;
ull >>= 24 ;
pts = (0x000000000000FFFE & ull) >> 1 ; // [0..14], 1 marker bit
pts |= (0x00000000FFFE0000 & ull) >> 2 ; // [29..15], 2 marker bits
pts |= (0x0000000E00000000 & ull) >> 3 ; // [32..30], 3 marker bits
return pts ;
// #define PES_PTS_VALUE(pb) (((NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 24) & 0x000000000000FFFE) >> 1) | \
// (((NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 24) & 0x00000000FFFE0000) >> 2) | \
// (((NTOH_LL(ULONGLONG_VALUE(pb,0)) >> 24) & 0x0000000E00000000) >> 3)
}
_inline ULONGLONG PES_DTS_VALUE (BYTE * pb)
{
ULONGLONG dts = -1 ;
dts = PES_PTS_VALUE (pb) ;
return dts ;
// #define PES_DTS_VALUE(pb) PES_PTS_VALUE(pb)
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
#endif // PARSE_WITH_MACROS
// general MPEG-2 - related macros follow
// ---------------------------------------------------------------------------
// general macros
// TRUE/FALSE if the PSI header is valid; can be used for PAT, PMT, CAT,
// non pure-private sections; checks the following items:
// 1. section_length should not exceed maximum allowed
// 2. section_length should include at least remaining header
// 3. last_section_number should be >= section_number
// 4. syntax_indicator bit should be '1'
// 5. section_length should have first 2 bits == '00'
#define VALID_PSI_HEADER(pbSection) \
( (PSI_SECTION_LENGTH_VALUE(pbSection) <= 0x3fd) && \
(PSI_SECTION_LENGTH_VALUE(pbSection) >= 5) && \
(PSI_LAST_SECTION_NUMBER_VALUE(pbSection) >= PSI_SECTION_NUMBER_VALUE(pbSection)) && \
(PSI_SECTION_SYNTAX_INDICATOR_BIT(pbSection) == TRUE) && \
(((PSI_SECTION_LENGTH_VALUE(pbSection) & 0xc000)) == 0x0000) )
// checks that he PAT section given is valid; checks the following items:
// 1. valid PSI header
// 2. even number of 4 byte program descriptors (section_length - 5 bytes
// remaining in header - 4 byte CRC_32)
// 3. table_id is 0x00 (see table 2-26)
#define VALID_PAT_SECTION(pbPAT) \
( VALID_PSI_HEADER(pbPAT) && \
(((PAT_SECTION_LENGTH_VALUE(pbPAT) - 4 - 5) % 4) == 0) && \
(PAT_TABLE_ID_VALUE(pbPAT) == PAT_TABLE_ID) )
// returns the number of programs described in the passed PAT section
#define NUMBER_PROGRAMS_IN_PAT_SECTION(pbPAT) ((DWORD) ((PAT_SECTION_LENGTH_VALUE(pbPAT) - 5 - 4) / 4))
// checks that he PAT section given is value; checks the following items:
// 1. valid PSI header
// 2. section_length, program_info_length are valid wrt each other; checked as
// follows: section_length >= program_info_length + 9 + 4, where
// 9 is the number of bytes that FOLLOW section_length and include program_info_length
// 4 is the size of the CRC_32 value at the end of the section
// 3. table_id is PMT_TABLE_ID
#define VALID_PMT_SECTION(pbPMT) \
( VALID_PSI_HEADER(pbPMT) && \
(PMT_SECTION_LENGTH_VALUE(pbPMT) >= PMT_PROGRAM_INFO_LENGTH_VALUE(pbPMT) + 9 + 4) && \
(PMT_TABLE_ID_VALUE(pbPMT) == PMT_TABLE_ID) )
// confirms that the PID value does not have bits higher than the first 13
// are set
#define VALID_PID(pid) (((pid) & 0xffffe000) == 0x00000000)
// confirms the continuity_counter holds a valid value
#define VALID_CONTINUITY_COUNTER(counter) (((counter) & 0xffffff00) == 0x00000000)
// see page 20 of the MPEG-2 systems spec
#define EXPECT_CONTINUITY_COUNTER_INCREMENT(pid, adaptation_field_control) \
((pid) != TS_NULL_PID && \
(adaptation_field_control) != 0x00000000 && \
(adaptation_field_control) != 0x00000002)
// increments and takes care of the wrapping case
#define INCREMENTED_CONTINUITY_COUNTER_VALUE(c) ((BYTE) (((c) + 1) & 0x0000000f))
// adaptation field macros follow --
// pp. 20 of the MPEG-2 systems spec
// adaptation_field_control == '11' ==> adaptation_field_length in [0, 182]
// adaptation_field_control == '10' ==> adaptation_field_length == 183
#define VALID_ADAPTATION_FIELD(adaptation_field_control, adaptation_field_length) \
(((adaptation_field_control) == 0x3 && (adaptation_field_length) <= 182) || \
((adaptation_field_control) == 0x2 && (adaptation_field_length) == 183))
// pp. 41 of the MPEG-2 systems spec
// make sure that the pointer_field field that precedes a PSI section is valid
// i.e. doesn't index us off the end of the packet; we check validity by making
// sure that it falls in the range [0, TransportPayloadLength - 1); 0 means
// the section follows immediately; if it's > 0, it must be
// < TransportPayloadLength - 1 because TransportPayloadLength - 1 is the payload
// that remains AFTER pointer_field, and we need at least 1 byte of section data
#define VALID_POINTER_FIELD(pointer_field, TransportPayloadLength) ((pointer_field) < (TransportPayloadLength) - 1)
#define IS_AV_STREAM(stream_type) (((stream_type) == 0x00000001) || \
((stream_type) == 0x00000002) || \
((stream_type) == 0x00000003) || \
((stream_type) == 0x00000004))
// ---------------------------------------------------------------------------
// PES packet - related
// TRUE/FALSE if the stream is a padding stream
#define IS_PADDING_STREAM(stream_id) ((stream_id) == STREAM_ID_PADDING_STREAM)
// TRUE/FALSE if stream is tier_1 (see first conditional in table 2-17,
// MPEG2 systems specification, p. 30)
#define IS_TIER1_STREAM(stream_id) (((stream_id) != STREAM_ID_PROGRAM_STREAM_MAP) && \
((stream_id) != STREAM_ID_PADDING_STREAM) && \
((stream_id) != STREAM_ID_PRIVATE_STREAM_2) && \
((stream_id) != STREAM_ID_ECM) && \
((stream_id) != STREAM_ID_EMM) && \
((stream_id) != STREAM_ID_PROGRAM_STREAM_DIRECTORY) && \
((stream_id) != STREAM_ID_DSMCC_STREAM) && \
((stream_id) != STREAM_ID_H_222_1_TYPE_E))
// TRUE/FALSE if stream is tier_2 (see second conditional in table 2-17,
// MPEG2 systems specification, p. 32)
#define IS_TIER2_STREAM(stream_id) (((stream_id) == STREAM_ID_PROGRAM_STREAM_MAP) || \
((stream_id) == STREAM_ID_PRIVATE_STREAM_2) || \
((stream_id) == STREAM_ID_ECM) || \
((stream_id) == STREAM_ID_EMM) || \
((stream_id) == STREAM_ID_PROGRAM_STREAM_DIRECTORY) || \
((stream_id) == STREAM_ID_DSMCC_STREAM) || \
((stream_id) == STREAM_ID_H_222_1_TYPE_E))
#define IS_TIER3_STREAM(stream_id) ((stream_id) == STREAM_ID_PADDING_STREAM)
// total PES header length (includes usual fields, optional fields,
// stuffing bytes); add the return value to a byte pointer to PES header
// to point to the byte that follows
// ho = PES_header_data_length
#define PES_HEADER_TOTAL_LENGTH(ho) (PES_TIER1_REQ_HEADER_FIELD_LEN + (ho))
// returns the total PES packet length, or -1 if pl (PES_packet_length) is 0
#define TOTAL_PES_PACKET_LENGTH(pl) ((pl) != 0 ? ((pl) + PES_ALWAYS_HEADER_FIELD_LEN) : -1)
// TRUE/FALSE if packet has video
#define IS_PES_VIDEO(id) IN_RANGE(id,STREAM_ID_VIDEO_STREAM_MIN,STREAM_ID_VIDEO_STREAM_MAX)
// TRUE/FALSE if the packet has audio
#define IS_PES_AUDIO(id) IN_RANGE(id,STREAM_ID_AUDIO_STREAM_MIN,STREAM_ID_AUDIO_STREAM_MAX)
// ---------------------------------------------------------------------------
// analog copy protection-related
// PES_packet_length defines the number of bytes that *follow* the field
#define PES_PACKET_LENGTH_IS_MIN_VALID_ANALOGCOPYPROTECTION(pbPES) (PES_PACKET_LENGTH_VALUE(pbPES) >= (1 + 4 + 2))
#define SUBSTREAMID_IS_ANALOGCOPYPROTECTION(pbPES) (PES_ACP_SUBSTREAM_ID(pbPES) == SUBSTREAM_ID_ANALOGCOPYPROTECTION)
#define IS_VALID_ANALOGCOPYPROTECTION_PACKET(pbPES) (PES_PACKET_LENGTH_IS_MIN_VALID_ANALOGCOPYPROTECTION(pbPES) && SUBSTREAMID_IS_ANALOGCOPYPROTECTION(pbPES))
#endif // __mp2demux_parsemac_h