~ubuntu-branches/ubuntu/breezy/kdemultimedia/breezy

« back to all changes in this revision

Viewing changes to mpeglib/lib/mpegplay/pesSystemStream.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-03-24 04:48:58 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050324044858-8ff88o9jxej6ii3d
Tags: 4:3.4.0-0ubuntu3
Add kubuntu_02_hide_arts_menu_entries.diff to hide artsbuilder and artscontrol k-menu entries

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  demux pes mpeg stream 
 
3
  Copyright (C) 2001  Martin Vogt
 
4
 
 
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.
 
8
 
 
9
  For more information look at the file COPYRIGHT in this package
 
10
 
 
11
 */
 
12
 
 
13
 
 
14
 
 
15
#include "pesSystemStream.h"
 
16
 
 
17
#include <iostream>
 
18
 
 
19
using namespace std;
 
20
 
 
21
PESSystemStream::PESSystemStream(InputStream* input) {
 
22
  this->input=input;
 
23
}
 
24
 
 
25
 
 
26
PESSystemStream::~PESSystemStream() {
 
27
}
 
28
 
 
29
 
 
30
 
 
31
int PESSystemStream::getByteDirect() {
 
32
  unsigned char byte;
 
33
  if (input->read((char*)&byte,1) != 1) {
 
34
    return -1;
 
35
  }
 
36
  bytes_read++;
 
37
  return (int)byte;
 
38
}
 
39
 
 
40
int PESSystemStream::read(char* pointer,int bytes) {
 
41
  if (input->read(pointer,bytes) != bytes) {
 
42
    return false;
 
43
  }
 
44
  bytes_read+=bytes;
 
45
  
 
46
  return true;
 
47
}
 
48
 
 
49
int PESSystemStream::processStartCode(unsigned int startCode,
 
50
                                      MpegSystemHeader* mpegHeader) {
 
51
  int lok=true;
 
52
  bytes_read=4;           // startcode
 
53
  mpegHeader->setPacketLen(0);
 
54
  mpegHeader->setPacketID(_PAKET_ID_NUKE);
 
55
 
 
56
  // handle default
 
57
  bytes_read=processPacket(startCode,mpegHeader);
 
58
  return bytes_read;
 
59
}
 
60
 
 
61
 
 
62
/* Returns:
 
63
   0 - no error, but not video packet we want
 
64
   -1 - error
 
65
   >0 - length of packet
 
66
*/
 
67
int PESSystemStream::processPacket(unsigned int startCode,
 
68
                                    MpegSystemHeader* mpegHeader) {
 
69
 
 
70
  int ioBytes;
 
71
  unsigned short packetLength;
 
72
  int packetDataLength;
 
73
 
 
74
  /* Leftovers from previous video packets */
 
75
 
 
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);
 
81
    return false;
 
82
  }
 
83
  
 
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");
 
88
  }
 
89
  
 
90
  if (read((char*)&packetLength, 2) == false) return false;
 
91
  packetLength = htons(packetLength);
 
92
 
 
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:
 
100
    break;
 
101
  default:
 
102
    switch(packetID) {
 
103
    case _PRIVATE_STREAM_1_ID:
 
104
      break;
 
105
    default:
 
106
      switch (packetID) {
 
107
      case _PRIVATE_STREAM_2_ID:
 
108
      case _PADDING_STREAM_ID:
 
109
      case _RESERVED_STREAM_ID:
 
110
      case _ECM_STREAM_ID:
 
111
      case _EMM_STREAM_ID:
 
112
      case _PROGRAM_STREAM_DIRECTORY_ID:
 
113
      case _DSMCC_STREAM_ID:
 
114
      case _ITUTRECH222TYPEE_STREAM_ID:
 
115
        return bytes_read;
 
116
      }
 
117
      printf("\nUnknown packet type. (%x) at %ld\n",
 
118
             packetID,input->getBytePosition());
 
119
      return bytes_read;
 
120
    }
 
121
  }
 
122
  // this is only processed if audio or video found
 
123
  
 
124
  if (mpegHeader->getMPEG2()==false) {
 
125
    packetDataLength = packetLength-processPacketHeader(mpegHeader);
 
126
  } else {
 
127
    int len=processMPEG2PacketHeader(mpegHeader);
 
128
 
 
129
    if (len < 0) {
 
130
      return false;
 
131
    }
 
132
    packetDataLength = packetLength-len;
 
133
 
 
134
    // now check in private stream for AC3
 
135
    if ( packetID == _PRIVATE_STREAM_1_ID ) {
 
136
      packetDataLength = packetDataLength-processPrivateHeader(mpegHeader);
 
137
    }
 
138
  }
 
139
 
 
140
  if (packetDataLength <= 0) {
 
141
    if (mpegHeader->hasPSHeader()) return false;
 
142
    // -> buggy TS stream
 
143
    packetDataLength=0;
 
144
  }
 
