/*******************************************************}

{                                                       }

{       File : MPEGTSUtils.h                            }

{       Created by Tsviatko Jongov                      }

{       http://tsviatko.jongov.com                      }

{                                                       }

{       Transport stream utils.                         }

{                                                       }

{*******************************************************/

   

#ifndef __MPEGTSUTILS_H__

#define __MPEGTSUTILS_H__

   

struct adaptation_field

{

    unsigned long adaptation_field_length;                      //  8 uimsbf

    unsigned long discontinuity_indicator;                      //  1 bslbf

    unsigned long random_access_indicator;                      //  1 bslbf

    unsigned long elementary_stream_priority_indicator;         //  1 bslbf

    unsigned long PCR_flag;                                     //  1 bslbf

    unsigned long OPCR_flag;                                    //  1 bslbf

    unsigned long splicing_point_flag;                          //  1 bslbf

    unsigned long transport_private_data_flag;                  //  1 bslbf

    unsigned long adaptation_field_extension_flag;              //  1 bslbf

   

    __int64       program_clock_reference_base;                 // 33 uimsbf

    unsigned long reserved0;                                    //  6 bslbf

    unsigned long program_clock_reference_extension;            //  9 uimsbf

   

    __int64       original_program_clock_reference_base;        // 33 uimsbf

    unsigned long reserved1;                                    //  6 bslbf

    unsigned long original_program_clock_reference_extension;   //  9 uimsbf

    unsigned long splice_countdown;                             //  8 tcimsbf

   

    unsigned long transport_private_data_length;                //  8 uimsbf

    unsigned char private_data_byte[256];                       // x8 bslbf

   

    unsigned long adaptation_field_extension_length;            //  8 uimsbf

    unsigned long ltw_flag;                                     //  1 bslbf

    unsigned long piecewise_rate_flag;                          //  1 bslbf

    unsigned long seamless_splice_flag;                         //  1 bslbf

    unsigned long reserved2;                                    //  5 bslbf

   

    unsigned long ltw_valid_flag;                               //  1 bslbf

    unsigned long ltw_offset;                                   // 15 uimsbf

   

    unsigned long reserved3;                                    //  2 bslbf

    unsigned long piecewise_rate;                               // 22 uimsbf

   

    unsigned long splice_type;                                  //  4 bslbf

    unsigned long DTS_next_AU_32_30;                            //  3 bslbf

    unsigned long marker_bit0;                                  //  1 bslbf

    unsigned long DTS_next_AU_29_15;                            // 15 bslbf

    unsigned long marker_bit1;                                  //  1 bslbf

    unsigned long DTS_next_AU_14_0;                             // 15 bslbf

    unsigned long marker_bit2;                                  //  1 bslbf

   

    unsigned char reserved4[256];                               //  8 bslbf

   

    unsigned char stuffing_byte[256];                           //  8 bslbf

};

   

struct transport_packet

{

    unsigned long sync_byte;                                    //  8 bslbf

    unsigned long transport_error_indicator;                    //  1 bslbf

    unsigned long payload_unit_start_indicator;                 //  1 bslbf

    unsigned long transport_priority;                           //  1 bslbf

    unsigned long PID;                                          // 13 uimsbf

    unsigned long transport_scrambling_control;                 //  2 bslbf

    unsigned long adaptation_field_control;                     //  2 bslbf

    unsigned long continuity_counter;                           //  4 uimsbf

    adaptation_field adaptation_fld;

    unsigned char data_byte[256];                               //  8 bslbf

};

   

struct program_association_section

{

    unsigned long table_id;                                     //  8 uimsbf

    unsigned long section_syntax_indicator;                     //  1 bslbf

    unsigned long zero_bit;                                     //  1 bslbf (must be zero)

    unsigned long reserved0;                                    //  2 bslbf

    unsigned long section_length;                               // 12 uimsbf

    unsigned long transport_stream_id;                          // 16 uimsbf

    unsigned long reserved1;                                    //  2 bslbf

    unsigned long version_number;                               //  5 uimsbf

    unsigned long current_next_indicator;                       //  1 bslbf

    unsigned long section_number;                               //  8 uimsbf

    unsigned long last_section_number;                          //  8 uimsbf

   

    unsigned long programs_count;

    unsigned long program_number[256];                          // 16 uimsbf

    unsigned long reserved2[256];                               //  3 bslbf

