5 const int Constants::TS_PAYLOAD_SIZE = 184;
6 const int Constants::TS_SIZE = 188;
7 const int Constants::STRIDE_SIZE = 192;
8 const int Constants::DISK_BUFFER = 0x8D000 << 5;
9 const byte Constants::SYNC_BYTE = 0x47;
10 const byte Constants::PAT_PID = 0x00;
11 const byte Constants::SIT_PID = 0x1f;
12 const byte Constants::PAT_TABLE_ID = 0x00;
13 const byte Constants::PMT_TABLE_ID = 0x02;
14 const byte Constants::DTCP_DESCRIPTOR_TAG = 0x88;
15 const byte Constants::PACK_ID = 0xba;
16 const byte Constants::SYS_ID = 0xbb;
17 const byte Constants::MAP_ID = 0xbc;
18 const byte Constants::DIR_ID = 0xff;
19 const byte Constants::PAD_ID = 0xbe;
22 const ushort Constants::DEFAULT_PMT_PID = 0x0100;
23 const ushort Constants::DEFAULT_VIDEO_PID = 0x1011;
24 const ushort Constants::MAX_VIDEO_PID = 0x1019;
25 const ushort Constants::DEFAULT_AUDIO_PID = 0x1100;
26 const ushort Constants::MAX_AUDIO_PID = 0x111f;
27 const ushort Constants::DEFAULT_PCR_PID = 0x1001;
28 const ushort Constants::DEFAULT_SUBTITLE_PID = 0x1800;
29 const ushort Constants::DEFAULT_PRESENTATION_GRAPHICS_PID = 0x1200;
30 const ushort Constants::DEFAULT_INTERACTIVE_GRAPHICS_PID = 0x1400;
31 const ushort Constants::DEFAULT_PROGRAM_NUMBER = 0x01;
32 const int Constants::MAX_BUFFER_COUNT = 0xff;
33 const int Constants::MIN_BUFFER_COUNT = 0x02;
34 const Int64 Constants::AUDIO_DELAY = 30000;
35 const UInt32 Constants::MKVCLUSTER_START = 0x1f43b675;
36 const UInt32 Constants::MKVFILE_START = 0x1a45dfa3;
37 const UInt32 Constants::MKVSEGMENT_START = 0x18538067;
38 const UInt32 Constants::MKVTRACKINFO_START = 0x1654AE6B;
41 const byte Constants::PES_VIDEO = 0xe0;
42 const byte Constants::PES_AUDIO_MPEG = 0xc0;
43 const byte Constants::PES_PRIVATE1 = 0xbd;
44 const byte Constants::PES_PADDING = 0xbe;
45 const byte Constants::PES_PRIVATE2 = 0xbf;
46 const byte Constants::PES_VIDEO_VC1 = 0xfd;
47 const byte Constants::PES_PRIVATE_AC3 = 0x80;
48 const byte Constants::PES_PRIVATE_AC3_PLUS = 0xc0;
49 const byte Constants::PES_PRIVATE_DTS_HD = 0x88;
50 const byte Constants::PES_PRIVATE_LPCM = 0xa0;
51 const byte Constants::PES_PRIVATE_AC3_TRUE_HD = 0xb0;
52 const UInt32 Constants::VC1_SEQ_SC = 0x0000010f;
53 const UInt32 Constants::VC1_END_OF_STREAM = 0x0000010a;
54 const ushort Constants::AC3_SYNC = 0x0b77;
55 const UInt32 Constants::H264_PREFIX = 0x00000107;
56 const UInt32 Constants::H264_END_OF_STREAM = 0x0000010b;
57 const UInt32 Constants::DTS_SYNC = 0x7ffe8001;
58 const UInt32 Constants::DTS_EXT_SYNC = 0x64582025;
59 const UInt32 Constants::MLP_SYNC = 0xF8726FBA;
60 const UInt32 Constants::MPEG2_SEQ_CODE = 0x000001b3;
61 const UInt32 Constants::MPEG2_SEQ_EXT = 0x000001b5;
62 const UInt32 Constants::MPEG2_SEQ_END = 0x000001b7;
65 const Int64 Constants::MPEG2TS_CLOCK_RATE = 27000000LL;
66 const Int64 Constants::MAX_MPEG2TS_CLOCK = 0x25800000000LL;
67 const Int64 Constants::MAX_BLURAY_CLOCK = 0x40000000LL;
68 const Int64 Constants::MAX_FIREWIRE_CLOCK = 24576000LL;
69 const Int64 Constants::MAX_PTS_CLOCK = 0x200000000LL;
70 const Int64 Constants::PTS_CLOCK_RATE = 90000LL;
71 const int Constants::MAX_OFFSET = 3072;
72 const int Constants::MAX_COUNT = 8000;
75 readonly byte Constants::hdmv_registration_descriptor[]
76 = { 0x05, 0x04, 0x48, 0x44, 0x4d, 0x56 };
77 readonly byte Constants::copy_control_descriptor[]
78 = { 0x88, 0x04, 0x0f, 0xff, 0x84, 0xfc };
79 readonly byte Constants::vc1_descriptor[]
80 = { 0x05, 0x05, 0x56, 0x43, 0x2d, 0x31, 0xff };
81 readonly byte Constants::ac3_registration_descriptor[]
82 = { 0x05, 0x04, 0x41, 0x43, 0x2d, 0x33 };
83 readonly byte Constants::DefaultSitTableOne[] = {
84 0x47, 0x40, 0x1f, 0x10, 0x00, 0x7f, 0xf0, 0x19,
85 0xff, 0xff, 0xc1, 0x00, 0x00, 0xf0, 0x0a, 0x63,
86 0x08, 0xc1, 0x5a, 0xae, 0xff, 0xff, 0xff, 0xff,
87 0xff, 0x00, 0x01, 0x80, 0x00, 0x34, 0x1e, 0xe7,
88 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
89 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
90 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
91 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
92 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
93 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
94 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
95 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
96 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
97 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
98 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
99 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
100 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
101 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
102 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
103 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
104 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
105 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
106 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
107 0xff, 0xff, 0xff, 0xff };
108 readonly uint Constants::crc_table[] = {
109 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
110 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
111 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
112 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
113 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
114 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
115 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
116 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
117 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
118 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
119 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
120 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
121 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
122 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
123 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
124 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
125 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
126 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
127 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
128 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
129 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
130 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
131 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
132 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
133 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
134 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
135 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
136 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
137 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
138 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
139 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
140 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
141 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
142 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
143 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
144 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
145 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
146 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
147 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
148 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
149 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
150 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
151 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 };
153 pByte Utility::ToArray(const std::vector<byte> vctr)
155 pByte array = pByte(new byte[vctr.size()]);
156 for(int i = 0; i < vctr.size(); i++)
158 array[i] = vctr.at(i);
163 const int DATA_HEADER = 5;
164 StreamInfo::StreamInfo(pByte data, int index)throw(std::invalid_argument)
167 throw std::invalid_argument("stream data is NULL");
169 if(sizeof(data.get()) + index < DATA_HEADER)
170 throw std::invalid_argument("stream data too short");
172 uint descLength = (data[3 + index] & 0x0f) << 8 + data[4 + index];
174 if(descLength > Constants::TS_SIZE)
175 throw std::invalid_argument("descriptors data too long");
177 if(5 + descLength > sizeof(data.get()) - index)
179 throw std::invalid_argument("stream data too short");
182 mData = pByte(new byte[DATA_HEADER + descLength]);
183 for(int i = 0; i < sizeof(mData.get()); i++)
185 mData[i] = data[i + index];
188 SetVideoFormat(VF_Reserved);
189 SetAspectRatio(AR_Reserved);
190 SetFrameRate(FR_Reserved);
191 SetAudioPresentationType(AP_Reserved);
192 SetSamplingFrequency(SF_Reserved);
195 VideoFormat StreamInfo::GetVideoFormat(void)
200 void StreamInfo::SetVideoFormat(VideoFormat video_format)
202 mVideoFormat = video_format;
205 AspectRatio StreamInfo::GetAspectRatio(void)
210 void StreamInfo::SetAspectRatio(AspectRatio aspect_ratio)
212 mAspectRatio = aspect_ratio;
215 FrameRate StreamInfo::GetFrameRate(void)
220 void StreamInfo::SetFrameRate(FrameRate frame_rate)
222 mFrameRate = frame_rate;
225 AudioPresentationType StreamInfo::GetAudioPresentationType(void)
227 return mAudioPresentationType;
230 void StreamInfo::SetAudioPresentationType(AudioPresentationType ap_type)
232 mAudioPresentationType = ap_type;
235 SamplingFrequency StreamInfo::GetSamplingFrequency(void)
237 return mSamplingFrequency;
240 void StreamInfo::SetSamplingFrequency(SamplingFrequency sampling_frequency)
242 mSamplingFrequency = sampling_frequency;
245 StreamInfo::StreamInfo(ElementaryStreamTypes streamType, ushort elementaryPid)
247 mData = pByte(new byte[DATA_HEADER]);
248 SetElementaryStreamTypes(streamType);
249 SetElementaryPID(elementaryPid);
250 // reserved and descriptors length
255 pByte StreamInfo::GetByteData(void)
260 ElementaryStreamTypes StreamInfo::GetElementaryStreamTypes(void)
262 return (ElementaryStreamTypes)mData[0];
265 void StreamInfo::SetElementaryStreamTypes(ElementaryStreamTypes stream_type)
267 mData[0] = (byte)stream_type;
269 ushort StreamInfo::GetElementaryPID(void)
271 return (ushort)(((mData[1] & 0x1f) << 8) + mData[2]);
274 void StreamInfo::SetElementaryPID(ushort pid)
276 mData[1] = (byte)(((pid >> 8) & 0x1f) | 0xe0);
277 mData[2] = (byte)(pid & 0xff);
280 pByte StreamInfo::GetElementaryDescriptors(void)
283 if(sizeof(mData.get()) == DATA_HEADER)
289 descriptors = pByte(new byte[sizeof(mData.get()) - DATA_HEADER]);
290 for (int i = 0; i < (sizeof(mData.get()) - DATA_HEADER); i++)
292 descriptors[i] = mData[i + DATA_HEADER];
298 void StreamInfo::SetElementaryDescriptors(pByte value)
299 throw(std::invalid_argument)
301 if(!value || 0 == sizeof(value.get()))
303 if(sizeof(mData.get()) > DATA_HEADER)
305 // need to remove existing descriptors
306 pByte data = pByte(new byte[DATA_HEADER]);
322 if(sizeof(value.get()) > 180) {
323 throw std::invalid_argument("descriptors data too long");
326 pByte data = pByte(new byte[DATA_HEADER + sizeof(value.get())]);
330 data[3] = (byte)(0xf0 | (byte)((sizeof(value.get()) >> 8) & 0x0f));
331 data[4] = (byte)(sizeof(value.get()) & 0xff);
332 for (int i = 0; i < sizeof(value.get()); i++)
334 data[DATA_HEADER + i] = value[i];
340 ProgramInfo::ProgramInfo(pByte data, int index)throw(std::invalid_argument)
343 throw std::invalid_argument("program data is null");
345 if(sizeof(data.get()) + index < 4)
346 throw std::invalid_argument("program data too short");
348 mData = pByte(new byte[4]);
349 for(int i = 0; i < sizeof(mData.get()); i++)
351 mData[i] = data[i + index];
355 ProgramInfo::ProgramInfo(ushort programNumber, ushort programPid)
357 mData = pByte(new byte[4]);
358 SetProgramNumber(programNumber);
359 SetProgramPID(programPid);
362 ushort ProgramInfo::GetProgramNumber(void)
364 return (ushort)((mData[0] << 8) + mData[1]);
367 void ProgramInfo::SetProgramNumber(ushort value)
369 mData[0] = (byte)((value >> 8) & 0xff);
370 mData[1] = (byte)(value & 0xff);
373 ushort ProgramInfo::GetProgramPID(void)
375 return (ushort)(((mData[2] & 0x1f) << 8) + mData[3]);
378 void ProgramInfo::SetProgramPID(ushort value)
380 mData[2] = (byte)(((value >> 8) & 0x1f) | 0xe0);
381 mData[3] = (byte)(value & 0xff);
384 pByte ProgramInfo::GetData(void)
389 ElementaryParse::ElementaryParse(void)
394 byte ElementaryParse::GetNextBit(void)
396 byte ret = (byte)(((mData[indicator / 8]) >> (7 - (indicator % 8))) & 1);
401 TsPacket::TsPacket(void)
403 // initialize the packet as a null packet
404 mData = pByte(new byte[Constants::TS_SIZE]);
405 mData[0] = Constants::SYNC_BYTE; // sync byte
406 mData[1] = 0x1f; // PID = 0x1FFF
407 mData[2] = 0xff; // PID == 0x1FFF
408 mData[3] = 0x10; // no adaptation field
409 for (int i = 4; i < Constants::TS_SIZE; i++)
413 bool TsPacket::GetPriority(void)
415 if ((mData[1] & 0x20) > 0)
421 void TsPacket::SetPriority(bool priority)
429 ushort TsPacket::GetPID(void)
431 return (ushort)(((mData[1] & 0x1f) << 8) + mData[2]);
433 void TsPacket::SetPID(ushort pid)
435 byte b = (byte)(mData[1] & 0xE0);
436 b += (byte)((pid >> 8) & 0x1f);
438 mData[2] = (byte)(pid & 0xff);
441 byte TsPacket::GetPointerSize(void)
443 if ((mData[3] & 0x20) == 0) // No adaptation field present
445 return (byte)(mData[4] + 1 + mData[mData[4] + DATA_HEADER]);
448 pByte TsPacket::GetData(void)
453 void TsPacket::SetData(pByte data, int startIndex)throw(std::invalid_argument)
456 throw std::invalid_argument("NULL packet");
457 else if (Constants::TS_SIZE > sizeof(data.get()) - startIndex)
458 throw std::invalid_argument("small packet");
459 else if (Constants::SYNC_BYTE != data[0 + startIndex])
460 throw std::invalid_argument("sync byte missing");
461 for (int i = 0; i < Constants::TS_SIZE; i++) {
462 mData[i] = data[i + startIndex];
465 bool TsPacket::HasPcr(void)
467 if ((mData[3] & 0x20) > 0 // Adaptation field present
468 && (mData[4] > 0) // length > 0
469 && (mData[DATA_HEADER] & 0x10) > 0) // and a PCR
473 Int64 TsPacket::GetPcr(void)throw(std::out_of_range)
475 if (false == this->HasPcr())
476 throw std::out_of_range("PCR not present in this packet");
477 Int64 mpeg2tsClock = mData[6];
479 mpeg2tsClock += (mData[7] << 17);
480 mpeg2tsClock += (mData[8] << 9);
481 mpeg2tsClock += (mData[9] << 1);
482 mpeg2tsClock += ((mData[10] & 0x80) >> 7);
484 mpeg2tsClock += ((mData[10] & 0x1) << 8);
485 mpeg2tsClock += (mData[11]);
489 bool TsPacket::HasPesHeader(void)
491 if ((mData[1] & 0x40) == 0)
494 if ((mData[3] & 0x20) > 0)
496 // adaptation field present
497 offset += (1 + mData[4]);
498 if (offset >= Constants::TS_SIZE)
501 if ((mData[3] & 0x10) > 0)
504 int len = Constants::TS_SIZE - offset;
508 if(mData[offset] == 0
509 && mData[offset + 1] == 0
510 && mData[offset + 2] == 1
511 && len >= 9 + mData[offset + 8])
513 else if(mData[offset] == 0
514 && mData[offset + 1] == 0
515 && mData[offset + 2] == 1)
521 pByte TsPacket::Payload(void)
526 if ((mData[3] & 0x20) > 0)
528 // adaptation field present
529 offset += (1 + mData[4]);
530 if (offset >= Constants::TS_SIZE)
533 if ((mData[3] & 0x10) > 0)
536 ret = pByte(new byte[Constants::TS_SIZE - offset]);
537 for (int i = 0; i < sizeof(ret); i++)
538 ret[i] = mData[i + offset];
539 ret[Constants::TS_SIZE - offset] = '\0';
545 void TsPacket::IncrementContinuityCounter(void)
547 if (0xf == (mData[3] & 0xf))
553 byte TsPacket::GetContinuityCounter(void)
555 return (byte)(mData[3] & 0xf);
558 void TsPacket::SetContinuityCounter(byte value)throw(std::out_of_range)
561 throw std::out_of_range("Invalid continuity counter");
566 TsTable::TsTable(void)
568 // error = 0, payload = 1, priority = 0
570 // scrambling = 0, adaptation = 01, continuity = 0
574 // reserved, version, current/next
582 TsTable::TsTable(pByte data)
587 void TsTable::AddData(pByte value, int offset, int len)
589 pByte data = pByte(new byte[sizeof(mData.get()) + len]);
590 memcpy(reinterpret_cast<char*>(data.get()),
591 reinterpret_cast<char*>(mData.get()),
592 sizeof(mData.get()));
593 memcpy(reinterpret_cast<char*>(data.get() + sizeof(mData.get())),
594 reinterpret_cast<char*>(value.get() + offset),
599 bool TsTable::Complete(void)
601 int currentLen = sizeof(mData.get()) - (GetPointerSize() + 8);
602 if (GetLength() > currentLen)
607 byte TsTable::GetTableId(void)
609 return mData[DATA_HEADER + GetPointerSize()];
612 void TsTable::SetTableId(byte value)
614 mData[DATA_HEADER + GetPointerSize()] = value;
617 ushort TsTable::GetNumberId(void)
619 return (ushort)((mData[8 + GetPointerSize()] << 8)
620 + mData[9 + GetPointerSize()]);
623 void TsTable::SetNumberId(ushort value)
625 mData[8 + GetPointerSize()] = (byte)((value >> 8) & 0xff);
626 mData[9 + GetPointerSize()] = (byte)(value & 0xff);
629 ushort TsTable::GetLength(void)
631 return (ushort)(((mData[6 + GetPointerSize()] & 0x0f) << 8)
632 + mData[7 + GetPointerSize()]);
635 void TsTable::SetLength(ushort value)
637 // syntax, reserved, length
638 mData[6 + GetPointerSize()]
639 = (byte)(0xb0 | (byte)((value >> 8) & 0x0f));
640 mData[7 + GetPointerSize()] = (byte)(value & 0xff);
643 void TsTable::RefreshCrc(void)
645 uint crc = Constants::ComputeCrc(
646 mData, GetLength() - 1, DATA_HEADER + GetPointerSize());
647 mData[GetLength() + 4 + GetPointerSize()]
648 = (byte)((crc >> 24) & 0xff);
649 mData[GetLength() + DATA_HEADER + GetPointerSize()]
650 = (byte)((crc >> 16) & 0xff);
651 mData[GetLength() + 6 + GetPointerSize()]
652 = (byte)((crc >> 8) & 0xff);
653 mData[GetLength() + 7 + GetPointerSize()]
654 = (byte)(crc & 0xff);
655 for (int i = GetLength() + 8 + GetPointerSize();
656 i < Constants::TS_SIZE; i++) {
661 Descriptor::Descriptor(pByte data, int startIndex)throw(std::invalid_argument)
663 if (sizeof(data.get()) < 2)
664 throw std::invalid_argument("Invalid descriptor");
666 if (startIndex + 2 + data[startIndex + 1]
667 > strlen(reinterpret_cast<char*>(data.get())))
668 throw std::invalid_argument("Invalid descriptor");
670 mData = pByte(new byte[2 + data[startIndex + 1]]);
671 for (int i = 0; i < sizeof(mData.get()); i++)
672 mData[i] = data[i + startIndex];
675 byte Descriptor::GetTag(void)
680 byte Descriptor::GetLength(void)
685 pByte Descriptor::GetData(void)
690 PcrPacket::PcrPacket(Int64 pcr, byte counter, ushort pid)
693 SetContinuityCounter(counter);
694 mData[3] &= 0x0f; // adaptation field only, no payload
695 mData[3] |= 0x20; // adaptation field only, no payload
696 mData[4] = 183; // length
697 mData[DATA_HEADER] = 0x10; // only PCR present
698 Int64 tsClockValue = pcr / 300;
699 Int64 tsOffsetValue = pcr % 300;
700 mData[6] = (byte)((tsClockValue & 0x1fe000000LL) >> 25);
701 mData[7] = (byte)((tsClockValue & 0x1fe0000) >> 17);
702 mData[8] = (byte)((tsClockValue & 0x1fe00) >> 9);
703 mData[9] = (byte)((tsClockValue & 0x1fe) >> 1);
704 if ((tsClockValue & 0x1) == 0)
706 if ((tsOffsetValue & 0x100) == 0)
708 mData[11] = (byte)(tsOffsetValue & 0xff);
709 for (int i = 12; i < Constants::TS_SIZE; i++)
713 PesPacket::PesPacket(pByte buff, int offset, int length, ushort pid)
715 mData = pByte(new byte[length]);
717 AddData(buff, offset, length);
721 bool PesPacket::GetPriority(void)
726 void PesPacket::SetPriority(bool value)
731 pByte PesPacket::GetData(void)
736 pByte PesPacket::GetPayload(void)
738 boost::shared_ptr<PesHeader> ph = GetHeader();
739 if(!ph) return GetData();
741 new byte[sizeof(mData.get()) - 9 + ph.get()->GetHeaderLength() + 1]);
742 for(int i=(9 + ph.get()->GetHeaderLength()); i < sizeof(mData.get()); i++)
744 buff[sizeof(mData.get()) - (9 + ph.get()->GetHeaderLength())] = '\0';
748 byte PesPacket::GetByte(int i)
753 void PesPacket::SetByte(int i, byte value)
758 ushort PesPacket::GetPID(void)
763 void PesPacket::SetPID(ushort id)
768 bool PesPacket::GetComplete(void)
770 if(sizeof(mData.get()) < 6) return false;
771 ushort len = (ushort)((mData[4] << 8) + mData[DATA_HEADER]);
772 if(len == 0) return false;
773 if(sizeof(mData.get()) != len + 6) return false;
777 void PesPacket::SetComplete(bool value)
781 ushort len = (ushort)(sizeof(mData.get()) - 6);
782 if (sizeof(mData.get()) > (0xffff - 6))
784 mData[4] = (byte)((len >> 8) & 0xff);
785 mData[DATA_HEADER] = (byte)(len & 0xff);
789 boost::shared_ptr<PesHeader> PesPacket::GetHeader(void)
791 boost::shared_ptr<PesHeader> ph;
794 ph = boost::shared_ptr<PesHeader>(new PesHeader(mData));
799 // no valid header (yet)
805 void PesPacket::AddData(pByte moredata)
807 pByte data = pByte(new byte[sizeof(mData.get()) + sizeof(moredata.get())]);
808 memcpy(reinterpret_cast<char*>(data.get()),
809 reinterpret_cast<char*>(mData.get()),
810 sizeof(mData.get()));
811 memcpy(reinterpret_cast<char*>(data.get() + sizeof(mData.get())),
812 reinterpret_cast<char*>(mData.get()),
813 sizeof(mData.get()));
817 void PesPacket::AddData(pByte buff, int offset, int len)
819 pByte data = pByte(new byte[sizeof(mData.get()) + len]);
820 memcpy(reinterpret_cast<char*>(data.get()),
821 reinterpret_cast<char*>(mData.get()),
822 sizeof(mData.get()));
823 memcpy(reinterpret_cast<char*>(data.get() + sizeof(mData.get())),
824 reinterpret_cast<char*>(mData.get() + offset),
829 byte PesPacket::GetBaseId(void)
831 if (sizeof(mData.get()) > 3)
836 byte PesPacket::GetExtendedId(void)
838 if ((sizeof(mData.get()) > 8) && sizeof(mData.get()) > (8 + mData[8]))
839 return mData[9 + mData[8]];
843 UInt32 PesPacket::GetExtendedType(void)
845 if ((sizeof(mData.get()) > 8) && sizeof(mData.get()) > (11 + mData[8]))
847 UInt32 format = (UInt32)mData[9 + mData[8]] << 24;
848 format += (UInt32)mData[10 + mData[8]] << 16;
849 format += (UInt32)mData[11 + mData[8]] << 8;
850 format += (UInt32)mData[12 + mData[8]];
856 PesHeader::PesHeader(pByte data)throw(std::invalid_argument)
858 if (sizeof(data.get()) < 9)
859 throw std::invalid_argument("Invalid PES header length");
860 if (data[0] != 0x00 || data[1] != 0x00 || data[2] != 0x01)
861 throw std::invalid_argument("Invalid PES prefix");
862 int hlen = 9 + data[8];
863 int plen = 6 + (data[4] << 8) + data[DATA_HEADER];
864 if (plen != 6 && hlen > plen)
865 throw new std::invalid_argument("Invalid PES header/packet length");
866 if (sizeof(data.get()) < hlen)
867 throw std::invalid_argument("PES Header too short");
868 mData = pByte(new byte[hlen]);
869 for (int i = 0; i < hlen; i++)
873 byte PesHeader::GetStreamId(void)
878 byte PesHeader::GetByte(int i)
883 void PesHeader::SetByte(int i, byte data)
888 byte PesHeader::GetHeaderLength(void)
893 int PesHeader::GetTotalHeaderLength(void)
895 return 9 + GetHeaderLength();
898 ushort PesHeader::GetPacketLength(void)
900 return (ushort)((mData[4] << 8) + mData[DATA_HEADER]);
903 bool PesHeader::HasPts(void)
905 if(sizeof(mData.get()) > 13)
906 return (mData[7] & 0x80) > 0;
910 bool PesHeader::HasDts(void)
912 if(sizeof(mData.get()) > 18 )
913 return (mData[7] & 0x40) > 0;
917 Int64 PesHeader::GetPts(void)throw(std::invalid_argument)
919 if (HasPts() == false)
920 throw std::invalid_argument("No Pts available");
922 ret += ((Int64)(mData[9] & 0x0e)) << 29;
923 ret += ((Int64)(mData[10])) << 22;
924 ret += ((Int64)(mData[11] & 0xfe)) << 14;
925 ret += ((Int64)(mData[12])) << 7;
926 ret += ((Int64)(mData[13] & 0xfe)) >> 1;
930 void PesHeader::SetPts(Int64 value)throw(std::invalid_argument)
932 if (HasPts() == false)
933 throw std::invalid_argument("No Pts available");
934 byte old = (byte)(mData[9] & 0xf1);
935 mData[9] = (byte)(((value & 0x1C0000000LL) >> 29) | old);
936 mData[10] = (byte)((value & 0x3fC00000LL) >> 22);
937 mData[11] = (byte)(((value & 0x3f8000LL) >> 14) | 0x01);
938 mData[12] = (byte)((value & 0x7f80LL) >> 7);
939 mData[13] = (byte)(((value & 0x7fLL) << 1) | 0x01);
942 Int64 PesHeader::GetDts(void)throw(std::invalid_argument)
944 if (HasDts() == false)
945 throw std::invalid_argument("No Dts available");
947 ret += ((Int64)(mData[14] & 0x0e)) << 29;
948 ret += ((Int64)(mData[15])) << 22;
949 ret += ((Int64)(mData[16] & 0xfe)) << 14;
950 ret += ((Int64)(mData[17])) << 7;
951 ret += ((Int64)(mData[18] & 0xfe)) >> 1;
955 void PesHeader::SetDts(Int64 value)throw(std::invalid_argument)
957 if (HasDts() == false)
958 throw std::invalid_argument("No Dts available");
959 byte old = (byte)(mData[14] & 0xf1);
960 mData[14] = (byte)(((value & 0x1C0000000LL) >> 29) | old);
961 mData[15] = (byte)((value & 0x3fC00000LL) >> 22);
962 mData[16] = (byte)(((value & 0x3f8000LL) >> 14) | 0x01);
963 mData[17] = (byte)((value & 0x7f80LL) >> 7);
964 mData[18] = (byte)(((value & 0x7fLL) << 1) | 0x01);
967 byte PesHeader::GetExtention2(void)
970 if((mData[offset] & 0xc0) != 0x80)
971 return 0; // first two bits must be '10'
972 byte PTS_DTS_flags = (byte)(mData[offset + 1] & 0xc0);
973 byte ESCR_flag = (byte)(mData[offset + 1] & 0x20);
974 byte ES_rate_flag = (byte)(mData[offset + 1] & 0x10);
975 byte DSM_trick_mode_flag = (byte)(mData[offset + 1] & 0x08);
976 byte additional_copy_info_flag = (byte)(mData[offset + 1] & 0x04);
977 byte PES_CRC_flag = (byte)(mData[offset + 1] & 0x02);
978 byte PES_extension_flag = (byte)(mData[offset + 1] & 0x01);
979 if(mData[offset + 2] == 0)
981 int length = offset + mData[offset + 2] + 3;
982 if(sizeof(mData.get()) < length)
985 if(PTS_DTS_flags == 0x80)
987 if(PTS_DTS_flags == 0xc0)
993 if(DSM_trick_mode_flag > 0)
995 if(additional_copy_info_flag > 0)
999 if(PES_extension_flag == 0)
1001 byte PES_private_data_flag = (byte)(mData[offset] & 0x80);
1002 byte pack_header_field_flag = (byte)(mData[offset] & 0x40);
1003 byte program_packet_sequence_counter_flag
1004 = (byte)(mData[offset] & 0x20);
1005 byte PSTD_mDataer_flag = (byte)(mData[offset] & 0x10);
1006 byte PES_extension_flag_2 = (byte)(mData[offset] & 0x01);
1008 if(PES_private_data_flag > 0)
1010 if(pack_header_field_flag > 0)
1011 offset += (mData[offset] + 1);
1012 if(program_packet_sequence_counter_flag > 0)
1014 if(PSTD_mDataer_flag > 0)
1016 if(PES_extension_flag_2 == 0)
1018 if(mData[offset] != 0x81)
1020 return mData[offset + 1];
1023 pByte PesHeader::GetData(void)
1028 VC1SequenceInfo::VC1SequenceInfo(pByte data, int offset)
1030 UInt32 marker = 0xffffffff;
1031 for(; offset < sizeof(data.get()); offset++)
1033 marker = marker << 8;
1034 marker &= 0xffffff00;
1035 marker += data[offset];
1036 if(marker == Constants::VC1_SEQ_SC)
1040 if(offset < sizeof(data.get()))
1043 mData = pByte(new byte[sizeof(data.get()) - offset]);
1044 for(int i = 0; offset < sizeof(data.get()); i++, offset++)
1045 mData[i] = data[offset];
1051 int VC1SequenceInfo::GetHeight(void)
1053 if(!mData && sizeof(mData.get()) > 4)
1054 return ((((mData[3] & 0x0f) << 8) + mData[4]) << 1) + 2;
1059 int VC1SequenceInfo::GetWidth(void)
1061 if(!mData && sizeof(mData.get()) > 3)
1062 return (((mData[2] << 4) + ((mData[3] & 0xf0) >> 4)) << 1) + 2;
1067 bool VC1SequenceInfo::Valid(void)
1072 bool VC1SequenceInfo::Interlaced(void)
1074 if(!mData && sizeof(mData.get()) > DATA_HEADER)
1075 return ((mData[DATA_HEADER] & 0x40) > 0);
1079 bool VC1SequenceInfo::DisplayExt(void)
1081 if(!mData && sizeof(mData.get()) > DATA_HEADER)
1082 return ((mData[DATA_HEADER] & 0x02) > 0);
1086 bool VC1SequenceInfo::AspectFlag(void)
1088 if(DisplayExt() && sizeof(mData.get()) > 9)
1089 return ((mData[9] & 0x10) > 0);
1093 byte VC1SequenceInfo::GetVc1AspectRatio(void)
1095 if(AspectFlag() && sizeof(mData.get()) > 9)
1096 return (byte)(mData[9] & 0x0f);
1100 bool VC1SequenceInfo::FrameFlag(void)
1104 if(GetVc1AspectRatio() == 15 && sizeof(mData.get()) > 12)
1105 return ((mData[12] & 0x80) > 0);
1106 else if(GetVc1AspectRatio() != 15 && sizeof(mData.get()) > 10)
1107 return ((mData[10] & 0x80) > 0);
1111 else if(sizeof(mData.get()) > 9)
1112 return ((mData[9] & 0x08) > 0);
1117 bool VC1SequenceInfo::FrameRateIndicatorFlag(void)
1123 if (GetVc1AspectRatio() == 15 && sizeof(mData.get()) > 12)
1124 return ((mData[12] & 0x40) > 0);
1125 else if (GetVc1AspectRatio() != 15 && sizeof(mData.get()) > 10)
1126 return ((mData[10] & 0x40) > 0);
1130 else if (sizeof(mData.get()) > 9)
1131 return ((mData[9] & 0x04) > 0);
1139 AspectRatio VC1SequenceInfo::GetAspectRatio(void)
1141 if(GetVc1AspectRatio() == 1)
1143 if(GetWidth() == 1920 && GetHeight() == 1080)
1145 if(GetWidth() == 1280 && GetHeight() == 720)
1147 if(GetWidth() == 640 && GetHeight() == 480)
1150 if(GetVc1AspectRatio() >= 2 && GetVc1AspectRatio() <= 5)
1152 if(GetVc1AspectRatio() >= 6 && GetVc1AspectRatio() <= 9)
1154 if(GetVc1AspectRatio() >= 10 && GetVc1AspectRatio() <= 11)
1156 if(GetVc1AspectRatio() >= 12 && GetVc1AspectRatio() <= 13)
1161 VideoFormat VC1SequenceInfo::GetVideoFormat(void)
1163 if (GetHeight() == 480 && Interlaced() == true)
1165 else if (GetHeight() == 480 && Interlaced() == false)
1167 else if (GetHeight() == 576 && Interlaced() == true)
1169 else if (GetHeight() == 576 && Interlaced() == false)
1171 else if (GetHeight() == 720 && Interlaced() == false)
1173 else if (GetHeight() == 1080 && Interlaced() == true)
1175 else if (GetHeight() == 1080 && Interlaced() == false)
1180 FrameRate VC1SequenceInfo::GetFrameRate(void)
1182 if(false == FrameFlag())
1184 if(false == FrameRateIndicatorFlag())
1186 byte FrameRateNr = 0;
1187 byte FrameRateDr = 0;
1190 if(GetVc1AspectRatio() == 15 && sizeof(mData.get()) > 13)
1192 FrameRateNr = (byte)(((mData[12] & 0x3f) << 2)
1193 + ((mData[13] & 0xc0) >> 6));
1194 FrameRateDr = (byte)((mData[13] & 0x3c) >> 2);
1196 else if(GetVc1AspectRatio() != 15 && sizeof(mData.get()) > 11)
1198 FrameRateNr = (byte)(((mData[10] & 0x3f) << 2)
1199 + ((mData[11] & 0xc0) >> 6));
1200 FrameRateDr = (byte)((mData[11] & 0x3c) >> 2);
1203 else if(sizeof(mData.get()) > 11)
1205 FrameRateNr = (byte)(((mData[9] & 0x03) << 6)
1206 + ((mData[10] & 0xfc) >> 2));
1207 FrameRateDr = (byte)(((mData[10] & 0x03) << 2)
1208 + ((mData[11] & 0xc0) >> 6));
1211 if(FrameRateNr == 1 && FrameRateDr == 2)
1213 else if(FrameRateNr == 1 && FrameRateDr == 1)
1215 else if(FrameRateNr == 2 && FrameRateDr == 1)
1217 else if(FrameRateNr == 3 && FrameRateDr == 2)
1219 else if(FrameRateNr == 4 && FrameRateDr == 1)
1221 else if(FrameRateNr == 5 && FrameRateDr == 2)
1227 // implement class PatPacket : TsTable
1228 PatPacket::PatPacket(void)
1230 SetPID(Constants::PAT_PID);
1231 SetTableId(Constants::PAT_TABLE_ID);
1233 SetTransportStreamId(1);
1237 PatPacket::PatPacket(pByte data)throw(std::invalid_argument)
1239 if(GetTableId() != Constants::PAT_TABLE_ID)
1240 throw std::invalid_argument(
1241 "packet does not contain a valid PAT table ID");
1243 throw std::invalid_argument("packet does not contain a valid PAT PID");
1246 ushort PatPacket::GetTransportStreamId(void)
1248 return GetNumberId();
1251 void PatPacket::SetTransportStreamId(ushort value)
1257 boost::shared_array<ProgramInfo> PatPacket::GetPrograms(void)
1259 boost::shared_array<ProgramInfo> programs;
1261 if (GetProgramInfoLength() == 0)
1263 programs = boost::shared_array(new ProgramInfo[GetProgramInfoLength() / 4]);
1264 for (int i = 0; i < GetProgramInfoLength(); i += 4)
1265 programs[i / 4] = boost::shared_array<ProgramInfo>(
1266 new ProgramInfo(mData, 13 + GetPointerSize() + i));
1270 void PatPacket::SetPrograms(boost::shared_ptr<ProgramInfo> value)
1271 throw(std::invalid_argument)
1273 if (NULL == value || sizeof(value.get()) == 0)
1275 if (GetProgramInfoLength() == 0)
1282 if ((sizeof(value.get()) * 4) + 17 + GetPointerSize()
1283 > Constants.TS_SIZE)
1284 throw std::invalid_argument("program info data too long");
1285 SetLength((ushort)(9 + (sizeof(value.get()) * 4)));
1286 int index = 13 + GetPointerSize();
1287 for(int pi = 0; pi < GetProgramInfoLength() / 4; pi++)
1289 for (int i = 0; i < 4; i++)
1290 mData[index + i] = value[pi].Data[i];
1297 ushort PatPacket::GetProgramInfoLength(void)
1299 return (ushort)(GetLength() - 9);
1302 DTCP_Descriptor::DTCP_Descriptor(pByte data, int startIndex)
1303 throw(std::invalid_argument):Descriptor(data, startIndex)
1305 if (sizeof(data.get()) < 6)
1306 throw std::invalid_argument("Invalid DTCP descriptor");
1307 if (GetTag() != Constants::DTCP_DESCRIPTOR_TAG)
1308 throw std::invalid_argument("Invalid DTCP descriptor tag");
1309 if (GetLength() < 4)
1310 throw std::invalid_argument("Invalid DTCP descriptor length");
1311 if (data[startIndex + 2] != 0x0f || data[startIndex + 3] != 0xff)
1312 throw std::invalid_argument("Invalid DTCP descriptor CA system ID");
1315 DtcpCci DTCP_Descriptor::GetCopyStatus(void)
1317 return (DtcpCci)(mData[4] & 0x3);
1320 bool DTCP_Descriptor::GetAnalogConstrain(void)
1322 return ((mData[5] & 0x4) == 0);
1325 bool DTCP_Descriptor::GetMacrovision(void)
1327 return ((mData[5] & 0x3) > 0);
1330 MlpInfo::MlpInfo(pByte data, int offset)
1332 UInt32 marker = 0xffffffff;
1333 for (; offset < sizeof(data.get()); offset++)
1335 marker = (UInt32)marker << 8;
1336 marker &= 0xffffff00;
1337 marker += data[offset];
1338 if (marker == Constants::MLP_SYNC)
1342 if (offset < sizeof(data.get()))
1345 mData = pByte(new byte[sizeof(data.get()) - offset]);
1346 for (int i = 0; offset < sizeof(data.get()); i++, offset++)
1347 mData[i] = data[offset];
1353 AspectRatio MlpInfo::GetAspectRatio(void)
1358 FrameRate MlpInfo::GetFrameRate(void)
1363 VideoFormat MlpInfo::GetVideoFormat(void)
1368 pByte MlpInfo::GetElementaryDescriptors(void)
1370 std::vector<byte> descriptors;
1371 for(int i = 0; i < sizeof(Constants::ac3_registration_descriptor); i++)
1373 descriptors.push_back(Constants::ac3_registration_descriptor[i]);
1375 pByte ad = GetAC3AudioDescriptor();
1376 for(int i = 0; i < sizeof(ad.get()); i++)
1378 descriptors.push_back(ad[i]);
1380 return Utility::ToArray(descriptors);
1383 AudioPresentationType MlpInfo::GetAudioPresentationType(void)
1388 SamplingFrequency MlpInfo::GetSamplingFrequency(void)
1390 switch (GetSampleRateCode())
1400 case 10: // 176.4kHz
1406 pByte MlpInfo::GetAC3AudioDescriptor(void)
1408 std::vector<byte> desc;
1409 desc.push_back(0x81);
1410 desc.push_back(0x00);
1411 desc.push_back((byte)((GetSampleRateCode() << 5) | 0x08));
1412 desc.push_back(200);
1413 desc.push_back((byte)(0x0f));
1414 desc[1] = (byte)(desc.size() - 2);
1415 return Utility::ToArray(desc);
1418 byte MlpInfo::GetSampleRateCode(void)
1420 if (sizeof(mData.get()) > 0)
1421 return (byte)(mData[0] >> 4);
1425 // implement class AC3Info : ElementaryParse
1426 readonly int AC3Info::len48k[] = {
1427 128, 128, 160, 160, 192, 192, 224, 224,
1428 256, 256, 320, 320, 384, 384, 448, 448,
1429 512, 512, 640, 640, 768, 768, 896, 896,
1430 1024, 1024, 1280, 1280, 1536, 1536, 1792, 1792,
1431 2048, 2048, 2304, 2304, 2560, 2560 };
1433 readonly int AC3Info::len44k[] = {
1434 138, 140, 174, 176, 208, 210, 242, 244,
1435 278, 280, 348, 350, 416, 418, 486, 488,
1436 556, 558, 696, 698, 834, 836, 974, 976,
1437 1114, 1116, 1392, 1394, 1670, 1672, 1950, 1952,
1438 2228, 2230, 2506, 2508, 2786, 2788 };
1440 readonly int AC3Info::len32k[] = {
1441 192, 192, 240, 240, 288, 288, 336, 336,
1442 384, 384, 480, 480, 576, 576, 672, 672,
1443 768, 768, 960, 960, 1152, 1152, 1344, 1344,
1444 1536, 1536, 1920, 1920, 2304, 2304, 2688, 2688,
1445 3072, 3072, 3456, 3456, 3840, 3840 };
1447 int AC3Info::GetMaxFrameLength(void)
1449 return len32k[sizeof(len32k) - 1];
1452 int AC3Info::GetFrameLength(void)
1454 if(GetSyntaxType() == Standard
1455 || GetSyntaxType() == Alternative)
1457 byte index = (byte)(mData[2] & 0x3f);
1460 switch (GetSampleRateCode())
1463 return len48k[mData[2] & 0x3f];
1465 return len44k[mData[2] & 0x3f];
1467 return len32k[mData[2] & 0x3f];
1471 else if (GetSyntaxType() == Enhanced)
1472 return (((mData[0] & 0x03) << 8) + mData[1] + 1) << 1;
1476 bool AC3Info::Valid(void)
1478 return mValid && GetSyntaxType() != Invalid;
1481 byte AC3Info::GetSampleRateCode(void)
1483 if (sizeof(mData.get()) > 2)
1484 return (byte)(mData[2] >> 6);
1488 byte AC3Info::GetBsid(void)
1490 if (sizeof(mData.get()) > 3)
1491 return (byte)(mData[3] >> 3);
1495 byte AC3Info::GetBsmod(void)
1497 if (sizeof(mData.get()) > 3
1498 && (GetSyntaxType() == Standard
1499 || GetSyntaxType() == Alternative))
1500 return (byte)(mData[3] & 0x07);
1504 byte AC3Info::GetAcmod(void)
1506 if (sizeof(mData.get()) > 4
1507 && (GetSyntaxType() == Standard
1508 || GetSyntaxType() == Alternative))
1509 return (byte)(mData[4] >> 5);
1510 else if (sizeof(mData.get()) > 2
1511 && GetSyntaxType() == Enhanced)
1512 return (byte)((mData[2] >> 1) & 0x07);
1516 bool AC3Info::IsIndependentStream(void)
1518 if (Enhanced != GetSyntaxType())
1520 byte res = (byte)(mData[0] >> 6);
1526 Ac3SyntaxType AC3Info::GetSyntaxType(void)
1530 case (byte)Standard:
1532 case (byte)Alternative:
1534 case (byte)Enhanced:
1540 pByte AC3Info::GetAC3AudioDescriptor(void)
1542 std::vector<byte> desc;
1543 desc.push_back(0x81);
1544 desc.push_back((byte)(desc.size() - 2));
1545 desc.push_back((byte)((GetSampleRateCode() << 5) | GetBsid()));
1546 desc.push_back(200);
1547 desc.push_back((byte)((GetBsmod() << 5) | (GetAcmod() << 1) | 1));
1548 return Utility::ToArray(desc);
1551 AC3Info::AC3Info(pByte data, int offset)
1553 ushort marker = 0xffff;
1554 for (; offset < sizeof(data.get()); offset++)
1556 marker = (ushort)(marker << 8);
1558 marker += data[offset];
1559 if (marker == Constants::AC3_SYNC)
1563 if (offset < sizeof(data.get()))
1566 mData = pByte(new byte[sizeof(data.get()) - offset]);
1567 for (int i = 0; offset < sizeof(data.get()); i++, offset++)
1568 mData[i] = data[offset];
1574 AudioPresentationType AC3Info::GetAudioPresentationType(void)
1589 SamplingFrequency AC3Info::GetSamplingFrequency(void)
1591 switch (GetSampleRateCode())
1599 pByte AC3Info::GetElementaryDescriptors(void)
1601 std::vector<byte> descriptors;
1602 for(int i = 0; i < sizeof(Constants::ac3_registration_descriptor); i++)
1604 descriptors.push_back(Constants::ac3_registration_descriptor[i]);
1606 pByte ac3ad = GetAC3AudioDescriptor();
1607 for(int j = 0; j < sizeof(ac3ad.get()); j++)
1609 descriptors.push_back(ac3ad[j]);
1611 return Utility::ToArray(descriptors);
1614 AspectRatio AC3Info::GetAspectRatio(void)
1619 FrameRate AC3Info::GetFrameRate(void)
1624 VideoFormat AC3Info::GetVideoFormat(void)
1629 // implement class DtsInfo : ElementaryParse
1630 DtsInfo::DtsInfo(pByte data, int offset)
1632 UInt32 marker = 0xffffffff;
1633 for(; offset < sizeof(data.get()); offset++)
1635 marker = (UInt32)marker << 8;
1636 marker &= 0xffffff00;
1637 marker += data[offset];
1638 if(marker == Constants::DTS_SYNC)
1642 if(offset < sizeof(data.get()))
1645 mData = pByte(new byte[sizeof(data.get()) - offset]);
1646 for(int i = 0; offset < sizeof(data.get()); i++, offset++)
1647 mData[i] = data[offset];
1653 ushort DtsInfo::GetFrameSize(void)
1657 for (int i = 0; i < 14; i++)
1660 ret |= GetNextBit();
1666 byte DtsInfo::GetAmode(void)
1670 for (int i = 0; i < 6; i++)
1673 ret |= GetNextBit();
1679 byte DtsInfo::GetSamplingFrequency(void)
1683 for (int i = 0; i < 4; i++)
1686 ret |= GetNextBit();
1692 bool DtsInfo::GetExtAudio(void)
1695 if (1 == GetNextBit())
1700 byte DtsInfo::GetExtAudioId(void)
1702 if (false == GetExtAudio())
1706 for (int i = 0; i < 3; i++)
1709 ret |= GetNextBit();
1714 AudioPresentationType DtsInfo::GetAudioPresentationType(void)
1730 SamplingFrequency DtsInfo::GetSamplingFrequency(void)
1732 switch (mSamplingFrequency)
1740 pByte DtsInfo::GetElementaryDescriptors(void)
1742 // DTS registration descriptor
1743 pByte regdesc = pByte(new byte[6]);
1749 if(sizeof(mData.get()) < 0x400)
1751 else if(sizeof(mData.get()) < 0x800)
1758 AspectRatio DtsInfo::GetAspectRatio(void)
1763 FrameRate DtsInfo::GetFrameRate(void)
1768 VideoFormat DtsInfo::GetVideoFormat(void)
1774 // implement class Mpeg2Info : ElementaryParse
1775 Mpeg2Info::Mpeg2Info(void)
1777 private class Mpeg2Ext : ElementaryParse
1779 public Mpeg2Ext(byte[] data, int offset)
1782 UInt32 marker = 0xffffffff;
1783 for (; offset < data.Length - 1; offset++)
1785 marker = (UInt32)marker << 8;
1786 marker &= 0xffffff00;
1787 marker += data[offset];
1788 if (marker == Constants.MPEG2_SEQ_EXT)
1790 if((data[offset + 1] & 0xf0) == 0x10)
1795 if (offset < data.Length)
1798 mData = new byte[data.Length - offset];
1799 for (int i = 0; offset < data.Length; i++, offset++)
1800 mData[i] = data[offset];
1806 public override AspectRatio AspectRatio
1808 get { throw new Exception("The method or operation is not implemented."); }
1810 public override AudioPresentationType AudioPresentationType
1812 get { throw new Exception("The method or operation is not implemented."); }
1814 public override byte[] ElementaryDescriptors
1816 get { throw new Exception("The method or operation is not implemented."); }
1818 public override FrameRate FrameRate
1820 get { throw new Exception("The method or operation is not implemented."); }
1822 public override SamplingFrequency SamplingFrequency
1824 get { throw new Exception("The method or operation is not implemented."); }
1826 public override VideoFormat VideoFormat
1828 get { throw new Exception("The method or operation is not implemented."); }
1830 public bool Progressive
1835 if (GetNextBit() == 1)
1841 Mpeg2Info::Mpeg2Info(pByte data, int offset)
1843 UInt32 marker = 0xffffffff;
1844 int oldOffset = offset;
1845 for (; offset < sizeof(data.get()); offset++)
1847 marker = (UInt32)marker << 8;
1848 marker &= 0xffffff00;
1849 marker += data[offset];
1850 if (marker == Constants::MPEG2_SEQ_CODE)
1854 if(offset < sizeof(data.get()))
1857 mData = pByte(new byte[sizeof(data.get()) - offset]);
1858 for(int i = 0; offset < sizeof(data.get()); i++, offset++)
1859 mData[i] = data[offset];
1860 mpgext = new Mpeg2Ext(data, oldOffset);
1866 Mpeg2Info::~Mpeg2Info(void)
1871 AspectRatio Mpeg2Info::GetAspectRatio(void)
1873 switch (GetAspect())
1876 if (GetVertical() == 1080 || GetVertical() == 1088 || GetVertical() == 720)
1889 FrameRate Mpeg2Info::GetFrameRate(void)
1891 switch (GetFrameRateCode())
1910 VideoFormat Mpeg2Info::GetVideoFormat(void)
1912 if (GetVertical() == 1080 || GetVertical() == 1088)
1914 if(GetProgressive())
1919 else if (GetVertical() == 576)
1921 if (GetProgressive())
1926 else if (GetVertical() == 720)
1928 else if (GetVertical() == 480)
1930 if (GetProgressive())
1938 pByte Mpeg2Info::GetElementaryDescriptors(void)
1940 return GetMpeg2VideoRegistrationDescriptor();
1943 AudioPresentationType Mpeg2Info::GetAudioPresentationType(void)
1948 SamplingFrequency Mpeg2Info::GetSamplingFrequency(void)
1953 pByte Mpeg2Info::GetMpeg2VideoRegistrationDescriptor(void)
1955 pByte data = pByte(new byte[10]);
1964 data[8] = (byte)((((byte)GetVideoFormat()) << 4) | ((byte)GetFrameRate()));
1965 data[9] = (byte)((((byte)GetAspectRatio()) << 4) | 0x0f);
1969 ushort Mpeg2Info::GetHorizontal(void)
1973 for (int i = 0; i < 12; i++)
1976 ret |= GetNextBit();
1981 ushort Mpeg2Info::GetVertical(void)
1985 for (int i = 0; i < 12; i++)
1988 ret |= GetNextBit();
1993 byte Mpeg2Info::GetAspect(void)
1997 for (int i = 0; i < 4; i++)
2000 ret |= GetNextBit();
2005 byte Mpeg2Info::GetFrameRateCode(void)
2009 for (int i = 0; i < 4; i++)
2012 ret |= GetNextBit();
2017 bool Mpeg2Info::GetProgressive(void)
2019 if (mpgext.mValid() && mpgext.GetProgressive())
2025 // implement class H264Info : ElementaryParse
2026 H264Info::H264Info(pByte data, int offset)
2028 UInt32 marker = 0xffffffff;
2029 for (; offset < sizeof(data.get()); offset++)
2031 marker = marker << 8;
2032 marker &= 0xffffff00;
2033 marker += data[offset];
2034 if ((marker & 0xffffff9f) == Constants::H264_PREFIX)
2040 if (offset < sizeof(data.get()))
2042 // sequence parameter set
2043 mData = pByte(new byte[sizeof(data.get()) - offset]);
2044 for (int i = 0; offset < sizeof(data.get()); i++, offset++)
2045 mData[i] = data[offset];
2051 UInt32 H264Info::GetNextExpGolomb(void)
2053 int leadingZeroBits = -1;
2055 for (; b == 0; leadingZeroBits++)
2057 UInt32 codeNum = (UInt32)(1 << leadingZeroBits);
2060 for (; leadingZeroBits > 0; leadingZeroBits-- )
2070 void H264Info::ScalingListSkip(int skip)
2074 for (int i = 0; i < skip; i++)
2078 int deltaScale = (int)GetNextExpGolomb();
2079 nextScale = (lastScale + deltaScale) % 256;
2084 UInt32 H264Info::GetWidth(void)
2088 if (mData[0] == 100 || mData[0] == 110 || mData[0] == 122 || mData[0] == 144)
2090 UInt32 chroma = GetNextExpGolomb();
2096 if (GetNextBit() == 1)
2098 for (int i = 0; i < 6; i++)
2100 if (GetNextBit() == 1)
2102 ScalingListSkip(16);
2105 for (int i = 6; i < 8; i++)
2107 if (GetNextBit() == 1)
2109 ScalingListSkip(64);
2115 UInt32 pic = GetNextExpGolomb();
2123 UInt32 numFrame = GetNextExpGolomb();
2124 for (int i = 0; i < numFrame; i++)
2129 UInt32 wid = GetNextExpGolomb();
2135 UInt32 H264Info::GetHeigth(void)
2137 UInt32 width = GetWidth();
2138 UInt32 height = GetNextExpGolomb();
2144 pByte H264Info::GetHdmvVideoRegistrationDescriptor(void)
2146 pByte data = pByte(new byte[10]);
2155 data[8] = (byte)((((byte)GetVideoFormat()) << 4) | ((byte)GetFrameRate()));
2156 data[9] = (byte)((((byte)GetAspectRatio()) << 4) | 0x0f);
2160 VideoFormat H264Info::GetVideoFormat(void)
2162 UInt32 h = GetHeigth();
2163 if (h == 1080 || h == 1088)
2171 else if (h == 540 || h == 544)
2181 AspectRatio H264Info::GetAspectRatio(void)
2183 if (GetVideoFormat() == i480 || GetVideoFormat() == i576)
2188 FrameRate H264Info::GetFrameRate(void)
2190 if (GetVideoFormat() == p720)
2192 else if (GetVideoFormat() == p1080 || GetVideoFormat() == p480)
2194 else if (GetVideoFormat() == p576 || GetVideoFormat() == i576)
2200 pByte H264Info::GetElementaryDescriptors(void)
2202 return GetHdmvVideoRegistrationDescriptor();
2205 AudioPresentationType H264Info::GetAudioPresentationType(void)
2210 SamplingFrequency H264Info::GetSamplingFrequency(void)
2215 // implement class SitPacket : TsTable
2216 SitPacket::SitPacket(void)
2220 SitPacket::SitPacket(pByte data)
2224 // implement class PmPacket : TsTable
2225 PmPacket::PmPacket(void)
2228 SetTableId(Constants::PMT_TABLE_ID);
2231 SetProgramNumber(1);
2233 SetPcrPID(Constants::DEFAULT_PCR_PID);
2234 // reserved, program info length
2235 SetProgramDescriptorsLength(0);
2236 SetPID(Constants::DEFAULT_PMT_PID);
2240 PmPacket::PmPacket(pByte data)throw(std::invalid_argument)
2242 if (GetTableId() != Constants::PMT_TABLE_ID)
2243 throw std::invalid_argument("packet does not contain a valid PMT table ID");
2246 DTCP_Descriptor PmPacket::GetDtcpInfo(void)
2248 pByte descriptors = GetProgramDescriptorsData();
2250 return reinterpret_cast<DTCP_Descriptor>(NULL);
2251 DTCP_Descriptor dt = NULL;
2253 for (int i = 0; i < sizeof(descriptors.get()); )
2257 dt = new DTCP_Descriptor(descriptors, i);
2260 catch (std::invalid_argument)
2262 i += (2 + descriptors[i + 1]);
2269 pByte PmPacket::GetProgramDescriptorsData(void)
2271 if (GetProgramDescriptorsLength() == 0)
2273 pByte descriptors = pByte(new byte[GetProgramDescriptorsLength()]);
2274 for (int i = 0; i < sizeof(descriptors.get()); i++)
2276 descriptors[i] = mData[i + 17 + GetPointerSize()];
2281 void PmPacket::SetProgramDescriptorsData(pByte value)
2283 if (!value || 0 == sizeof(value.get()))
2285 if (GetProgramDescriptorsLength() > 0)
2287 // need to remove existing descriptors
2288 pByte data = pByte(new byte[GetStreamInfoLength()]);
2289 int index = 17 + GetProgramDescriptorsLength() + GetPointerSize();
2290 // copy data between descriptor and crc
2291 for (int i = 0; i < sizeof(data.get()); i++)
2293 data[i] = mData[index + i];
2294 mData[17 + i + GetPointerSize()] = data[i];
2296 SetLength(GetLength() - GetProgramDescriptorsLength());
2297 SetProgramDescriptorsLength(0);
2308 if (sizeof(value.get()) + GetLength() + GetPointerSize() + 5
2309 - GetProgramDescriptorsLength() > Constants::TS_SIZE)
2310 throw std::invalid_argument("program descriptors data too long");
2311 // need to remove existing descriptors
2312 pByte data = pByte(new byte[GetStreamInfoLength()]);
2313 int index = 17 + GetProgramDescriptorsLength() + GetPointerSize();
2314 // copy data between descriptor and crc
2315 for (int i = 0; i < sizeof(data.get()); i++)
2316 data[i] = mData[index + i];
2317 SetLength(GetLength() - GetProgramDescriptorsLength());
2318 SetLength(GetLength() + sizeof(value.get()));
2319 SetProgramDescriptorsLength(sizeof(value.get()));
2320 // copy the new descriptor
2321 for (int i = 0; i < sizeof(value.get()); i++)
2322 mData[17 + i + GetPointerSize()] = value[i];
2323 // recover data between descriptor and crc
2324 for (int i = 0; i < sizeof(data.get()); i++)
2325 mData[17 + sizeof(value.get()) + i + GetPointerSize()] = data[i];
2331 // implement class BluRayOutput
2332 readonly byte BluRayOutput::index_bdmv[] = {
2333 0x49, 0x4e, 0x44, 0x58, 0x30, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x78,
2334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00,
2336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2338 0x00, 0x26, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
2339 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00,
2340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, 0x00, 0x00, 0x00, 0x18,
2341 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x01, 0x7e,
2342 0x49, 0x44, 0x45, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x00, 0x00, 0x00, 0x00,
2343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36, 0x10, 0x13, 0x00, 0x01,
2345 0x54, 0x52, 0x20, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2e, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2347 0x00, 0x06, 0xff, 0xff, 0x42, 0x20, 0x07, 0x08, 0x08, 0x00, 0x54, 0x53, 0x00, 0x90, 0x0a, 0x54,
2348 0x52, 0x20, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2e, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2364 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
2365 0x00, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00 };
2367 readonly byte BluRayOutput::MovieObject_bdmv[] = {
2368 0x4d, 0x4f, 0x42, 0x4a, 0x30, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00,
2371 0x00, 0x03, 0x80, 0x00, 0x00, 0x04, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00,
2372 0x00, 0x00, 0x50, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x82,
2373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x21, 0x81, 0x00, 0x00, 0x00, 0x00,
2374 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x09, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00,
2375 0x00, 0x0a, 0x00, 0x00, 0x00, 0x03, 0x50, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
2376 0xff, 0xff, 0x48, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x22, 0x00,
2377 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00,
2378 0x00, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x50, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
2379 0x00, 0x00, 0x48, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01,
2380 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0x00, 0x00, 0x00, 0x00,
2381 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x05, 0x50, 0x40, 0x00, 0x01, 0x00, 0x00,
2382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
2383 0x00, 0x01, 0x50, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xff, 0xff, 0x50, 0x40,
2384 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x21, 0x81, 0x00, 0x00, 0x00, 0x00,
2385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2387 readonly byte BluRayOutput::PlayList_00000_mpls[] = { 0x4d, 0x50, 0x4c, 0x53, 0x30, 0x31, 0x30, 0x30 };
2389 readonly byte BluRayOutput::AppInfoPlayList[] = {
2390 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00 };
2392 readonly byte BluRayOutput::PgStreamAttributes[] = { 0x05, 0x90, 0x65, 0x6e, 0x67, 0x00 };
2394 readonly byte BluRayOutput::ClipInfo_0000_clpi[] = { 0x48, 0x44, 0x4d, 0x56, 0x30, 0x31, 0x30, 0x30 };
2396 readonly byte BluRayOutput::TsTypeInfoBlock[] = {
2397 0x00, 0x1e, 0x80, 0x48, 0x44, 0x4d, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2400 BluRayOutput::BluRayOutput(std::string arg_path, TimeSpan arg_chapterLen)
2403 chapterLen = arg_chapterLen;
2404 boost::filesystem::path full_path(boost::filesystem::initial_path<boost::filesystem::path>());
2405 if(boost::filesystem::exists(full_path))
2406 boost::filesystem::remove(full_path);
2407 boost::filesystem::create_directory(full_path);
2408 boost::filesystem::create_directory(full_path / "BDMV");
2409 boost::filesystem::create_directory(full_path / "BDMV" / "AUXDATA");
2410 boost::filesystem::create_directory(full_path / "BDMV" / "BACKUP");
2411 boost::filesystem::create_directory(full_path / "BDMV" / "BACKUP" / "BDJO");
2412 boost::filesystem::create_directory(full_path / "BDMV" / "BACKUP" / "CLIPINF");
2413 boost::filesystem::create_directory(full_path / "BDMV" / "BACKUP" / "PLAYLIST");
2414 boost::filesystem::create_directory(full_path / "BDMV" / "BDJO");
2415 boost::filesystem::create_directory(full_path / "BDMV" / "CLIPINF");
2416 boost::filesystem::create_directory(full_path / "BDMV" / "JAR");
2417 boost::filesystem::create_directory(full_path / "BDMV" / "META");
2418 boost::filesystem::create_directory(full_path / "BDMV" / "PLAYLIST");
2419 boost::filesystem::create_directory(full_path / "BDMV" / "STREAM");
2420 boost::filesystem::create_directory(full_path / "CERTIFICATE");
2421 boost::filesystem::create_directory(full_path / "CERTIFICATE" / "BACKUP");
2423 boost::filesystem::ofstream file_index_bdmv(full_path / "BDMV/index.bdmv");
2424 file_index_bdmv << index_bdmv;
2425 boost::filesystem::ofstream file_index_bdmv_backup(full_path / "BDMV/BACKUP/index.bdmv");
2426 file_index_bdmv_backup << index_bdmv;
2428 boost::filesystem::ofstream file_movieobject_bdmv(full_path / "BDMV/MovieObject.bdmv");
2429 file_movieobject_bdmv << MovieObject_bdmv;
2430 boost::filesystem::ofstream file_movieobject_bdmv_backup(full_path / "BDMV/BACKUP/MovieObject.bdmv");
2431 file_movieobject_bdmv_backup << MovieObject_bdmv;
2435 void BluRayOutput::Author(EpElement* EpInfo, StreamInfo* sis, UInt32 numOfSourcePackets)
2437 List<ushort> Pids = new List<ushort>();
2438 List<byte[]> StreamCodingInfos = new List<byte[]>();
2439 List<byte[]> AudioEntries = new List<byte[]>();
2440 List<byte[]> AudioAttributes = new List<byte[]>();
2441 List<byte[]> PgEntries = new List<byte[]>();
2442 List<byte[]> PgAttributes = new List<byte[]>();
2443 byte[] VideoEntry = null;
2444 byte[] VideoAttribute = null;
2445 ElementaryStreamTypes VideoType = ElementaryStreamTypes.INVALID;
2446 foreach(StreamInfo si in sis)
2448 switch (si.StreamType)
2450 case ElementaryStreamTypes.AUDIO_STREAM_AC3:
2451 case ElementaryStreamTypes.AUDIO_STREAM_AC3_PLUS:
2452 case ElementaryStreamTypes.AUDIO_STREAM_AC3_TRUE_HD:
2453 case ElementaryStreamTypes.AUDIO_STREAM_DTS:
2454 case ElementaryStreamTypes.AUDIO_STREAM_DTS_HD:
2455 case ElementaryStreamTypes.AUDIO_STREAM_DTS_HD_MASTER_AUDIO:
2456 case ElementaryStreamTypes.AUDIO_STREAM_LPCM:
2457 case ElementaryStreamTypes.AUDIO_STREAM_MPEG1:
2458 case ElementaryStreamTypes.AUDIO_STREAM_MPEG2:
2459 byte[] AudioEntry = BuildStreamEntry(si.ElementaryPID);
2460 byte[] AudioAttribute = BuildAudioStreamAttributes((byte)si.StreamType,si.AudioPresentationType,si.SamplingFrequency);
2461 AudioEntries.Add(AudioEntry);
2462 AudioAttributes.Add(AudioAttribute);
2463 byte[] AudioCodingInfo = BuildAudioStreamCodingInfo(si.StreamType, si.AudioPresentationType, si.SamplingFrequency);
2464 Pids.Add(si.ElementaryPID);
2465 StreamCodingInfos.Add(AudioCodingInfo);
2467 case ElementaryStreamTypes.VIDEO_STREAM_H264:
2468 case ElementaryStreamTypes.VIDEO_STREAM_MPEG1:
2469 case ElementaryStreamTypes.VIDEO_STREAM_MPEG2:
2470 case ElementaryStreamTypes.VIDEO_STREAM_VC1:
2471 VideoType = si.StreamType;
2472 VideoEntry = BuildStreamEntry(si.ElementaryPID);
2473 VideoAttribute = BuildVideoStreamAttributes((byte)si.StreamType,si.VideoFormat,si.FrameRate);
2474 byte[] VideoCodingInfo = BuildVideoStreamCodingInfo(si.StreamType, si.VideoFormat, si.FrameRate, si.AspectRatio);
2475 Pids.Add(si.ElementaryPID);
2476 StreamCodingInfos.Add(VideoCodingInfo);
2478 case ElementaryStreamTypes.PRESENTATION_GRAPHICS_STREAM:
2479 byte[] PgEntry = BuildStreamEntry(si.ElementaryPID);
2480 PgEntries.Add(PgEntry);
2481 PgAttributes.Add(PgStreamAttributes);
2482 byte[] PgCodingInfo = BuildPgStreamCodingInfo();
2483 Pids.Add(si.ElementaryPID);
2484 StreamCodingInfos.Add(PgCodingInfo);
2488 byte[][] PlayItems = new byte[1][];
2489 UInt32 Start = (UInt32)((EpInfo[0].PTS >> 1) & 0xffffffff);
2490 UInt32 End = (UInt32)((EpInfo[EpInfo.Length - 1].PTS >> 1) & 0xffffffff);
2491 UInt32 Interval = ((UInt32)(chapterLen.TotalMinutes)) * 2700000;
2492 byte[] StnTable = BuildStnTable(VideoEntry, VideoAttribute, AudioEntries.ToArray(), AudioAttributes.ToArray(), PgEntries.ToArray(), PgAttributes.ToArray());
2493 PlayItems[0] = BuildFirstPlayItem(0, Start, End, StnTable);
2494 byte[] PlayList = BuildPlayList(PlayItems);
2495 byte[] PlayListMark = BuildFirstPlayMarks(Start, End, Interval);
2496 byte[] mlps = Build_mlps(PlayList, PlayListMark);
2497 File.WriteAllBytes(Path.Combine(path, @"BDMV\PLAYLIST\00000.mpls"), mlps);
2498 File.Copy(Path.Combine(path, @"BDMV\PLAYLIST\00000.mpls"), Path.Combine(path, @"BDMV\BACKUP\PLAYLIST\00000.mpls"),true);
2500 byte[] ClipInfo = BuildClipInfo(numOfSourcePackets,EpInfo);
2501 byte[] SequenceInfo = BuildSequenceInfo(Start, End);
2502 byte[] ProgramInf = BuildProgramInfo(Pids.ToArray(), StreamCodingInfos.ToArray());
2503 byte[] EpMap = BuildEpMap(EpInfo);
2504 byte[] CPI = BuildCpi(EpMap);
2505 byte[] clpi = Build_clpi(ClipInfo, SequenceInfo, ProgramInf, CPI);
2506 File.WriteAllBytes(Path.Combine(path, @"BDMV\CLIPINF\00001.clpi"), clpi);
2507 File.Copy(Path.Combine(path, @"BDMV\CLIPINF\00001.clpi"), Path.Combine(path, @"BDMV\BACKUP\CLIPINF\00001.clpi"),true);
2511 pByte BluRayOutput::BuildStreamEntry(ushort pid)
2513 pByte StreamEntry = pByte(new byte[10] {
2514 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
2515 StreamEntry[2] = (byte)((pid >> 8) & 0xff);
2516 StreamEntry[3] = (byte)(pid & 0xff);
2520 pByte BluRayOutput::BuildVideoStreamAttributes(byte type, VideoFormat vf, FrameRate fr)
2521 throw(std::invalid_argument)
2523 if (type != reinterpret_cast<byte>VIDEO_STREAM_VC1
2524 && type != repreinterpret_cast<byte>VIDEO_STREAM_MPEG2
2525 && type != reinterpret_cast<byte>VIDEO_STREAM_H264)
2526 throw std::invalid_argument("Video stream of type is not supported by Blu Ray");
2527 pByte attributes = pByte(new byte[6]);
2528 attributes[0] = 0x05;
2529 attributes[1] = type;
2530 attributes[2] = (byte)((((byte)vf) << 4) & 0xf0);
2531 attributes[2] |= (byte)(((byte)fr) & 0x0f);
2532 attributes[3] = attributes[4] = attributes[5] = 0;
2536 pByte BluRayOutput::BuildAudioStreamAttributes(byte type, AudioPresentationType vf, SamplingFrequency fr)
2537 throw(std::invalid_argument)
2539 if (type != reinterpret_cast<byte>AUDIO_STREAM_AC3
2540 && type != reiterpret_cast<byte>AUDIO_STREAM_AC3_PLUS
2541 && type != reiterpret_cast<byte>AUDIO_STREAM_AC3_TRUE_HD
2542 && type != reiterpret_cast<byte>AUDIO_STREAM_DTS
2543 && type != reiterpret_cast<byte>AUDIO_STREAM_DTS_HD
2544 && type != reiterpret_cast<byte>AUDIO_STREAM_DTS_HD_MASTER_AUDIO
2545 && type != reiterpret_cast<byte>AUDIO_STREAM_LPCM)
2546 throw std::invalid_argument("Audio stream of type is not supported by Blu Ray");
2547 pByte attributes = pByte(new byte[6]);
2548 attributes[0] = 0x05;
2549 attributes[1] = type;
2550 attributes[2] = (byte)((((byte)vf) << 4) & 0xf0);
2551 attributes[2] |= (byte)(((byte)fr) & 0x0f);
2552 attributes[3] = 0x65;
2553 attributes[4] = 0x6e;
2554 attributes[5] = 0x67;
2559 pByte BluRayOutput::BuildStnTable(pByte VideoEntry, pByte VideoAttributes, byte[][] AudioEntries, byte[][] AudioAttributes, byte[][] PgEntries, byte[][] PgAttributes)
2561 List<byte> table = new List<byte>();
2562 List<byte> temp = new List<byte>();
2566 if (AudioEntries.Length > 0)
2567 table.Add((byte)AudioEntries.Length);
2570 if (PgEntries.Length > 0)
2571 table.Add((byte)PgEntries.Length);
2574 for (int i = 0; i < 9; i++)
2576 table.AddRange(VideoEntry);
2577 table.AddRange(VideoAttributes);
2578 for (int i = 0; i < AudioEntries.Length; i++)
2580 table.AddRange(AudioEntries[i]);
2581 table.AddRange(AudioAttributes[i]);
2583 for (int i = 0; i < PgEntries.Length; i++)
2585 table.AddRange(PgEntries[i]);
2586 table.AddRange(PgAttributes[i]);
2588 UInt32 len = (UInt32)table.Count;
2589 temp.Add((byte)((len >> 8) & 0xff));
2590 temp.Add((byte)(len & 0xff));
2591 temp.AddRange(table);
2592 return temp.ToArray();
2595 pByte BluRayOutput:: UintToByteArraryNetwork(UInt32 value)
2597 pByte ret = pByte(new byte[4]);
2598 ret[0] = reinterpret_cast<byte>((value >> 24) & 0xff);
2599 ret[1] = reinterpret_cast<byte>((value >> 16) & 0xff);
2600 ret[2] = reinterpret_cast<byte>((value >> 8) & 0xff);
2601 ret[3] = reinterpret_cast<byte>(value & 0xff);
2605 pByte BluRayOutput::Build_mlps(pByte PlayList, pByte PlayListMark)
2608 mlps.AddRange(PlayList_00000_mpls);
2609 UInt32 temp = (UInt32)AppInfoPlayList.Length;
2611 mlps.AddRange(UintToByteArraryNetwork(temp));
2612 temp += (UInt32)PlayList.Length;
2613 mlps.AddRange(UintToByteArraryNetwork(temp));
2614 for (int i = 0; i < 24; i++)
2616 mlps.AddRange(AppInfoPlayList);
2617 mlps.AddRange(PlayList);
2618 mlps.AddRange(PlayListMark);
2619 return mlps.ToArray();
2622 pByte BluRayOutput::BuildPlayList(byte[][] PlayItems)
2624 std::List<byte> playList;
2625 UInt32 playItemNum = sizeof(PlayItems);
2627 playItemNum &= 0xffff0000;
2628 UInt32 len = sizeof(PlayItems) + 6;
2629 playList.AddRange(UintToByteArraryNetwork(len));
2630 playList.push_back(0x00);
2631 playList.push_back(0x00);
2632 playList.AddRange(UintToByteArraryNetwork(playItemNum));
2633 for (int i = 0; i < PlayItems.Length; i++)
2634 playList.AddRange(PlayItems[i]);
2635 return playList.ToArray();
2638 byte[] BuildFirstPlayItem(byte stc_id, UInt32 start, UInt32 end, byte[] StnTable)
2640 List<byte> playItem = new List<byte>();
2641 List<byte> playTemp = new List<byte>();
2642 for (int i = 0; i < 4; i++)
2651 playItem.Add(stc_id);
2652 playItem.AddRange(UintToByteArraryNetwork(start));
2653 playItem.AddRange(UintToByteArraryNetwork(end));
2654 for (int i = 0; i < 12; i++)
2656 playItem.AddRange(StnTable);
2657 UInt32 len = (UInt32)playItem.Count;
2658 playTemp.Add((byte)((len >> 8) & 0xff));
2659 playTemp.Add((byte)(len & 0xff));
2660 playTemp.AddRange(playItem);
2661 return playTemp.ToArray();
2664 byte[] BuildFirstPlayMarks(UInt32 start, UInt32 end, UInt32 interval)
2666 List<byte> marks = new List<byte>();
2667 List<byte> temp = new List<byte>();
2669 for (UInt32 i = start; i < end; i += interval, num++)
2676 marks.AddRange(UintToByteArraryNetwork(time));
2680 marks.AddRange(UintToByteArraryNetwork(time));
2682 UInt32 len = (UInt32)marks.Count;
2684 temp.AddRange(UintToByteArraryNetwork(len));
2685 temp.Add((byte)((num >> 8) & 0xff));
2686 temp.Add((byte)(num & 0xff));
2687 temp.AddRange(marks);
2688 return temp.ToArray();
2691 byte[] Build_clpi(byte[] ClipInfo, byte[] SequenceInfo, byte[] ProgramInfo, byte[] CPI)
2693 List<byte> clpi = new List<byte>();
2694 clpi.AddRange(ClipInfo_0000_clpi);
2696 len += (UInt32)ClipInfo.Length;
2697 clpi.AddRange(UintToByteArraryNetwork(len));
2698 len += (UInt32)SequenceInfo.Length;
2699 clpi.AddRange(UintToByteArraryNetwork(len));
2700 len += (UInt32)ProgramInfo.Length;
2701 clpi.AddRange(UintToByteArraryNetwork(len));
2702 len += (UInt32)CPI.Length;
2703 clpi.AddRange(UintToByteArraryNetwork(len));
2704 for (int i = 0; i < 16; i++)
2706 clpi.AddRange(ClipInfo);
2707 clpi.AddRange(SequenceInfo);
2708 clpi.AddRange(ProgramInfo);
2710 clpi.AddRange(UintToByteArraryNetwork(0x00000000));
2711 return clpi.ToArray();
2714 byte[] BuildClipInfo(UInt32 numOfSourcePackets, EpElement[] EpInfo)
2716 List<byte> clip = new List<byte>();
2717 List<byte> temp = new List<byte>();
2727 Int64 rate = EpInfo[EpInfo.Length - 1].SPN - EpInfo[0].SPN;
2729 rate /= ((EpInfo[EpInfo.Length - 1].PTS - EpInfo[0].PTS) / 90000);
2730 clip.AddRange(UintToByteArraryNetwork((UInt32)rate));
2731 clip.AddRange(UintToByteArraryNetwork(numOfSourcePackets));
2732 for (int i = 0; i < 128; i++)
2734 clip.AddRange(TsTypeInfoBlock);
2735 UInt32 len = (UInt32)clip.Count;
2736 temp.AddRange(UintToByteArraryNetwork(len));
2737 temp.AddRange(clip);
2738 return temp.ToArray();
2741 byte[] BuildSequenceInfo(UInt32 start, UInt32 end)
2743 List<byte> seq = new List<byte>();
2744 List<byte> temp = new List<byte>();
2754 seq.Add((byte)((Constants.DEFAULT_PCR_PID >> 8) & 0xff));
2755 seq.Add((byte)(Constants.DEFAULT_PCR_PID & 0xff));
2760 seq.AddRange(UintToByteArraryNetwork(start));
2761 seq.AddRange(UintToByteArraryNetwork(end));
2762 UInt32 len = (UInt32)seq.Count;
2763 temp.AddRange(UintToByteArraryNetwork(len));
2765 return temp.ToArray();
2768 byte[] BuildProgramInfo(ushort[] pids, byte[][] StreamCodingInfos)
2770 List<byte> info = new List<byte>();
2771 List<byte> temp = new List<byte>();
2778 info.Add((byte)((Constants.DEFAULT_PMT_PID >> 8) & 0xff));
2779 info.Add((byte)(Constants.DEFAULT_PMT_PID & 0xff));
2780 info.Add((byte)pids.Length);
2782 for (int i = 0; i < pids.Length; i++)
2784 info.Add((byte)((pids[i] >> 8) & 0xff));
2785 info.Add((byte)(pids[i] & 0xff));
2786 info.AddRange(StreamCodingInfos[i]);
2789 UInt32 len = (UInt32)info.Count;
2790 temp.AddRange(UintToByteArraryNetwork(len));
2791 temp.AddRange(info);
2792 return temp.ToArray();
2795 byte[] BuildVideoStreamCodingInfo(ElementaryStreamTypes type, VideoFormat format, FrameRate rate, AspectRatio ratio)
2797 List<byte> info = new List<byte>();
2799 info.Add((byte)type);
2800 info.Add((byte)((((byte)format) << 4) | (byte)rate));
2801 info.Add((byte)(((byte)(ratio)) << 4));
2802 for(int i = 0; i < 18; i++)
2804 return info.ToArray();
2807 byte[] BuildAudioStreamCodingInfo(ElementaryStreamTypes type, AudioPresentationType format, SamplingFrequency rate)
2809 List<byte> info = new List<byte>();
2811 info.Add((byte)type);
2812 info.Add((byte)((((byte)format) << 4) | (byte)rate));
2816 for (int i = 0; i < 16; i++)
2818 return info.ToArray();
2821 byte[] BuildPgStreamCodingInfo()
2823 List<byte> info = new List<byte>();
2829 for (int i = 0; i < 17; i++)
2831 return info.ToArray();
2834 byte[] BuildCpi(byte[] EpMap)
2836 List<byte> info = new List<byte>();
2837 UInt32 len = (UInt32)EpMap.Length + 2;
2838 info.AddRange(UintToByteArraryNetwork(len));
2841 info.AddRange(EpMap);
2842 return info.ToArray();
2845 byte[] BuildEpMap(EpElement[] EpInfo)
2847 UInt32 lastepfine = 0x7ff;
2848 UInt32 lastspnfine = 0x1ffff;
2849 UInt32 numofcoarse = 0;
2850 List<byte> coarseloop = new List<byte>();
2851 List<byte> fineloop = new List<byte>(EpInfo.Length);
2852 List<byte> EpMap = new List<byte>();
2854 for (int i = 0; i < EpInfo.Length; i++)
2856 UInt32 epfine = (UInt32)((EpInfo[i].PTS >> 9) % 0x800);
2857 UInt32 epcoarse = (UInt32)((EpInfo[i].PTS >> 19) % 0x4000);
2858 UInt32 spnfine = EpInfo[i].SPN % 0x20000;
2859 if (lastepfine > epfine || lastspnfine > spnfine)
2861 UInt32 reftofine = (UInt32)i;
2863 reftofine |= epcoarse;
2864 coarseloop.AddRange(UintToByteArraryNetwork(reftofine));
2865 coarseloop.AddRange(UintToByteArraryNetwork(EpInfo[i].SPN));
2868 UInt32 value = 0x1000;
2869 value |= (epfine << 17);
2871 fineloop.AddRange(UintToByteArraryNetwork(value));
2872 lastepfine = epfine;
2873 lastspnfine = spnfine;
2878 EpMap.Add((byte)((Constants.DEFAULT_VIDEO_PID >> 8) & 0xff));
2879 EpMap.Add((byte)(Constants.DEFAULT_VIDEO_PID & 0xff));
2882 btemp |= (byte)((numofcoarse >> 14) & 0xff);
2884 btemp = (byte)((numofcoarse >> 6) & 0xff);
2886 btemp = (byte)((numofcoarse & 0x3f) << 2);
2887 btemp |= (byte)((EpInfo.Length >> 16) & 0x03);
2889 btemp = (byte)((EpInfo.Length >> 8) & 0xff);
2891 btemp = (byte)(EpInfo.Length& 0xff);
2893 UInt32 count = 4 + (UInt32)EpMap.Count;
2894 EpMap.AddRange(UintToByteArraryNetwork(count));
2895 UInt32 start = 4 + (UInt32)coarseloop.Count;
2896 EpMap.AddRange(UintToByteArraryNetwork(start));
2897 EpMap.AddRange(coarseloop);
2898 EpMap.AddRange(fineloop);
2899 return EpMap.ToArray();