~ubuntu-branches/ubuntu/precise/mplayer2/precise-proposed

1.1.2 by Reinhard Tartler
Import upstream version 2.0-134-g84d8671
1
/*
2
 * MPG/VOB file parser for DEMUXER v2.5
3
 * copyright (c) 2001 by A'rpi/ESP-team
4
 *
5
 * This file is part of MPlayer.
6
 *
7
 * MPlayer is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * MPlayer is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <unistd.h>
25
#include <math.h>
26
27
#include "config.h"
28
#include "mp_msg.h"
29
#include "options.h"
30
31
#include "libavutil/attributes.h"
32
#include "libmpcodecs/dec_audio.h"
33
#include "stream/stream.h"
34
#include "demuxer.h"
35
#include "parse_es.h"
36
#include "stheader.h"
37
#include "mp3_hdr.h"
38
39
//#define MAX_PS_PACKETSIZE 2048
40
#define MAX_PS_PACKETSIZE (224*1024)
41
42
#define UNKNOWN         0
43
#define VIDEO_MPEG1     0x10000001
44
#define VIDEO_MPEG2     0x10000002
45
#define VIDEO_MPEG4     0x10000004
46
#define VIDEO_H264      0x10000005
47
#define AUDIO_MP2       0x50
48
#define AUDIO_A52       0x2000
49
#define AUDIO_LPCM_BE   0x10001
50
#define AUDIO_AAC       mmioFOURCC('M', 'P', '4', 'A')
51
52
typedef struct mpg_demuxer {
53
  float last_pts;
54
  float first_pts;              // first pts found in stream
55
  float first_to_final_pts_len; // difference between final pts and first pts
56
  int has_valid_timestamps;     // !=0 iff time stamps look linear
57
                                // (not necessarily starting with 0)
58
  unsigned int es_map[0x40];	//es map of stream types (associated to the pes id) from 0xb0 to 0xef
59
  int num_a_streams;
60
  int a_stream_ids[MAX_A_STREAMS];
61
} mpg_demuxer_t;
62
63
static int mpeg_pts_error=0;
64
off_t ps_probe = 0;
65
66
static int parse_psm(demuxer_t *demux, int len) {
67
  unsigned char c, id, type;
68
  unsigned int plen, prog_len, es_map_len;
69
  mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
70
71
  mp_dbg(MSGT_DEMUX,MSGL_V, "PARSE_PSM, len=%d\n", len);
72
  if(! len || len > 1018)
73
    return 0;
74
75
  c = stream_read_char(demux->stream);
76
  if(! (c & 0x80)) {
77
    stream_skip(demux->stream, len - 1);  //not yet valid, discard
78
    return 0;
79
  }
80
  stream_skip(demux->stream, 1);
81
  prog_len = stream_read_word(demux->stream);		//length of program descriptors
82
  stream_skip(demux->stream, prog_len);			//.. that we ignore
83
  es_map_len = stream_read_word(demux->stream);		//length of elementary streams map
84
  es_map_len = FFMIN(es_map_len, len - prog_len - 8);	//sanity check
85
  while(es_map_len > 0) {
86
    type = stream_read_char(demux->stream);
87
    id = stream_read_char(demux->stream);
88
    if(id >= 0xB0 && id <= 0xEF && priv) {
89
      int idoffset = id - 0xB0;
90
      switch(type) {
91
        case 0x1:
92
          priv->es_map[idoffset] = VIDEO_MPEG1;
93
          break;
94
        case 0x2:
95
          priv->es_map[idoffset] = VIDEO_MPEG2;
96
          break;
97
        case 0x3:
98
        case 0x4:
99
          priv->es_map[idoffset] = AUDIO_MP2;
100
          break;
101
        case 0x0f:
102
        case 0x11:
103
          priv->es_map[idoffset] = AUDIO_AAC;
104
          break;
105
        case 0x10:
106
          priv->es_map[idoffset] = VIDEO_MPEG4;
107
          break;
108
        case 0x1b:
109
          priv->es_map[idoffset] = VIDEO_H264;
110
          break;
111
        case 0x81:
112
          priv->es_map[idoffset] = AUDIO_A52;
113
          break;
114
      }
115
      mp_dbg(MSGT_DEMUX,MSGL_V, "PSM ES, id=0x%x, type=%x, stype: %x\n", id, type, priv->es_map[idoffset]);
116
    }
117
    plen = stream_read_word(demux->stream);		//length of elementary stream descriptors
118
    plen = FFMIN(plen, es_map_len);			//sanity check
119
    stream_skip(demux->stream, plen);			//skip descriptors for now
120
    es_map_len -= 4 + plen;
121
  }
122
  stream_skip(demux->stream, 4);			//skip crc32
123
  return 1;
124
}
125
126
// 500000 is a wild guess
127
#define TIMESTAMP_PROBE_LEN 500000
128
129
//MAX_PTS_DIFF_FOR_CONSECUTIVE denotes the maximum difference
130
//between two pts to consider them consecutive
131
//1.0 is a wild guess
132
#define MAX_PTS_DIFF_FOR_CONSECUTIVE 1.0
133
134
//returns the first pts found within TIME_STAMP_PROBE_LEN bytes after stream_pos in demuxer's stream.
135
//if no pts is found or an error occurs, -1.0 is returned.
136
//Packs are freed.
137
static float read_first_mpeg_pts_at_position(demuxer_t* demuxer, off_t stream_pos)
138
{
139
  stream_t *s = demuxer->stream;
140
  mpg_demuxer_t *mpg_d = demuxer->priv;
141
  float pts = -1.0; //the pts to return;
142
  float found_pts1; //the most recently found pts
143
  float found_pts2; //the pts found before found_pts1
144
  float found_pts3; //the pts found before found_pts2
145
  int found = 0;
146
147
  if(!mpg_d || stream_pos < 0)
148
    return pts;
149
150
  found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts;
151
  stream_seek(s, stream_pos);
152
153
  //We look for pts.
154
  //However, we do not stop at the first found one, as timestamps may reset
155
  //Therefore, we seek until we found three consecutive
156
  //pts within MAX_PTS_DIFF_FOR_CONSECUTIVE.
157
158
  while(found<3 && !s->eof
159
   && (fabsf(found_pts2-found_pts1) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
160
   && (fabsf(found_pts3-found_pts2) < MAX_PTS_DIFF_FOR_CONSECUTIVE)
161
   && (stream_tell(s) < stream_pos + TIMESTAMP_PROBE_LEN)
162
   && ds_fill_buffer(demuxer->video))
163
  {
164
    if(mpg_d->last_pts != found_pts1)
165
    {
166
      if(!found)
167
        found_pts3 = found_pts2 = found_pts1 = mpg_d->last_pts; //the most recently found pts
168
      else
169
      {
170
        found_pts3 = found_pts2;
171
        found_pts2 = found_pts1;
172
        found_pts1 = mpg_d->last_pts;
173
      }
174
      found++;
175
    }
176
  }
177
178
  if(found == 3) pts = found_pts3;
179
180
  //clean up from searching of first pts;
181
  demux_flush(demuxer);
182
183
  return pts;
184
}
185
186
/// Open an mpg physical stream
187
static demuxer_t* demux_mpg_open(demuxer_t* demuxer) {
188
  stream_t *s = demuxer->stream;
189
  mpg_demuxer_t* mpg_d;
190
191
  if (!ds_fill_buffer(demuxer->video)) return 0;
192
  mpg_d = calloc(1,sizeof(mpg_demuxer_t));
193
  if(mpg_d)
194
  {
195
    demuxer->priv = mpg_d;
196
    mpg_d->last_pts = -1.0;
197
    mpg_d->first_pts = -1.0;
198
199
    //if seeking is allowed set has_valid_timestamps if appropriate
200
    if(demuxer->seekable
201
       && (demuxer->stream->type == STREAMTYPE_FILE
202
           || demuxer->stream->type == STREAMTYPE_VCD)
203
       && demuxer->movi_start != demuxer-> movi_end
204
    )
205
    {
206
      //We seek to the beginning of the stream, to somewhere in the
207
      //middle, and to the end of the stream, while remembering the pts
208
      //at each of the three positions. With these pts, we check whether
209
      //or not the pts are "linear enough" to justify seeking by the pts
210
      //of the stream
211
212
      //The position where the stream is now
213
      off_t pos = stream_tell(s);
214
      float first_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_start);
215
      if(first_pts != -1.0)
216
      {
217
        float middle_pts = read_first_mpeg_pts_at_position(demuxer, (demuxer->movi_end + demuxer->movi_start)/2);
218
        if(middle_pts != -1.0)
219
        {
220
          float final_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_end - TIMESTAMP_PROBE_LEN);
221
          if(final_pts != -1.0)
222
          {
223
            // found proper first, middle, and final pts.
224
            float proportion = (middle_pts-first_pts==0) ? -1 : (final_pts-middle_pts)/(middle_pts-first_pts);
225
            // if they are linear enough set has_valid_timestamps
226
            if((0.5 < proportion) && (proportion < 2))
227
            {
228
              mpg_d->first_pts = first_pts;
229
              mpg_d->first_to_final_pts_len = final_pts - first_pts;
230
              mpg_d->has_valid_timestamps = 1;
231
            }
232
          }
233
        }
234
      }
235
236
      //Cleaning up from seeking in stream
237
      demuxer->stream->eof=0;
238
      demuxer->video->eof=0;
239
      demuxer->audio->eof=0;
240
241
      stream_seek(s,pos);
242
      ds_fill_buffer(demuxer->video);
243
    } // if ( demuxer->seekable )
244
  } // if ( mpg_d )
245
  return demuxer;
246
}
247
248
static void demux_close_mpg(demuxer_t* demuxer) {
249
  mpg_demuxer_t* mpg_d = demuxer->priv;
250
  free(mpg_d);
251
}
252
253
254
static unsigned long long read_mpeg_timestamp(stream_t *s,int c){
255
  unsigned int d,e;
256
  unsigned long long pts;
257
  d=stream_read_word(s);
258
  e=stream_read_word(s);
259
  if( ((c&1)!=1) || ((d&1)!=1) || ((e&1)!=1) ){
260
    ++mpeg_pts_error;
261
    return 0; // invalid pts
262
  }
263
  pts=(((uint64_t)((c>>1)&7))<<30)|((d>>1)<<15)|(e>>1);
1.1.3 by Reinhard Tartler
Import upstream version 2.0-426-gc32b3ed
264
  mp_dbg(MSGT_DEMUX,MSGL_DBG3," pts {%llu}",pts);
1.1.2 by Reinhard Tartler
Import upstream version 2.0-134-g84d8671
265
  return pts;
266
}
267
268
static void new_audio_stream(demuxer_t *demux, int aid){
269
  if(!demux->a_streams[aid]){
270
    mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demux->priv;
271
    sh_audio_t* sh_a;
272
    new_sh_audio(demux,aid);
273
    sh_a = (sh_audio_t*)demux->a_streams[aid];
274
    sh_a->needs_parsing = 1;
275
    switch(aid & 0xE0){  // 1110 0000 b  (high 3 bit: type  low 5: id)
276
      case 0x00: sh_a->format=0x50;break; // mpeg
277
      case 0xA0: sh_a->format=0x10001;break;  // dvd pcm
278
      case 0x80: if((aid & 0xF8) == 0x88) sh_a->format=0x2001;//dts
279
                  else sh_a->format=0x2000;break; // ac3
280
    }
281
    //evo files
282
    if((aid & 0xC0) == 0xC0) sh_a->format=0x2000;
283
    else if(aid >= 0x98 && aid <= 0x9f) sh_a->format=0x2001;
284
    if (mpg_d) mpg_d->a_stream_ids[mpg_d->num_a_streams++] = aid;
285
  }
286
  if(demux->audio->id==-1) demux->audio->id=aid;
287
}
288
289
static int demux_mpg_read_packet(demuxer_t *demux,int id){
290
  int d av_unused;
291
  int len;
292
  int set_pts=0; // !=0 iff pts has been set to a proper value
293
  unsigned char c=0;
294
  unsigned long long pts=0;
295
  unsigned long long dts av_unused = 0;
296
  int l;
297
  int pes_ext2_subid=-1;
298
  double stream_pts = MP_NOPTS_VALUE;
299
  demux_stream_t *ds=NULL;
300
  demux_packet_t* dp;
301
  mpg_demuxer_t *priv = (mpg_demuxer_t *) demux->priv;
302
303
  mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_read_packet: %X\n",id);
304
305
//  if(id==0x1F0){
306
//    demux->synced=0; // force resync after 0x1F0
307
//    return -1;
308
//}
309
310
//  if(id==0x1BA) packet_start_pos=stream_tell(demux->stream);
311
  if((id<0x1BC || id>=0x1F0) && id != 0x1FD) return -1;
312
  if(id==0x1BE) return -1; // padding stream
313
  if(id==0x1BF) return -1; // private2
314
315
  len=stream_read_word(demux->stream);
316
  mp_dbg(MSGT_DEMUX,MSGL_DBG3,"PACKET len=%d",len);
317
//  if(len==62480){ demux->synced=0;return -1;} /* :) */
318
  if(len==0 || len>MAX_PS_PACKETSIZE){
319
    mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS packet len: %d\n",len);
320
    return -2;  // invalid packet !!!!!!
321
  }
