3
Copyright (C) 2001 Martin Vogt
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU Library General Public License as published by
7
the Free Software Foundation.
9
For more information look at the file COPYRIGHT in this package
15
#include "pesSystemStream.h"
21
PESSystemStream::PESSystemStream(InputStream* input) {
26
PESSystemStream::~PESSystemStream() {
31
int PESSystemStream::getByteDirect() {
33
if (input->read((char*)&byte,1) != 1) {
40
int PESSystemStream::read(char* pointer,int bytes) {
41
if (input->read(pointer,bytes) != bytes) {
49
int PESSystemStream::processStartCode(unsigned int startCode,
50
MpegSystemHeader* mpegHeader) {
52
bytes_read=4; // startcode
53
mpegHeader->setPacketLen(0);
54
mpegHeader->setPacketID(_PAKET_ID_NUKE);
57
bytes_read=processPacket(startCode,mpegHeader);
63
0 - no error, but not video packet we want
67
int PESSystemStream::processPacket(unsigned int startCode,
68
MpegSystemHeader* mpegHeader) {
71
unsigned short packetLength;
74
/* Leftovers from previous video packets */
76
int packetID=startCode & 0xff;
77
mpegHeader->setPacketID(packetID);
78
int lPacket=startCode & _PACKET_START_CODE_MASK &_PACKET_START_CODE_PREFIX;
79
if ((lPacket == false) || (packetID < 0xbc)) {
80
//printf("unknown startcode,packet or packetID:%8x\n",startCode);
84
if (packetID == _NOT_PACKET_ID) {
85
cout << "(vid_stream->mpegVideoStream)->makeEnd()"<<endl;
86
} else if (packetID==_KILL_BUFFER) {
87
printf("packetID==_KILL_BUFFER\n");
90
if (read((char*)&packetLength, 2) == false) return false;
91
packetLength = htons(packetLength);
93
mpegHeader->setPTSFlag(false);
94
mpegHeader->setPacketID(packetID);
95
mpegHeader->setPESPacketLen(packetLength);
96
switch (packetID>>4) {
97
case _PAKET_ID_AUDIO_1>>4:
98
case _PAKET_ID_AUDIO_2>>4:
99
case _PAKET_ID_VIDEO>>4:
103
case _PRIVATE_STREAM_1_ID:
107
case _PRIVATE_STREAM_2_ID:
108
case _PADDING_STREAM_ID:
109
case _RESERVED_STREAM_ID:
112
case _PROGRAM_STREAM_DIRECTORY_ID:
113
case _DSMCC_STREAM_ID:
114
case _ITUTRECH222TYPEE_STREAM_ID:
117
printf("\nUnknown packet type. (%x) at %ld\n",
118
packetID,input->getBytePosition());
122
// this is only processed if audio or video found
124
if (mpegHeader->getMPEG2()==false) {
125
packetDataLength = packetLength-processPacketHeader(mpegHeader);
127
int len=processMPEG2PacketHeader(mpegHeader);
132
packetDataLength = packetLength-len;
134
// now check in private stream for AC3
135
if ( packetID == _PRIVATE_STREAM_1_ID ) {
136
packetDataLength = packetDataLength-processPrivateHeader(mpegHeader);
140
if (packetDataLength <= 0) {
141
if (mpegHeader->hasPSHeader()) return false;
142
// -> buggy TS stream
145
mpegHeader->setPESPacketLen(packetDataLength);
152
int PESSystemStream::processPrivateHeader(MpegSystemHeader* mpegHeader) {
155
int one=getByteDirect();
157
mpegHeader->setSubStreamID(one);
159
case _SUBSTREAM_AC3_ID>>4:
160
if (read(nukeBuffer,3) == false) return false;
161
mpegHeader->addAvailableLayer(one);
162
cout << "addAvailableLayer:"<<one<<endl;
165
case _SUBSTREAM_LPCM_ID>>4:
166
if (read(nukeBuffer,6) == false) return false;
169
case _SUBSTREAM_SUBPIC_ID>>4:
170
if (read(nukeBuffer,3) == false) return false;
174
printf("unknown sub id :%8x\n",one);
181
int PESSystemStream::processMPEG2PacketHeader(MpegSystemHeader* mpegHeader){
190
encrypted = getbits(2); // PES_scrambling_control
193
u_char original_or_copy : 1;
194
u_char copyright : 1;
195
u_char data_alignment_indicator : 1;
196
u_char pes_priority : 1;
197
u_char pes_scrambling_control : 2;
198
u_char start_code_prefix : 2; // 0x02
201
int first=getByteDirect();
203
mpegHeader->setOriginalOrCopy(first&(128)>>7);
204
mpegHeader->setCopyRight(first&(64)>>6);
205
mpegHeader->setDataAlignmentIndicator(first&(32)>>5);
206
mpegHeader->setPesPriority(first&(16)>>4);
207
mpegHeader->setEncrypted((first&(8+4))>>2);
208
mpegHeader->setStartCodePrefix(first&(1+2));
213
PTS_DTS_flags = getbits(2);
214
ESCR_flag = get1bit();
215
ES_rate_flag = get1bit();
216
DSM_trick_mode_flag = get1bit();
217
additional_copy_info_flag = get1bit();
218
PES_CRC_flag = get1bit();
219
PES_extension_flag = get1bit();
221
int second=getByteDirect();
224
mpegHeader->setPTSDTSFlag((second&(128+64))>>6);
225
mpegHeader->setESCRFlag((second&(32))>>5);
226
mpegHeader->setES_RATE_Flag((second%(16))>>4);
227
mpegHeader->setDMSTRICKFLAG((second&(8))>>3);
228
mpegHeader->setADDITIONAL_COPY_FLAG((second&(4))>>2);
229
mpegHeader->setPES_CRC_FLAG((second&(2))>>1);
230
mpegHeader->setPES_EXT_FLAG(second&(1));
235
PES_header_data_length = getbits(8);
237
int third=getByteDirect();
239
mpegHeader->setPES_HEADER_DATA_LENGTH(third);
243
// PARSING MPEG 2 HEADER FLAGS [START]
245
unsigned char nukeBuffer[300];
247
int PTS_DTS_flags=mpegHeader->getPTSDTSFlag();
248
if (PTS_DTS_flags == 0) {
249
mpegHeader->setPTSFlag(false);
251
mpegHeader->setPTSFlag(true);
254
if (PTS_DTS_flags > 0x1) {
255
if (read((char*)nukeBuffer,5) == false) return false;
256
double pts=GET_MPEG2_PTS(nukeBuffer);
257
pts=(pts*300.0)/(double)MPEG2_CLK_REF;
258
mpegHeader->setPTSTimeStamp(pts);
261
if (PTS_DTS_flags > 0x2) {
262
if (read((char*)nukeBuffer,5) == false) return false;
263
double dts=GET_MPEG2_PTS(nukeBuffer);
264
mpegHeader->setDTSTimeStamp((dts*300.0)/(double)MPEG2_CLK_REF);
268
int ESCRFlag=mpegHeader->getESCRFlag();
270
cout << "ESCRFlag == 1"<<endl;
271
if (read((char*)nukeBuffer,6) == false) return false;
275
int ES_rate_flag=mpegHeader->getES_RATE_Flag();
276
if (ES_rate_flag == 1){
277
cout << "ES_rate_flag == 1"<<endl;
278
if (read((char*)nukeBuffer,3) == false) return false;
282
int DSM_trick_mode_flag=mpegHeader->getDMSTRICKFLAG();
283
if (DSM_trick_mode_flag == 1){
284
cout << "DSM_trick_mode_flag == 1"<<endl;
285
if (read((char*)nukeBuffer,1) == false) return false;
289
int additional_copy_info_flag=mpegHeader->getADDITIONAL_COPY_FLAG();
290
if (additional_copy_info_flag == 1) {
291
cout << "additional_copy_info_flag == 1"<<endl;
292
if (read((char*)nukeBuffer,1) == false) return false;
296
int PES_CRC_flag=mpegHeader->getPES_CRC_FLAG();
297
if (PES_CRC_flag == 1) {
298
cout << "PES_CRC_flag == 1"<<endl;
299
if (read((char*)nukeBuffer,2) == false) return false;
304
// PES Extension [START]
307
int PES_extension_flag=mpegHeader->getPES_EXT_FLAG();
308
if (PES_extension_flag == 1) {
311
PES_private_data_flag = get1bit();
312
pack_header_field_flag = get1bit();
313
program_packet_sequence_counter_flag = get1bit();
314
PSTD_buffer_flag = get1bit();
316
PES_extension_flag_2 = get1bit();
318
int extensionByte=getByteDirect();
321
mpegHeader->setPrivateDataFlag((extensionByte&(128))>>7);
322
mpegHeader->setPackHeaderFieldFlag((extensionByte&(64))>>6);
323
mpegHeader->setSequenceCounterFlag((extensionByte&(32))>>5);
324
mpegHeader->setSTDBufferFlag((extensionByte&(16))>>4);
325
mpegHeader->setPES_EXT_FLAG_2(extensionByte&(1));
327
int PES_private_data_flag=mpegHeader->getPrivateDataFlag();
328
if (PES_private_data_flag == 1) {
329
if (read((char*)nukeBuffer,128) == false) return false;
333
int pack_header_field_flag=mpegHeader->getPackHeaderFieldFlag();
334
if (pack_header_field_flag == 1) {
335
printf("pack header field flag value not allowed in program streams\n");
339
int sequence_counter_flag=mpegHeader->getSequenceCounterFlag();
340
if (sequence_counter_flag==1) {
341
cout<<"sequence_counter_flag ==1"<<endl;
342
if (read((char*)nukeBuffer,2) == false) return false;
346
int PSTD_buffer_flag=mpegHeader->getSTDBufferFlag();
347
if (PSTD_buffer_flag==1) {
348
if (read((char*)nukeBuffer,2) == false) return false;
352
int PES_extension_flag_2=mpegHeader->getPES_EXT_FLAG_2();
353
if (PES_extension_flag_2 == 1) {
354
int extension2_byte=getByteDirect();
356
mpegHeader->setPES_EXT_FIELD_LENGTH(extension2_byte&(254));
359
int PES_field_length=mpegHeader->getPES_EXT_FIELD_LENGTH();
361
for (j=0;j<PES_field_length ; j++) {
362
cout << "PES_field_length (nuke)"<<endl;
369
// PES Extension [END]
372
// now nuke remaining bytes from PES DATA Length
373
int PES_HEADER_DATA_LENGTH=mpegHeader->getPES_HEADER_DATA_LENGTH();
374
int tmp=PES_HEADER_DATA_LENGTH-pos;
376
if (read((char*)nukeBuffer,tmp) == false) return false;
385
// PARSING MPEG 2 HEADER FLAGS [START]
388
int parsed=stdCnt+pos;
394
int PESSystemStream::processPacketHeader(MpegSystemHeader* mpegHeader) {
395
unsigned char nextByte;
398
unsigned char scratch[10];
401
nextByte=getByteDirect();
403
mpegHeader->setPTSFlag(false);
406
while (nextByte & 0x80) {
409
if (val == -1) return false;
414
if ((nextByte >> 6) == 0x01) {
416
scratch[1]=getByteDirect();
417
scratch[2]=getByteDirect();
420
if ((nextByte >> 4) == 0x02) {
421
scratch[0] = nextByte;
422
if (read((char*)&scratch[1],4) == false) return false;
423
/* presentation time stamps */
425
unsigned long low4Bytes;
427
double dtsTimeStamp=0.0;
428
readTimeStamp((unsigned char*)scratch,&hiBit,&low4Bytes);
429
makeClockTime(hiBit,low4Bytes,&ptsTimeStamp);
430
mpegHeader->setPTSFlag(true);
431
mpegHeader->setPTSTimeStamp(ptsTimeStamp);
432
mpegHeader->setDTSTimeStamp(dtsTimeStamp);
436
else if ((nextByte >> 4) == 0x03) {
437
scratch[0] = nextByte;
438
if (read((char*)&scratch[1],9) == false) return false;
439
/* presentation and decoding time stamps */
441
unsigned long low4Bytes;
444
readTimeStamp((unsigned char*)scratch,&hiBit,&low4Bytes);
445
makeClockTime(hiBit,low4Bytes,&ptsTimeStamp);
447
readTimeStamp((unsigned char*)&(scratch[5]),&hiBit,&low4Bytes);
448
makeClockTime(hiBit,low4Bytes,&dtsTimeStamp);
449
mpegHeader->setPTSFlag(true);
450
mpegHeader->setPTSTimeStamp(ptsTimeStamp);
451
mpegHeader->setDTSTimeStamp(dtsTimeStamp);
460
void PESSystemStream::readTimeStamp(unsigned char* inputBuffer,
461
unsigned char* hiBit,
462
unsigned long* low4Bytes) {
463
*hiBit = ((unsigned long)inputBuffer[0] >> 3) & 0x01;
464
*low4Bytes = (((unsigned long)inputBuffer[0] >> 1) & 0x03) << 30;
465
*low4Bytes |= (unsigned long)inputBuffer[1] << 22;
466
*low4Bytes |= ((unsigned long)inputBuffer[2] >> 1) << 15;
467
*low4Bytes |= (unsigned long)inputBuffer[3] << 7;
468
*low4Bytes |= ((unsigned long)inputBuffer[4]) >> 1;
472
void PESSystemStream::readSTD(unsigned char* inputBuffer,
473
MpegSystemHeader* mpegHeader) {
475
unsigned long stdBufferSize;
476
stdBufferScale = ((int)(inputBuffer[0] & 0x20) >> 5);
477
stdBufferSize = ((unsigned long)inputBuffer[0] & 0x1f) << 8;
478
stdBufferSize |= (unsigned long)inputBuffer[1];
479
mpegHeader->setStdBufferScale(stdBufferScale);
480
mpegHeader->setStdBufferSize(stdBufferSize);
484
int PESSystemStream::makeClockTime(unsigned char hiBit,
485
unsigned long low4Bytes,
486
double * clockTime) {
487
if (hiBit != 0 && hiBit != 1) {
491
*clockTime = (double)hiBit*FLOAT_0x10000*FLOAT_0x10000 + (double)low4Bytes;
492
*clockTime /= (double)_STD_SYSTEM_CLOCK_FREQ;