/*******************************************************}
{ }
{ File : MPEGPSUtils.h }
{ Created by Tsviatko Jongov }
{ http://tsviatko.jongov.com }
{ }
{ Program stream utils. }
{
}
{*******************************************************/
#ifndef
__MPEGPSUTILS_H__
#define
__MPEGPSUTILS_H__
#include <windows.h>
#define
PACK_START_CODE 0x000001BA
#define
PACK_START_CODE_SWP 0xBA010000
#define
SYSTEM_HEADER_START_CODE 0x000001BB
#define
SYSTEM_HEADER_START_CODE_SWP 0xBB010000
struct
PSTD_buffer_params
{
unsigned long stream_id; // 8 bits
unsigned long reserved; // 2 bits '11'
unsigned long P_STD_buffer_bound_scale; // 1 bit
unsigned long P_STD_buffer_size_bound; // 13 bits
};
struct
system_header
{
unsigned long system_header_start_code; // 32 bits
unsigned long header_length; //
16 bits
unsigned long marker_bit_1; // 1 bit
unsigned long rate_bound; // 22
bits
unsigned long marker_bit_2; // 1 bit
unsigned long audio_bound; // 6 bits
unsigned long fixed_flag; // 1 bit
unsigned long CSPS_flag; // 1 bit
unsigned long system_audio_lock_flag; // 1 bit
unsigned long system_video_lock_flag; // 1 bit
unsigned long marker_bit_3; // 1 bit
unsigned long video_bound; // 5 bits
unsigned long packet_rate_restriction_flag; // 1 bits
unsigned long reserved_bits; // 7 bits
unsigned long PSTD_buffer_params_count; // custom
PSTD_buffer_params PSTD_buffer[256];
};
struct
pack_header
{
unsigned long pack_start_code; //
32 bits
unsigned long reserved_1; // 2 bits '01'
unsigned long system_clock_reference_base_32_30; // 3 bits
unsigned long
marker_bit_1; // 1 bit
unsigned long system_clock_reference_base_29_15; // 15 bits
unsigned long marker_bit_2; // 1 bit
unsigned long system_clock_reference_base_14_0; // 15 bits
unsigned long marker_bit_3; // 1 bit
unsigned long system_clock_reference_extension; // 9 bits
unsigned long marker_bit_4; // 1 bit
unsigned long program_mux_rate; //
22 bits
unsigned long marker_bit_5; // 1 bit
unsigned long marker_bit_6; // 1 bit
unsigned long reserved_2; // 5 bits
unsigned long pack_stuffing_length; // 3 bits
unsigned char stuffing_byte[7]; //
up to 7 bytes (x8 bits)
system_header system_hdr;
};
bool IsPS(char * FileName)
{
FILE * FileStream;
unsigned char * Buffer = NULL;
unsigned long Read;
unsigned char * P;
bool Found
= false;
if
(fopen_s(&FileStream, FileName, "rb")
!= 0)
{
OutputDebugString(L"tsv: Error in IsPS - cannot open file.");
return false;
}
Buffer = new
unsigned char[3
* 1024];
if
(!Buffer)
{
OutputDebugString(L"tsv: Error in IsPS - cannot allocate buffer.");
fclose(FileStream);
return false;
}
fseek(FileStream, 0, SEEK_SET);
Read = (unsigned
long)fread(Buffer, 1, 2 * 1024, FileStream);
if (Read
<= 0)
{
OutputDebugString(L"tsv: Error in IsPS - file is empty.");
fclose(FileStream);
delete
[] Buffer;
return false;
}
P = Buffer;
for (;;)
{
if (
*(DWORD *)(P) == PACK_START_CODE_SWP)
{
Found = true;
break;
}
P++;
Read--;
if
(!Read)
{
break;
}
}
fclose(FileStream);
delete []
Buffer;
return
Found;
}
bool
ParseSystemHeader(unsigned char * Data, unsigned
long Size, system_header * system_hdr)
{
unsigned char * p = NULL;
unsigned long i = 0;
if (
(!Data) ||(Size < 12) || (!system_hdr) )
{
OutputDebugString(L"tsv: Error in ParseSystemHeader - system header not
full.");
return false;
}
system_hdr->system_header_start_code =
(Data[0] << 24) |
(Data[1] << 16) |
(Data[2] << 8) |
(Data[3]); // 32 bits
system_hdr->header_length = (Data[4]
<< 8) | (Data[5]); // 16 bits
system_hdr->marker_bit_1 = (Data[6]
>> 7) & 0x01; // 1 bit
system_hdr->rate_bound = ((Data[6] &
0x7F) << 15) |
(Data[7] <<
7) |
((Data[8] >>
1) & 0x7F); // 22 bits
system_hdr->marker_bit_2 = Data[8] &
0x01; // 1 bit
system_hdr->audio_bound = (Data[9]
>> 2) & 0x3F;
// 6
bits
system_hdr->fixed_flag = (Data[9]
>> 1) & 0x01;
// 1
bit
system_hdr->CSPS_flag = Data[9] &
0x01; // 1 bit
system_hdr->system_audio_lock_flag =
(Data[10] >> 7) & 0x01; // 1 bit
system_hdr->system_video_lock_flag =
(Data[10] >> 6) & 0x01; // 1 bit
system_hdr->marker_bit_3 = (Data[10]
>> 5) & 0x01; // 1 bit
system_hdr->video_bound = Data[10] &
0x1F; // 5 bits
system_hdr->packet_rate_restriction_flag
= (Data[11] >> 7) & 0x01; // 1 bits
system_hdr->reserved_bits = Data[11]
& 0x7F; // 7 bits
p = &Data[12];
system_hdr->PSTD_buffer_params_count =
0;
while (p[0]
& 0x80)
{
system_hdr->PSTD_buffer_params_count++;
system_hdr->PSTD_buffer[i].stream_id =
p[0];
p++;
system_hdr->PSTD_buffer[i].reserved
= (p[0] >> 6) & 0x03;
system_hdr->PSTD_buffer[i].P_STD_buffer_bound_scale = (p[0] >>
5) & 0x01;
system_hdr->PSTD_buffer[i].P_STD_buffer_size_bound = ((p[0] &
0xF8) << 5) | p[1];
p += 2;
i++;
}
return true;
}
bool
ParsePackHeader(unsigned char * Data, unsigned
long Size, pack_header * pack_hdr)
{
if ( (!Data)
|| (Size < 14) || (!pack_hdr) )
{
OutputDebugString(L"tsv: Error in ParsePackHeader - pack not full.");
return false;
}
pack_hdr->pack_start_code = (Data[0]
<< 24) |
(Data[1]
<< 16) |
(Data[2]
<< 8) |
(Data[3]);
pack_hdr->reserved_1 = (Data[4] <<
6) & 0x03;
// 2
bits '01'
pack_hdr->system_clock_reference_base_32_30
= (Data[4] << 3) & 0x07; // 3 bits
pack_hdr->marker_bit_1 = (Data[4]
<< 2) & 0x01; // 1 bit
pack_hdr->system_clock_reference_base_29_15 = ((Data[4] & 0x03)
<< 13) |
((Data[5] ) << 5) |
((Data[6] >> 3) && 0x1F);
// 15 bits
pack_hdr->marker_bit_2 = (Data[6]
>> 2) & 0x01; // 1 bit
pack_hdr->system_clock_reference_base_14_0 = ((Data[6] & 0x03)
<< 13) |
((Data[7] ) << 5) |
((Data[8] >> 3) &
0x1F); // 15
bits
pack_hdr->marker_bit_3 = ((Data[8]
>> 2) & 0x01);
// 1
bit
pack_hdr->system_clock_reference_extension = ((Data[8] & 0x03)
<< 7) |
((Data[9] >> 1) & 0x7F);
// 9
bits
pack_hdr->marker_bit_4 = Data[9] &
0x01; // 1 bit
pack_hdr->program_mux_rate = (Data[10]
<< 14) |
(Data[11]
<< 6) |
((Data[12]
>> 2) & 0x3F); //
22 bits
pack_hdr->marker_bit_5 = ((Data[12]
>> 1) & 0x01);
// 1
bit
pack_hdr->marker_bit_6 = (Data[12] &
0x01); // 1 bit
pack_hdr->reserved_2 = ((Data[13]
>> 3) & 0x1F); // 5 bits
pack_hdr->pack_stuffing_length =
Data[13] & 0x07;
// 3
bits
if (Size
< 14 + pack_hdr->pack_stuffing_length)
{
OutputDebugString(L"tsv: Error in ParsePackHeader - pack not full.");
return false;
}
for (unsigned int i = 0; i
< pack_hdr->pack_stuffing_length; i++)
{
pack_hdr->stuffing_byte[i] = Data[14
+ i]; // x8 bits
}
if (Size
< 14 + pack_hdr->pack_stuffing_length + 4)
{
OutputDebugString(L"tsv: Error in ParsePackHeader - pack not full.");
return false;
}
if (*(DWORD
*)(&Data[14 + pack_hdr->pack_stuffing_length]) ==
SYSTEM_HEADER_START_CODE_SWP)
{
ParseSystemHeader(&Data[14 +
pack_hdr->pack_stuffing_length], Size - (14 +
pack_hdr->pack_stuffing_length), &pack_hdr->system_hdr);
}
return true;
}
__int64
GetSCRInt64(pack_header * pack_hdr) //27 MHz units
{
__int64 i;
i =
pack_hdr->system_clock_reference_base_14_0;
i = i |
(pack_hdr->system_clock_reference_base_29_15 << 15);
i = i |
(pack_hdr->system_clock_reference_base_32_30 << 29);
return (i *
300 + pack_hdr->system_clock_reference_extension);
}
#endif // __MPEGPSUTILS_H__