322
323
  mpeg_pts_error=0;
324
325
  if(id==0x1BC) {
326
    parse_psm(demux, len);
327
    return 0;
328
  }
329
330
  while(len>0){   // Skip stuFFing bytes
331
    c=stream_read_char(demux->stream);
332
    --len;
333
    if(c!=0xFF)break;
334
  }
335
  if((c>>6)==1){  // Read (skip) STD scale & size value
336
//    printf("  STD_scale=%d",(c>>5)&1);
337
    d=((c&0x1F)<<8)|stream_read_char(demux->stream);
338
    len-=2;
339
//    printf("  STD_size=%d",d);
340
    c=stream_read_char(demux->stream);
341
  }
342
  // Read System-1 stream timestamps:
343
  if((c>>4)==2){
344
    pts=read_mpeg_timestamp(demux->stream,c);
345
    set_pts=1;
346
    len-=4;
347
  } else
348
  if((c>>4)==3){
349
    pts=read_mpeg_timestamp(demux->stream,c);
350
    c=stream_read_char(demux->stream);
351
    if((c>>4)!=1) pts=0; //printf("{ERROR4}");
352
    else set_pts = 1;
353
    dts=read_mpeg_timestamp(demux->stream,c);
354
    len-=4+1+4;
355
  } else
356
  if((c>>6)==2){
357
    int pts_flags;
358
    int hdrlen;
359
    int parse_ext2;
360
    // System-2 (.VOB) stream:
361
    c=stream_read_char(demux->stream);
362
    pts_flags=c>>6;
363
    parse_ext2 = (id == 0x1FD) && ((c & 0x3F) == 1);
364
    c=stream_read_char(demux->stream);
365
    hdrlen=c;
366
    len-=2;
367
    mp_dbg(MSGT_DEMUX,MSGL_DBG3,"  hdrlen=%d  (len=%d)",hdrlen,len);
368
    if(hdrlen>len){ mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: invalid header length  \n"); return -1;}
369
    if(pts_flags==2 && hdrlen>=5){
370
      c=stream_read_char(demux->stream);
371
      pts=read_mpeg_timestamp(demux->stream,c);
372
      set_pts=1;
373
      len-=5;hdrlen-=5;
374
    } else
375
    if(pts_flags==3 && hdrlen>=10){
376
      c=stream_read_char(demux->stream);
377
      pts=read_mpeg_timestamp(demux->stream,c);
378
      set_pts=1;
379
      c=stream_read_char(demux->stream);
380
      dts=read_mpeg_timestamp(demux->stream,c);
381
      len-=10;hdrlen-=10;
382
    }
383
    len-=hdrlen;
384
    if(parse_ext2 && hdrlen>=3) {
385
      c=stream_read_char(demux->stream);
386
      hdrlen--;
387
388
      if((c & 0x0F) != 0x0F) {
389
        mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: pes_extension_flag2 not set, discarding pes packet\n");
390
        return -1;
391
      }
392
      if(c & 0x80) { //pes_private_data_flag
393
        if(hdrlen<16) {
394
          mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pes_private_data bytes: %d < 16, discarding pes packet\n", hdrlen);
395
          return -1;
396
        }
397
        stream_skip(demux->stream, 16);
398
        hdrlen-=16;
399
      }
400
      if(c & 0x40) { //pack_header_field_flag
401
        int l = stream_read_char(demux->stream);
402
        if(l < 0) //couldn't read from the stream?
403
          return -1;
404
        hdrlen--;
405
        if(l < 0 || hdrlen < l) {
406
          mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough pack_header bytes: hdrlen: %d < skip: %d, discarding pes packet\n",
407
                                   hdrlen, l);
408
          return -1;
409
        }
410
        stream_skip(demux->stream, l);
411
        hdrlen-=l;
412
      }
413
      if(c & 0x20) { //program_packet_sequence_counter_flag
414
        if(hdrlen < 2) {
415
          mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: not enough program_packet bytes: hdrlen: %d, discarding pes packet\n", hdrlen);
416
          return -1;
417
        }
418
        stream_skip(demux->stream, 2);
419
        hdrlen-=2;
420
      }
421
      if(c & 0x10) {
422
        //STD
423
        stream_skip(demux->stream, 2);
424
        hdrlen-=2;
425
      }
426
      c=stream_read_char(demux->stream); //pes_extension2 flag
427
      hdrlen--;
428
      if(c!=0x81)  { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown pes_extension2 format, len is > 1  \n"); return -1;}
429
      c=stream_read_char(demux->stream); //pes_extension2 payload === substream id
430
      hdrlen--;
431
      if(c<0x55 || c>0x5F)   { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown vc1 substream_id: 0x%x  \n", c); return -1;}
432
      pes_ext2_subid=c;
433
    }
434
    if(hdrlen>0)
435
      stream_skip(demux->stream,hdrlen); // skip header and stuffing bytes
436
437
    if(id==0x1FD && pes_ext2_subid!=-1) {
438
      //==== EVO VC1 STREAMS ===//
439
      if(!demux->v_streams[pes_ext2_subid]) new_sh_video(demux,pes_ext2_subid);
440
      if(demux->video->id==-1) demux->video->id=pes_ext2_subid;
441
      if(demux->video->id==pes_ext2_subid){
442
        ds=demux->video;
443
        if(!ds->sh) ds->sh=demux->v_streams[pes_ext2_subid];
444
        if(priv && ds->sh) {
445
          sh_video_t *sh = (sh_video_t *)ds->sh;
446
          sh->format = mmioFOURCC('W', 'V', 'C', '1');
447
        }
448
      }
449
    }
450
    //============== DVD Audio sub-stream ======================
451
    if(id==0x1BD){
452
      int aid, rawa52 = 0;
453
      off_t tmppos;
454
      unsigned int tmp;
455
456
      tmppos = stream_tell(demux->stream);
457
      tmp = stream_read_word(demux->stream);
458
      stream_seek(demux->stream, tmppos);
459
      /// vdr stores A52 without the 4 header bytes, so we have to check this condition first
460
      if(tmp == 0x0B77) {
461
        aid = 128;
462
        rawa52 = 1;
463
      }
464
      else {
465
        aid=stream_read_char(demux->stream);--len;
466
        if(len<3) return -1; // invalid audio packet
467
      }
468
469
      // AID:
470
      // 0x20..0x3F  subtitle
471
      // 0x80..0x87 and 0xC0..0xCF  AC3 audio
472
      // 0x88..0x8F and 0x98..0x9F  DTS audio
473
      // 0xA0..0xBF  PCM audio
474
475
      if((aid & 0xE0) == 0x20){
476
        // subtitle:
477
        aid&=0x1F;
478
479
        if(!demux->s_streams[aid]){
480
            sh_sub_t *sh = new_sh_sub(demux, aid);
481
            if (sh) sh->type = 'v';
482
            mp_msg(MSGT_DEMUX,MSGL_V,"==> Found subtitle: %d\n",aid);
483
        }
484
485
        if(demux->sub->id > -1)
486
          demux->sub->id &= 0x1F;
487
        if(!demux->opts->sub_lang && demux->sub->id == -1)
488
          demux->sub->id = aid;
489
        if(demux->sub->id==aid){
490
            ds=demux->sub;
491
        }
492
      } else if((aid >= 0x80 && aid <= 0x8F) || (aid >= 0x98 && aid <= 0xAF) || (aid >= 0xC0 && aid <= 0xCF)) {
493
494
//        aid=128+(aid&0x7F);
495
        // aid=0x80..0xBF
496
        new_audio_stream(demux, aid);
497
      if(demux->audio->id==aid){
498
        int type;
499
        ds=demux->audio;
500
        if(!ds->sh) ds->sh=demux->a_streams[aid];
501
        // READ Packet: Skip additional audio header data:
502
        if(!rawa52) {
503
        c=stream_read_char(demux->stream);//num of frames
504
        type=stream_read_char(demux->stream);//startpos hi
505
        type=(type<<8)|stream_read_char(demux->stream);//startpos lo
506
//        printf("\r[%02X][%04X]",c,type);
507
        len-=3;
508
        }
509
        if((aid&0xE0)==0xA0 && len>=3){
510
	  unsigned char* hdr;
511
	  // save audio header as codecdata!
512
	  if(!((sh_audio_t*)(ds->sh))->codecdata_len){
513
	      ((sh_audio_t*)(ds->sh))->codecdata=malloc(3);
514
	      ((sh_audio_t*)(ds->sh))->codecdata_len=3;
515
	  }
516
	  hdr=((sh_audio_t*)(ds->sh))->codecdata;
517
          // read LPCM header:
518
	  // emphasis[1], mute[1], rvd[1], frame number[5]:
519
          hdr[0]=stream_read_char(demux->stream);
520
//          printf(" [%01X:%02d]",c>>5,c&31);
521
	  // quantization[2],freq[2],rvd[1],channels[3]
522
          hdr[1]=stream_read_char(demux->stream);
523
//          printf("[%01X:%01X] ",c>>4,c&15);
524
	  // dynamic range control (0x80=off):
525
          hdr[2]=stream_read_char(demux->stream);
526
//          printf("[%02X] ",c);
527
          len-=3;
528
          if(len<=0) mp_msg(MSGT_DEMUX,MSGL_V,"End of packet while searching for PCM header\n");
529
        }
530
//        printf("  \n");
531
      } //  if(demux->audio->id==aid)
532
533
      } else mp_msg(MSGT_DEMUX,MSGL_V,"Unknown 0x1BD substream: 0x%02X  \n",aid);
534
    } //if(id==0x1BD)
535
  } else {
536
    if(c!=0x0f){
537
      mp_msg(MSGT_DEMUX,MSGL_V,"  {ERROR5,c=%d}  \n",c);
538
      return -1;  // invalid packet !!!!!!
539
    }
540
  }
541
  if(mpeg_pts_error) mp_msg(MSGT_DEMUX,MSGL_V,"  {PTS_err:%d}  \n",mpeg_pts_error);
542
  mp_dbg(MSGT_DEMUX,MSGL_DBG3," => len=%d\n",len);
543
544
//  if(len<=0 || len>MAX_PS_PACKETSIZE) return -1;  // Invalid packet size
545
  if(len<=0 || len>MAX_PS_PACKETSIZE){
546
    mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS data len: %d\n",len);
547
    return -1;  // invalid packet !!!!!!
548
  }
549
550
  if(id>=0x1C0 && id<=0x1DF){
551
    // mpeg audio
552
    int aid=id-0x1C0;
553
    new_audio_stream(demux, aid);
554
    if(demux->audio->id==aid){
555
      ds=demux->audio;
556
      if(!ds->sh) ds->sh=demux->a_streams[aid];
557
      if(priv && ds->sh) {
558
        sh_audio_t *sh = (sh_audio_t *)ds->sh;
559
        if(priv->es_map[id - 0x1B0])
560
          sh->format = priv->es_map[id - 0x1B0];
561
          mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
562
      }
563
    }
564
  } else
565
  if(id>=0x1E0 && id<=0x1EF){
566
    // mpeg video
567
    int aid=id-0x1E0;
568
    if(!demux->v_streams[aid]) new_sh_video(demux,aid);
569
    if(demux->video->id==-1) demux->video->id=aid;
570
    if(demux->video->id==aid){
571
      ds=demux->video;
572
      if(!ds->sh) ds->sh=demux->v_streams[aid];
573
      if(priv && ds->sh) {
574
        sh_video_t *sh = (sh_video_t *)ds->sh;
575
        if(priv->es_map[id - 0x1B0]) {
576
          sh->format = priv->es_map[id - 0x1B0];
577
          mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);
578
        }
579
      }
580
    }
581
  }
582
583
  if(ds){
584
    mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Read %d data bytes from packet %04X\n",len,id);
585
//    printf("packet start = 0x%X  \n",stream_tell(demux->stream)-packet_start_pos);
586
587
    dp=new_demux_packet(len);
588
    if(!dp) {
589
      mp_dbg(MSGT_DEMUX,MSGL_ERR,"DEMUX_MPG ERROR: couldn't create demux_packet(%d bytes)\n",len);
590
      stream_skip(demux->stream,len);
591
      return 0;
592
    }
593
    l = stream_read(demux->stream,dp->buffer,len);
594
    if(l<len)
595
      resize_demux_packet(dp, l);
596
    len = l;
597
    if(set_pts)
598
      dp->pts=pts/90000.0f;
599
    dp->pos=demux->filepos;
600
    /*
601
      workaround:
602
      set dp->stream_pts only when feeding the video stream, or strangely interleaved files
603
      (such as SWIII) will show strange alternations in the stream time, wildly going
604
      back and forth
605
    */
606
    if(ds == demux->video && stream_control(demux->stream, STREAM_CTRL_GET_CURRENT_TIME,(void *)&stream_pts)!=STREAM_UNSUPPORTED)
607
      dp->stream_pts = stream_pts;
608
    ds_add_packet(ds,dp);
609
    if (demux->priv && set_pts) ((mpg_demuxer_t*)demux->priv)->last_pts = pts/90000.0f;
610
//    if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len);
611
    return 1;
612
  }
613
  mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len,id);
