OSDN Git Service

8a0b77b8f6dcbd6f057152cd7e9539e4e7673008
[tsremuxcpp/developing01.git] / src / Utils.cc
1 #include "Utils.h"
2
3 namespace TsRemux
4 {
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;
20
21     // defaults
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;
39
40     // stream types
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;
63
64     // clocks
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;
73
74    // descriptors
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 };
152
153 StreamInfo::StreamInfo(byte* data, int index)throw(std::invalid_argument)
154 {
155     if (NULL == data) {
156                 throw std::invalid_argument("stream data is NULL");
157     }
158
159     if (std::strlen(data) + index < 5) {
160                 throw std::invalid_argument("stream data too short");
161     }
162
163     uint descLength = (uint)((data[3 + index] & 0x0f) << 8) + data[4 + index];
164
165     if (descLength > Constants::TS_SIZE) {
166                 throw std::invalid_argument("descriptors data too long");
167     }
168
169     if (5 + descLength > std::strlen(data) - index) {
170                 throw std::invalid_argument("stream data too short");
171     }
172
173     mData = new byte[5 + descLength];
174     for (int i = 0; i < sizeof(mData); i++) {
175         mData[i] = data[i + index];
176     }
177
178     SetVideoFormat(VF_Reserved);
179     SetAspectRatio(AR_Reserved);
180     SetFrameRate(FR_Reserved);
181     SetAudioPresentationType(AP_Reserved);
182     SetSamplingFrequency(SF_Reserved);
183 }
184
185 VideoFormat StreamInfo::GetVideoFormat(void)
186 {
187     return mVideoFormat;
188 }
189
190 void StreamInfo::SetVideoFormat(VideoFormat video_format)
191 {
192     mVideoFormat = video_format;
193 }
194
195 AspectRatio StreamInfo::GetAspectRatio(void)
196 {
197     return mAspectRatio;
198 }
199
200 void StreamInfo::SetAspectRatio(AspectRatio aspect_ratio)
201 {
202     mAspectRatio = aspect_ratio;
203 }
204
205 FrameRate StreamInfo::GetFrameRate(void)
206 {
207     return mFrameRate;
208 }
209
210 void StreamInfo::SetFrameRate(FrameRate frame_rate)
211 {
212     mFrameRate = frame_rate;
213 }
214
215 AudioPresentationType StreamInfo::GetAudioPresentationType(void)
216 {
217     return mAudioPresentationType;
218 }
219
220 void StreamInfo::SetAudioPresentationType(AudioPresentationType ap_type)
221 {
222     mAudioPresentationType = ap_type;
223 }
224
225 SamplingFrequency StreamInfo::GetSamplingFrequency(void)
226 {
227     return mSamplingFrequency;
228 }
229
230 void StreamInfo::SetSamplingFrequency(SamplingFrequency sampling_frequency)
231 {
232     mSamplingFrequency = sampling_frequency;
233 }
234
235 StreamInfo::StreamInfo(ElementaryStreamTypes streamType, ushort elementaryPid)
236 {
237     mData = new byte[5];
238     StreamType = streamType;
239     ElementaryPID = elementaryPid;
240     // reserved and descriptors length
241     mData[3] = 0xf0;
242     mData[4] = 0x00;
243 }
244
245 byte* StreamInfo::GetByteData(void)
246 {
247     return mData;
248 }
249
250 ElementaryStreamTypes StreamInfo::GetElementaryStreamTypes(void)
251 {
252     return (ElementaryStreamTypes)mData[0];
253 }
254
255 void StreamInfo::SetElementaryStreamTypes(ElementaryStreamTypes stream_type)
256 {
257     mData[0] = (byte)stream_type;
258 }
259 ushort StreamInfo::GetElementaryPID(void)
260 {
261     return (ushort)(((mData[1] & 0x1f) << 8) + mData[2]);
262 }
263
264 void StreamInfo::GetElementaryPID(ushort pid)
265 {
266     mData[1] = (byte)(((pid >> 8) & 0x1f) | 0xe0);
267     mData[2] = (byte)(pid & 0xff);
268 }
269
270 byte* StreamInfo::GetElementaryDescriptors(void)
271 {
272     if (std::strlen(mData) == 5) return NULL;
273     byte* descriptors = new byte[std::strlen(mData) - 5];
274     for (int i = 0; i < sizeof(descriptors); i++)
275     {
276         descriptors[i] = mData[i + 5];
277     }
278     return descriptors;
279 }
280
281 void StreamInfo::SetElementaryDescriptors(byte* value)
282     throw(std::invalid_argument)
283 {
284     if(NULL == value || 0 == sizeof(value))
285     {
286         if(std::strlen(mData) > 5)
287         {
288             // need to remove existing descriptors
289             byte* data = new byte[5];
290             data[0] = mData[0];
291             data[1] = mData[1];
292             data[2] = mData[2];
293             data[3] = 0xf0;
294             data[4] = 0x00;
295             mData = data;
296         }
297         else
298         {
299             // nothing to do
300             return;
301         }
302     }
303     else
304     {
305         if(std::strlen(value) > 180) {
306             throw std::invalid_argument("descriptors data too long");
307         }
308
309         byte* data = new byte[5 + std::strlen(value)];
310         data[0] = mData[0];
311         data[1] = mData[1];
312         data[2] = mData[2];
313         data[3] = (byte)(0xf0 | (byte)((std::strlen(value) >> 8) & 0x0f));
314         data[4] = (byte)(std::strlen(value) & 0xff);
315         for (int i = 0; i < std::strlen(value); i++)
316         {
317             data[5 + i] = value[i];
318         }
319         mData = data;
320     }
321 }
322
323 ElementaryParse::ElementaryParse(void)
324 {
325     indicator = 0;
326 }
327
328 byte ElementaryParse::GetNextBit(void)
329 {
330     byte ret = (byte)(((mData[indicator / 8]) >> (7 - (indicator % 8))) & 1);
331     indicator++;
332     return ret;
333 }
334
335 TsPacket::TsPacket(void)
336 {
337     // initialize the packet as a NULL packet
338     mData = new byte[Constants::TS_SIZE];
339     mData[0] = Constants::SYNC_BYTE; // sync byte
340     mData[1] = 0x1f; // PID = 0x1FFF
341     mData[2] = 0xff; // PID == 0x1FFF
342     mData[3] = 0x10; // no adaptation field
343     for (int i = 4; i < Constants::TS_SIZE; i++) {
344         mData[i] = 0xff;
345     }
346 }
347
348 bool TsPacket::GetPriority(void)
349 {
350     if ((mData[1] & 0x20) > 0)
351         return true;
352     else
353         return false;
354 }
355
356 void TsPacket::SetPriority(bool priority)
357 {
358     if (priority)
359         mData[1] |= 0x20;
360     else
361         mData[1] &= 0xdf;
362 }
363
364 ushort TsPacket::GetPID(void)
365 {
366     return (ushort)(((mData[1] & 0x1f) << 8) + mData[2]);
367 }
368 void TsPacket::SetPID(ushort pid)
369 {
370     byte b = (byte)(mData[1] & 0xE0);
371     b += (byte)((pid >> 8) & 0x1f);
372     mData[1] = b;
373     mData[2] = (byte)(pid & 0xff);
374 }
375
376 byte TsPacket::GetPointerSize(void)
377 {
378     if ((mData[3] & 0x20) == 0) // No adaptation field present
379         return mData[4];
380     return (byte)(mData[4] + 1 + mData[mData[4] + 5]);
381 }
382
383 byte* TsPacket::GetData(void)
384 {
385     return mData;
386 }
387
388 void TsPacket::SetData(byte* data, int startIndex)throw(std::invalid_argument)
389 {
390     if (NULL == data)
391         throw std::invalid_argument("NULL packet");
392     else if (Constants::TS_SIZE > std::strlen(data) - startIndex)
393         throw std::invalid_argument("small packet");
394     else if (Constants::SYNC_BYTE != data[0 + startIndex])
395         throw std::invalid_argument("sync byte missing");
396     for (int i = 0; i < Constants::TS_SIZE; i++) {
397         mData[i] = data[i + startIndex];
398     }
399 }
400 bool TsPacket::HasPcr(void)
401 {
402     if ((mData[3] & 0x20) > 0  // Adaptation field present
403      && (mData[4] > 0)         // length > 0
404      && (mData[5] & 0x10) > 0) // and a PCR
405         return true;
406     return false;
407 }
408 Int64 TsPacket::GetPcr(void)throw(std::out_of_range)
409 {
410     if (false == this->HasPcr())
411         throw std::out_of_range("PCR not present in this packet");
412     Int64 mpeg2tsClock = mData[6];
413     mpeg2tsClock <<= 25;
414     mpeg2tsClock += (mData[7] << 17);
415     mpeg2tsClock += (mData[8] << 9);
416     mpeg2tsClock += (mData[9] << 1);
417     mpeg2tsClock += ((mData[10] & 0x80) >> 7);
418     mpeg2tsClock *= 300;
419     mpeg2tsClock += ((mData[10] & 0x1) << 8);
420     mpeg2tsClock += (mData[11]);
421     return mpeg2tsClock;
422 }
423
424 bool TsPacket::HasPesHeader(void)
425 {
426     if ((mData[1] & 0x40) == 0)
427         return false;
428     int offset = 4;
429     if ((mData[3] & 0x20) > 0)
430     {
431         // adaptation field present
432         offset += (1 + mData[4]);
433         if (offset >= Constants::TS_SIZE)
434             return false;
435     }
436     if ((mData[3] & 0x10) > 0)
437     {
438         // payload present
439         int len = Constants::TS_SIZE - offset;
440         if (len < 10)
441             return false;
442
443         if(mData[offset] == 0
444         && mData[offset + 1] == 0
445         && mData[offset + 2] == 1
446         && len >= 9 + mData[offset + 8])
447             return true;
448         else if(mData[offset] == 0
449              && mData[offset + 1] == 0
450              && mData[offset + 2] == 1)
451             return false;
452     }
453     return false;
454 }
455
456 byte* TsPacket::Payload(void)
457 {
458     int offset = 4;
459     if ((mData[3] & 0x20) > 0)
460     {
461         // adaptation field present
462         offset += (1 + mData[4]);
463         if (offset >= Constants::TS_SIZE)
464             return NULL;
465     }
466     if ((mData[3] & 0x10) > 0)
467     {
468         // payload present
469         byte* ret = new byte[Constants::TS_SIZE - offset];
470         for (int i = 0; i < sizeof(ret); i++)
471             ret[i] = mData[i + offset];
472         return ret;
473     }
474     return NULL;
475 }
476
477 void TsPacket::IncrementContinuityCounter(void)
478 {
479     if (0xf == (mData[3] & 0xf))
480         mData[3] &= 0xf0;
481     else
482         mData[3]++;
483 }
484
485 byte TsPacket::GetContinuityCounter(void)
486 {
487     return (byte)(mData[3] & 0xf);
488 }
489
490 void TsPacket::SetContinuityCounter(byte value)throw(std::out_of_range)
491 {
492     if (value > 0x0f)
493         throw std::out_of_range("Invalid continuity counter");
494     mData[3] &= 0xf0;
495     mData[3] |= value;
496 }
497
498 TsTable::TsTable(void)
499 {
500     // error = 0, payload = 1, priority = 0
501     mData[1] = 0x40;
502     // scrambling = 0, adaptation = 01, continuity = 0
503     mData[3] = 0x10;
504     // pointer = 00
505     mData[4] = 0x0;
506     // reserved, version, current/next
507     mData[10] = 0xc1;
508     // section
509     mData[11] = 0x0;
510     // last section
511     mData[12] = 0x0;
512 }
513
514 TsTable::TsTable(byte* data)
515 {
516     SetData(data, 0);
517 }
518
519 void TsTable::AddData(byte* data, int offset, int len)
520 {
521     byte* newData = NULL;
522     newData = new byte[std::strlen(mData)+(len-offset)+1];
523     std::strncpy(&newData[0], &mData[0], std::strlen(mData));
524     std::strncat(&newData[0], &data[0], (len-offset));
525     mData = &newData[0];
526 }
527
528 bool TsTable::Complete(void)
529 {
530     int currentLen = strlen(mData) - (GetPointerSize() + 8);
531     if (GetLength() > currentLen)
532         return false;
533     return true;
534 }
535
536 byte TsTable::GetTableId(void)
537 {
538     return mData[5 + GetPointerSize()];
539 }
540
541 void TsTable::SetTableId(byte value)
542 {
543     mData[5 + GetPointerSize()] = value;
544 }
545
546 ushort TsTable::GetNumberId(void)
547 {
548     return (ushort)((mData[8 + GetPointerSize()] << 8)
549         + mData[9 + GetPointerSize()]);
550 }
551
552 void TsTable::SetNumberId(ushort value)
553 {
554     mData[8 + GetPointerSize()] = (byte)((value >> 8) & 0xff);
555     mData[9 + GetPointerSize()] = (byte)(value & 0xff);
556 }
557
558 ushort TsTable::GetLength(void)
559 {
560     return (ushort)(((mData[6 + GetPointerSize()] & 0x0f) << 8)
561         + mData[7 + GetPointerSize()]);
562 }
563
564 void TsTable::SetLength(ushort value)
565 {
566     // syntax, reserved, length
567     mData[6 + GetPointerSize()]
568         = (byte)(0xb0 | (byte)((value >> 8) & 0x0f));
569     mData[7 + GetPointerSize()] = (byte)(value & 0xff);
570 }
571
572 void TsTable::RefreshCrc(void)
573 {
574     uint crc = Constants::ComputeCrc(
575         mData, GetLength() - 1, 5 + GetPointerSize());
576     mData[GetLength() + 4 + GetPointerSize()]
577         = (byte)((crc >> 24) & 0xff);
578     mData[GetLength() + 5 + GetPointerSize()]
579         = (byte)((crc >> 16) & 0xff);
580     mData[GetLength() + 6 + GetPointerSize()]
581         = (byte)((crc >> 8) & 0xff);
582     mData[GetLength() + 7 + GetPointerSize()]
583         = (byte)(crc & 0xff);
584     for (int i = GetLength() + 8 + GetPointerSize();
585         i < Constants::TS_SIZE; i++) {
586         mData[i] = 0xff;
587     }
588 }
589
590
591
592
593 Descriptor::Descriptor(byte* data, int startIndex)throw(std::invalid_argument)
594 {
595     if (strlen(data) < 2)
596         throw std::invalid_argument("Invalid descriptor");
597     if (startIndex + 2 + data[startIndex + 1] > strlen(data))
598         throw std::invalid_argument("Invalid descriptor");
599     mData = new byte[2 + data[startIndex + 1]];
600     for (int i = 0; i < strlen(mData); i++)
601         mData[i] = data[i + startIndex];
602 }
603
604 byte Descriptor::GetTag(void)
605 {
606     return mData[0];
607 }
608
609 byte Descriptor::GetLength(void)
610 {
611     return mData[1];
612 }
613
614 byte* Descriptor::GetData(void)
615 {
616     return mData;
617 }
618
619 PcrPacket::PcrPacket(Int64 pcr, byte counter, ushort pid)
620 {
621     SetPID(pid);
622     SetContinuityCounter(counter);
623     mData[3] &= 0x0f; // adaptation field only, no payload
624     mData[3] |= 0x20; // adaptation field only, no payload
625     mData[4] = 183; // length
626     mData[5] = 0x10; // only PCR present
627     Int64 tsClockValue = pcr / 300;
628     Int64 tsOffsetValue = pcr % 300;
629     mData[6] = (byte)((tsClockValue & 0x1fe000000LL) >> 25);
630     mData[7] = (byte)((tsClockValue & 0x1fe0000) >> 17);
631     mData[8] = (byte)((tsClockValue & 0x1fe00) >> 9);
632     mData[9] = (byte)((tsClockValue & 0x1fe) >> 1);
633     if ((tsClockValue & 0x1) == 0)
634         mData[10] &= 0x7f;
635     if ((tsOffsetValue & 0x100) == 0)
636         mData[10] &= 0xfe;
637     mData[11] = (byte)(tsOffsetValue & 0xff);
638     for (int i = 12; i < Constants::TS_SIZE; i++)
639         mData[i] = 0xff;
640 }
641
642 PesPacket::PesPacket(byte* buff, int offset, int length, ushort pid)
643 {
644     mData.assign(0,length);
645     SetPID(pid);
646     AddData(buff, offset, length);
647     SetPriority(false);
648 }
649
650 bool PesPacket::GetPriority(void)
651 {
652     return mPriority;
653 }
654
655 void PesPacket::SetPriority(bool value)
656 {
657     mPriority = value;
658 }
659
660 byte* PesPacket::GetData(void)
661 {
662     byte* buff = new byte[mData.size()+1];
663     for(int i = 0; i < mData.size();i++)
664         buff[i] = mData.at(i);
665     buff[mData.size()] = '\0';
666     return buff;
667 }
668
669 byte* PesPacket::GetPayload(void)
670 {
671     PesHeader* ph = GetHeader();
672     if(ph == NULL) return GetData();
673     byte* buff = new byte[mData.size()-(9 + ph->HeaderLength)+1];
674     for(int i=(9 + ph->HeaderLength); i < mData.size(); i++)
675         buff[i] = mData.at(i);
676     buff[mData.size()-(9 + ph->HeaderLength)] = '\0';
677     return buff;
678 }
679
680 byte PesPacket::GetByte(int i)
681 {
682     return mData[i];
683 }
684
685 void PesPacket::SetByte(byte value)
686 {
687 //    mData[i] = value;
688 }
689
690 ushort PesPacket::GetPID(void)
691 {
692     return mPID;
693 }
694
695 void PesPacket::SetPID(ushort id)
696 {
697     mPID = id;
698 }
699
700 bool PesPacket::GetComplete(void)
701 {
702     if(mData.size() < 6) return false;
703     ushort len = (ushort)((mData[4] << 8) + mData[5]);
704     if(len == 0) return false;
705     if(mData.size() != len + 6) return false;
706     return true;
707 }
708
709 void PesPacket::SetComplete(bool value)
710 {
711     if(value)
712     {
713         ushort len = (ushort)(mData.size() - 6);
714         if (mData.size() > (0xffff - 6))
715             len = 0;
716         mData[4] = (byte)((len >> 8) & 0xff);
717         mData[5] = (byte)(len & 0xff);
718     }
719 }
720
721 /*
722         public PesHeader GetHeader()
723         {
724             try
725             {
726                 PesHeader* ph = new PesHeader(data.ToArray());
727                 return ph;
728             }
729             catch (FormatException)
730             {
731                 // no valid header (yet)
732                 return null;
733             }
734         }
735
736         public void AddData(List<byte> moredata)
737         {
738             data.AddRange(moredata);
739         }
740
741
742         public void AddData(byte[] buff, int offset, int length)
743         {
744             for (int i = offset; i < length + offset; i++)
745                 data.Add(buff[i]);
746         }
747
748         public byte BaseId
749         {
750             get
751             {
752                 if (data.Count > 3)
753                     return data[3];
754                 return 0;
755             }
756         }
757
758         public byte ExtendedId
759         {
760             get
761             {
762                 if ((data.Count > 8) && data.Count > (8 + data[8]))
763                     return data[9 + data[8]];
764                 return 0;
765             }
766         }
767
768         public UInt32 ExtendedType
769         {
770             get
771             {
772                 if ((data.Count > 8) && data.Count > (11 + data[8]))
773                 {
774                     UInt32 format = (UInt32)data[9 + data[8]] << 24;
775                     format += (UInt32)data[10 + data[8]] << 16;
776                     format += (UInt32)data[11 + data[8]] << 8;
777                     format += (UInt32)data[12 + data[8]];
778                     return format;
779                 }
780                 return 0;
781             }
782         }
783 */
784
785 } // namespace
786
787