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