614
  if(len<=2356) stream_skip(demux->stream,len);
615
  return 0;
616
}
617
618
static int num_elementary_packets100=0;
619
static int num_elementary_packets101=0;
620
static int num_elementary_packets12x=0;
621
static int num_elementary_packets1B6=0;
622
static int num_elementary_packetsPES=0;
623
static int num_mpeg12_startcode=0;
624
static int num_h264_slice=0; //combined slice
625
static int num_h264_dpa=0; //DPA Slice
626
static int num_h264_dpb=0; //DPB Slice
627
static int num_h264_dpc=0; //DPC Slice
628
static int num_h264_idr=0; //IDR Slice
629
static int num_h264_sps=0;
630
static int num_h264_pps=0;
631
632
static int num_mp3audio_packets=0;
633
634
static void clear_stats(void)
635
{
636
  num_elementary_packets100=0;
637
  num_elementary_packets101=0;
638
  num_elementary_packets1B6=0;
639
  num_elementary_packets12x=0;
640
  num_elementary_packetsPES=0;
641
  num_mpeg12_startcode=0;
642
  num_h264_slice=0; //combined slice
643
  num_h264_dpa=0; //DPA Slice
644
  num_h264_dpb=0; //DPB Slice
645
  num_h264_dpc=0; //DPC Slice
646
  num_h264_idr=0; //IDR Slice
647
  num_h264_sps=0;
648
  num_h264_pps=0;
649
  num_mp3audio_packets=0;
650
}
651
652
//assumes demuxer->synced < 2
653
static inline void update_stats(int head)
654
{
655
  if(head==0x1B6) ++num_elementary_packets1B6;
656
  else if(head==0x1B3 || head==0x1B8) ++num_mpeg12_startcode;
657
  else if(head==0x100) ++num_elementary_packets100;
658
  else if(head==0x101) ++num_elementary_packets101;
659
  else if(head==0x1BD || (0x1C0<=head && head<=0x1EF))
660
    num_elementary_packetsPES++;
661
  else if(head>=0x120 && head<=0x12F) ++num_elementary_packets12x;
662
  if(head>=0x100 && head<0x1B0)
663
  {
664
    if((head&~0x60) == 0x101) ++num_h264_slice;
665
    else if((head&~0x60) == 0x102) ++num_h264_dpa;
666
    else if((head&~0x60) == 0x103) ++num_h264_dpb;
667
    else if((head&~0x60) == 0x104) ++num_h264_dpc;
668
    else if((head&~0x60) == 0x105 && head != 0x105) ++num_h264_idr;
669
    else if((head&~0x60) == 0x107 && head != 0x107) ++num_h264_sps;
670
    else if((head&~0x60) == 0x108 && head != 0x108) ++num_h264_pps;
671
  }
672
}
673
674
static int demux_mpg_probe(demuxer_t *demuxer) {
675
  int pes av_unused = 1;
676
  int tmp;
677
  off_t tmppos;
678
  int file_format = DEMUXER_TYPE_UNKNOWN;
679
680
  tmppos=stream_tell(demuxer->stream);
681
  tmp=stream_read_dword(demuxer->stream);
682
  if(tmp==0x1E0 || tmp==0x1C0) {
683
    tmp=stream_read_word(demuxer->stream);
684
    if(tmp>1 && tmp<=2048) pes=0; // demuxer->synced=3; // PES...
685
  }
686
  stream_seek(demuxer->stream,tmppos);
687
688
  clear_stats();
689
690
  if(demux_mpg_open(demuxer))
691
    file_format=DEMUXER_TYPE_MPEG_PS;
692
  else {
693
    mp_msg(MSGT_DEMUX,MSGL_V,"MPEG packet stats: p100: %d  p101: %d p1B6: %d p12x: %d sli: %d a: %d b: %d c: %d idr: %d sps: %d pps: %d PES: %d  MP3: %d, synced: %d\n",
694
     num_elementary_packets100,num_elementary_packets101,
695
     num_elementary_packets1B6,num_elementary_packets12x,
696
     num_h264_slice, num_h264_dpa,
697
     num_h264_dpb, num_h264_dpc=0,
698
     num_h264_idr, num_h264_sps=0,
699
     num_h264_pps,
700
     num_elementary_packetsPES,num_mp3audio_packets, demuxer->synced);
701
702
     //MPEG packet stats: p100: 458  p101: 458  PES: 0  MP3: 1103  (.m2v)
703
     if(num_mp3audio_packets>50 && num_mp3audio_packets>2*num_elementary_packets100
704
        && abs(num_elementary_packets100-num_elementary_packets101)>2)
705
       return file_format;
706
707
      // some hack to get meaningfull error messages to our unhappy users:
708
      if(num_mpeg12_startcode>=2 && num_elementary_packets100>=2 && num_elementary_packets101>=2 &&
709
         abs(num_elementary_packets101+8-num_elementary_packets100)<16) {
710
         if(num_elementary_packetsPES>=4 && num_elementary_packetsPES>=num_elementary_packets100-4) {
711
           return file_format;
712
         }
713
         file_format=DEMUXER_TYPE_MPEG_ES; //  <-- hack is here :)
714
      } else
715
          // fuzzy mpeg4-es detection. do NOT enable without heavy testing of mpeg formats detection!
716
        if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
717
           num_elementary_packetsPES==0 && num_elementary_packets100<=num_elementary_packets12x &&
718
           demuxer->synced<2) {
719
             file_format=DEMUXER_TYPE_MPEG4_ES;
720
        } else
721
         // fuzzy h264-es detection. do NOT enable without heavy testing of mpeg formats detection!
722
        if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
723
          /* FIXME num_h264_sps>=1 && */ num_h264_pps>=1 && num_h264_idr>=1 &&
724
          num_elementary_packets1B6==0 && num_elementary_packetsPES==0 &&
725
          demuxer->synced<2) {
726
            file_format=DEMUXER_TYPE_H264_ES;
727
        } else
