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