1 /*
2  * Copyright (C) 2000-2019 the xine project
3  *
4  * This file is part of xine, a free video player.
5  *
6  * xine is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * xine is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  * demultiplexer for mpeg 2 PES (Packetized Elementary Streams)
21  * reads streams of variable blocksizes
22  *
23  * 1-7-2003 New implementation of mpeg 2 PES demuxers.
24  *   (c) 2003 James Courtier-Dutton James@superbug.demon.co.uk
25  *   This code might also decode normal MPG files.
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <string.h>
37 
38 #define LOG_MODULE "demux_mpeg_pes"
39 #define LOG_VERBOSE
40 /*
41 #define LOG
42 */
43 
44 #include "group_video.h"
45 
46 #include <xine/xine_internal.h>
47 #include <xine/xineutils.h>
48 #include <xine/demux.h>
49 
50 #define NUM_PREVIEW_BUFFERS   250
51 #define DISC_TRESHOLD       90000
52 
53 #define WRAP_THRESHOLD     270000
54 #define PTS_AUDIO 0
55 #define PTS_VIDEO 1
56 
57 /* disabled for now.
58 #define PTS_BOUNCE
59 */
60 
61 /* redefine abs as macro to handle 64-bit diffs.
62    i guess llabs may not be available everywhere */
63 #define abs(x) ( ((x)<0) ? -(x) : (x) )
64 
65 typedef struct demux_mpeg_pes_s {
66   demux_plugin_t        demux_plugin;
67 
68   xine_stream_t        *stream;
69   fifo_buffer_t        *audio_fifo;
70   fifo_buffer_t        *video_fifo;
71 
72   input_plugin_t       *input;
73   int                   is_vdr;
74 
75   int                   status;
76 
77   int                   rate;
78 
79   int64_t               nav_last_end_pts;
80   int64_t               nav_last_start_pts;
81   int64_t               last_pts[2];
82 #ifdef PTS_BOUNCE
83   int64_t               apts, bpts;
84   int32_t               bounce_left;
85 #endif
86   int64_t               scr;
87   uint32_t              packet_len;
88   uint32_t              stream_id;
89 
90   int64_t               pts;
91   int64_t               dts;
92 
93   uint8_t               send_newpts:1;
94   uint8_t               buf_flag_seek:1;
95   uint8_t               preview_mode:1;
96   uint8_t               mpeg1:1;
97   uint8_t               wait_for_program_stream_pack_header:1;
98   uint8_t               mpeg12_h264_detected:2;
99 
100   int                   last_begin_time;
101   int64_t               last_cell_time;
102   off_t                 last_cell_pos;
103 
104   uint8_t               preview_data[ MAX_PREVIEW_SIZE ];
105   off_t                 preview_size, preview_done;
106 } demux_mpeg_pes_t ;
107 
108 static int32_t parse_video_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
109 static int32_t parse_audio_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
110 static int32_t parse_ancillary_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
111 static int32_t parse_program_stream_system_header(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
112 static int32_t parse_private_stream_1(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
113 //static int32_t parse_private_stream_2(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
114 static int32_t parse_program_stream_map(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
115 static int32_t parse_padding_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
116 static int32_t parse_ecm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
117 static int32_t parse_emm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
118 static int32_t parse_dsmcc_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
119 static int32_t parse_emm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
120 static int32_t parse_iec_13522_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
121 static int32_t parse_h222_typeA_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
122 static int32_t parse_h222_typeB_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
123 static int32_t parse_h222_typeC_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
124 static int32_t parse_h222_typeD_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
125 static int32_t parse_h222_typeE_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
126 static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
127 static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
128 static int32_t parse_program_stream_directory(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
129 static int32_t parse_program_stream_pack_header(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf);
130 
131 #ifdef PTS_BOUNCE
132 #define ts_abs(x) (((x) < 0) ? -(x) : (x))
133 /* bounce detection like in metronom. looks like double work but saves
134  * up to 80 discontinuity messages. */
check_newpts(demux_mpeg_pes_t * this,int64_t pts,int video)135 static void check_newpts (demux_mpeg_pes_t *this, int64_t pts, int video) {
136 #ifdef TS_LOG
137   printf ("demux_mpeg_pes: check_newpts %lld, send_newpts %d, buf_flag_seek %d\n",
138     pts, this->send_newpts, this->buf_flag_seek);
139 #endif
140 /*if (pts)*/
141   {
142     int64_t diff;
143     do {
144       this->last_pts[video] = pts;
145       if (!this->apts) {
146         diff = 0;
147         this->apts = pts;
148         break;
149       }
150       diff = pts - this->apts;
151       if (ts_abs (diff) <= WRAP_THRESHOLD) {
152         this->apts = pts;
153         break;
154       }
155       if (this->bpts) {
156         diff = pts - this->bpts;
157         if (ts_abs (diff) <= WRAP_THRESHOLD) {
158           this->bpts = pts;
159           break;
160         }
161       }
162       this->bpts = this->apts;
163       this->apts = pts;
164       this->bounce_left = WRAP_THRESHOLD;
165       _x_demux_control_newpts (this->stream, pts, this->buf_flag_seek ? BUF_FLAG_SEEK : 0);
166       this->send_newpts = 0;
167       this->buf_flag_seek = 0;
168       return;
169     } while (0);
170     if (this->bounce_left) {
171       this->bounce_left -= diff;
172       if (this->bounce_left <= 0) {
173         this->bpts = 0;
174         this->bounce_left = 0;
175       }
176     }
177     if (this->send_newpts || this->buf_flag_seek) {
178       _x_demux_control_newpts (this->stream, pts, this->buf_flag_seek ? BUF_FLAG_SEEK : 0);
179       this->send_newpts = 0;
180       this->buf_flag_seek = 0;
181     }
182   }
183 }
184 #else /* !PTS_BOUNCE */
185 
detect_pts_discontinuity(demux_mpeg_pes_t * this,int64_t pts,int video)186 static int detect_pts_discontinuity( demux_mpeg_pes_t *this, int64_t pts, int video )
187 {
188   int64_t diff;
189 
190   /* discontinuity detection is difficult to implement in the demuxer as it gets
191    * for example video packets in decoding order and there can be multiple audio
192    * and video tracks. So for simplicity, let's just deal with a single audio and
193    * a single video track.
194    *
195    * To start with, let's have a look at the audio and video track independently.
196    * Whenever pts differs from last_pts[video] by at least WRAP_THRESHOLD, a jump
197    * in pts is detected. Such a jump can happen for example when the pts counter
198    * overflows, as shown below (video decoding order ignored for simplicity; the
199    * variable values are shown after returning from the below function check_newpts;
200    * an asterisk means that this value has been cleared (see check_newpts)):
201    *
202    *         pts: 7v 7a 8v 9v 9a : 0v 1v 1a 2v 3v 3a 4v
203    * last_pts[0]: 6  7  7  7  9  : *  *  1  1  1  3  3
204    * last_pts[1]: 7  7  8  9  9  : 0  1  1  2  3  3  4
205    *                             | |     |
206    *                             | |     +--- audio pts wrap ignored
207    *                             | +--------- video pts wrap detected
208    *                             +----------- pts wrap boundary
209    */
210   diff = pts - this->last_pts[video];
211 
212   if (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD)
213     return 1;
214 
215   /* but the above code can cause a huge delay while replaying when audio and video
216    * track are not aligned on a common pts wrap boundery, as shown below:
217    *
218    *         pts: 7v 8v 7a 9v : 0v 9a 1v 2v : 1a 3v 4v 3a
219    * last_pts[0]: 6  6  7  7  : *  9  9  9  : 1  1  1  3
220    * last_pts[1]: 7  8  8  9  : 0  0  1  2  : *  3  4  4
221    *                          | |  |        | |
222    *                          | |  |        | +--- audio pts wrap detected
223    *                          | |  |        +----- audio pts wrap boundary
224    *                          | |  +-------------- audio packet causes a huge delay
225    *                          | +----------------- video pts wrap detected
226    *                          +------------------- video pts wrap boundery
227    *
228    * So there is the need to compare audio track pts against video track pts
229    * to detect when pts values are in between pts wrap bounderies, where a
230    * jump needs to be detected too, as shown below:
231    *
232    *         pts: 7v 8v 7a 9v : 0v 9a 1v 2v : 1a 3v 4v 3a
233    * last_pts[0]: 6  6  7  7  : *  9  *  *  : 1  1  1  3
234    * last_pts[1]: 7  8  8  9  : 0  *  1  2  : 2  3  4  4
235    *                          | |  |  |     | |
236    *                          | |  |  |     | +--- (audio pts wrap ignored)
237    *                          | |  |  |     +----- audio pts wrap boundary
238    *                          | |  |  +----------- video pts wrap detected
239    *                          | |  +-------------- audio pts wrap detected
240    *                          | +----------------- video pts wrap detected
241    *                          +------------------- (video pts wrap boundery)
242    *
243    * Basically, it's almost the same test like above, but against the other track's
244    * pts value and with a different limit. As the pts counter is a 33 bit unsigned
245    * integer, we choose 2^31 as limit (2^32 would require the tracks to be aligned).
246    */
247   diff = pts - this->last_pts[1-video];
248 
249   if (this->last_pts[1-video] && abs(diff)>(1u<<31))
250     return 1;
251 
252   /* no discontinuity detected */
253   return 0;
254 }
255 
check_newpts(demux_mpeg_pes_t * this,int64_t pts,int video)256 static void check_newpts( demux_mpeg_pes_t *this, int64_t pts, int video )
257 {
258   if( pts && (this->send_newpts || detect_pts_discontinuity(this, pts, video) ) ) {
259 
260     /* check if pts is outside nav pts range. any stream without nav must enter here. */
261     if( pts > this->nav_last_end_pts || pts < this->nav_last_start_pts )
262     {
263       lprintf("discontinuity detected by pts wrap\n");
264 
265       if (this->buf_flag_seek) {
266         _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK);
267         this->buf_flag_seek = 0;
268       } else {
269         _x_demux_control_newpts(this->stream, pts, 0);
270       }
271       this->send_newpts = 0;
272     } else {
273       lprintf("no wrap detected\n" );
274     }
275 
276     /* clear pts on the other track to avoid detecting the same discontinuity again */
277     this->last_pts[1-video] = 0;
278   }
279 
280   if( pts )
281     this->last_pts[video] = pts;
282 }
283 #endif
284 
read_data(demux_mpeg_pes_t * this,uint8_t * buf,off_t nlen)285 static off_t read_data(demux_mpeg_pes_t *this, uint8_t *buf, off_t nlen)
286 {
287   int preview_avail;
288 
289   if (this->preview_size <= 0)
290     return this->input->read(this->input, (char *)buf, nlen);
291 
292   preview_avail = this->preview_size - this->preview_done;
293   if (preview_avail <= 0)
294     return 0;
295 
296   if (nlen > preview_avail)
297     nlen = preview_avail;
298 
299   memcpy(buf, &this->preview_data[ this->preview_done ], nlen);
300   this->preview_done += nlen;
301 
302   return nlen;
303 }
304 
demux_mpeg_pes_parse_pack(demux_mpeg_pes_t * this,int preview_mode)305 static void demux_mpeg_pes_parse_pack (demux_mpeg_pes_t *this, int preview_mode) {
306 
307   buf_element_t *buf = NULL;
308   uint8_t       *p;
309   int32_t        result;
310   off_t          i;
311   uint8_t        buf6[ 6 ];
312 
313   this->scr = 0;
314   this->preview_mode = preview_mode;
315 
316   /* read first 6 bytes of PES packet into a local buffer. */
317   i = read_data(this, buf6, (off_t) 6);
318   if (i != 6) {
319     this->status = DEMUX_FINISHED;
320     return;
321   }
322 
323   p = buf6;
324 
325   while ((p[2] != 1) || p[0] || p[1]) {
326     /* resync code */
327     memmove(p, p+1, 5);
328     i = read_data(this, p+5, (off_t) 1);
329     if (i != 1) {
330       this->status = DEMUX_FINISHED;
331       return;
332     }
333   }
334 
335   /* FIXME: buf must be allocated from somewhere before calling here. */
336 
337   /* these streams should be allocated on the audio_fifo, if available. */
338   if ((0xC0 <= p[ 3 ] && p[ 3 ] <= 0xDF) /* audio_stream */
339       || 0xBD == p[ 3 ])                 /* private_sream_1 */
340   {
341     if (this->audio_fifo)
342       buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
343   }
344 
345   if (!buf)  /* still no buffer => try video fifo first. */
346   {
347     if (this->video_fifo) {
348       buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
349     } else if (this->audio_fifo) {
350       buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
351     } else {
352       return;
353     }
354   }
355 
356   p = buf->mem;
357 
358   /* copy local buffer to fifo element. */
359   memcpy(p, buf6, sizeof(buf6));
360 
361   if (preview_mode)
362     buf->decoder_flags = BUF_FLAG_PREVIEW;
363   else
364     buf->decoder_flags = 0;
365 
366   if( this->input->get_length (this->input) )
367     buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) *
368                                      65535 / this->input->get_length (this->input) );
369 
370   this->stream_id  = p[3];
371   if (this->stream_id == 0xBA) {
372     this->wait_for_program_stream_pack_header=0;
373     /* This just fills this->scr, this->rate and this->mpeg1 */
374     result = parse_program_stream_pack_header(this, p, buf);
375     return;
376   } else if (this->stream_id == 0xB9) {
377     /* End of stream marker */
378     buf->free_buffer (buf);
379     return;
380   } else if (this->stream_id < 0xB9) {
381     /* FIXME: This should only be tested for after a seek. */
382     buf->free_buffer (buf);
383     return;
384   }
385 #if 0
386   /* FIXME: #if 0 while trying to detect mpeg1 in parse_pes_for_pts() */
387   if (this->wait_for_program_stream_pack_header==1) {
388     /* Wait until this->mpeg1 has been initialised. */
389     buf->free_buffer (buf);
390     return;
391   }
392 #endif
393 
394   this->packet_len = p[4] << 8 | p[5];
395   lprintf("stream_id=0x%x, packet_len=%d\n",this->stream_id, this->packet_len);
396 
397   if ((int)(this->packet_len) <= (buf->max_size - 6)) {
398     i = read_data(this, buf->mem+6, (off_t) this->packet_len);
399     if (i != this->packet_len) {
400       buf->free_buffer (buf);
401       this->status = DEMUX_FINISHED;
402       return;
403     }
404     buf->size = this->packet_len + 6;
405   } else {
406     lprintf("Jumbo PES packet length=%d, stream_id=0x%x\n",this->packet_len, this->stream_id);
407 
408     i = read_data(this, buf->mem+6, (off_t) (buf->max_size - 6));
409     if (i != ( buf->max_size - 6)) {
410       buf->free_buffer (buf);
411       this->status = DEMUX_FINISHED;
412       return;
413     }
414     buf->size = buf->max_size;
415   }
416 
417   if (this->stream_id == 0xBB) {
418     result = parse_program_stream_system_header(this, p, buf);
419   } else if (this->stream_id == 0xBC) {
420     result = parse_program_stream_map(this, p, buf);
421   } else if (this->stream_id == 0xBD) {
422     result = parse_private_stream_1(this, p, buf);
423   } else if (this->stream_id == 0xBE) {
424     result = parse_padding_stream(this, p, buf);
425   } else if (this->stream_id == 0xBF) {
426     buf->free_buffer (buf);
427     return;
428     //result = parse_private_stream_2(this, p, buf);
429   } else if ((this->stream_id >= 0xC0)
430              && (this->stream_id <= 0xDF)) {
431     result = parse_audio_stream(this, p, buf);
432   } else if ((this->stream_id >= 0xE0)
433              && (this->stream_id <= 0xEF)) {
434     result = parse_video_stream(this, p, buf);
435   } else if (this->stream_id == 0xF0) {
436     result = parse_ecm_stream(this, p, buf);
437   } else if (this->stream_id == 0xF1) {
438     result = parse_emm_stream(this, p, buf);
439   } else if (this->stream_id == 0xF2) {
440     result = parse_dsmcc_stream(this, p, buf);
441   } else if (this->stream_id == 0xF3) {
442     result = parse_iec_13522_stream(this, p, buf);
443   } else if (this->stream_id == 0xF4) {
444     result = parse_h222_typeA_stream(this, p, buf);
445   } else if (this->stream_id == 0xF5) {
446     result = parse_h222_typeB_stream(this, p, buf);
447   } else if (this->stream_id == 0xF6) {
448     result = parse_h222_typeC_stream(this, p, buf);
449   } else if (this->stream_id == 0xF7) {
450     result = parse_h222_typeD_stream(this, p, buf);
451   } else if (this->stream_id == 0xF8) {
452     result = parse_h222_typeE_stream(this, p, buf);
453   } else if (this->stream_id == 0xF9) {
454     result = parse_ancillary_stream(this, p, buf);
455   } else if (this->stream_id == 0xFA) {
456     result = parse_IEC14496_SL_packetized_stream(this, p, buf);
457   } else if (this->stream_id == 0xFB) {
458     result = parse_IEC14496_FlexMux_stream(this, p, buf);
459     /* 0xFC, 0xFD, 0xFE reserved */
460   } else if (this->stream_id == 0xFF) {
461     result = parse_program_stream_directory(this, p, buf);
462   } else {
463     xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
464             _("xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. "
465               "Please report this to xine developers.\n"), this->stream_id);
466     xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
467             "xine-lib:demux_mpeg_pes: packet_len=%d\n", this->packet_len);
468     buf->free_buffer (buf);
469     return;
470   }
471   if (result < 0) {
472     xine_log (this->stream->xine, XINE_LOG_MSG,
473               _("demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n"), this->stream_id);
474     /* What to do here? */
475     return;
476   }
477   return;
478 }
479 
demux_mpeg_pes_vdr_seek_0(demux_mpeg_pes_t * this,int n)480 static void demux_mpeg_pes_vdr_seek_0 (demux_mpeg_pes_t *this, int n) {
481   xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
482     "demux_mpeg_pes: vdr sync point #%d.\n", n);
483   this->last_cell_time = 0;
484   this->send_newpts = 1;
485   this->buf_flag_seek = 0;
486   this->nav_last_end_pts = this->nav_last_start_pts = 0;
487   this->status   = DEMUX_OK ;
488   this->last_pts[0]   = 0;
489   this->last_pts[1]   = 0;
490 #ifdef PTS_BOUNCE
491   this->apts = this->bpts = 0;
492   this->bounce_left = 0;
493 #endif
494 }
495 
parse_padding_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)496 static int32_t parse_padding_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
497   /* Just skip padding. */
498   int todo = 6 + this->packet_len;
499   int done = buf->size;
500 
501   (void)p;
502 
503   if (this->is_vdr && (buf->content[4] == 0xff))
504     demux_mpeg_pes_vdr_seek_0 (this, buf->content[5]);
505 
506   while (done < todo)
507   {
508     /* Handle Jumbo frames from VDR. */
509     int i;
510 
511     int size = buf->max_size;
512     if ((todo - done) < size)
513       size = todo - done;
514 
515     i = read_data(this, buf->mem, (off_t)size);
516     if (i != size)
517       break;
518 
519     done += i;
520   }
521 
522   /* trigger detection of MPEG 1/2 respectively H.264 content */
523   this->mpeg12_h264_detected = 0;
524 
525   buf->free_buffer(buf);
526   return this->packet_len + 6;
527 }
528 
parse_program_stream_map(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)529 static int32_t parse_program_stream_map(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
530   /* FIXME: Implement */
531   (void)p;
532   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
533           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x.\n", this->stream_id);
534   buf->free_buffer (buf);
535   return -1;
536 }
parse_ecm_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)537 static int32_t parse_ecm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
538   /* FIXME: Implement */
539   (void)p;
540   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
541           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
542   buf->free_buffer (buf);
543   return -1;
544 }
parse_emm_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)545 static int32_t parse_emm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
546   /* FIXME: Implement */
547   (void)p;
548   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
549           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
550   buf->free_buffer (buf);
551   return -1;
552 }
parse_dsmcc_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)553 static int32_t parse_dsmcc_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
554   /* FIXME: Implement */
555   (void)p;
556   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
557           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
558   buf->free_buffer (buf);
559   return -1;
560 }
parse_iec_13522_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)561 static int32_t parse_iec_13522_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
562   /* FIXME: Implement */
563   (void)p;
564   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
565           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
566   buf->free_buffer (buf);
567   return -1;
568 }
parse_h222_typeA_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)569 static int32_t parse_h222_typeA_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
570   /* FIXME: Implement */
571   (void)p;
572   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
573           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
574   buf->free_buffer (buf);
575   return -1;
576 }
parse_h222_typeB_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)577 static int32_t parse_h222_typeB_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
578   /* FIXME: Implement */
579   (void)p;
580   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
581           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
582   buf->free_buffer (buf);
583   return -1;
584 }
parse_h222_typeC_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)585 static int32_t parse_h222_typeC_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
586   /* FIXME: Implement */
587   (void)p;
588   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
589           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
590   buf->free_buffer (buf);
591   return -1;
592 }
parse_h222_typeD_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)593 static int32_t parse_h222_typeD_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
594   /* FIXME: Implement */
595   (void)p;
596   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
597           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
598   buf->free_buffer (buf);
599   return -1;
600 }
parse_h222_typeE_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)601 static int32_t parse_h222_typeE_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
602   /* FIXME: Implement */
603   (void)p;
604   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
605           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
606   buf->free_buffer (buf);
607   return -1;
608 }
parse_IEC14496_SL_packetized_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)609 static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
610   /* FIXME: Implement */
611   (void)p;
612   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
613           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
614   buf->free_buffer (buf);
615   return -1;
616 }
parse_IEC14496_FlexMux_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)617 static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
618   /* FIXME: Implement */
619   (void)p;
620   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
621           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
622   buf->free_buffer (buf);
623   return -1;
624 }
parse_program_stream_directory(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)625 static int32_t parse_program_stream_directory(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
626   /* FIXME: Implement */
627   (void)p;
628   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
629           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
630   buf->free_buffer (buf);
631   return -1;
632 }
parse_ancillary_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)633 static int32_t parse_ancillary_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
634   /* FIXME: Implement */
635   (void)p;
636   xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
637           "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id);
638   buf->free_buffer (buf);
639   return -1;
640 }
641 
parse_program_stream_pack_header(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)642 static int32_t parse_program_stream_pack_header(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
643   /* program stream pack header */
644   off_t          i;
645 
646   i = read_data(this, buf->mem+6, (off_t) 6);
647   if (i != 6) {
648     buf->free_buffer (buf);
649     this->status = DEMUX_FINISHED;
650     return -1;
651   }
652   this->mpeg1 = (p[4] & 0x40) == 0;
653 
654   if (this->mpeg1) {
655   /* system_clock_reference */
656 
657     this->scr  = (int64_t)(p[4] & 0x02) << 30;
658     this->scr |= (p[5] & 0xFF) << 22;
659     this->scr |= (p[6] & 0xFE) << 14;
660     this->scr |= (p[7] & 0xFF) <<  7;
661     this->scr |= (p[8] & 0xFE) >>  1;
662 
663     /* buf->scr = scr; */
664 
665     /* mux_rate */
666 
667     if (!this->rate) {
668       this->rate = (p[9] & 0x7F) << 15;
669       this->rate |= (p[10] << 7);
670       this->rate |= (p[11] >> 1);
671     }
672 
673     buf->free_buffer (buf);
674     return 12;
675 
676   } else { /* mpeg2 */
677 
678     int      num_stuffing_bytes;
679 
680     /* system_clock_reference */
681 
682     this->scr  = (int64_t)(p[4] & 0x08) << 27 ;
683     this->scr |= (p[4] & 0x03) << 28 ;
684     this->scr |= p[5] << 20;
685     this->scr |= (p[6] & 0xF8) << 12 ;
686     this->scr |= (p[6] & 0x03) << 13 ;
687     this->scr |= p[7] << 5;
688     this->scr |= (p[8] & 0xF8) >> 3;
689     /*  optional - decode extension:
690     this->scr *=300;
691     this->scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) );
692     */
693 
694     lprintf ("SCR=%"PRId64"\n", this->scr);
695 
696     /* mux_rate */
697 
698     if (!this->rate) {
699       this->rate = (p[0xA] << 14);
700       this->rate |= (p[0xB] << 6);
701       this->rate |= (p[0xC] >> 2);
702     }
703     i = read_data(this, buf->mem+12, (off_t) 2);
704     if (i != 2) {
705       buf->free_buffer (buf);
706       this->status = DEMUX_FINISHED;
707       return -1;
708     }
709 
710     num_stuffing_bytes = p[0xD] & 0x07;
711     i = read_data(this, buf->mem+14, (off_t) num_stuffing_bytes);
712     if (i != num_stuffing_bytes) {
713       buf->free_buffer (buf);
714       this->status = DEMUX_FINISHED;
715       return -1;
716     }
717 
718     buf->free_buffer (buf);
719     return 14 + num_stuffing_bytes;
720   }
721 
722 }
723 
parse_program_stream_system_header(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)724 static int32_t parse_program_stream_system_header(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
725   /* program stream system header */
726   /* FIXME: Implement */
727   (void)p;
728   buf->free_buffer (buf);
729   return 6 + this->packet_len;
730 }
731 
732 #if 0
parse_private_stream_2(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)733 static int32_t parse_private_stream_2(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
734   int64_t start_pts, end_pts;
735 
736   /* NAV Packet */
737 
738   start_pts  = ((int64_t)p[7+12] << 24);
739   start_pts |= (p[7+13] << 16);
740   start_pts |= (p[7+14] << 8);
741   start_pts |= p[7+15];
742 
743   end_pts  = ((int64_t)p[7+16] << 24);
744   end_pts |= (p[7+17] << 16);
745   end_pts |= (p[7+18] << 8);
746   end_pts |= p[7+19];
747 
748   /* some input plugins like DVD can have better timing information and have
749    * already set the input_time, so we can use the cell elapsed time from
750    * the NAV packet for a much more accurate timing */
751   if (buf->extra_info->input_time) {
752     int64_t cell_time, frames;
753 
754     cell_time  = (p[7+0x18] >> 4  ) * 10 * 60 * 60 * 1000;
755     cell_time += (p[7+0x18] & 0x0f)      * 60 * 60 * 1000;
756     cell_time += (p[7+0x19] >> 4  )      * 10 * 60 * 1000;
757     cell_time += (p[7+0x19] & 0x0f)           * 60 * 1000;
758     cell_time += (p[7+0x1a] >> 4  )           * 10 * 1000;
759     cell_time += (p[7+0x1a] & 0x0f)                * 1000;
760     frames  = ((p[7+0x1b] & 0x30) >> 4) * 10;
761     frames += ((p[7+0x1b] & 0x0f)     )     ;
762 
763     if (p[7+0x1b] & 0x80)
764       cell_time += (frames * 1000)/25;
765     else
766       cell_time += (frames * 1000)/30;
767 
768     this->last_cell_time = cell_time;
769     this->last_cell_pos = this->input->get_current_pos (this->input);
770     this->last_begin_time = buf->extra_info->input_time;
771   }
772 
773   lprintf ("NAV packet, start pts = %"PRId64", end_pts = %"PRId64"\n",
774            start_pts, end_pts);
775 
776   if (this->nav_last_end_pts != start_pts && !this->preview_mode) {
777 
778     lprintf("discontinuity detected by nav packet\n" );
779 
780     if (this->buf_flag_seek) {
781       _x_demux_control_newpts(this->stream, start_pts, BUF_FLAG_SEEK);
782       this->buf_flag_seek = 0;
783     } else {
784       _x_demux_control_newpts(this->stream, start_pts, 0);
785     }
786   }
787   this->nav_last_end_pts = end_pts;
788   this->nav_last_start_pts = start_pts;
789   this->send_newpts = 0;
790   this->last_pts[PTS_AUDIO] = this->last_pts[PTS_VIDEO] = 0;
791 
792   buf->content   = p;
793   buf->size      = this->packet_len;
794   buf->type      = BUF_SPU_DVD;
795   buf->decoder_flags |= BUF_FLAG_SPECIAL;
796   buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
797   buf->decoder_info[2] = SPU_DVD_SUBTYPE_NAV;
798   buf->pts       = 0;   /* NAV packets do not have PES values */
799   this->video_fifo->put (this->video_fifo, buf);
800 
801   return this->packet_len;
802 }
803 #endif
804 
805 /* FIXME: Extension data is not parsed, and is also not skipped. */
806 
parse_pes_for_pts(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)807 static int32_t parse_pes_for_pts(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
808   int32_t header_len;
809 
810   /* some input plugins like DVD can have better timing information and have
811    * already set the total_time, so we can derive our datarate from this */
812   if (buf->extra_info->total_time)
813     this->rate = (int)((int64_t)this->input->get_length (this->input) * 1000 /
814                        (buf->extra_info->total_time * 50));
815 
816   if (this->rate && this->last_cell_time) {
817     if( this->last_begin_time == buf->extra_info->input_time )
818       buf->extra_info->input_time = this->last_cell_time + buf->extra_info->input_time +
819        ((this->input->get_current_pos (this->input) - this->last_cell_pos) * 1000 / (this->rate * 50));
820   }
821 
822   if (this->rate && !buf->extra_info->input_time)
823     buf->extra_info->input_time = (int)((int64_t)this->input->get_current_pos (this->input)
824                                         * 1000 / (this->rate * 50));
825 
826   /* FIXME: This was determined by comparing a single MPEG1 and a single MPEG2 stream */
827   if ((p[6] & 0xC0) != 0x80) {
828     this->mpeg1 = 1;
829   } else {
830     this->mpeg1 = 0;
831   }
832 
833   if (this->mpeg1) {
834     header_len = 6;
835     p   += 6; /* packet_len -= 6; */
836 
837     while ((p[0] & 0x80) == 0x80) {
838       p++;
839       header_len++;
840       this->packet_len--;
841       /* printf ("stuffing\n");*/
842     }
843 
844     if ((p[0] & 0xc0) == 0x40) {
845       /* STD_buffer_scale, STD_buffer_size */
846       p += 2;
847       header_len += 2;
848       this->packet_len -= 2;
849     }
850 
851     this->pts = 0;
852     this->dts = 0;
853 
854     if ((p[0] & 0xf0) == 0x20) {
855       this->pts  = (int64_t) (p[ 0] & 0x0E) << 29 ;
856       this->pts |= (int64_t)  p[ 1]         << 22 ;
857       this->pts |= (int64_t) (p[ 2] & 0xFE) << 14 ;
858       this->pts |= (int64_t)  p[ 3]         <<  7 ;
859       this->pts |= (int64_t) (p[ 4] & 0xFE) >>  1 ;
860       p   += 5;
861       header_len+= 5;
862       this->packet_len -=5;
863       return header_len;
864     } else if ((p[0] & 0xf0) == 0x30) {
865       this->pts  = (int64_t) (p[ 0] & 0x0E) << 29 ;
866       this->pts |= (int64_t)  p[ 1]         << 22 ;
867       this->pts |= (int64_t) (p[ 2] & 0xFE) << 14 ;
868       this->pts |= (int64_t)  p[ 3]         <<  7 ;
869       this->pts |= (int64_t) (p[ 4] & 0xFE) >>  1 ;
870 
871       this->dts  = (int64_t) (p[ 5] & 0x0E) << 29 ;
872       this->dts |= (int64_t)  p[ 6]         << 22 ;
873       this->dts |= (int64_t) (p[ 7] & 0xFE) << 14 ;
874       this->dts |= (int64_t)  p[ 8]         <<  7 ;
875       this->dts |= (int64_t) (p[ 9] & 0xFE) >>  1 ;
876 
877       p   += 10;
878       header_len += 10;
879       this->packet_len -= 10;
880       return header_len;
881     } else {
882       p++;
883       header_len++;
884       this->packet_len--;
885       return header_len;
886     }
887 
888   } else { /* mpeg 2 */
889 
890 
891     if ((p[6] & 0xC0) != 0x80) {
892       xine_log (this->stream->xine, XINE_LOG_MSG,
893                 _("demux_mpeg_pes: warning: PES header reserved 10 bits not found\n"));
894       buf->free_buffer(buf);
895       return -1;
896     }
897 
898 
899     /* check PES scrambling_control */
900 
901     if ((p[6] & 0x30) != 0) {
902       xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
903               _("demux_mpeg_pes: warning: PES header indicates that "
904                 "this stream may be encrypted (encryption mode %d)\n"), (p[6] & 0x30) >> 4);
905       _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE,
906                       "Media stream scrambled/encrypted", NULL);
907       this->status = DEMUX_FINISHED;
908       buf->free_buffer(buf);
909       return -1;
910     }
911 
912     if (p[7] & 0x80) { /* pts avail */
913 
914       this->pts  = (int64_t) (p[ 9] & 0x0E) << 29 ;
915       this->pts |= (int64_t)  p[10]         << 22 ;
916       this->pts |= (int64_t) (p[11] & 0xFE) << 14 ;
917       this->pts |= (int64_t)  p[12]         <<  7 ;
918       this->pts |= (int64_t) (p[13] & 0xFE) >>  1 ;
919 
920       lprintf ("pts = %"PRId64"\n", this->pts);
921 
922     } else
923       this->pts = 0;
924 
925     if (p[7] & 0x40) { /* dts avail */
926 
927       this->dts  = (int64_t) (p[14] & 0x0E) << 29 ;
928       this->dts |= (int64_t)  p[15]         << 22 ;
929       this->dts |= (int64_t) (p[16] & 0xFE) << 14 ;
930       this->dts |= (int64_t)  p[17]         <<  7 ;
931       this->dts |= (int64_t) (p[18] & 0xFE) >>  1 ;
932 
933     } else
934       this->dts = 0;
935 
936 
937     header_len = p[8];
938 
939     this->packet_len -= header_len + 3;
940     return header_len + 9;
941   }
942   return 0;
943 }
944 
parse_private_stream_1(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)945 static int32_t parse_private_stream_1(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
946 
947     int track, spu_id;
948     int32_t result;
949 
950     result = parse_pes_for_pts(this, p, buf);
951     if (result < 0) return -1;
952 
953     p += result;
954     /* printf("demux_mpeg_pes: private_stream_1: p[0] = 0x%02X\n", p[0]); */
955 
956     if((p[0] & 0xE0) == 0x20) {
957       spu_id = (p[0] & 0x1f);
958 
959       buf->content   = p+1;
960       buf->size      = this->packet_len-1;
961 
962       buf->type      = BUF_SPU_DVD + spu_id;
963       buf->decoder_flags |= BUF_FLAG_SPECIAL;
964       buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
965       buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE;
966       buf->pts       = this->pts;
967 
968       this->video_fifo->put (this->video_fifo, buf);
969       lprintf ("SPU PACK put on fifo\n");
970 
971       return this->packet_len + result;
972     }
973 
974     /* SVCD OGT subtitles in stream 0x70 */
975     if(p[0] == 0x70 && (p[1] & 0xFC) == 0x00) {
976       spu_id = p[1];
977 
978       buf->content   = p+1;
979       buf->size      = this->packet_len-1;
980       buf->type      = BUF_SPU_SVCD + spu_id;
981       buf->pts       = this->pts;
982       /* this is probably wrong:
983       if( !preview_mode )
984         check_newpts( this, this->pts, PTS_VIDEO );
985       */
986       this->video_fifo->put (this->video_fifo, buf);
987       lprintf ("SPU SVCD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id);
988 
989       return this->packet_len + result;
990     }
991 
992     /* SVCD CVD subtitles in streams 0x00-0x03 */
993     if((p[0] & 0xFC) == 0x00) {
994       spu_id = (p[0] & 0x03);
995 
996       buf->content   = p+1;
997       buf->size      = this->packet_len-1;
998       buf->type      = BUF_SPU_CVD + spu_id;
999       buf->pts       = this->pts;
1000       /* this is probably wrong:
1001       if( !preview_mode )
1002         check_newpts( this, this->pts, PTS_VIDEO );
1003       */
1004       this->video_fifo->put (this->video_fifo, buf);
1005       lprintf ("SPU CVD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id);
1006 
1007       return this->packet_len + result;
1008     }
1009 
1010     if ((p[0]&0xF0) == 0x80) {
1011 
1012       track = p[0] & 0x0F; /* hack : ac3 track */
1013       buf->decoder_info[1] = p[1]; /* Number of frame headers */
1014       buf->decoder_info[2] = p[2] << 8 | p[3]; /* First access unit pointer */
1015 
1016       buf->content   = p+4;
1017       buf->size      = this->packet_len-4;
1018       if (track & 0x8) {
1019         buf->type      = BUF_AUDIO_DTS + (track & 0x07); /* DVDs only have 8 tracks */
1020       } else {
1021         buf->type      = BUF_AUDIO_A52 + track;
1022       }
1023       buf->pts       = this->pts;
1024       if( !this->preview_mode )
1025         check_newpts( this, this->pts, PTS_AUDIO );
1026 
1027       if(this->audio_fifo) {
1028         this->audio_fifo->put (this->audio_fifo, buf);
1029         lprintf ("A52 PACK put on fifo\n");
1030 
1031       } else {
1032         buf->free_buffer(buf);
1033       }
1034       return this->packet_len + result;
1035 
1036     /* EVOB AC3/E-AC-3 */
1037     } else if ((p[0]&0xf0) == 0xc0) {
1038 
1039       track = p[0] & 0x0F; /* hack : ac3 track */
1040       buf->decoder_info[1] = p[1]; /* Number of frame headers */
1041       buf->decoder_info[2] = p[2] << 8 | p[3]; /* First access unit pointer */
1042 
1043       buf->content   = p+4;
1044       buf->size      = this->packet_len-4;
1045       if (p[4] == 0x0b && p[5] == 0x77 && ((p[9] >> 3) & 0x1f) <= 8) {
1046         buf->type      = BUF_AUDIO_A52 + track;
1047       } else {
1048         buf->type      = BUF_AUDIO_EAC3 + track;
1049         buf->decoder_flags |= BUF_FLAG_FRAME_END;
1050       }
1051       buf->pts       = this->pts;
1052       if( !this->preview_mode )
1053         check_newpts( this, this->pts, PTS_AUDIO );
1054 
1055       if(this->audio_fifo) {
1056         this->audio_fifo->put (this->audio_fifo, buf);
1057         lprintf ("A52/EAC3 PACK put on fifo\n");
1058 
1059       } else {
1060         buf->free_buffer(buf);
1061       }
1062       return this->packet_len + result;
1063 
1064     } else if ((p[0]&0xf0) == 0xa0) {
1065 
1066       int pcm_offset;
1067 #if 0
1068       int number_of_frame_headers;
1069       int first_access_unit_pointer;
1070       int audio_frame_number;
1071       int bits_per_sample;
1072       int sample_rate;
1073       int num_channels;
1074       int dynamic_range;
1075 #endif
1076       /*
1077        * found in http://members.freemail.absa.co.za/ginggs/dvd/mpeg2_lpcm.txt
1078        * appears to be correct.
1079        */
1080 
1081       track = p[0] & 0x0F;
1082 #if 0
1083       number_of_frame_headers = p[1];
1084       /* unknown = p[2]; */
1085       first_access_unit_pointer = p[3];
1086       audio_frame_number = p[4];
1087 
1088       /*
1089        * 000 => mono
1090        * 001 => stereo
1091        * 010 => 3 channel
1092        * ...
1093        * 111 => 8 channel
1094        */
1095       num_channels = (p[5] & 0x7) + 1;
1096       switch ((p[5]>>4) & 3) {
1097       case 0: sample_rate = 48000; break;
1098       case 1: sample_rate = 96000; break;
1099       case 2: sample_rate = 44100; break;
1100       case 3: sample_rate = 32000; break;
1101       }
1102       switch ((p[5]>>6) & 3) {
1103       case 3: /* illegal, use 16-bits? */
1104       default:
1105         xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
1106                  "illegal lpcm sample format (%d), assume 16-bit samples\n",
1107                  (p[5]>>6) & 3 );
1108       case 0: bits_per_sample = 16; break;
1109       case 1: bits_per_sample = 20; break;
1110       case 2: bits_per_sample = 24; break;
1111       }
1112       dynamic_range = p[6];
1113 #endif
1114 
1115       /* send lpcm config byte */
1116       buf->decoder_flags |= BUF_FLAG_SPECIAL;
1117       buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG;
1118       buf->decoder_info[2] = p[5];
1119 
1120       pcm_offset = 7;
1121 
1122       buf->content   = p+pcm_offset;
1123       buf->size      = this->packet_len-pcm_offset;
1124       buf->type      = BUF_AUDIO_LPCM_BE + track;
1125       buf->pts       = this->pts;
1126       if( !this->preview_mode )
1127         check_newpts( this, this->pts, PTS_AUDIO );
1128 
1129       if(this->audio_fifo) {
1130         this->audio_fifo->put (this->audio_fifo, buf);
1131         lprintf ("LPCM PACK put on fifo\n");
1132 
1133       } else {
1134         buf->free_buffer(buf);
1135       }
1136       return this->packet_len + result;
1137 
1138     } else if((p[0]==0x0b) && (p[1]==0x77)) {
1139       int offset;
1140       int size;
1141 
1142       /*
1143        * A52/AC3 streams in some DVB-S recordings made with VDR.
1144        * It is broadcast by a german tv-station called PRO7.
1145        * PRO7 uses dolby 5.1 (A52 5.1) in some of the movies they broadcast,
1146        * (and they would switch it to stereo-sound(A52 2.0) during commercials.)
1147        * Here is the coresponding line from a channel.conf for the astra-satelite:
1148        * Pro-7:12480:v:S19.2E:27500:255:256;257:32:0:898:0:0:0
1149        */
1150 
1151       buf->decoder_info[1] = 0; /* Number of frame headers */
1152       buf->decoder_info[2] = 0; /* First access unit pointer */
1153 
1154       buf->content   = p;
1155       size = this->packet_len;
1156       if ((size + result) > buf->max_size) {
1157         size = buf->max_size - result;
1158       }
1159       buf->size      = size;
1160       buf->type      = BUF_AUDIO_A52;
1161       buf->pts       = this->pts;
1162       if( !this->preview_mode )
1163         check_newpts( this, this->pts, PTS_AUDIO );
1164 
1165       if (this->audio_fifo) {
1166         this->audio_fifo->put (this->audio_fifo, buf);
1167         lprintf ("A52 PACK put on fifo\n");
1168       } else {
1169         buf->free_buffer(buf);
1170         /* skip tail */
1171         if (this->input->seek (this->input, this->packet_len - size, SEEK_CUR) < 0)
1172           return -1;
1173         return this->packet_len + result;
1174       }
1175 
1176       if (size == (int)(this->packet_len)) {
1177         return this->packet_len + result;
1178       }
1179 
1180       /* Handle Jumbo A52 frames from VDR. */
1181       offset = size;
1182       while (offset < (int)(this->packet_len)) {
1183         int i;
1184         buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
1185         size = this->packet_len - offset;
1186         if (size > buf->max_size)
1187           size = buf->max_size;
1188         offset += size;
1189         i = read_data(this, buf->mem, (off_t) (size));
1190         if (i != size) {
1191           buf->free_buffer(buf);
1192           return this->packet_len + result;
1193         }
1194         buf->content   = buf->mem;
1195         buf->size      = size;
1196         buf->type      = BUF_AUDIO_A52;
1197         buf->pts       = 0;
1198 
1199         this->audio_fifo->put (this->audio_fifo, buf);
1200         lprintf ("A52 PACK put on fifo\n");
1201       }
1202 
1203       return this->packet_len + result;
1204     }
1205 
1206 
1207 
1208     /* Some new streams have been encountered.
1209        1) DVD+RW disc recorded with a Philips DVD recorder: -  new unknown sub-stream id of 0xff
1210      */
1211     xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
1212             _("demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to xine developers.\n"), p[0]);
1213     buf->free_buffer(buf);
1214     return this->packet_len + result;
1215 }
1216 
parse_video_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)1217 static int32_t parse_video_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
1218   int32_t result;
1219   uint32_t todo_length=0;
1220   uint32_t i;
1221   uint32_t chunk_length;
1222   int buf_type = BUF_VIDEO_MPEG;
1223   int payload_size;
1224 
1225   result = parse_pes_for_pts(this, p, buf);
1226   if (result < 0) return -1;
1227 
1228   p += result;
1229 
1230   buf->content = p;
1231   payload_size = buf->max_size - result;
1232   if (payload_size > (int)(this->packet_len))
1233     payload_size = this->packet_len;
1234 
1235   /* H.264 broadcasts via DVB-S use standard video PES packets,
1236      so there is no way other than scanning the video data to
1237      detect whether BUF_VIDEO_H264 needs to be used.
1238      For performance reasons, this is not a general scanner for
1239      H.264 content, as this kind of data format is likely to be
1240      used only by VDR and VDR will ensure that an AUD-NAL unit
1241      will be at the beginning of the PES packet's payload.
1242      To minimize false hits, the whole payload is scanned for
1243      MPEG 1/2 start codes, so there is only a little chance left
1244      that a MPEG 1/2 slice 9 start code will be considered as a
1245      H.264 access unit delimiter (should only happen after a seek).
1246 
1247      Meaning of bit 0 and 1 of mpeg12_h264_detected:
1248      Bit 0: H.264 access unit delimiter seen
1249      Bit 1: H.264 AUD seen again or MPEG 1/2 start code seen
1250 
1251      For performance reasons, the scanner is only active until
1252      a H.264 AUD has been seen a second time or a MPEG 1/2 start
1253      code has been seen. The scanner get's activated initially
1254      (e. g. when opening the stream), after seeking or when VDR
1255      sends a padding packet.
1256      Until the scanner is convinced of it's decision by setting
1257      bit 1, the default behaviour is to assume MPEG 1/2 unless
1258      an AUD has been found at the beginning of the payload.
1259    */
1260   if (this->mpeg12_h264_detected < 2) {
1261     uint8_t *pp = p + 2, *pp_limit = p + payload_size - 1;
1262     while (pp && pp < pp_limit) {
1263       if (pp[0] == 0x01 && pp[-1] == 0x00 && pp[-2] == 0x00) {
1264         if (pp[1] >= 0x80 || !pp[1]) { /* MPEG 1/2 start code */
1265           this->mpeg12_h264_detected = 2;
1266           break;
1267         } else {
1268           int nal_type_code = pp[1] & 0x1f;
1269           if (nal_type_code == 9 && pp == (p + 2)) { /* access unit delimiter */
1270             if (this->mpeg12_h264_detected == 1) {
1271               this->mpeg12_h264_detected = 3;
1272               break;
1273             }
1274             this->mpeg12_h264_detected = 1;
1275           }
1276         }
1277       }
1278       pp++;
1279       pp = memchr(pp, 0x01, pp_limit - pp);
1280     }
1281     lprintf("%s%c\n", (this->mpeg12_h264_detected & 1) ? "H.264" : "MPEG1/2", (this->mpeg12_h264_detected & 2) ? '!' : '?');
1282   }
1283 
1284   /* when an H.264 AUD is seen, we first need to tell the decoder that the
1285      previous frame was complete.
1286    */
1287   if (this->mpeg12_h264_detected & 1) {
1288     buf_type = BUF_VIDEO_H264;
1289     /* omit sending BUF_FLAG_FRAME_END for the first AUD occurence */
1290     if (this->mpeg12_h264_detected > 2) {
1291       int nal_type_code = -1;
1292       if (payload_size >= 4 && p[2] == 0x01 && p[1] == 0x00 && p[0] == 0x00)
1293         nal_type_code = p[3] & 0x1f;
1294       if (nal_type_code == 9) { /* access unit delimiter */
1295         buf_element_t *b = this->video_fifo->buffer_pool_alloc (this->video_fifo);
1296         b->content       = b->mem;
1297         b->size          = 0;
1298         b->pts           = 0;
1299         b->type          = buf_type;
1300         b->decoder_flags = BUF_FLAG_FRAME_END | (this->preview_mode ? BUF_FLAG_PREVIEW : 0);
1301         this->video_fifo->put (this->video_fifo, b);
1302       }
1303     }
1304   }
1305 
1306   if ((int)(this->packet_len) <= (buf->max_size - result)) {
1307     buf->size = this->packet_len;
1308     /* VDR ensures that H.264 still images end with an end of sequence NAL unit. We
1309        need to detect this to inform the decoder that the current frame is complete.
1310      */
1311     if (this->mpeg12_h264_detected & 1) {
1312       uint8_t *t = buf->content + buf->size;
1313       if (buf->size >=4 && t[-1] == 10 && t[-2] == 0x01 && t[-3] == 0x00 && t[-4] == 0x00) /* end of sequence */
1314         buf->decoder_flags = BUF_FLAG_FRAME_END | (this->preview_mode ? BUF_FLAG_PREVIEW : 0);
1315     }
1316   } else {
1317     buf->size    = buf->max_size - result;
1318     todo_length  = this->packet_len - buf->size;
1319   }
1320   buf->type      = buf_type;
1321   buf->pts       = this->pts;
1322   buf->decoder_info[0] = this->pts - this->dts;
1323   if( !this->preview_mode )
1324     check_newpts( this, this->pts, PTS_VIDEO );
1325 
1326   this->video_fifo->put (this->video_fifo, buf);
1327   while (todo_length > 0) {
1328     buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
1329     if ((int)todo_length < buf->max_size) {
1330       chunk_length = todo_length;
1331     } else {
1332       chunk_length = buf->max_size;
1333     }
1334     i = read_data(this, buf->mem, (off_t) (chunk_length));
1335       if (i !=  chunk_length) {
1336         buf->free_buffer (buf);
1337         this->status = DEMUX_FINISHED;
1338         return -1;
1339       }
1340     buf->content   = buf->mem;
1341     buf->size      = chunk_length;
1342     buf->type      = buf_type;
1343     buf->pts       = 0;
1344     todo_length -= chunk_length;
1345 
1346     /* VDR ensures that H.264 still images end with an end of sequence NAL unit. We
1347        need to detect this to inform the decoder that the current frame is complete.
1348      */
1349     if ((this->mpeg12_h264_detected & 1) && todo_length <= 0) {
1350       uint8_t *t = buf->content + buf->size;
1351       if (buf->size >= 4 && t[-1] == 10 && t[-2] == 0x01 && t[-3] == 0x00 && t[-4] == 0x00) /* end of sequence */
1352         buf->decoder_flags = BUF_FLAG_FRAME_END | (this->preview_mode ? BUF_FLAG_PREVIEW : 0);
1353     }
1354 
1355     this->video_fifo->put (this->video_fifo, buf);
1356   }
1357 
1358   lprintf ("MPEG Video PACK put on fifo\n");
1359 
1360   return this->packet_len + result;
1361 }
1362 
parse_audio_stream(demux_mpeg_pes_t * this,uint8_t * p,buf_element_t * buf)1363 static int32_t parse_audio_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) {
1364 
1365   int track;
1366   int32_t result;
1367 
1368   result = parse_pes_for_pts(this, p, buf);
1369   if (result < 0) return -1;
1370 
1371   p += result;
1372 
1373   track = this->stream_id & 0x1f;
1374 
1375   buf->content   = p;
1376   buf->size      = this->packet_len;
1377   buf->type      = BUF_AUDIO_MPEG + track;
1378   buf->pts       = this->pts;
1379   if( !this->preview_mode )
1380       check_newpts( this, this->pts, PTS_AUDIO );
1381 
1382   if(this->audio_fifo) {
1383     this->audio_fifo->put (this->audio_fifo, buf);
1384     lprintf ("MPEG Audio PACK put on fifo\n");
1385   } else {
1386     buf->free_buffer(buf);
1387   }
1388 
1389   return this->packet_len + result;
1390 }
1391 
demux_mpeg_pes_send_chunk(demux_plugin_t * this_gen)1392 static int demux_mpeg_pes_send_chunk (demux_plugin_t *this_gen) {
1393 
1394   demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen;
1395 
1396   demux_mpeg_pes_parse_pack(this, 0);
1397 
1398   return this->status;
1399 }
1400 
1401 #ifdef ESTIMATE_RATE_FIXED
1402 /*!
1403    Estimate bitrate by looking inside the MPEG file for presentation
1404    time stamps (PTS) and computing how far apart these are
1405    in bytes and in time.
1406 
1407    On failure return 0.
1408 
1409    This might be used after deciding that mux_rate in a stream is faulty.
1410 
1411 */
1412 
1413 /* How many *sucessful* PTS samples do we take? */
1414 #define MAX_SAMPLES 5
1415 
1416 /* How many times we read blocks before giving up. */
1417 #define MAX_READS 30
1418 
1419 /* TRUNCATE x to the nearest multiple of y. */
1420 #define TRUNC(x,y) (((x) / (y)) * (y))
1421 
demux_mpeg_pes_estimate_rate(demux_mpeg_pes_t * this)1422 static int demux_mpeg_pes_estimate_rate (demux_mpeg_pes_t *this) {
1423 
1424   buf_element_t *buf = NULL;
1425   unsigned char *p;
1426   int            is_mpeg1=0;
1427   off_t          pos, last_pos=0;
1428   off_t          step, mpeg_length;
1429   int64_t        pts, last_pts=0;
1430   int            reads=0    /* Number of blocks read so far */;
1431   int            count=0;   /* Number of sucessful PTS found so far */
1432   int            rate=0;    /* The return rate value */
1433   int            stream_id;
1434 
1435   /* We can't estimate by sampling if we don't thave the ability to
1436      randomly access the and more importantly reset after accessessing.  */
1437   if (!(this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE))
1438     return 0;
1439 
1440   mpeg_length= this->input->get_length (this->input);
1441   step = TRUNC((mpeg_length/MAX_SAMPLES), 2048);
1442   if (step <= 0) step = 2048; /* avoid endless loop for tiny files */
1443   pos = step;
1444 
1445   /* At this point "pos", and "step" are a multiple of blocksize and
1446      they should continue to be so throughout.
1447    */
1448 
1449   if (this->input->seek (this->input, pos, SEEK_SET) != pos)
1450     return 0;
1451 
1452   while ( (buf = this->input->read_block (this->input, this->video_fifo, 2048))
1453           && count < MAX_SAMPLES && reads++ < MAX_READS ) {
1454 
1455     p = buf->content; /* len = this->mnBlocksize; */
1456 
1457     if (p[3] == 0xBA) { /* program stream pack header */
1458 
1459       is_mpeg1 = (p[4] & 0x40) == 0;
1460 
1461       if (is_mpeg1)
1462         p   += 12;
1463       else
1464         p += 14 + (p[0xD] & 0x07);
1465     }
1466 
1467     if (p[3] == 0xbb)  /* program stream system header */
1468       p  += 6 + ((p[4] << 8) | p[5]);
1469 
1470     /* we should now have a PES packet here */
1471 
1472     if (p[0] || p[1] || (p[2] != 1)) {
1473       xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
1474                "demux_mpeg_pes: error %02x %02x %02x (should be 0x000001) \n", p[0], p[1], p[2]);
1475       buf->free_buffer (buf);
1476       return rate;
1477     }
1478 
1479     stream_id  = p[3];
1480     pts = 0;
1481 
1482     if ((stream_id < 0xbc) || ((stream_id & 0xf0) != 0xe0)) {
1483       pos += (off_t) 2048;
1484       buf->free_buffer (buf);
1485       continue; /* only use video packets */
1486     }
1487 
1488     if (is_mpeg1) {
1489 
1490       if (p[3] != 0xBF) { /* stream_id */
1491 
1492         p += 6; /* packet_len -= 6; */
1493 
1494         while ((p[0] & 0x80) == 0x80) {
1495           p++; /* stuffing */
1496         }
1497 
1498         if ((p[0] & 0xc0) == 0x40) {
1499           /* STD_buffer_scale, STD_buffer_size */
1500           p += 2;
1501         }
1502 
1503         if ( ((p[0] & 0xf0) == 0x20) || ((p[0] & 0xf0) == 0x30) ) {
1504           pts  = (int64_t)(p[ 0] & 0x0E) << 29 ;
1505           pts |=  p[ 1]         << 22 ;
1506           pts |= (p[ 2] & 0xFE) << 14 ;
1507           pts |=  p[ 3]         <<  7 ;
1508           pts |= (p[ 4] & 0xFE) >>  1 ;
1509         }
1510       }
1511     } else { /* mpeg 2 */
1512 
1513       if (p[7] & 0x80) { /* pts avail */
1514 
1515         pts  = (int64_t)(p[ 9] & 0x0E) << 29 ;
1516         pts |=  p[10]         << 22 ;
1517         pts |= (p[11] & 0xFE) << 14 ;
1518         pts |=  p[12]         <<  7 ;
1519         pts |= (p[13] & 0xFE) >>  1 ;
1520 
1521       } else
1522         pts = 0;
1523     }
1524 
1525     if (pts) {
1526 
1527 
1528       if ( (pos>last_pos) && (pts>last_pts) ) {
1529         int cur_rate;
1530 
1531         cur_rate = ((pos - last_pos)*90000) / ((pts - last_pts) * 50);
1532 
1533         rate = (count * rate + cur_rate) / (count+1);
1534 
1535         count ++;
1536 
1537         /*
1538         printf ("demux_mpeg_pes: stream_id %02x, pos: %"PRId64", pts: %d, cur_rate = %d, overall rate : %d\n",
1539                 stream_id, pos, pts, cur_rate, rate);
1540         */
1541       }
1542 
1543       last_pos = pos;
1544       last_pts = pts;
1545       pos += step;
1546     } else
1547       pos += 2048;
1548 
1549     buf->free_buffer (buf);
1550 
1551     if (pos > mpeg_length || this->input->seek (this->input, pos, SEEK_SET) == (off_t)-1)
1552       break;
1553 
1554   }
1555 }
1556 
1557   lprintf("est_rate=%d\n",rate);
1558   return rate;
1559 
1560 }
1561 #endif /*ESTIMATE_RATE_FIXED*/
1562 
1563 static int demux_mpeg_pes_get_status (demux_plugin_t *this_gen) {
1564   demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen;
1565 
1566   return this->status;
1567 }
1568 
1569 static void demux_mpeg_pes_send_headers (demux_plugin_t *this_gen) {
1570 
1571   demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen;
1572 
1573   this->video_fifo  = this->stream->video_fifo;
1574   this->audio_fifo  = this->stream->audio_fifo;
1575 
1576   /*
1577    * send start buffer
1578    */
1579 
1580   _x_demux_control_start(this->stream);
1581 
1582 #ifdef USE_ILL_ADVISED_ESTIMATE_RATE_INITIALLY
1583   if (!this->rate)
1584     this->rate = demux_mpeg_pes_estimate_rate (this);
1585 #else
1586   /* Set to Use rate given in by stream initially. */
1587   this->rate = 0;
1588 #endif
1589 
1590   if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
1591 
1592     int num_buffers = NUM_PREVIEW_BUFFERS;
1593 
1594     if (this->input->seek (this->input, 0, SEEK_SET) != 0) {
1595       this->status = DEMUX_FINISHED;
1596       return;
1597     }
1598 
1599     this->status = DEMUX_OK ;
1600     while ( (num_buffers>0) && (this->status == DEMUX_OK) ) {
1601 
1602       demux_mpeg_pes_parse_pack(this, 1);
1603       num_buffers --;
1604     }
1605   }
1606   else if((this->input->get_capabilities(this->input) & INPUT_CAP_PREVIEW) != 0) {
1607 
1608     this->preview_size = this->input->get_optional_data(this->input, &this->preview_data, INPUT_OPTIONAL_DATA_PREVIEW);
1609     this->preview_done = 0;
1610 
1611     this->status = DEMUX_OK ;
1612     while ( (this->preview_done < this->preview_size) && (this->status == DEMUX_OK) )
1613       demux_mpeg_pes_parse_pack(this, 1);
1614 
1615     this->preview_size = 0;
1616   }
1617 
1618   this->status = DEMUX_OK;
1619 
1620   _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
1621   _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
1622   _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->rate * 50 * 8);
1623 }
1624 
1625 
1626 static int demux_mpeg_pes_seek (demux_plugin_t *this_gen,
1627                                    off_t start_pos, int start_time, int playing) {
1628 
1629   demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen;
1630   start_time /= 1000;
1631   start_pos = (off_t) ( (double) start_pos / 65535 *
1632               this->input->get_length (this->input) );
1633 
1634   if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) {
1635 
1636     if (start_pos) {
1637       start_pos /= (off_t) 2048;
1638       start_pos *= (off_t) 2048;
1639 
1640       this->input->seek (this->input, start_pos, SEEK_SET);
1641     } else if (start_time) {
1642 
1643       if (this->last_cell_time) {
1644         start_pos = start_time - (this->last_cell_time + this->last_begin_time)/1000;
1645         start_pos *= this->rate;
1646         start_pos *= 50;
1647         start_pos += this->last_cell_pos;
1648       } else {
1649         start_pos = start_time;
1650         start_pos *= this->rate;
1651         start_pos *= 50;
1652       }
1653       start_pos /= (off_t) 2048;
1654       start_pos *= (off_t) 2048;
1655 
1656       this->input->seek (this->input, start_pos, SEEK_SET);
1657     } else
1658       this->input->seek (this->input, 0, SEEK_SET);
1659   }
1660 
1661   /*
1662    * now start demuxing
1663    */
1664   this->last_cell_time = 0;
1665   this->send_newpts = 1;
1666   if( !playing ) {
1667 
1668     this->buf_flag_seek = 0;
1669     this->nav_last_end_pts = this->nav_last_start_pts = 0;
1670     this->status   = DEMUX_OK ;
1671     this->last_pts[0]   = 0;
1672     this->last_pts[1]   = 0;
1673 #ifdef PTS_BOUNCE
1674     this->apts = this->bpts = 0;
1675     this->bounce_left = 0;
1676 #endif
1677   } else {
1678     this->buf_flag_seek = 1;
1679     this->nav_last_end_pts = this->nav_last_start_pts = 0;
1680     /* trigger detection of MPEG 1/2 respectively H.264 content */
1681     this->mpeg12_h264_detected = 0;
1682     _x_demux_flush_engine(this->stream);
1683   }
1684 
1685   return this->status;
1686 }
1687 
1688 
1689 static int demux_mpeg_pes_get_stream_length (demux_plugin_t *this_gen) {
1690 
1691   demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen;
1692   /*
1693    * find input plugin
1694    */
1695 
1696   if (this->rate)
1697     return (int)((int64_t) 1000 * this->input->get_length (this->input) /
1698                  (this->rate * 50));
1699   else
1700     return 0;
1701 }
1702 
1703 static uint32_t demux_mpeg_pes_get_capabilities(demux_plugin_t *this_gen) {
1704   (void)this_gen;
1705   return DEMUX_CAP_NOCAP;
1706 }
1707 
1708 static int demux_mpeg_pes_get_optional_data(demux_plugin_t *this_gen,
1709                                         void *data, int data_type) {
1710   (void)this_gen;
1711   (void)data;
1712   (void)data_type;
1713   return DEMUX_OPTIONAL_UNSUPPORTED;
1714 }
1715 
1716 static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
1717                                    input_plugin_t *input) {
1718   demux_mpeg_pes_t *this;
1719 
1720   lprintf ("open_plugin:detection_method=%d\n",
1721            stream->content_detection_method);
1722 
1723   switch (stream->content_detection_method) {
1724 
1725   case METHOD_BY_CONTENT: {
1726     uint8_t buf[6];
1727 
1728     /* use demux_mpeg_block for block devices */
1729     if ((input->get_capabilities(input) & INPUT_CAP_BLOCK)) {
1730       return NULL;
1731     }
1732 
1733     if (_x_demux_read_header(input, buf, sizeof(buf)) != 6) {
1734       return NULL;
1735     }
1736 
1737     if (buf[0] || buf[1] || (buf[2] != 0x01)) {
1738       lprintf("open_plugin:preview_data failed\n");
1739       return NULL;
1740     }
1741     switch (buf[3]) {
1742       case 0xe0 ... 0xef:
1743       case 0xc0 ... 0xdf:
1744       case 0xbd ... 0xbe:
1745         break;
1746       default:
1747         return NULL;
1748     }
1749 
1750     lprintf("open_plugin:Accepting detection_method XINE_DEMUX_CONTENT_STRATEGY (preview_data)\n");
1751   }
1752   break;
1753 
1754   case METHOD_BY_MRL:
1755     break;
1756 
1757   case METHOD_EXPLICIT:
1758     break;
1759 
1760   default:
1761     return NULL;
1762   }
1763 
1764   this = calloc(1, sizeof(demux_mpeg_pes_t));
1765   if (!this)
1766     return NULL;
1767 
1768   /* trigger detection of MPEG 1/2 respectively H.264 content */
1769   this->mpeg12_h264_detected = 0;
1770   this->preview_size = 0;
1771   this->stream = stream;
1772   this->input  = input;
1773   this->status = DEMUX_FINISHED;
1774 
1775   this->is_vdr = 0;
1776   if (input->input_class->identifier && !strcmp (input->input_class->identifier, "VDR"))
1777     this->is_vdr = 1;
1778 
1779   /* Don't start demuxing stream until we see a program_stream_pack_header */
1780   /* We need to system header in order to identify is the stream is mpeg1 or mpeg2. */
1781   this->wait_for_program_stream_pack_header = 1;
1782 
1783   this->demux_plugin.send_headers      = demux_mpeg_pes_send_headers;
1784   this->demux_plugin.send_chunk        = demux_mpeg_pes_send_chunk;
1785   this->demux_plugin.seek              = demux_mpeg_pes_seek;
1786   this->demux_plugin.dispose           = default_demux_plugin_dispose;
1787   this->demux_plugin.get_status        = demux_mpeg_pes_get_status;
1788   this->demux_plugin.get_stream_length = demux_mpeg_pes_get_stream_length;
1789   this->demux_plugin.get_capabilities  = demux_mpeg_pes_get_capabilities;
1790   this->demux_plugin.get_optional_data = demux_mpeg_pes_get_optional_data;
1791   this->demux_plugin.demux_class       = class_gen;
1792 
1793   return &this->demux_plugin;
1794 }
1795 
1796 void *demux_pes_init_class (xine_t *xine, const void *data) {
1797 
1798   (void)xine;
1799   (void)data;
1800 
1801   static const demux_class_t demux_mpeg_pes_class = {
1802     .open_plugin     = open_plugin,
1803     .description     = N_("mpeg pes demux plugin"),
1804     .identifier      = "MPEG_PES",
1805     .mimetypes       = "video/mp2p: m2p: MPEG2 program stream;",
1806     .extensions      = "pes vdr:/ netvdr:/",
1807     .dispose         = NULL,
1808   };
1809 
1810   return (void *)&demux_mpeg_pes_class;
1811 }
1812 
1813 
1814