728
        {
729
          if(demuxer->synced==2)
730
              mp_msg(MSGT_DEMUXER, MSGL_ERR, "MPEG: %s",
731
                     mp_gtext("Missing video stream!? Contact the author, it may be a bug :(\n"));
732
          else
733
            mp_tmsg(MSGT_DEMUXER,MSGL_V,"Not MPEG System Stream format... (maybe Transport Stream?)\n");
734
        }
735
  }
736
  //FIXME this shouldn't be necessary
737
  stream_seek(demuxer->stream,tmppos);
738
  return file_format;
739
}
740
741
static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){
742
  // Elementary video stream
743
  if(demux->stream->eof) return 0;
744
  demux->filepos=stream_tell(demux->stream);
745
  ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,demux->filepos,0);
746
  return 1;
747
}
748
749
/**
750
 * \brief discard until 0x100 header and return a filled buffer
751
 * \param b buffer-end pointer
752
 * \param pos current pos in stream, negative since b points to end of buffer
753
 * \param s stream to read from
754
 * \return new position, differs from original pos when eof hit and thus
755
 *             b was modified to point to the new end of buffer
756
 */
757
static int find_end(unsigned char **b, int pos, stream_t *s) {
758
  register int state = 0xffffffff;
759
  unsigned char *buf = *b;
760
  int start = pos;
761
  int read, unused;
762
  // search already read part
763
  while (state != 0x100 && pos) {
764
    state = state << 8 | buf[pos++];
765
  }
766
  // continue search in stream
767
  while (state != 0x100) {
768
    register int c = stream_read_char(s);
769
    if (c < 0) break;
770
    state = state << 8 | c;
771
  }
772
  // modify previous header (from 0x1bc or 0x1bf to 0x100)
773
  buf[start++] = 0;
774
  // copy remaining buffer part to current pos
775
  memmove(&buf[start], &buf[pos], -pos);
776
  unused = start + -pos; // -unused bytes in buffer
777
  read = stream_read(s, &buf[unused], -unused);
778
  unused += read;
779
  // fix buffer so it ends at pos == 0 (eof case)
780
  *b = &buf[unused];
781
  start -= unused;
782
  return start;
783
}
784
785
/**
786
 * This format usually uses an insane bitrate, which makes this function
787
 * performance-critical!
788
 * Be sure to benchmark any changes with different compiler versions.
789
 */
