1 /*
2 * Copyright (C) 2000-2018 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
21 /*
22 * demultiplexer for mpeg 1/2 program streams
23 * reads streams of variable blocksizes
24 */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <string.h>
35
36 #define LOG_MODULE "demux_mpeg"
37 #define LOG_VERBOSE
38 /*
39 #define LOG
40 */
41
42 #include "group_video.h"
43
44 #include <xine/xine_internal.h>
45 #include <xine/demux.h>
46 #include <xine/xineutils.h>
47
48 #define NUM_PREVIEW_BUFFERS 150
49 #define SCRATCH_SIZE 256
50
51 #define WRAP_THRESHOLD 120000
52
53 #define PTS_AUDIO 0
54 #define PTS_VIDEO 1
55
56 typedef struct demux_mpeg_s {
57 demux_plugin_t demux_plugin;
58
59 xine_stream_t *stream;
60 fifo_buffer_t *audio_fifo;
61 fifo_buffer_t *video_fifo;
62 input_plugin_t *input;
63 int status;
64
65 int preview_mode;
66 int rate;
67
68 int64_t last_pts[2];
69 int send_newpts;
70 int buf_flag_seek;
71 int has_pts;
72
73 int num_audio;
74 uint8_t audio_dvd[16];
75 uint8_t audio_lpcm[16];
76 uint8_t audio_mpeg[32];
77
78 int num_spu;
79 uint8_t spu_dvd[32];
80 uint8_t spu_svcd[4];
81 uint8_t spu_cvd[4];
82
83 uint8_t tbuf[4096];
84 } demux_mpeg_t;
85
86 /* code never reached, is it still usefull ?? */
87 /*
88 * borrow a little knowledge from the Quicktime demuxer
89 */
90 #include "bswap.h"
91
92 #define QT_ATOM BE_FOURCC
93 /* these are the known top-level QT atoms */
94 #define FREE_ATOM QT_ATOM('f', 'r', 'e', 'e')
95 #define JUNK_ATOM QT_ATOM('j', 'u', 'n', 'k')
96 #define MDAT_ATOM QT_ATOM('m', 'd', 'a', 't')
97 #define MOOV_ATOM QT_ATOM('m', 'o', 'o', 'v')
98 #define PNOT_ATOM QT_ATOM('p', 'n', 'o', 't')
99 #define SKIP_ATOM QT_ATOM('s', 'k', 'i', 'p')
100 #define WIDE_ATOM QT_ATOM('w', 'i', 'd', 'e')
101
102 #define ATOM_PREAMBLE_SIZE 8
103
104 /* a little something for dealing with RIFF headers */
105
106 #define FOURCC_TAG BE_FOURCC
107 #define RIFF_TAG FOURCC_TAG('R', 'I', 'F', 'F')
108 #define WAVE_TAG FOURCC_TAG('W', 'A', 'V', 'E')
109 #define AVI_TAG FOURCC_TAG('A', 'V', 'I', ' ')
110 #define FOURXM_TAG FOURCC_TAG('4', 'X', 'M', 'V')
111
112 /* arbitrary number of initial file bytes to check for an MPEG marker */
113 #define RIFF_CHECK_KILOBYTES 1024
114
115 #define MPEG_MARKER FOURCC_TAG( 0x00, 0x00, 0x01, 0xBA )
116
117 /*
118 * This function traverses a file and looks for a mdat atom. Upon exit:
119 * *mdat_offset contains the file offset of the beginning of the mdat
120 * atom (that means the offset * of the 4-byte length preceding the
121 * characters 'mdat')
122 * *mdat_size contains the 4-byte size preceding the mdat characters in
123 * the atom. Note that this will be 1 in the case of a 64-bit atom.
124 * Both mdat_offset and mdat_size are set to -1 if not mdat atom was
125 * found.
126 *
127 * Note: Do not count on the input stream being positioned anywhere in
128 * particular when this function is finished.
129 */
find_mdat_atom(input_plugin_t * input,off_t * mdat_offset,int64_t * mdat_size)130 static void find_mdat_atom(input_plugin_t *input, off_t *mdat_offset,
131 int64_t *mdat_size) {
132
133 off_t atom_size;
134 unsigned int atom;
135 unsigned char atom_preamble[ATOM_PREAMBLE_SIZE];
136
137 /* init the passed variables */
138 *mdat_offset = *mdat_size = -1;
139
140 /* take it from the top */
141 if (input->seek(input, 0, SEEK_SET) != 0)
142 return;
143
144 /* traverse through the input */
145 while (*mdat_offset == -1) {
146 if (input->read(input, atom_preamble, ATOM_PREAMBLE_SIZE) !=
147 ATOM_PREAMBLE_SIZE)
148 break;
149
150 atom_size = _X_BE_32(&atom_preamble[0]);
151 atom = _X_BE_32(&atom_preamble[4]);
152
153 if (atom == MDAT_ATOM) {
154 *mdat_offset = input->get_current_pos(input) - ATOM_PREAMBLE_SIZE;
155 *mdat_size = atom_size;
156 break;
157 }
158
159 /* make sure the atom checks out as some other top-level atom before
160 * proceeding */
161 if ((atom != FREE_ATOM) &&
162 (atom != JUNK_ATOM) &&
163 (atom != MOOV_ATOM) &&
164 (atom != PNOT_ATOM) &&
165 (atom != SKIP_ATOM) &&
166 (atom != WIDE_ATOM))
167 break;
168
169 /* 64-bit length special case */
170 if (atom_size == 1) {
171 if (input->read(input, atom_preamble, ATOM_PREAMBLE_SIZE) !=
172 ATOM_PREAMBLE_SIZE)
173 break;
174
175 atom_size = _X_BE_32(&atom_preamble[0]);
176 atom_size <<= 32;
177 atom_size |= _X_BE_32(&atom_preamble[4]);
178 atom_size -= ATOM_PREAMBLE_SIZE * 2;
179 } else
180 atom_size -= ATOM_PREAMBLE_SIZE;
181
182
183 input->seek(input, atom_size, SEEK_CUR);
184 }
185 }
186
reset_track_map(fifo_buffer_t * fifo)187 static void reset_track_map (fifo_buffer_t *fifo) {
188 if (fifo) {
189 #if 0 /* not needed yet */
190 buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
191 buf->type = BUF_CONTROL_RESET_TRACK_MAP;
192 buf->decoder_info[1] = -1;
193 fifo->put (fifo, buf);
194 #endif
195 ;
196 }
197 }
198
read_bytes(demux_mpeg_t * this,uint32_t n)199 static uint32_t read_bytes (demux_mpeg_t *this, uint32_t n) {
200
201 uint32_t res;
202 uint32_t i;
203 unsigned char buf[8];
204
205 _x_assert(n > 0);
206 _x_assert(n <= 4);
207
208 i = this->input->read (this->input, buf, n);
209
210 if (i != n) {
211 this->status = DEMUX_FINISHED;
212 return 0;
213 }
214
215 switch (n) {
216 case 1:
217 res = buf[0];
218 break;
219 case 2:
220 res = (buf[0]<<8) | buf[1];
221 break;
222 case 3:
223 res = (buf[0]<<16) | (buf[1]<<8) | buf[2];
224 break;
225 case 4:
226 default: /* calm down gcc */
227 res = (buf[2]<<8) | buf[3] | (buf[1]<<16) | (buf[0] << 24);
228 break;
229 }
230
231 return res;
232 }
233
234 /* redefine abs as macro to handle 64-bit diffs.
235 i guess llabs may not be available everywhere */
236 #define abs(x) ( ((x)<0) ? -(x) : (x) )
237
check_newpts(demux_mpeg_t * this,int64_t pts,int video)238 static void check_newpts( demux_mpeg_t *this, int64_t pts, int video ) {
239 int64_t diff;
240
241 diff = pts - this->last_pts[video];
242
243 if( !this->preview_mode && pts &&
244 (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) {
245
246 if (this->buf_flag_seek) {
247 _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK);
248 this->buf_flag_seek = 0;
249 } else {
250 _x_demux_control_newpts(this->stream, pts, 0);
251 }
252 this->send_newpts = 0;
253 this->last_pts[1-video] = 0;
254 }
255
256 if( !this->preview_mode && pts )
257 this->last_pts[video] = pts;
258 }
259
mpeg1_read_pts(demux_mpeg_t * this,int64_t * pts,uint32_t leadbyte)260 static int mpeg1_read_pts (demux_mpeg_t *this, int64_t *pts, uint32_t leadbyte) {
261 union { uint32_t w; uint8_t b[4]; } tbuf;
262 int64_t v;
263 uint32_t w;
264 if (this->input->read (this->input, &tbuf.b[0], 4) != 4) {
265 this->status = DEMUX_FINISHED;
266 return 1;
267 }
268 v = (uint64_t)(leadbyte & 0x0e) << 29;
269 w = tbuf.w;
270 #ifndef WORDS_BIGENDIAN
271 /* gcc sees __builtin_bswap32 () here. */
272 w = (w >> 24) | ((w & 0xff0000) >> 8) | ((w & 0xff00) << 8) | (w << 24);
273 #endif
274 v |= (w >> 2) & 0x3fff8000;
275 v |= (w >> 1) & 0x7fff;
276 *pts = v;
277 return 0;
278 }
279
mpeg2_read_pts(demux_mpeg_t * this,int64_t * pts)280 static int mpeg2_read_pts (demux_mpeg_t *this, int64_t *pts) {
281 union { uint32_t w[2]; uint8_t b[8]; } tbuf;
282 int64_t v;
283 uint32_t w;
284 if (this->input->read (this->input, &tbuf.b[3], 5) != 5) {
285 this->status = DEMUX_FINISHED;
286 return 1;
287 }
288 v = (uint64_t)(tbuf.b[3] & 0x0e) << 29;
289 w = tbuf.w[1];
290 #ifndef WORDS_BIGENDIAN
291 /* gcc sees __builtin_bswap32 () here. */
292 w = (w >> 24) | ((w & 0xff0000) >> 8) | ((w & 0xff00) << 8) | (w << 24);
293 #endif
294 v |= (w >> 2) & 0x3fff8000;
295 v |= (w >> 1) & 0x7fff;
296 *pts = v;
297 return 0;
298 }
299
mpeg_get_pts(const uint8_t * p)300 static int64_t mpeg_get_pts (const uint8_t *p) {
301 int64_t v = (uint64_t)(p[0] & 0x0e) << 29;
302 uint32_t w = _X_BE_32 (p + 1);
303 v |= (w >> 2) & 0x3fff8000;
304 v |= (w >> 1) & 0x7fff;
305 return v;
306 }
307
parse_mpeg2_packet(demux_mpeg_t * this,int stream_id,int64_t scr)308 static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) {
309
310 int normpos, itime;
311 int64_t pts, dts;
312 {
313 off_t ilen = this->input->get_length (this->input);
314 off_t ipos = this->input->get_current_pos (this->input);
315 normpos = ilen > 0 ? (int64_t)ipos * 65535 / ilen : 0;
316 itime = this->rate ? (int64_t)ipos * 20 / this->rate : 0;
317 }
318
319 (void)scr;
320 //printf( "parse_mpeg2_packet: stream_id=%X\n", stream_id);
321
322 if (stream_id==0xbd) {
323
324 uint32_t len, flags, header_len;
325 uint8_t *p = this->tbuf;
326
327 if (this->input->read (this->input, p, 5) != 5) {
328 this->status = DEMUX_FINISHED;
329 return;
330 }
331 flags = p[3];
332 header_len = p[4];
333 len = (flags & 0x80) ? 5 : 0;
334 if (header_len < len)
335 header_len = len;
336 len = _X_BE_16 (p);
337 p += 5;
338
339 if (this->input->read (this->input, p, header_len + 1) != (int)header_len + 1) {
340 this->status = DEMUX_FINISHED;
341 return;
342 }
343 pts = 0;
344 if (flags & 0x80)
345 pts = mpeg_get_pts (p);
346 p += header_len;
347
348 len -= header_len + 3;
349
350 /* DVD spu/subtitles */
351 if ((p[0] & 0xe0) == 0x20) {
352
353 int track = p[0] & 0x1f;
354 len -= 1;
355
356 /* register */
357 if (this->spu_dvd[track] == 255) {
358 this->spu_dvd[track] = this->num_spu++;
359 reset_track_map (this->video_fifo);
360 }
361
362 if (!this->video_fifo) {
363 this->input->seek (this->input, len, SEEK_CUR);
364 } else {
365 int bufflags = BUF_FLAG_SPECIAL | (this->preview_mode ? BUF_FLAG_PREVIEW : 0);
366 int type = BUF_SPU_DVD + this->spu_dvd[track];
367 while (len > 0) {
368 buf_element_t *buf;
369 int part;
370 buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len);
371 part = buf->max_size < (int)len ? buf->max_size : (int)len;
372 buf->size = this->input->read (this->input, buf->content, part);
373 if (buf->size != part) {
374 buf->free_buffer (buf);
375 this->status = DEMUX_FINISHED;
376 return;
377 }
378 len -= buf->size;
379 if (len <= 0)
380 bufflags |= BUF_FLAG_FRAME_END;
381 buf->type = type;
382 buf->decoder_flags = bufflags;
383 buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
384 buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE;
385 buf->pts = pts;
386 buf->extra_info->input_normpos = normpos;
387 buf->extra_info->input_time = itime;
388 this->video_fifo->put (this->video_fifo, buf);
389 pts = 0;
390 }
391 }
392 return;
393 }
394
395 /* SVCD OGT subtitles are in stream 0x70 */
396 if (p[0] == 0x70) {
397
398 len -= 1;
399
400 if (!this->video_fifo) {
401 this->input->seek (this->input, len, SEEK_CUR);
402 } else {
403 /* FIXME: previous code did use p[1] for track number without reading it first.
404 * Assume that byte to be sent to decoder as well.
405 */
406 int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0;
407 int type = -1;
408 while (len > 0) {
409 buf_element_t *buf;
410 int part;
411 buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len);
412 part = buf->max_size < (int)len ? buf->max_size : (int)len;
413 buf->size = this->input->read (this->input, buf->content, part);
414 if (buf->size != part) {
415 buf->free_buffer (buf);
416 this->status = DEMUX_FINISHED;
417 return;
418 }
419 len -= buf->size;
420 if (len <= 0)
421 bufflags |= BUF_FLAG_FRAME_END;
422 if (type < 0) {
423 int track = buf->content[0] & 0x03;
424 /* register */
425 if (this->spu_svcd[track] == 255) {
426 this->spu_svcd[track] = this->num_spu++;
427 reset_track_map (this->video_fifo);
428 }
429 type = BUF_SPU_SVCD + this->spu_svcd[track];
430 }
431 buf->type = type;
432 buf->decoder_flags = bufflags;
433 buf->pts = pts;
434 buf->extra_info->input_normpos = normpos;
435 buf->extra_info->input_time = itime;
436 this->video_fifo->put (this->video_fifo, buf);
437 pts = 0;
438 }
439 lprintf ("SPU SVCD PACK (pts: %"PRId64", spu id: %d) put on FIFO\n", pts, type & 3);
440 }
441 /* There is a bug in WinSubMux doesn't redo PACK headers in
442 the private stream 1. This might cause the below to mess up.
443 if( !preview_mode )
444 check_newpts( this, this->pts, PTS_VIDEO );
445 */
446 return;
447 }
448
449 /* CVD subtitles are in stream 0x00-0x03 */
450 if ((p[0] & 0xfc) == 0x00) {
451
452 int track = p[0] & 0x03;
453 /* register */
454 if (this->spu_cvd[track] == 255) {
455 this->spu_cvd[track] = this->num_spu++;
456 reset_track_map (this->video_fifo);
457 }
458
459 len -= 1;
460
461 if (!this->video_fifo) {
462 this->input->seek (this->input, len, SEEK_CUR);
463 } else {
464 int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0;
465 while (len > 0) {
466 buf_element_t *buf;
467 int part;
468 buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len);
469 part = buf->max_size < (int)len ? buf->max_size : (int)len;
470 buf->size = this->input->read (this->input, buf->content, part);
471 if (buf->size != part) {
472 buf->free_buffer (buf);
473 this->status = DEMUX_FINISHED;
474 return;
475 }
476 len -= buf->size;
477 if (len <= 0)
478 bufflags |= BUF_FLAG_FRAME_END;
479 buf->type = BUF_SPU_CVD + this->spu_cvd[track];
480 buf->decoder_flags = bufflags;
481 buf->pts = pts;
482 buf->extra_info->input_normpos = normpos;
483 buf->extra_info->input_time = itime;
484 this->video_fifo->put (this->video_fifo, buf);
485 pts = 0;
486 }
487 }
488 return;
489 }
490
491 if ((p[0] & 0xf0) == 0x80) {
492
493 int track = p[0] & 0x0f;
494
495 /* read rest of header - AC3 */
496 if (this->input->read (this->input, p + 1, 3) != 3) {
497 this->status = DEMUX_FINISHED;
498 return;
499 }
500 len -= 4;
501
502 /* register */
503 if (this->audio_dvd[track] == 255) {
504 this->audio_dvd[track] = this->num_audio++;
505 reset_track_map (this->audio_fifo);
506 }
507
508 /* contents */
509 if (!this->audio_fifo) {
510 this->input->seek (this->input, len, SEEK_CUR);
511 } else {
512 int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0;
513 /* DVDs only have 8 tracks */
514 int type = ((track & 0x8) ? BUF_AUDIO_DTS : BUF_AUDIO_A52) + this->audio_dvd[track];
515 check_newpts (this, pts, PTS_AUDIO);
516 while (len > 0) {
517 buf_element_t *buf;
518 int part;
519 buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, len);
520 part = buf->max_size < (int)len ? buf->max_size : (int)len;
521 buf->size = this->input->read (this->input, buf->content, part);
522 if (buf->size != part) {
523 buf->free_buffer (buf);
524 this->status = DEMUX_FINISHED;
525 return;
526 }
527 len -= buf->size;
528 if (len <= 0)
529 bufflags |= BUF_FLAG_FRAME_END;
530 buf->type = type;
531 buf->decoder_flags = bufflags;
532 buf->pts = pts;
533 buf->extra_info->input_normpos = normpos;
534 buf->extra_info->input_time = itime;
535 this->audio_fifo->put (this->audio_fifo, buf);
536 pts = 0;
537 }
538 }
539 return;
540
541 } else if ((p[0] & 0xf0) == 0xa0) {
542
543 int track = p[0] & 0x0f;
544
545 if (this->input->read (this->input, p + 1, 6) != 6) {
546 this->status = DEMUX_FINISHED;
547 return;
548 }
549 len -= 7;
550
551 /* register */
552 if (this->audio_lpcm[track] == 255) {
553 this->audio_lpcm[track] = this->num_audio++;
554 reset_track_map (this->audio_fifo);
555 }
556
557 if (!this->audio_fifo) {
558 this->input->seek (this->input, len, SEEK_CUR);
559 } else {
560 int bufflags = BUF_FLAG_SPECIAL | (this->preview_mode ? BUF_FLAG_PREVIEW : 0);
561 check_newpts (this, pts, PTS_AUDIO);
562 while (len > 0) {
563 buf_element_t *buf;
564 int part;
565 buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, len);
566 part = buf->max_size < (int)len ? buf->max_size : (int)len;
567 buf->size = this->input->read (this->input, buf->content, part);
568 if (buf->size != part) {
569 buf->free_buffer (buf);
570 this->status = DEMUX_FINISHED;
571 return;
572 }
573 len -= buf->size;
574 if (len <= 0)
575 bufflags |= BUF_FLAG_FRAME_END;
576 buf->type = BUF_AUDIO_LPCM_BE + this->audio_lpcm[track];
577 buf->decoder_flags = bufflags;
578 buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG;
579 buf->decoder_info[2] = p[5];
580 buf->pts = pts;
581 buf->extra_info->input_normpos = normpos;
582 buf->extra_info->input_time = itime;
583 this->audio_fifo->put (this->audio_fifo, buf);
584 pts = 0;
585 }
586 }
587 return;
588
589 } else {
590 this->input->seek (this->input, len - 1, SEEK_CUR);
591 }
592
593 } else if ((stream_id & 0xe0) == 0xc0) {
594 int track = stream_id & 0x1f;
595
596 uint32_t len, flags, header_len;
597 uint8_t *p = this->tbuf;
598
599 if (this->input->read (this->input, p, 5) != 5) {
600 this->status = DEMUX_FINISHED;
601 return;
602 }
603 flags = p[3];
604 header_len = p[4];
605 len = (flags & 0x80) ? 5 : 0;
606 if (header_len < len)
607 header_len = len;
608 len = _X_BE_16 (p);
609 p += 5;
610
611 if (this->input->read (this->input, p, header_len) != (int)header_len) {
612 this->status = DEMUX_FINISHED;
613 return;
614 }
615 pts = 0;
616 if (flags & 0x80)
617 pts = mpeg_get_pts (p);
618
619 len -= header_len + 3;
620
621 /* register */
622 if (this->audio_mpeg[track] == 255) {
623 this->audio_mpeg[track] = this->num_audio++;
624 reset_track_map (this->audio_fifo);
625 }
626
627 if (!this->audio_fifo) {
628 this->input->seek (this->input, len, SEEK_CUR);
629 } else {
630 int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0;
631 check_newpts (this, pts, PTS_AUDIO);
632 while (len > 0) {
633 buf_element_t *buf;
634 int part;
635 buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, len);
636 part = buf->max_size < (int)len ? buf->max_size : (int)len;
637 buf->size = this->input->read (this->input, buf->content, part);
638 if (buf->size != part) {
639 buf->free_buffer (buf);
640 this->status = DEMUX_FINISHED;
641 return;
642 }
643 len -= buf->size;
644 if (len <= 0)
645 bufflags |= BUF_FLAG_FRAME_END;
646 buf->type = BUF_AUDIO_MPEG + this->audio_mpeg[track];
647 buf->decoder_flags = bufflags;
648 buf->pts = pts;
649 buf->extra_info->input_normpos = normpos;
650 buf->extra_info->input_time = itime;
651 this->audio_fifo->put (this->audio_fifo, buf);
652 pts = 0;
653 }
654 }
655
656 } else if ( ((stream_id >= 0xbc) && ((stream_id & 0xf0) == 0xe0)) || stream_id==0xfd ) {
657
658 uint32_t len, flags, header_len;
659 uint8_t *p = this->tbuf;
660
661 if (this->input->read (this->input, p, 5) != 5) {
662 this->status = DEMUX_FINISHED;
663 return;
664 }
665 flags = p[3];
666 header_len = p[4];
667 len = ((flags & 0x80) ? 5 : 0) + ((flags & 0x40) ? 5 : 0);
668 if (header_len < len)
669 header_len = len;
670 len = _X_BE_16 (p);
671 p += 5;
672
673 if (this->input->read (this->input, p, header_len) != (int)header_len) {
674 this->status = DEMUX_FINISHED;
675 return;
676 }
677 pts = 0;
678 if (flags & 0x80) {
679 pts = mpeg_get_pts (p);
680 p += 5;
681 }
682 dts = 0;
683 if (flags & 0x40) {
684 dts = mpeg_get_pts (p);
685 }
686
687 len -= header_len + 3;
688
689 /* contents */
690 if (!this->video_fifo) {
691 this->input->seek (this->input, len, SEEK_CUR);
692 } else {
693 int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0;
694 check_newpts (this, pts, PTS_VIDEO);
695 while (len > 0) {
696 buf_element_t *buf;
697 int part;
698 buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len);
699 part = buf->max_size < (int)len ? buf->max_size : (int)len;
700 buf->size = this->input->read (this->input, buf->content, part);
701 if (buf->size != part) {
702 buf->free_buffer (buf);
703 this->status = DEMUX_FINISHED;
704 return;
705 }
706 len -= buf->size;
707 if (len <= 0)
708 bufflags |= BUF_FLAG_FRAME_END;
709 buf->type = (stream_id == 0xfd) ? BUF_VIDEO_VC1 : BUF_VIDEO_MPEG;
710 buf->decoder_flags = bufflags;
711 buf->decoder_info[0] = pts - dts;
712 buf->pts = pts;
713 buf->extra_info->input_normpos = normpos;
714 buf->extra_info->input_time = itime;
715 this->video_fifo->put (this->video_fifo, buf);
716 pts = 0;
717 }
718 }
719
720 } else {
721
722 uint32_t len;
723 uint8_t *p = this->tbuf;
724
725 if (this->input->read (this->input, p, 2) != 2) {
726 this->status = DEMUX_FINISHED;
727 return;
728 }
729 len = _X_BE_16 (p);
730 this->input->seek (this->input, len, SEEK_CUR);
731
732 }
733
734 }
735
parse_mpeg1_packet(demux_mpeg_t * this,int stream_id,int64_t scr)736 static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr) {
737
738 int len;
739 uint32_t w;
740 int normpos, itime;
741 int64_t pts, dts;
742 {
743 off_t ilen = this->input->get_length (this->input);
744 off_t ipos = this->input->get_current_pos (this->input);
745 normpos = ilen > 0 ? (int64_t)ipos * 65535 / ilen : 0;
746 itime = this->rate ? (int64_t)ipos * 20 / this->rate : 0;
747 }
748
749 len = read_bytes(this, 2);
750
751 pts=0;
752 dts=0;
753
754 if (stream_id != 0xbf) {
755
756 w = read_bytes(this, 1); len--;
757
758 while ((w & 0x80) == 0x80) {
759
760 if (this->status != DEMUX_OK)
761 return;
762
763 /* stuffing bytes */
764 w = read_bytes(this, 1); len--;
765 }
766
767 if ((w & 0xC0) == 0x40) {
768
769 if (this->status != DEMUX_OK)
770 return;
771
772 /* buffer_scale, buffer size */
773 w = read_bytes(this, 1); len--;
774 w = read_bytes(this, 1); len--;
775 }
776
777 if ((w & 0xF0) == 0x20) {
778
779 if (this->status != DEMUX_OK)
780 return;
781
782 if (mpeg1_read_pts (this, &pts, w))
783 return;
784 len -= 4;
785 /* pts = 0; */
786
787 } else if ((w & 0xF0) == 0x30) {
788
789 if (this->status != DEMUX_OK)
790 return;
791
792 if (mpeg1_read_pts (this, &pts, w))
793 return;
794 len -= 4;
795
796 if (mpeg2_read_pts (this, &dts))
797 return;
798 len -= 5;
799
800 } else {
801
802 /*
803 if (w != 0x0f)
804 lprintf("ERROR w (%02x) != 0x0F ",w);
805 */
806 }
807
808 }
809
810 if (pts && !this->has_pts) {
811 lprintf("this stream has pts\n");
812 this->has_pts = 1;
813 } else if (scr && !this->has_pts) {
814 lprintf("use scr\n");
815 pts = scr;
816 }
817
818 if ((stream_id & 0xe0) == 0xc0) {
819 int track = stream_id & 0x1f;
820
821 /* register */
822 if (this->audio_mpeg[track] == 255) {
823 this->audio_mpeg[track] = this->num_audio++;
824 reset_track_map (this->audio_fifo);
825 }
826
827 if (!this->audio_fifo) {
828 this->input->seek (this->input, len, SEEK_CUR);
829 } else {
830 int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0;
831 check_newpts (this, pts, PTS_AUDIO);
832 while (len > 0) {
833 buf_element_t *buf;
834 int part;
835 buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, len);
836 part = buf->max_size < len ? buf->max_size : len;
837 buf->size = this->input->read (this->input, buf->content, part);
838 if (buf->size != part) {
839 buf->free_buffer (buf);
840 this->status = DEMUX_FINISHED;
841 return;
842 }
843 len -= buf->size;
844 if (len <= 0)
845 bufflags |= BUF_FLAG_FRAME_END;
846 buf->type = BUF_AUDIO_MPEG + this->audio_mpeg[track];
847 buf->decoder_flags = bufflags;
848 buf->pts = pts;
849 buf->extra_info->input_normpos = normpos;
850 buf->extra_info->input_time = itime;
851 this->audio_fifo->put (this->audio_fifo, buf);
852 pts = 0;
853 }
854 }
855
856 } else if ((stream_id & 0xf0) == 0xe0) {
857
858 if (!this->video_fifo) {
859 this->input->seek (this->input, len, SEEK_CUR);
860 } else {
861 int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0;
862 check_newpts (this, pts, PTS_VIDEO);
863 while (len > 0) {
864 buf_element_t *buf;
865 int part;
866 buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len);
867 part = buf->max_size < len ? buf->max_size : len;
868 buf->size = this->input->read (this->input, buf->content, part);
869 if (buf->size != part) {
870 buf->free_buffer (buf);
871 this->status = DEMUX_FINISHED;
872 return;
873 }
874 len -= buf->size;
875 if (len <= 0)
876 bufflags |= BUF_FLAG_FRAME_END;
877 buf->type = BUF_VIDEO_MPEG;
878 buf->decoder_flags = bufflags;
879 buf->decoder_info[0] = pts - dts;
880 buf->pts = pts;
881 buf->extra_info->input_normpos = normpos;
882 buf->extra_info->input_time = itime;
883 this->video_fifo->put (this->video_fifo, buf);
884 pts = 0;
885 }
886 }
887
888 } else if (stream_id == 0xbd) {
889
890 this->input->seek (this->input, len, SEEK_CUR);
891
892 } else {
893
894 this->input->seek (this->input, len, SEEK_CUR);
895 }
896 }
897
parse_pack(demux_mpeg_t * this)898 static uint32_t parse_pack(demux_mpeg_t *this) {
899
900 uint32_t buf ;
901 int mpeg_version;
902 int64_t scr;
903 uint8_t tbuf[20];
904
905 if (this->input->read (this->input, &tbuf[0], 12) != 12) {
906 this->status = DEMUX_FINISHED;
907 return 0;
908 }
909
910 if ((tbuf[0] >> 6) == 0x01) {
911
912 int stuffing;
913
914 mpeg_version = 2;
915
916 /* system_clock_reference */
917 scr = (uint64_t)(tbuf[0] & 0x38) << 27;
918 scr |= (uint32_t)(tbuf[0] & 0x03) << 28;
919 scr |= (uint32_t) tbuf[1] << 20;
920 scr |= (uint32_t)(tbuf[2] & 0xF8) << 12;
921 scr |= (uint32_t)(tbuf[2] & 0x03) << 13;
922 scr |= (uint32_t) tbuf[3] << 5;
923 scr |= (uint32_t)(tbuf[4] & 0xF8) >> 3;
924
925 /* tbuf[5] == extension */
926
927 /* mux_rate */
928 if (!this->rate) {
929 this->rate = (uint32_t)tbuf[6] << 14;
930 this->rate |= (uint32_t)tbuf[7] << 6;
931 this->rate |= (uint32_t)tbuf[8] >> 2;
932 }
933
934 /* stuffing bytes */
935 stuffing = tbuf[9] & 0x03;
936 if (this->input->read (this->input, &tbuf[12], 2 + stuffing) != 2 + stuffing) {
937 this->status = DEMUX_FINISHED;
938 return 0;
939 }
940
941 /* system header */
942 buf = _X_BE_32 (tbuf + 10 + stuffing);
943
944 } else {
945
946 mpeg_version = 1;
947
948 /* system_clock_reference */
949 scr = (uint32_t)(tbuf[0] & 0x2) << 29;
950 scr |= (uint32_t) tbuf[1] << 22;
951 scr |= (uint32_t)(tbuf[2] & 0xfe) << 14;
952 scr |= (uint32_t) tbuf[3] << 7;
953 scr |= (uint32_t) tbuf[4] >> 1;
954
955 /* mux_rate */
956 if (!this->rate) {
957 this->rate = (uint32_t)(tbuf[5] & 0x7f) << 15;
958 this->rate |= (uint32_t) tbuf[6] << 7;
959 this->rate |= (uint32_t) tbuf[7] >> 1;
960 lprintf ("mux_rate = %d\n",this->rate);
961 }
962
963 /* system header */
964 buf = _X_BE_32 (tbuf + 8);
965 }
966
967 /* lprintf("code = %08x\n",buf);*/
968
969 if (buf == 0x000001bb) {
970 buf = read_bytes (this, 2);
971
972 this->input->seek (this->input, buf, SEEK_CUR);
973
974 buf = read_bytes (this, 4) ;
975 }
976
977 /* lprintf("code = %08x\n",buf); */
978
979 while ( ((buf & 0xFFFFFF00) == 0x00000100)
980 && ((buf & 0xff) != 0xba) ) {
981
982 if (this->status != DEMUX_OK)
983 return buf;
984
985 if (mpeg_version == 1)
986 parse_mpeg1_packet (this, buf & 0xFF, scr);
987 else
988 parse_mpeg2_packet (this, buf & 0xFF, scr);
989
990 buf = read_bytes (this, 4);
991
992 }
993
994 return buf;
995
996 }
997
parse_pack_preview(demux_mpeg_t * this,int * num_buffers)998 static uint32_t parse_pack_preview (demux_mpeg_t *this, int *num_buffers) {
999 uint32_t buf ;
1000 int mpeg_version;
1001 uint8_t tbuf[20];
1002
1003 if (this->input->read (this->input, &tbuf[0], 12) != 12) {
1004 this->status = DEMUX_FINISHED;
1005 return 0;
1006 }
1007
1008 if ((tbuf[0] >> 6) == 0x01) {
1009
1010 int stuffing;
1011
1012 mpeg_version = 2;
1013
1014 /* mux_rate */
1015 if (!this->rate) {
1016 this->rate = (uint32_t)tbuf[6] << 14;
1017 this->rate |= (uint32_t)tbuf[7] << 6;
1018 this->rate |= (uint32_t)tbuf[8] >> 2;
1019 }
1020
1021 /* stuffing bytes */
1022 stuffing = tbuf[9] & 0x03;
1023 if (this->input->read (this->input, &tbuf[12], 2 + stuffing) != 2 + stuffing) {
1024 this->status = DEMUX_FINISHED;
1025 return 0;
1026 }
1027
1028 /* system header */
1029 buf = _X_BE_32 (tbuf + 10 + stuffing);
1030
1031 } else {
1032
1033 mpeg_version = 1;
1034
1035 /* mux_rate */
1036 if (!this->rate) {
1037 this->rate = (uint32_t)(tbuf[5] & 0x7f) << 15;
1038 this->rate |= (uint32_t) tbuf[6] << 7;
1039 this->rate |= (uint32_t) tbuf[7] >> 1;
1040 lprintf ("mux_rate = %d\n",this->rate);
1041 }
1042
1043 /* system header */
1044 buf = _X_BE_32 (tbuf + 8);
1045 }
1046
1047 if (buf == 0x000001bb) {
1048 buf = read_bytes (this, 2);
1049 this->input->seek (this->input, buf, SEEK_CUR);
1050 buf = read_bytes (this, 4) ;
1051 }
1052
1053 while ( ((buf & 0xFFFFFF00) == 0x00000100)
1054 && ((buf & 0xff) != 0xba)
1055 && (*num_buffers > 0)) {
1056
1057 if (this->status != DEMUX_OK)
1058 return buf;
1059
1060 if (mpeg_version == 1)
1061 parse_mpeg1_packet (this, buf & 0xFF, 0);
1062 else
1063 parse_mpeg2_packet (this, buf & 0xFF, 0);
1064
1065 buf = read_bytes (this, 4);
1066 *num_buffers = *num_buffers - 1;
1067 }
1068
1069 return buf;
1070
1071 }
1072
demux_mpeg_resync(demux_mpeg_t * this,uint32_t buf)1073 static void demux_mpeg_resync (demux_mpeg_t *this, uint32_t buf) {
1074
1075 if (INPUT_IS_SEEKABLE(this->input)) {
1076 off_t len, pos;
1077
1078 /* fast resync, read 4K block at once */
1079 pos = 0;
1080 len = 0;
1081 while ((buf != 0x000001ba) && (this->status == DEMUX_OK)) {
1082 if (pos == len) {
1083 len = this->input->read (this->input, this->tbuf, 4096);
1084 pos = 0;
1085 if (len <= 0) {
1086 this->status = DEMUX_FINISHED;
1087 break;
1088 }
1089 }
1090 buf = (buf << 8) | this->tbuf[pos];
1091 pos++;
1092 }
1093 /* seek back to the pos of the 0x00001ba tag */
1094 this->input->seek(this->input, pos-len, SEEK_CUR);
1095
1096 } else {
1097 /* slow resync */
1098 while ((buf !=0x000001ba) && (this->status == DEMUX_OK)) {
1099 buf = (buf << 8) | read_bytes (this, 1);
1100 }
1101 }
1102 }
1103
demux_mpeg_send_chunk(demux_plugin_t * this_gen)1104 static int demux_mpeg_send_chunk (demux_plugin_t *this_gen) {
1105 demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
1106
1107 uint32_t w=0;
1108
1109 w = parse_pack (this);
1110 if (w != 0x000001ba)
1111 demux_mpeg_resync (this, w);
1112
1113 return this->status;
1114 }
1115
demux_mpeg_get_status(demux_plugin_t * this_gen)1116 static int demux_mpeg_get_status (demux_plugin_t *this_gen) {
1117 demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
1118
1119 return this->status;
1120 }
1121
demux_mpeg_send_headers(demux_plugin_t * this_gen)1122 static void demux_mpeg_send_headers (demux_plugin_t *this_gen) {
1123
1124 demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
1125 uint32_t w;
1126 int num_buffers = NUM_PREVIEW_BUFFERS;
1127
1128 this->video_fifo = this->stream->video_fifo;
1129 this->audio_fifo = this->stream->audio_fifo;
1130
1131 this->rate = 0; /* fixme */
1132 this->last_pts[0] = 0;
1133 this->last_pts[1] = 0;
1134
1135 _x_demux_control_start(this->stream);
1136
1137 /*
1138 * send preview buffers for stream/meta_info
1139 */
1140
1141 _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
1142 _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
1143
1144 this->preview_mode = 1;
1145
1146 this->input->seek (this->input, 4, SEEK_SET);
1147
1148 this->status = DEMUX_OK ;
1149
1150 do {
1151
1152 w = parse_pack_preview (this, &num_buffers);
1153
1154 if (w != 0x000001ba)
1155 demux_mpeg_resync (this, w);
1156
1157 num_buffers --;
1158
1159 } while ( (this->status == DEMUX_OK) && (num_buffers > 0));
1160
1161 this->status = DEMUX_OK ;
1162
1163 _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->rate * 50 * 8);
1164 }
1165
demux_mpeg_seek(demux_plugin_t * this_gen,off_t start_pos,int start_time,int playing)1166 static int demux_mpeg_seek (demux_plugin_t *this_gen,
1167 off_t start_pos, int start_time, int playing) {
1168
1169 demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
1170 start_time /= 1000;
1171 start_pos = (off_t) ( ((int64_t)start_pos * this->input->get_length (this->input)) / 65535);
1172
1173 if (INPUT_IS_SEEKABLE(this->input)) {
1174
1175 if ( (!start_pos) && (start_time)) {
1176 start_pos = start_time;
1177 start_pos *= this->rate;
1178 start_pos *= 50;
1179 }
1180
1181 this->input->seek (this->input, start_pos+4, SEEK_SET);
1182
1183 if( start_pos )
1184 demux_mpeg_resync (this, read_bytes(this, 4) );
1185
1186 } else
1187 read_bytes(this, 4);
1188
1189 this->send_newpts = 1;
1190 this->status = DEMUX_OK ;
1191
1192 if( !playing ) {
1193 this->preview_mode = 0;
1194 this->buf_flag_seek = 0;
1195 } else {
1196 this->buf_flag_seek = 1;
1197 _x_demux_flush_engine(this->stream);
1198 }
1199
1200 return this->status;
1201 }
1202
demux_mpeg_get_stream_length(demux_plugin_t * this_gen)1203 static int demux_mpeg_get_stream_length (demux_plugin_t *this_gen) {
1204 demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
1205
1206 if (this->rate)
1207 return (int)((int64_t) 1000 * this->input->get_length (this->input) /
1208 (this->rate * 50));
1209 else
1210 return 0;
1211
1212 }
1213
demux_mpeg_get_capabilities(demux_plugin_t * this_gen)1214 static uint32_t demux_mpeg_get_capabilities(demux_plugin_t *this_gen) {
1215 (void)this_gen;
1216 return DEMUX_CAP_AUDIOLANG | DEMUX_CAP_SPULANG;
1217 }
1218
demux_mpeg_get_optional_data(demux_plugin_t * this_gen,void * data,int data_type)1219 static int demux_mpeg_get_optional_data(demux_plugin_t *this_gen,
1220 void *data, int data_type) {
1221 demux_mpeg_t *this = (demux_mpeg_t *)this_gen;
1222
1223 /* be a bit paranoid */
1224 if (this == NULL || this->stream == NULL)
1225 return DEMUX_OPTIONAL_UNSUPPORTED;
1226
1227 switch (data_type) {
1228 case DEMUX_OPTIONAL_DATA_AUDIOLANG: {
1229 char *str = data;
1230 int channel = *((int *)data);
1231 if ((channel < 0) || (channel >= this->num_audio)) {
1232 strcpy (str, "none");
1233 } else {
1234 strcpy (str, "und");
1235 return DEMUX_OPTIONAL_SUCCESS;
1236 }
1237 }
1238 break;
1239 case DEMUX_OPTIONAL_DATA_SPULANG: {
1240 char *str = data;
1241 int channel = *((int *)data);
1242 if ((channel < 0) || (channel >= this->num_spu)) {
1243 strcpy (str, "none");
1244 } else {
1245 strcpy (str, "und");
1246 return DEMUX_OPTIONAL_SUCCESS;
1247 }
1248 }
1249 break;
1250 default: ;
1251 }
1252 return DEMUX_OPTIONAL_UNSUPPORTED;
1253 }
1254
open_plugin(demux_class_t * class_gen,xine_stream_t * stream,input_plugin_t * input)1255 static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
1256 input_plugin_t *input) {
1257 /* Test our support first. */
1258
1259 switch (stream->content_detection_method) {
1260
1261 case METHOD_BY_CONTENT: {
1262 off_t mdat_atom_offset = -1;
1263 int64_t mdat_atom_size = -1;
1264 unsigned int fourcc_tag;
1265 int i, j, read;
1266 int ok = 0;
1267 uint8_t buf[SCRATCH_SIZE];
1268
1269 /* use demux_mpeg_block for block devices */
1270 if (input->get_capabilities(input) & INPUT_CAP_BLOCK)
1271 return NULL;
1272
1273 /* look for mpeg header */
1274 read = _x_demux_read_header(input, buf, SCRATCH_SIZE);
1275 if (!read)
1276 return NULL;
1277
1278 for (i = 0; i < read - 4; i++) {
1279 lprintf ("%02x %02x %02x %02x\n", buf[i], buf[i+1], buf[i+2], buf[i+3]);
1280 if (!buf[i] && !buf[i+1] && (buf[i+2] == 0x01)
1281 && (buf[i+3] == 0xba)) /* if so, take it */ {
1282 ok = 1;
1283 break;
1284 }
1285 }
1286
1287 if (ok == 1)
1288 break;
1289
1290 /* the special cases need seeking */
1291 if (!INPUT_IS_SEEKABLE (input))
1292 return NULL;
1293
1294 /* special case for MPEG streams hidden inside QT files; check
1295 * is there is an mdat atom */
1296 find_mdat_atom(input, &mdat_atom_offset, &mdat_atom_size);
1297 if (mdat_atom_offset != -1) {
1298 /* seek to the start of the mdat data, which might be in different
1299 * depending on the size type of the atom */
1300 if (mdat_atom_size == 1)
1301 input->seek(input, mdat_atom_offset + 16, SEEK_SET);
1302 else
1303 input->seek(input, mdat_atom_offset + 8, SEEK_SET);
1304
1305 /* go through the same MPEG detection song and dance */
1306 if (input->read(input, buf, 4) == 4) {
1307
1308 if (!buf[0] && !buf[1] && (buf[2] == 0x01)
1309 && (buf[3] == 0xba)) /* if so, take it */
1310 break;
1311 }
1312
1313 return NULL;
1314 }
1315
1316 /* reset position for next check */
1317 if (input->seek (input, 0, SEEK_SET) != 0)
1318 return NULL;
1319
1320 /* special case for MPEG streams with a RIFF header */
1321 fourcc_tag = _X_BE_32(&buf[0]);
1322 if (fourcc_tag == RIFF_TAG) {
1323 uint8_t large_buf[1024];
1324
1325 if (input->read (input, large_buf, 12) != 12)
1326 return NULL;
1327 fourcc_tag = _X_BE_32(&large_buf[8]);
1328 /* disregard the RIFF file if it is certainly a better known
1329 * format like AVI or WAVE */
1330 if ((fourcc_tag == WAVE_TAG) ||
1331 (fourcc_tag == AVI_TAG) ||
1332 (fourcc_tag == FOURXM_TAG))
1333 return NULL;
1334
1335 /* Iterate through first n kilobytes of RIFF file searching for
1336 * MPEG video marker. No, it's not a very efficient approach, but
1337 * if execution has reached this special case, this is currently
1338 * the best chance for detecting the file automatically. Also,
1339 * be extra lazy and do not bother skipping over the data
1340 * header. */
1341 for (i = 0; i < RIFF_CHECK_KILOBYTES && !ok; i++) {
1342 if (input->read(input, large_buf, 1024) != 1024)
1343 break;
1344 for (j = 0; j < 1024 - 4; j++) {
1345 if (_X_BE_32(&large_buf[j]) == MPEG_MARKER) {
1346 ok = 1;
1347 break;
1348 }
1349 }
1350 }
1351 if (ok)
1352 break;
1353 }
1354 return NULL;
1355 }
1356
1357 case METHOD_BY_MRL:
1358 case METHOD_EXPLICIT:
1359 break;
1360
1361 default:
1362 return NULL;
1363 }
1364
1365 /* OK now set up instance. */
1366 {
1367 demux_mpeg_t *this = calloc (1, sizeof (demux_mpeg_t));
1368 if (!this)
1369 return NULL;
1370
1371 this->has_pts = 0;
1372 this->num_audio = 0;
1373 this->num_spu = 0;
1374
1375 this->stream = stream;
1376 this->input = input;
1377
1378 this->demux_plugin.send_headers = demux_mpeg_send_headers;
1379 this->demux_plugin.send_chunk = demux_mpeg_send_chunk;
1380 this->demux_plugin.seek = demux_mpeg_seek;
1381 this->demux_plugin.dispose = default_demux_plugin_dispose;
1382 this->demux_plugin.get_status = demux_mpeg_get_status;
1383 this->demux_plugin.get_stream_length = demux_mpeg_get_stream_length;
1384 this->demux_plugin.get_capabilities = demux_mpeg_get_capabilities;
1385 this->demux_plugin.get_optional_data = demux_mpeg_get_optional_data;
1386 this->demux_plugin.demux_class = class_gen;
1387
1388 this->status = DEMUX_FINISHED;
1389
1390 memset (this->audio_dvd, 255, sizeof (this->audio_dvd));
1391 memset (this->audio_lpcm, 255, sizeof (this->audio_lpcm));
1392 memset (this->audio_mpeg, 255, sizeof (this->audio_mpeg));
1393
1394 memset (this->spu_dvd, 255, sizeof (this->spu_dvd));
1395 memset (this->spu_svcd, 255, sizeof (this->spu_svcd));
1396 memset (this->spu_cvd, 255, sizeof (this->spu_cvd));
1397
1398 return &this->demux_plugin;
1399 }
1400 }
1401
demux_mpeg_init_class(xine_t * xine,const void * data)1402 void *demux_mpeg_init_class (xine_t *xine, const void *data) {
1403
1404 (void)xine;
1405 (void)data;
1406
1407 static const demux_class_t demux_mpeg_class = {
1408 .open_plugin = open_plugin,
1409 .description = N_("MPEG program stream demux plugin"),
1410 .identifier = "MPEG",
1411 .mimetypes =
1412 "video/mpeg: mpeg, mpg, mpe: MPEG animation;"
1413 "video/x-mpeg: mpeg, mpg, mpe: MPEG animation;",
1414 .extensions = "mpg mpeg",
1415 .dispose = NULL,
1416 };
1417
1418 return (void *)&demux_mpeg_class;
1419 }
1420