145
  mpegHeader->setPESPacketLen(packetDataLength);
 
146
 
 
147
  return bytes_read;
 
148
 
 
149
}
 
150
 
 
151
 
 
152
int PESSystemStream::processPrivateHeader(MpegSystemHeader* mpegHeader) {
 
153
  char nukeBuffer[30];
 
154
  int pos=0;
 
155
  int one=getByteDirect();  
 
156
  pos++;
 
157
  mpegHeader->setSubStreamID(one);
 
158
  switch(one>>4) {
 
159
  case _SUBSTREAM_AC3_ID>>4:
 
160
    if (read(nukeBuffer,3) == false) return false;
 
161
    mpegHeader->addAvailableLayer(one);
 
162
    cout << "addAvailableLayer:"<<one<<endl;
 
163
    pos+=3;
 
164
    break;
 
165
  case _SUBSTREAM_LPCM_ID>>4:
 
166
    if (read(nukeBuffer,6) == false) return false;
 
167
    pos+=6;
 
168
    break;
 
169
  case _SUBSTREAM_SUBPIC_ID>>4:
 
170
    if (read(nukeBuffer,3) == false) return false;
 
171
    pos+=3;
 
172
    break;
 
173
  default:
 
174
    printf("unknown sub id :%8x\n",one);
 
175
  }
 
176
  return pos;
 
177
 
 
178
}
 
179
 
 
180
 
 
181
int PESSystemStream::processMPEG2PacketHeader(MpegSystemHeader* mpegHeader){
 
182
 
 
183
  int stdCnt=0;
 
184
  int pos=0;
 
185
 
 
186
  // 1. Byte
 
187
  /*
 
188
    FROM FLASK:
 
189
    int getbits(2);
 
190
    encrypted = getbits(2);   // PES_scrambling_control
 
191
    getbits(4);
 
192
    //LIVID
 
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 
 
199
 
 
200
  */
 
201
  int first=getByteDirect();
 
202
  stdCnt++;
 
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));
 
209
 
 
210
 
 
211
  // 2. Byte
 
212
  /*
 
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();
 
220
  */
 
221
  int second=getByteDirect();
 
222
  stdCnt++;
 
223
 
 
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));
 
231
 
 
232
 
 
233
  // 3. Byte
 
234
  /*
 
235
    PES_header_data_length = getbits(8);
 
236
  */
 
237
  int third=getByteDirect();
 
238
  stdCnt++;
 
239
  mpegHeader->setPES_HEADER_DATA_LENGTH(third);
 
240
 
 
241
  
 
242
  //
 
243
  // PARSING MPEG 2 HEADER FLAGS [START]
 
244
  //  
 
245
  unsigned char nukeBuffer[300];
 
246
 
 
247
  int PTS_DTS_flags=mpegHeader->getPTSDTSFlag();
 
248
  if (PTS_DTS_flags == 0) {
 
249
    mpegHeader->setPTSFlag(false);
 
250
  } else {
 
251
    mpegHeader->setPTSFlag(true);
 
252
  }
 
253
    
 
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);
 
259
    pos+=5;
 
260
  }
 
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);
 
265
    pos+=5;
 
266
  }
 
267
 
 
268
  int ESCRFlag=mpegHeader->getESCRFlag();
 
269
  if (ESCRFlag == 1){
 
270
    cout << "ESCRFlag == 1"<<endl;
 
271
    if (read((char*)nukeBuffer,6) == false) return false;
 
272
    pos+=6;
 
273
  }
 
274
  
 
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;
 
279
    pos+=3;
 
280
  }
 
281
 
 
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;
 
286
    pos++;
 
287
  }
 
288
 
 
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;
 
293
    pos++;
 
294
  }
 
295
 
 
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;
 
300
    pos+=2;
 
301
  }
 
302
 
 
303
  //
 
304
  // PES Extension [START]
 
305
  //
 
306
 
 
307
  int PES_extension_flag=mpegHeader->getPES_EXT_FLAG();
 
308
  if (PES_extension_flag == 1) {
 
309
    /*
 
310
      FLASK:
 
311
      PES_private_data_flag = get1bit();
 
312
      pack_header_field_flag = get1bit();
 
313
      program_packet_sequence_counter_flag = get1bit();
 
314
      PSTD_buffer_flag = get1bit();
 
315
      getbits(3);
 
316
      PES_extension_flag_2 = get1bit();
 
317
    */
 
318
    int extensionByte=getByteDirect();
 
319
 
 
320
    pos++;
 
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));
 
326
 
 
327
    int PES_private_data_flag=mpegHeader->getPrivateDataFlag();
 