790
static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
791
  demux_packet_t *pack;
792
  int len;
793
  demux->filepos = stream_tell(demux->stream);
794
  pack = new_demux_packet(STREAM_BUFFER_SIZE);
795
  len = stream_read(demux->stream, pack->buffer, STREAM_BUFFER_SIZE);
796
  if (len <= 0)
797
  {
798
    free_demux_packet(pack);
799
    return 0;
800
  }
801
  {
802
    register uint32_t state = (uint32_t)demux->priv;
803
    register int pos = -len;
804
    unsigned char *buf = &pack->buffer[len];
805
    do {
806
      state = state << 8 | buf[pos];
807
      if (unlikely((state | 3) == 0x1bf))
808
        pos = find_end(&buf, pos, demux->stream);
809
    } while (++pos < 0);
810
    demux->priv = (void *)state;
811
    len = buf - pack->buffer;
812
  }
813
  if (len < STREAM_BUFFER_SIZE)
814
    resize_demux_packet(pack, len);
815
  ds_add_packet(ds, pack);
816
  return 1;
817
}
818
819
static int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds)
820
{
821
unsigned int head=0;
822
int skipped=0;
823
int max_packs=256; // 512kbyte
824
int ret=0;
825
826
// System stream
827
do{
828
  demux->filepos=stream_tell(demux->stream);
829
  //lame workaround: this is needed to show the progress bar when playing dvdnav://
830
  //(ths poor guy doesn't know teh length of the stream at startup)
831
  demux->movi_end = demux->stream->end_pos;
832
  head=stream_read_dword(demux->stream);
833
  if((head&0xFFFFFF00)!=0x100){
834
   // sync...
835
   demux->filepos-=skipped;
836
   while(1){
837
    int c=stream_read_char(demux->stream);
838
    if(c<0) break; //EOF
839
    head<<=8;
840
    if(head!=0x100){
841
      head|=c;
842
      if(mp_check_mp3_header(head)) ++num_mp3audio_packets;
843
      ++skipped; //++demux->filepos;
844
      continue;
845
    }
846
    head|=c;
847
    break;
848
   }
849
   demux->filepos+=skipped;
850
  }
851
  if(stream_eof(demux->stream)) break;
852
  // sure: head=0x000001XX
853
  mp_dbg(MSGT_DEMUX,MSGL_DBG4,"*** head=0x%X\n",head);
854
  if(demux->synced==0){
855
    if(head==0x1BA) demux->synced=1; //else
856
//    if(head==0x1BD || (head>=0x1C0 && head<=0x1EF)) demux->synced=3; // PES?
857
  } else
858
  if(demux->synced==1){
859
    if(head==0x1BB || head==0x1BD || (head>=0x1C0 && head<=0x1EF)){
860
      demux->synced=2;
861
      mp_msg(MSGT_DEMUX,MSGL_V,"system stream synced at 0x%"PRIX64" (%"PRId64")!\n",(int64_t)demux->filepos,(int64_t)demux->filepos);
862
      num_elementary_packets100=0; // requires for re-sync!
863
      num_elementary_packets101=0; // requires for re-sync!
864
    } else demux->synced=0;
865
  } // else
866
  if(demux->synced>=2){
867
      ret=demux_mpg_read_packet(demux,head);
868
      if(!ret)
869
        if(--max_packs==0){
870
          demux->stream->eof=1;
871
          mp_tmsg(MSGT_DEMUX,MSGL_ERR,"demux: File doesn't contain the selected audio or video stream.\n");
872
          return 0;
873
        }
874
      if(demux->synced==3) demux->synced=(ret==1)?2:0; // PES detect
875
  } else {
876
    update_stats(head);
877
    if(head>=0x100 && head<0x1B0)
878
      mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... elementary video packet found: %03X\n",head);
879
    else if((head>=0x1C0 && head<0x1F0) || head==0x1BD)
880
      mp_msg(MSGT_DEMUX,MSGL_DBG3,"Opps... PES packet found: %03X\n",head);
881
882
    if(((num_elementary_packets100>50 && num_elementary_packets101>50) ||
883
        (num_elementary_packetsPES>50)) && skipped>4000000){
884
        mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be ES/PES stream...\n");
885
        demux->stream->eof=1;
886
        break;
887
    }
888
    if(num_mp3audio_packets>100 && num_elementary_packets100<10){
889
        mp_msg(MSGT_DEMUX,MSGL_V,"sync_mpeg_ps: seems to be MP3 stream...\n");
890
        demux->stream->eof=1;
891
        break;
892
    }
893
  }
894
} while(ret!=1);
895
  mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux: %d bad bytes skipped\n",skipped);
896
  if(demux->stream->eof){
897
    mp_msg(MSGT_DEMUX,MSGL_V,"MPEG Stream reached EOF\n");
898
    return 0;
899
  }
900
  return 1;
901
}
902
903
static void demux_seek_mpg(demuxer_t *demuxer, float rel_seek_secs,
904
                           float audio_delay, int flags)