    unsigned long PID[256];                                     // 13 uimsbf (network_PID or program_map_PID depending on the program_number)

   

    unsigned long CRC_32;                                       // 32 rpchof

};

   

struct CA_section

{

    unsigned long table_id;                                     //  8 uimsbf

    unsigned long section_syntax_indicator;                     //  1 bslbf

    unsigned long zero_bit;                                     //  1 bslbf (must be zero)

    unsigned long reserved0;                                    //  2 bslbf

    unsigned long section_length;                               // 12 uimsbf

    unsigned long reserved1;                                    // 18 bslbf

    unsigned long version_number;                               //  5 uimsbf

    unsigned long current_next_indicator;                       //  1 bslbf

    unsigned long section_number;                               //  8 uimsbf

    unsigned long last_section_number;                          //  8 uimsbf

   

    unsigned long descriptors_count;

    unsigned char descriptor[256];

   

    unsigned long CRC_32;                                       // 32 rpchof

};

   

struct TS_program_map_section

{

    unsigned long table_id;                                     //  8 uimsbf

    unsigned long section_syntax_indicator;                     //  1 bslbf

    unsigned long zero_bit;                                     //  1 bslbf (must be zero);

    unsigned long reserved0;                                    //  2 bslbf

    unsigned long section_length;                               // 12 uimsbf

    unsigned long program_number;                               // 16 uimsbf

    unsigned long reserved1;                                    //  2 bslbf

    unsigned long version_number;                               //  5 uimsbf

    unsigned long current_next_indicator;                       //  1 bslbf

    unsigned long section_number;                               //  8 uimsbf

    unsigned long last_section_number;                          //  8 uimsbf

    unsigned long reserved2;                                    //  3 bslbf

    unsigned long PCR_PID;                                      // 13 uimsbf

    unsigned long reserved3;                                    //  4 bslbf

    unsigned long program_info_length;                          // 12 uimsbf

   

    unsigned long descriptors_count;

    void * descriptor[256];

   

    unsigned long streams_count;

    unsigned long stream_type[256];                             //  8 uimsbf

    unsigned long reserved4[256];                               //  3 bslbf

    unsigned long elementary_PID[256];                          // 13 uimsnf

    unsigned long reserved5[256];                               //  4 bslbf

    unsigned long ES_info_length[256];                          // 12 uimsbf

   

    unsigned long ES_descriptors_count;

    void * ES_descriptor[256];

   

    unsigned long CRC_32;                                       // 32 rpchof

};

   

bool GetTSStreamType(void * Data, unsigned long Size, unsigned long * TSPacketLen)

{

    unsigned char * p = (unsigned char *)Data;

    unsigned long Len = Size;

   

    for (;;)

    {

        if (Len <= 188)

        {

            return false;

        }

       

        if (p[0] != 0x47)

        {

            p++;

            Len--;

            continue;

        }

       

        if (p[188] == 0x47)

        {

            *TSPacketLen = 188;

            return true;

        }

       

        if (Len <= 192)

        {

            return false;

        }

       

        if (p[192] == 0x47)

        {

            *TSPacketLen = 192;

            return true;

        }

       

        if (Len <= 196)

        {

            return false;

        }

       

        if (p[196] == 0x47)

        {

            *TSPacketLen = 196;

            return true;

        }

       

        if (Len <= 204)

        {

            return false;

        }

       

        if (p[204] == 0x47)

        {

            *TSPacketLen = 204;

            return true;

        }

       

        if (Len <= 212)

        {

            return false;

        }

       

        if (p[212] == 0x47)

        {

            *TSPacketLen = 212;

            return true;

        }

       

        p++;

        Len--;

    }

}

   

bool IsTS(char * FileName, unsigned long * TSPacketLength)

{

    unsigned char * Buffer; 

    FILE * FileStream;

    unsigned long Read;

   

    if (fopen_s(&FileStream, FileName, "rb") != 0)

    {

        return false;

    }

   

    Buffer = new unsigned char[3 * 1024];

    fseek(FileStream, 0, SEEK_SET);

   

    Read = (unsigned long)fread(Buffer, 1, 2 * 1024, FileStream);

    if (Read == 0)

    {

        fclose(FileStream);

        return false;

    }

   

    bool res = GetTSStreamType(Buffer, Read, TSPacketLength);

   

    fclose(FileStream);

    delete [] Buffer;

   

    return res;

}

 

#endif // __MPEGTSUTILS_H__