328
    if (PES_private_data_flag == 1) {
 
329
      if (read((char*)nukeBuffer,128) == false) return false;
 
330
      pos+=128;
 
331
    }
 
332
 
 
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");
 
336
      return false;
 
337
    }
 
338
 
 
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;
 
343
      pos+=2;
 
344
    }
 
345
 
 
346
    int PSTD_buffer_flag=mpegHeader->getSTDBufferFlag();
 
347
    if (PSTD_buffer_flag==1) {
 
348
      if (read((char*)nukeBuffer,2) == false) return false;
 
349
      pos+=2;
 
350
    }
 
351
    
 
352
    int PES_extension_flag_2=mpegHeader->getPES_EXT_FLAG_2();
 
353
    if (PES_extension_flag_2 == 1) {
 
354
      int extension2_byte=getByteDirect();
 
355
      pos++;
 
356
      mpegHeader->setPES_EXT_FIELD_LENGTH(extension2_byte&(254));
 
357
 
 
358
 
 
359
      int PES_field_length=mpegHeader->getPES_EXT_FIELD_LENGTH();
 
360
      int j;
 
361
      for (j=0;j<PES_field_length ; j++) {
 
362
        cout << "PES_field_length (nuke)"<<endl;
 
363
        getByteDirect();
 
364
        pos++;
 
365
      }
 
366
    }
 
367
  }
 
368
  //
 
369
  // PES Extension [END]
 
370
  //
 
371
 
 
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;
 
375
  if (tmp>0) {
 
376
    if (read((char*)nukeBuffer,tmp) == false) return false;
 
377
    pos+=tmp;
 
378
  }
 
379
 
 
380
 
 
381
 
 
382
  
 
383
 
 
384
  //
 
385
  // PARSING MPEG 2 HEADER FLAGS [START]
 
386
  //  
 
387
 
 
388
  int parsed=stdCnt+pos;
 
389
  return parsed;
 
390
  
 
391
}
 
392
   
 
393
 
 
394
int PESSystemStream::processPacketHeader(MpegSystemHeader* mpegHeader) {
 
395
  unsigned char nextByte;
 
396
  int pos;
 
397
  int val;
 
398
  unsigned char scratch[10];
 
399
 
 
400
 
 
401
  nextByte=getByteDirect();
 
402
 
 
403
  mpegHeader->setPTSFlag(false);
 
404
 
 
405
  pos = 1;
 
406
  while (nextByte & 0x80) {
 
407
    ++pos;
 
408
    val=getByteDirect();
 
409
    if (val == -1) return false;
 
410
    scratch[0]=val;
 
411
    
 
412
    nextByte=scratch[0];
 
413
  }
 
414
  if ((nextByte >> 6) == 0x01) {
 
415
    pos += 2;
 
416
    scratch[1]=getByteDirect();
 
417
    scratch[2]=getByteDirect();
 
418
    nextByte=scratch[2];
 
419
  } 
 
420
  if ((nextByte >> 4) == 0x02) {
 
421
    scratch[0] = nextByte;                     
 
422
    if (read((char*)&scratch[1],4) == false) return false;
 
423
    /* presentation time stamps */
 
424
    unsigned char hiBit;
 
425
    unsigned long low4Bytes;
 
426
    double ptsTimeStamp;
 
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);
 
433
    
 
434
    pos += 4;
 
435
  }
 
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 */
 
440
    unsigned char hiBit;
 
441
    unsigned long low4Bytes;
 
442
    double ptsTimeStamp;
 
443
    double dtsTimeStamp;
 
444
    readTimeStamp((unsigned char*)scratch,&hiBit,&low4Bytes);
 
445
    makeClockTime(hiBit,low4Bytes,&ptsTimeStamp);
 
446
 
 
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);
 
452
    
 
453
    pos += 9;
 
454
  } 
 
455
  return pos;
 
456
}
 
457
 
 
458
 
 
459
 
 
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; 
 
469
}
 
470
 
 
471
 
 
472
void PESSystemStream::readSTD(unsigned char* inputBuffer,
 
473
                               MpegSystemHeader* mpegHeader) {
 
474
  int stdBufferScale;
 
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);
 
481
}
 
482
 
 
483
 
 
484
int PESSystemStream::makeClockTime(unsigned char hiBit, 
 
485
                                    unsigned long low4Bytes,
 
486
                                    double * clockTime) {
 
487
  if (hiBit != 0 && hiBit != 1) {
 
488
    *clockTime = 0.0;
 
489
    return 1;
 
490
  }
 
491
  *clockTime = (double)hiBit*FLOAT_0x10000*FLOAT_0x10000 + (double)low4Bytes;
 
492
  *clockTime /= (double)_STD_SYSTEM_CLOCK_FREQ;
 
493
  return 0;
 
494
}
 
495
 
 
496
 
 
497
 
 
498