905
{
906
    demux_stream_t *d_audio=demuxer->audio;
907
    demux_stream_t *d_video=demuxer->video;
908
    sh_audio_t *sh_audio=d_audio->sh;
909
    sh_video_t *sh_video=d_video->sh;
910
    mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
911
    int precision = 1;
912
    float oldpts = 0;
913
    off_t oldpos = demuxer->filepos;
914
    float newpts = 0;
915
    off_t newpos = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : oldpos;
916
917
    if(mpg_d)
918
      oldpts = mpg_d->last_pts;
919
    newpts = (flags & SEEK_ABSOLUTE) ? 0.0 : oldpts;
920
  //================= seek in MPEG ==========================
921
  //calculate the pts to seek to
922
    if(flags & SEEK_FACTOR) {
923
      if (mpg_d && mpg_d->first_to_final_pts_len > 0.0)
924
        newpts += mpg_d->first_to_final_pts_len * rel_seek_secs;
925
      else
926
        newpts += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * oldpts / oldpos;
927
    } else
928
      newpts += rel_seek_secs;
929
    if (newpts < 0) newpts = 0;
930
931
    if(flags&SEEK_FACTOR){
932
	// float seek 0..1
933
	newpos+=(demuxer->movi_end-demuxer->movi_start)*rel_seek_secs;
934
    } else {
935
	// time seek (secs)
936
        if (mpg_d && mpg_d->has_valid_timestamps) {
937
          if (mpg_d->first_to_final_pts_len > 0.0)
938
            newpos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / mpg_d->first_to_final_pts_len;
939
          else if (oldpts > 0.0)
940
            newpos += rel_seek_secs * (oldpos - demuxer->movi_start) / oldpts;
941
        } else if(!sh_video || !sh_video->i_bps) // unspecified or VBR
942
          newpos+=2324*75*rel_seek_secs; // 174.3 kbyte/sec
943
        else
944
          newpos+=sh_video->i_bps*rel_seek_secs;
945
    }
946
947
    while (1) {
948
        if(newpos<demuxer->movi_start){
949
	    if(demuxer->stream->type!=STREAMTYPE_VCD) demuxer->movi_start=0; // for VCD
950
	    if(newpos<demuxer->movi_start) newpos=demuxer->movi_start;
951
	}
952
953
        stream_seek(demuxer->stream,newpos);
954
955
        // re-sync video:
956
        videobuf_code_len=0; // reset ES stream buffer
957
958
	ds_fill_buffer(d_video);
959
	if(sh_audio){
960
	  ds_fill_buffer(d_audio);
961
	}
962
963
	while(1){
964
	  int i;
965
          if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts){
966
	    float a_pts=d_audio->pts;
967
            a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
968
	    if(d_video->pts>a_pts){
969
	      skip_audio_frame(sh_audio);  // sync audio
970
	      continue;
971
	    }
972
          }
973
	  if(!sh_video) break;
974
          i=sync_video_packet(d_video);
975
          if(sh_video->format == mmioFOURCC('W', 'V', 'C', '1')) {
976
            if(i==0x10E || i==0x10F) //entry point or sequence header
977
              break;
978
          } else
979
          if(sh_video->format == 0x10000004) {	//mpeg4
980
            if(i==0x1B6) {			//vop (frame) startcode
981
	      int pos = videobuf_len;
982
	      if(!read_video_packet(d_video)) break; // EOF
983
	      if((videobuffer[pos+4] & 0x3F) == 0) break;	//I-frame
984
	    }
985
          } else if(sh_video->format == 0x10000005){	//h264
986
            if((i & ~0x60) == 0x105) break;
987
          } else { 	//default mpeg1/2
988
	    if(i==0x1B3 || i==0x1B8) break; // found it!
989
	  }
990
          if(!i || !skip_video_packet(d_video)) break; // EOF?
991
        }
992
	if(!mpg_d)
993
          break;
994
        if (!precision || abs(newpts - mpg_d->last_pts) < 0.5 || (mpg_d->last_pts == oldpts)) break;
995
        if ((newpos - oldpos) * (mpg_d->last_pts - oldpts) < 0) { // invalid timestamps
996
          mpg_d->has_valid_timestamps = 0;
997
          break;
998
        }
999
        precision--;
1000
        //prepare another seek because we are off by more than 0.5s
1001
	if(mpg_d) {
1002
        newpos += (newpts - mpg_d->last_pts) * (newpos - oldpos) / (mpg_d->last_pts - oldpts);
1003
        demux_flush(demuxer);
1004
        demuxer->stream->eof=0; // clear eof flag
1005
        d_video->eof=0;
1006
        d_audio->eof=0;
1007
	}
1008
    }
1009
}
1010
1011
static int demux_mpg_control(demuxer_t *demuxer, int cmd, void *arg)
1012
{
1013
    mpg_demuxer_t *mpg_d=(mpg_demuxer_t*)demuxer->priv;
1014
1015
    switch(cmd) {
1016
	case DEMUXER_CTRL_GET_TIME_LENGTH:
1017
            if(stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, arg) != STREAM_UNSUPPORTED) {
1018
              mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\r\nDEMUX_MPG_CTRL, (%.3f)\r\n", *((double*)arg));
1019
              return DEMUXER_CTRL_GUESS;
1020
            }
1021
            if (mpg_d && mpg_d->has_valid_timestamps) {
1022
              *((double *)arg)=(double)mpg_d->first_to_final_pts_len;
1023
              return DEMUXER_CTRL_OK;
1024
            }
1025
    		return DEMUXER_CTRL_DONTKNOW;
1026
1027
	case DEMUXER_CTRL_GET_PERCENT_POS:
1028
            if (mpg_d && mpg_d->has_valid_timestamps && mpg_d->first_to_final_pts_len > 0.0) {
1029
              *((int *)arg)=(int)(100 * (mpg_d->last_pts-mpg_d->first_pts) / mpg_d->first_to_final_pts_len);
1030
              return DEMUXER_CTRL_OK;
1031
            }
1032
	    return DEMUXER_CTRL_DONTKNOW;
1033
1034
	case DEMUXER_CTRL_SWITCH_AUDIO:
1035
            if(! (mpg_d && mpg_d->num_a_streams > 1 && demuxer->audio && demuxer->audio->sh))
1036
	      return DEMUXER_CTRL_NOTIMPL;
1037
	    else {
1038
              demux_stream_t *d_audio = demuxer->audio;
1039
              sh_audio_t *sh_audio = d_audio->sh;
1040
              sh_audio_t *sh_a = sh_audio;
1041
              int i;
1042
	      if(!sh_audio)
1043
	        return DEMUXER_CTRL_NOTIMPL;
1044
              if (*((int*)arg) < 0)
1045
              {
1046
              for (i = 0; i < mpg_d->num_a_streams; i++) {
1047
                if (d_audio->id == mpg_d->a_stream_ids[i]) break;
1048
              }
1049
                i = (i+1) % mpg_d->num_a_streams;
1050
                sh_a = (sh_audio_t*)demuxer->a_streams[mpg_d->a_stream_ids[i]];
1051
              }
1052
              else {
1053
                for (i = 0; i < mpg_d->num_a_streams; i++)
1054
                  if (*((int*)arg) == mpg_d->a_stream_ids[i]) break;
1055
                if (i < mpg_d->num_a_streams)
1056
                  sh_a = (sh_audio_t*)demuxer->a_streams[*((int*)arg)];
1057
              }
1058
              if (i < mpg_d->num_a_streams && d_audio->id != mpg_d->a_stream_ids[i]) {
1059
                d_audio->id = mpg_d->a_stream_ids[i];
1060
                d_audio->sh = sh_a;
1061
                ds_free_packs(d_audio);
1062
              }
1063
            }
1064
            *((int*)arg) = demuxer->audio->id;
1065
            return DEMUXER_CTRL_OK;
1066
1067
	default:
1068
	    return DEMUXER_CTRL_NOTIMPL;
1069
    }
1070
}
1071
1072
1073
static int demux_mpg_pes_probe(demuxer_t *demuxer) {
1074
   demuxer->synced = 3;
1075
   return (demux_mpg_probe(demuxer) == DEMUXER_TYPE_MPEG_PS) ? DEMUXER_TYPE_MPEG_PES : 0;
1076
}
1077
1078
1079
static demuxer_t* demux_mpg_es_open(demuxer_t* demuxer)
1080
{
1081
    sh_video_t *sh_video=NULL;
1082
1083
    demuxer->audio->sh = NULL;   // ES streams has no audio channel
1084
    demuxer->video->sh = new_sh_video(demuxer,0); // create dummy video stream header, id=0
1085
    sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1086
1087
    return demuxer;
1088
}
1089
1090
static demuxer_t *demux_mpg_gxf_open(demuxer_t *demuxer) {
1091
  demuxer->audio->sh = NULL;
1092
  demuxer->video->sh = new_sh_video(demuxer,0);
1093
  ((sh_video_t *)demuxer->video->sh)->ds = demuxer->video;
1094
  demuxer->priv = (void *) 0xffffffff;
1095
  return demuxer;
1096
}
1097
1098
static demuxer_t* demux_mpg_ps_open(demuxer_t* demuxer)
1099
{
1100
    sh_audio_t *sh_audio=NULL;
1101
    sh_video_t *sh_video=NULL;
1102
1103
    sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
1104
1105
    if(demuxer->audio->id!=-2) {
1106
        if(!ds_fill_buffer(demuxer->audio)){
1107
            mp_msg(MSGT_DEMUXER, MSGL_INFO, "MPEG: %s",
1108
                   mp_gtext("No audio stream found -> no sound.\n"));
1109
            demuxer->audio->sh=NULL;
1110
        } else {
1111
            sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio;
1112
        }
1113
    }
1114
1115
    if(!sh_video->format && ps_probe > 0) {
1116
        int head;
1117
        off_t pos = stream_tell(demuxer->stream);
1118
1119
        clear_stats();
1120
        do {
1121
            head=sync_video_packet(demuxer->video);
1122
            if(!head) break;
1123
            update_stats(head);
1124
            skip_video_packet(demuxer->video);
1125
        } while(stream_tell(demuxer->stream) < pos + ps_probe && !demuxer->stream->eof);
1126
1127
        ds_free_packs(demuxer->video);
1128
        demuxer->stream->eof=0;
1129
        stream_seek(demuxer->stream, pos);
1130
        mp_msg(MSGT_DEMUX,MSGL_INFO,"MPEG packet stats: p100: %d  p101: %d p1B6: %d p12x: %d sli: %d a: %d b: %d c: %d idr: %d sps: %d pps: %d\n",
1131
            num_elementary_packets100, num_elementary_packets101,
1132
            num_elementary_packets1B6, num_elementary_packets12x,
1133
            num_h264_slice, num_h264_dpa, num_h264_dpb, num_h264_dpc,
1134
            num_h264_idr, num_h264_sps, num_h264_pps);
1135
1136
        if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&
1137
            num_elementary_packets100<=num_elementary_packets12x)
1138
            sh_video->format = 0x10000004;
1139
        else if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&
1140
            num_h264_sps>=1 && num_h264_pps>=1 && num_h264_idr>=1 &&
1141
            num_elementary_packets1B6==0)
1142
                sh_video->format = 0x10000005;
1143
        else sh_video->format = 0x10000002;
1144
    }
1145
1146
    return demuxer;
1147
}
1148
1149
1150
const demuxer_desc_t demuxer_desc_mpeg_ps = {
1151
  "MPEG PS demuxer",
1152
  "mpegps",
1153
  "MPEG-PS",
1154
  "Arpi?",
1155
  "Mpeg",
1156
  DEMUXER_TYPE_MPEG_PS,
1157
  0, // unsafe autodetect
1158
  demux_mpg_probe,
1159
  demux_mpg_fill_buffer,
1160
  demux_mpg_ps_open,
1161
  demux_close_mpg,
1162
  demux_seek_mpg,
1163
  demux_mpg_control,
1164
};
1165
1166
1167
const demuxer_desc_t demuxer_desc_mpeg_pes = {
1168
  "MPEG PES demuxer",
1169
  "mpegpes",
1170
  "MPEG-PES",
1171
  "Arpi?",
1172
  "Mpeg",
1173
  DEMUXER_TYPE_MPEG_PES,
1174
  0, // unsafe autodetect
1175
  demux_mpg_pes_probe,
1176
  demux_mpg_fill_buffer,
1177
  demux_mpg_ps_open,
1178
  demux_close_mpg,
1179
  demux_seek_mpg,
1180
  demux_mpg_control,
1181
};
1182
1183
1184
const demuxer_desc_t demuxer_desc_mpeg_gxf = {
1185
  "MPEG ES in GXF demuxer",
1186
  "mpeggxf",
1187
  "MPEG-ES in GXF",
1188
  "Reimar Doeffinger",
1189
  "Mpeg",
1190
  DEMUXER_TYPE_MPEG_GXF,
1191
  0, // hack autodetection
1192
  NULL,
1193
  demux_mpg_gxf_fill_buffer,
1194
  demux_mpg_gxf_open,
1195
  NULL,
1196
  NULL,
1197
  NULL
1198
};
1199
1200
const demuxer_desc_t demuxer_desc_mpeg_es = {
1201
  "MPEG ES demuxer",
1202
  "mpeges",
1203
  "MPEG-ES",
1204
  "Arpi?",
1205
  "Mpeg",
1206
  DEMUXER_TYPE_MPEG_ES,
1207
  0, // hack autodetection
1208
  NULL,
1209
  demux_mpg_es_fill_buffer,
1210
  demux_mpg_es_open,
1211
  demux_close_mpg,
1212
  demux_seek_mpg,
1213
  demux_mpg_control,
1214
};
1215
1216
1217
const demuxer_desc_t demuxer_desc_mpeg4_es = {
1218
  "MPEG4 ES demuxer",
1219
  "mpeg4es",
1220
  "MPEG-ES",
1221
  "Arpi?",
1222
  "Mpeg",
1223
  DEMUXER_TYPE_MPEG4_ES,
1224
  0, // hack autodetection
1225
  NULL,
1226
  demux_mpg_es_fill_buffer,
1227
  demux_mpg_es_open,
1228
  demux_close_mpg,
1229
  demux_seek_mpg,
1230
  demux_mpg_control,
1231
};
1232
1233
1234
const demuxer_desc_t demuxer_desc_h264_es = {
1235
  "H.264 ES demuxer",
1236
  "h264es",
1237
  "H264-ES",
1238
  "Arpi?",
1239
  "Mpeg",
1240
  DEMUXER_TYPE_H264_ES,
1241
  0, // hack autodetection
1242
  NULL,
1243
  demux_mpg_es_fill_buffer,
1244
  demux_mpg_es_open,
1245
  demux_close_mpg,
1246
  demux_seek_mpg,
1247
  demux_mpg_control,
1248
};