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 * Real Media File Demuxer by Mike Melanson (melanson@pcisys.net)
23 * improved by James Stembridge (jstembridge@users.sourceforge.net)
24 * For more information regarding the Real file format, visit:
25 * http://www.pcisys.net/~melanson/codecs/
26 *
27 * video packet sub-demuxer ported from mplayer code (www.mplayerhq.hu):
28 * Real parser & demuxer
29 *
30 * (C) Alex Beregszaszi <alex@naxine.org>
31 *
32 * Based on FFmpeg's libav/rm.c.
33 *
34 * Reworked by Torsten Jager <t.jager@gmx.de>
35 */
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #include <stdio.h>
42 #include <fcntl.h>
43 #include <unistd.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <ctype.h>
47 #ifdef HAVE_MALLOC_H
48 #include <malloc.h>
49 #endif
50
51 #define LOG_MODULE "demux_real"
52 #define LOG_VERBOSE
53 /*
54 #define LOG
55 */
56
57 #include "group_video.h"
58
59 #include <xine/xine_internal.h>
60 #include <xine/xineutils.h>
61 #include <xine/compat.h>
62 #include <xine/demux.h>
63 #include "bswap.h"
64
65 #include "demux_real_common.h"
66
67 #define FOURCC_TAG BE_FOURCC
68 #define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P')
69 #define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R')
70 #define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T')
71 #define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A')
72 #define RA_TAG FOURCC_TAG('.', 'r', 'a', 0xfd)
73 #define VIDO_TAG FOURCC_TAG('V', 'I', 'D', 'O')
74
75 #define PREAMBLE_SIZE 8
76 #define REAL_SIGNATURE_SIZE 8
77 #define DATA_CHUNK_HEADER_SIZE 10
78 #define DATA_PACKET_HEADER_SIZE 12
79 #define INDEX_CHUNK_HEADER_SIZE 20
80 #define INDEX_RECORD_SIZE 14
81
82 #define PN_KEYFRAME_FLAG 0x0002
83
84 #define MAX_VIDEO_STREAMS 10
85 #define MAX_AUDIO_STREAMS 8
86
87 #define FRAGMENT_TAB_SIZE 256
88
89 typedef struct {
90 uint16_t object_version;
91
92 uint16_t stream_number;
93 uint32_t max_bit_rate;
94 uint32_t avg_bit_rate;
95 uint32_t max_packet_size;
96 uint32_t avg_packet_size;
97 uint32_t start_time;
98 uint32_t preroll;
99 uint32_t duration;
100 size_t stream_name_size;
101 char *stream_name;
102 size_t mime_type_size;
103 char *mime_type;
104 size_t type_specific_len;
105 uint8_t *type_specific_data;
106 } mdpr_t;
107
108 typedef struct {
109 uint32_t timestamp;
110 uint32_t offset;
111 uint32_t packetno;
112 } real_index_entry_t;
113
114 typedef struct {
115 uint32_t fourcc;
116 uint32_t buf_type;
117 uint32_t format;
118 /* seek index */
119 int index_entries;
120 real_index_entry_t *index;
121 /* stream info */
122 mdpr_t *mdpr;
123 /* interleaver type and settings */
124 uint32_t intl;
125 int sps, cfs, w, h;
126 int block_align;
127 size_t frame_size;
128 uint8_t *frame_buffer;
129 uint32_t frame_num_bytes;
130 uint32_t sub_packet_cnt;
131
132 uint32_t audio_time;
133 } real_stream_t;
134
135 typedef struct {
136 demux_plugin_t demux_plugin;
137 /* xine engine */
138 xine_stream_t *stream;
139 fifo_buffer_t *video_fifo;
140 fifo_buffer_t *audio_fifo;
141 /* an input or 2 ;-) */
142 input_plugin_t *input, *in1, *in2;
143 off_t startpos1;
144 off_t startpos2;
145 uint32_t pos1, endpos1, pos2, endpos2;
146 uint32_t lasttime1, lasttime2;
147 /* seek */
148 off_t index_start;
149 off_t data_start;
150 off_t data_size;
151 unsigned int duration;
152 /* top level chunk parser */
153 unsigned int current_data_chunk_packet_count;
154 unsigned int next_data_chunk_offset;
155 unsigned int data_chunk_size;
156 /* multirate database */
157 int num_audio_streams;
158 int num_video_streams;
159 real_stream_t audio_streams[MAX_AUDIO_STREAMS];
160 real_stream_t video_streams[MAX_VIDEO_STREAMS];
161 /* and what we use of it */
162 real_stream_t *audio_stream;
163 real_stream_t *video_stream;
164 int audio_id;
165 int video_id;
166 /* audio deobfuscation */
167 int audio_need_keyframe;
168 /* video deobfuscation */
169 uint32_t *fragment_tab;
170 int fragment_tab_max;
171 int fragment_size;
172 int fragment_count;
173 int old_seqnum;
174 /* mp4 video depacketizer */
175 buf_element_t *vbuf;
176 uint32_t vtime;
177 uint32_t vkeyframe;
178 /* timeline */
179 off_t avg_bitrate;
180 int64_t last_pts[2];
181 int send_newpts;
182 /* redirection */
183 int reference_mode;
184 /* our status */
185 int status;
186 } demux_real_t ;
187
188
real_parse_index(demux_real_t * this)189 static void real_parse_index(demux_real_t *this) {
190
191 off_t next_index_chunk = this->index_start;
192 off_t original_pos = this->input->get_current_pos(this->input);
193 uint8_t index_chunk_header[INDEX_CHUNK_HEADER_SIZE];
194 int i;
195
196 while(next_index_chunk) {
197 uint16_t version;
198 uint32_t entries;
199 uint16_t stream_num;
200 uint8_t *q;
201 real_index_entry_t **index = NULL;
202 lprintf("reading index chunk at %"PRIX64"\n", next_index_chunk);
203
204 /* Seek to index chunk */
205 this->input->seek(this->input, next_index_chunk, SEEK_SET);
206
207 /* Read index chunk header */
208 if(this->input->read(this->input, index_chunk_header, INDEX_CHUNK_HEADER_SIZE)
209 != INDEX_CHUNK_HEADER_SIZE) {
210 lprintf("index chunk header not read\n");
211 break;
212 }
213
214 /* Check chunk is actually an index chunk */
215 if(!_x_is_fourcc(&index_chunk_header[0], "INDX")) {
216 lprintf("expected index chunk found chunk type: %.4s\n", &index_chunk_header[0]);
217 break;
218 }
219
220 /* Check version */
221 version = _X_BE_16(&index_chunk_header[8]);
222 if(version != 0) {
223 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
224 "demux_real: unknown object version in INDX: 0x%04x\n", version);
225 break;
226 }
227
228 /* Read data from header */
229 entries = _X_BE_32(&index_chunk_header[10]);
230 stream_num = _X_BE_16(&index_chunk_header[14]);
231 next_index_chunk = _X_BE_32(&index_chunk_header[16]);
232
233 /* Find which stream this index is for */
234 for(i = 0; i < this->num_video_streams; i++) {
235 if(stream_num == this->video_streams[i].mdpr->stream_number) {
236 index = &this->video_streams[i].index;
237 this->video_streams[i].index_entries = entries;
238 lprintf("found index chunk for video stream with num %d\n", stream_num);
239 break;
240 }
241 }
242
243 if(!index) {
244 for(i = 0; i < this->num_audio_streams; i++) {
245 if(stream_num == this->audio_streams[i].mdpr->stream_number) {
246 index = &this->audio_streams[i].index;
247 this->audio_streams[i].index_entries = entries;
248 lprintf("found index chunk for audio stream with num %d\n", stream_num);
249 break;
250 }
251 }
252 }
253
254 q = NULL;
255 if (index && entries && (entries < (1 << 18))) {
256 free (*index);
257 *index = NULL;
258 /* Allocate memory for index */
259 if (sizeof (real_index_entry_t) > INDEX_RECORD_SIZE)
260 q = malloc (entries * sizeof (real_index_entry_t));
261 else
262 q = malloc (entries * INDEX_RECORD_SIZE);
263 }
264 if (index && entries && q) {
265 real_index_entry_t *e = (real_index_entry_t *)q;
266 if (sizeof (real_index_entry_t) > INDEX_RECORD_SIZE)
267 q += entries * (sizeof (real_index_entry_t) - INDEX_RECORD_SIZE);
268 /* Read index */
269 if (this->input->read (this->input, q, entries * INDEX_RECORD_SIZE) != entries * INDEX_RECORD_SIZE) {
270 lprintf ("index record not read\n");
271 free (e);
272 *index = NULL;
273 } else {
274 *index = e;
275 while (entries--) {
276 e->timestamp = _X_BE_32 (q + 2);
277 e->offset = _X_BE_32 (q + 6);
278 e->packetno = _X_BE_32 (q + 10);
279 e++;
280 q += INDEX_RECORD_SIZE;
281 }
282 }
283 } else {
284 lprintf("unused index chunk with %d entries for stream num %d\n",
285 entries, stream_num);
286 }
287 }
288
289 /* Seek back to position before index reading */
290 this->input->seek(this->input, original_pos, SEEK_SET);
291 }
292
real_parse_mdpr(const char * data,uint32_t size)293 static mdpr_t *real_parse_mdpr (const char *data, uint32_t size) {
294 const uint8_t *p, *p1, *p2, *p3;
295 uint8_t *q;
296 mdpr_t *mdpr;
297 uint32_t sall, s1, s2, s3;
298 /* get size needed */
299 if (size < 38)
300 return NULL;
301 p = (const uint8_t *)data + 32;
302 sall = size - 38;
303 s1 = *p++;
304 if (sall < s1)
305 return NULL;
306 p1 = p;
307 p += s1;
308 sall -= s1;
309 s2 = *p++;
310 if (sall < s2)
311 return NULL;
312 p2 = p;
313 p += s2;
314 sall -= s2;
315 s3 = _X_BE_32 (p); p += 4;
316 if (sall < s3)
317 return NULL;
318 p3 = p;
319 /* now build */
320 q = malloc (sizeof (mdpr_t) + s1 + s2 + s3 + 8);
321 if (!q)
322 return NULL;
323 mdpr = (mdpr_t *)q;
324 p = (const uint8_t *)data;
325 mdpr->object_version = _X_BE_16 (p);
326 mdpr->stream_number = _X_BE_16 (p + 2);
327 mdpr->max_bit_rate = _X_BE_32 (p + 4);
328 mdpr->avg_bit_rate = _X_BE_32 (p + 8);
329 mdpr->max_packet_size = _X_BE_32 (p + 12);
330 mdpr->avg_packet_size = _X_BE_32 (p + 16);
331 mdpr->start_time = _X_BE_32 (p + 20);
332 mdpr->preroll = _X_BE_32 (p + 24);
333 mdpr->duration = _X_BE_32 (p + 28);
334 q += sizeof (mdpr_t);
335 #define ALIGN4(q) q = (uint8_t *)(((uintptr_t)q + 3) & ~(uintptr_t)3)
336 memcpy (q, p1, s1);
337 mdpr->stream_name = (char *)q;
338 mdpr->stream_name_size = s1;
339 q += s1;
340 *q++ = 0;
341 ALIGN4 (q);
342 memcpy (q, p2, s2);
343 mdpr->mime_type = (char *)q;
344 mdpr->mime_type_size = s2;
345 q += s2;
346 *q++ = 0;
347 ALIGN4 (q);
348 memcpy (q, p3, s3);
349 mdpr->type_specific_data = q;
350 mdpr->type_specific_len = s3;
351 #undef ALIGN4
352
353 lprintf("MDPR: stream number: %i\n", mdpr->stream_number);
354 lprintf("MDPR: maximal bit rate: %i\n", mdpr->max_bit_rate);
355 lprintf("MDPR: average bit rate: %i\n", mdpr->avg_bit_rate);
356 lprintf("MDPR: largest packet size: %i bytes\n", mdpr->max_packet_size);
357 lprintf("MDPR: average packet size: %i bytes\n", mdpr->avg_packet_size);
358 lprintf("MDPR: start time: %i\n", mdpr->start_time);
359 lprintf("MDPR: pre-buffer: %i ms\n", mdpr->preroll);
360 lprintf("MDPR: duration of stream: %i ms\n", mdpr->duration);
361 lprintf("MDPR: stream name: %s\n", mdpr->stream_name);
362 lprintf("MDPR: mime type: %s\n", mdpr->mime_type);
363 lprintf("MDPR: type specific data:\n");
364 #ifdef LOG
365 xine_hexdump(mdpr->type_specific_data, mdpr->type_specific_len);
366 #endif
367 return mdpr;
368 }
369
real_free_mdpr(mdpr_t * mdpr)370 static void real_free_mdpr (mdpr_t *mdpr) {
371 free (mdpr);
372 }
373
real_parse_audio_specific_data(demux_real_t * this,real_stream_t * stream)374 static int real_parse_audio_specific_data (demux_real_t *this, real_stream_t *stream) {
375 uint8_t *p, *e;
376 uint32_t version;
377 uint32_t head_size, flavor, coded_frame_size, h, frame_size, subpacket_size;
378 uint32_t samplerate, samplesize, channels, intl, fourcc;
379 uint32_t codecdata_length;
380
381 p = stream->mdpr->type_specific_data;
382 e = p + stream->mdpr->type_specific_len;
383 if (p + 6 > e) goto truncated;
384 version = p[5];
385
386 if (version == 3) {
387 frame_size = 240;
388 samplerate = 8000;
389 samplesize = 16;
390 channels = 1;
391 intl = 0;
392 coded_frame_size = 0;
393 h = 0;
394 subpacket_size = 0;
395 if (p + 11 > e) goto truncated;
396 p = e - 5;
397 fourcc = _X_ME_32 (p);
398 } else {
399 if (p + 48 > e) goto truncated;
400 p += 20;
401 head_size = _X_BE_16 (p); p += 2;
402 flavor = _X_BE_16 (p); p += 2;
403 coded_frame_size = _X_BE_32 (p); p += 4;
404 p += 12;
405 h = _X_BE_16 (p); p += 2;
406 frame_size = _X_BE_16 (p); p += 2;
407 subpacket_size = _X_BE_16 (p); p += 2;
408 p += 2;
409 if (version == 5) p += 6;
410 if (p + 8 > e) goto truncated;
411 samplerate = _X_BE_16 (p); p += 2;
412 p += 2;
413 samplesize = _X_BE_16 (p); p += 2;
414 channels = _X_BE_16 (p); p += 2;
415 if (version == 5) {
416 if (p + 8 > e) goto truncated;
417 intl = _X_ME_32 (p); p += 4; /* integer ID's */
418 fourcc = _X_ME_32 (p); p += 4;
419 } else {
420 if (p + 10 > e) goto truncated;
421 intl = _X_ME_32 (p + 1); p += p[0] + 1; /* string ID's */
422 fourcc = _X_ME_32 (p + 1); p += p[0] + 1;
423 }
424 stream->block_align = frame_size;
425 switch (fourcc) {
426 case ME_FOURCC('d','n','e','t'):
427 /* AC3 with swapped byte order */
428 break;
429 case ME_FOURCC('1','4','_','4'):
430 stream->block_align = 20;
431 break;
432 case ME_FOURCC('2','8','_','8'):
433 stream->block_align = coded_frame_size;
434 break;
435 case ME_FOURCC('s','i','p','r'):
436 case ME_FOURCC('a','t','r','c'):
437 case ME_FOURCC('c','o','o','k'):
438 p += 3;
439 if (version == 5) p += 1;
440 if (p + 4 > e) goto truncated;
441 codecdata_length = _X_BE_32 (p); p += 4;
442 stream->block_align = intl == ME_FOURCC('g','e','n','r') ? subpacket_size : coded_frame_size;
443 break;
444 case ME_FOURCC('r','a','a','c'):
445 case ME_FOURCC('r','a','c','p'):
446 /* AAC */
447 p += 3;
448 if (version == 5) p += 1;
449 if (p + 4 > e) goto truncated;
450 codecdata_length = _X_BE_32 (p); p += 4;
451 fourcc = ME_FOURCC('m','p','4','a');
452 break;
453 }
454 }
455 if (0) {
456 truncated:
457 xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_real: truncated MDPR chunk\n");
458 return 0;
459 }
460 /* return 4CC */
461 stream->fourcc = fourcc;
462 /* return interleaver type and settings */
463 if (!((intl == ME_FOURCC('g','e','n','r')) || (intl == ME_FOURCC('I','n','t','4'))
464 || (intl == ME_FOURCC('s','i','p','r')))) intl = 0;
465 stream->intl = intl;
466
467 stream->sps = subpacket_size;
468 stream->w = frame_size;
469 stream->h = h;
470 stream->cfs = coded_frame_size;
471
472 {
473 char b[20];
474 _x_tag32_me2str (b, fourcc);
475 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
476 "demux_real: stream #%d: audio v%d, [%s] %ubps, %dch, %dHz, %dbit, start %d\n",
477 (int)stream->mdpr->stream_number, version, b, (unsigned int)stream->mdpr->avg_bit_rate,
478 channels, samplerate, samplesize, (int)stream->mdpr->start_time);
479 if (intl) {
480 _x_tag32_me2str (b, intl);
481 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
482 " interleaved [%s] %dx%d, align %d, sps %d, cfs %d\n",
483 b, stream->w, stream->h, stream->block_align, stream->sps, stream->cfs);
484 }
485 }
486 /*
487 * when stream->sps is set it used to do this:
488 * stream->frame_size = stream->w / stream->sps * stream->h * stream->sps;
489 * but it looks pointless? the compiler will probably optimise it away, I suppose?
490 */
491 free (stream->frame_buffer);
492 if (stream->w < 32768 && stream->h < 32768) {
493 stream->frame_size = stream->w * stream->h;
494 stream->frame_buffer = calloc (stream->frame_size, 1);
495 } else {
496 stream->frame_size = 0;
497 stream->frame_buffer = NULL;
498 }
499
500 stream->frame_num_bytes = 0;
501 stream->sub_packet_cnt = 0;
502
503 /* XXX: decoder parses these again - skip "unused" warning */
504 (void)head_size;
505 (void)flavor;
506 (void)codecdata_length;
507
508 if (!stream->frame_buffer) xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
509 "demux_real: failed to allocate the audio frame buffer!\n");
510 return 1;
511 }
512
real_parse_headers(demux_real_t * this)513 static void real_parse_headers (demux_real_t *this) {
514
515 char preamble[PREAMBLE_SIZE];
516 unsigned int chunk_type = 0;
517 unsigned int chunk_size;
518 unsigned int audio_bitrate = 0;
519 unsigned int video_bitrate = 0;
520 real_stream_t *stream;
521
522 if (INPUT_IS_SEEKABLE(this->input))
523 this->input->seek (this->input, 0, SEEK_SET);
524
525 {
526 uint8_t signature[REAL_SIGNATURE_SIZE];
527 if (this->input->read(this->input, signature, REAL_SIGNATURE_SIZE) !=
528 REAL_SIGNATURE_SIZE) {
529
530 lprintf ("signature not read\n");
531 this->status = DEMUX_FINISHED;
532 return;
533 }
534
535 if ( !_x_is_fourcc(signature, ".RMF") ) {
536 this->status = DEMUX_FINISHED;
537 lprintf ("signature not found '%.4s'\n", signature);
538 return;
539 }
540
541 /* skip to the start of the first chunk and start traversing */
542 chunk_size = _X_BE_32(&signature[4]);
543 }
544
545 this->data_start = 0;
546 this->data_size = 0;
547 this->num_video_streams = 0;
548 this->num_audio_streams = 0;
549
550 this->input->seek(this->input, chunk_size-8, SEEK_CUR);
551
552 /* iterate through chunks and gather information until the first DATA
553 * chunk is located */
554 while (chunk_type != DATA_TAG) {
555
556 if (this->input->read(this->input, preamble, PREAMBLE_SIZE) !=
557 PREAMBLE_SIZE) {
558 this->status = DEMUX_FINISHED;
559 return;
560 }
561 chunk_type = _X_BE_32(&preamble[0]);
562 chunk_size = _X_BE_32(&preamble[4]);
563
564 lprintf ("chunktype %.4s len %d\n", (char *) &chunk_type, chunk_size);
565 switch (chunk_type) {
566
567 case PROP_TAG:
568 case MDPR_TAG:
569 case CONT_TAG:
570 {
571 if (chunk_size < PREAMBLE_SIZE+1) {
572 this->status = DEMUX_FINISHED;
573 return;
574 }
575 chunk_size -= PREAMBLE_SIZE;
576 uint8_t *const chunk_buffer = malloc(chunk_size);
577 if (! chunk_buffer ||
578 this->input->read(this->input, chunk_buffer, chunk_size) !=
579 chunk_size) {
580 free (chunk_buffer);
581 this->status = DEMUX_FINISHED;
582 return;
583 }
584
585 uint16_t version = _X_BE_16(&chunk_buffer[0]);
586
587 if (chunk_type == PROP_TAG) {
588
589 if(version != 0) {
590 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
591 "demuxe_real: unknown object version in PROP: 0x%04x\n", version);
592 free(chunk_buffer);
593 this->status = DEMUX_FINISHED;
594 return;
595 }
596
597 this->duration = _X_BE_32(&chunk_buffer[22]);
598 this->index_start = _X_BE_32(&chunk_buffer[30]);
599 this->data_start = _X_BE_32(&chunk_buffer[34]);
600 this->avg_bitrate = _X_BE_32(&chunk_buffer[6]);
601
602 lprintf("PROP: duration: %d ms\n", this->duration);
603 lprintf("PROP: index start: %"PRIX64"\n", this->index_start);
604 lprintf("PROP: data start: %"PRIX64"\n", this->data_start);
605 lprintf("PROP: average bit rate: %"PRId64"\n", this->avg_bitrate);
606
607 if (this->avg_bitrate<1)
608 this->avg_bitrate = 1;
609
610 _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE,
611 this->avg_bitrate);
612
613 } else if (chunk_type == MDPR_TAG) {
614
615 mdpr_t *mdpr;
616 uint32_t fourcc = 0, isvideo = 0;
617
618 if (version != 0) {
619 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
620 "demux_real: unknown object version in MDPR: 0x%04x\n", version);
621 free (chunk_buffer);
622 continue;
623 }
624 mdpr = real_parse_mdpr ((char *)chunk_buffer, chunk_size);
625 if (!mdpr) {
626 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
627 "demux_real: invalid MDPR\n");
628 free (chunk_buffer);
629 continue;
630 }
631
632 lprintf ("parsing type specific data...\n");
633 /* identify by mime type */
634 if (!strcmp (mdpr->mime_type, "audio/X-MP3-draft-00")) {
635 fourcc = ME_FOURCC ('a','d','u',0x55);
636 } else if (!strcmp (mdpr->mime_type, "audio/mpeg4-generic")) {
637 fourcc = ME_FOURCC ('m','p','4','a');
638 } else if (!strcmp (mdpr->mime_type, "video/MP4V-ES")) {
639 fourcc = ME_FOURCC ('m','p','4','v');
640 isvideo = 1;
641 }
642 if (fourcc) {
643 if (isvideo) {
644 if (this->num_video_streams == MAX_VIDEO_STREAMS) {
645 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
646 "demux_real: maximum number of video stream exceeded\n");
647 goto unknown;
648 }
649 stream = &this->video_streams[this->num_video_streams];
650 /* stream->format = _X_BE_32(mdpr->type_specific_data + 30); */
651 } else {
652 char b[20];
653 if (this->num_audio_streams == MAX_AUDIO_STREAMS) {
654 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
655 "demux_real: maximum number of audio stream exceeded\n");
656 goto unknown;
657 }
658 stream = &this->audio_streams[this->num_audio_streams];
659 stream->mdpr = mdpr;
660 _x_tag32_me2str (b, fourcc);
661 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
662 "demux_real: stream #%d: audio [%s] %ubps, start %d\n",
663 (int)mdpr->stream_number, b, (unsigned int)mdpr->avg_bit_rate, (int)mdpr->start_time);
664 }
665 } else if ((mdpr->type_specific_len >= 4) && (_X_BE_32 (mdpr->type_specific_data) == RA_TAG)) {
666 /* identify by type specific data */
667 if(this->num_audio_streams == MAX_AUDIO_STREAMS) {
668 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
669 "demux_real: maximum number of audio stream exceeded\n");
670 goto unknown;
671 }
672 stream = &this->audio_streams[this->num_audio_streams];
673 stream->mdpr = mdpr;
674 if (!real_parse_audio_specific_data (this, stream))
675 goto unknown;
676 fourcc = stream->fourcc;
677
678 } else if ((mdpr->type_specific_len >= 34) && (_X_BE_32 (mdpr->type_specific_data + 4) == VIDO_TAG)) {
679
680 if(this->num_video_streams == MAX_VIDEO_STREAMS) {
681 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
682 "demux_real: maximum number of video stream exceeded\n");
683 goto unknown;
684 }
685
686 isvideo = 1;
687 lprintf ("video detected\n");
688 fourcc = _X_ME_32 (mdpr->type_specific_data + 8);
689
690 stream = &this->video_streams[this->num_video_streams];
691 stream->format = _X_BE_32 (mdpr->type_specific_data + 30);
692 }
693
694 if (fourcc) {
695 if (isvideo) {
696 char b[20];
697 _x_tag32_me2str (b, fourcc);
698 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
699 "demux_real: stream #%d: video [%s] %ubps, start %d\n",
700 (int)mdpr->stream_number, b, (unsigned int)mdpr->avg_bit_rate, (int)mdpr->start_time);
701 stream->index = NULL;
702 stream->mdpr = mdpr;
703 stream->fourcc = fourcc;
704 stream->buf_type = _x_fourcc_to_buf_video (fourcc);
705 if (!stream->buf_type)
706 _x_report_video_fourcc (this->stream->xine, LOG_MODULE, fourcc);
707 if (mdpr->avg_bit_rate > video_bitrate) { /* select best video */
708 video_bitrate = mdpr->avg_bit_rate;
709 this->video_stream = stream;
710 }
711 this->num_video_streams++;
712 } else {
713 stream->index = NULL;
714 stream->fourcc = fourcc;
715 stream->buf_type = _x_formattag_to_buf_audio (fourcc);
716 if (mdpr->avg_bit_rate > audio_bitrate) { /* select best audio */
717 audio_bitrate = mdpr->avg_bit_rate;
718 this->audio_stream = stream;
719 }
720 this->num_audio_streams++;
721 }
722 } else {
723 lprintf ("unrecognised mdpr or type specific data\n");
724 unknown:
725 real_free_mdpr (mdpr);
726 }
727
728 } else if (chunk_type == CONT_TAG) {
729
730 if(version != 0) {
731 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
732 "demux_real: unknown object version in CONT: 0x%04x\n", version);
733 free(chunk_buffer);
734 continue;
735 }
736
737 int stream_ptr = 2;
738 #define SET_METADATA_STRING(type) \
739 do { \
740 const uint16_t field_size = _X_BE_16(&chunk_buffer[stream_ptr]); \
741 stream_ptr += 2; \
742 _x_meta_info_n_set(this->stream, type, (char *)&chunk_buffer[stream_ptr], field_size); \
743 stream_ptr += field_size; \
744 } while(0)
745
746 /* load the title string */
747 SET_METADATA_STRING(XINE_META_INFO_TITLE);
748
749 /* load the author string */
750 SET_METADATA_STRING(XINE_META_INFO_ARTIST);
751
752 /* load the copyright string as the year */
753 SET_METADATA_STRING(XINE_META_INFO_YEAR);
754
755 /* load the comment string */
756 SET_METADATA_STRING(XINE_META_INFO_COMMENT);
757 }
758
759 free(chunk_buffer);
760 }
761 break;
762
763 case DATA_TAG: {
764 uint8_t data_chunk_header[DATA_CHUNK_HEADER_SIZE];
765
766 if (this->input->read(this->input, data_chunk_header,
767 DATA_CHUNK_HEADER_SIZE) != DATA_CHUNK_HEADER_SIZE) {
768 this->status = DEMUX_FINISHED;
769 return ;
770 }
771
772 /* check version */
773 const uint16_t version = _X_BE_16(&data_chunk_header[0]);
774 if(version != 0) {
775 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
776 "demux_real: unknown object version in DATA: 0x%04x\n", version);
777 this->status = DEMUX_FINISHED;
778 return;
779 }
780
781 this->current_data_chunk_packet_count = _X_BE_32(&data_chunk_header[2]);
782 this->next_data_chunk_offset = _X_BE_32(&data_chunk_header[6]);
783 this->data_chunk_size = chunk_size;
784 }
785 break;
786
787 default:
788 /* this should not occur, but in case it does, skip the chunk */
789 lprintf("skipping a chunk!\n");
790 this->input->seek(this->input, chunk_size - PREAMBLE_SIZE, SEEK_CUR);
791 break;
792
793 }
794 }
795
796 /* Read index tables */
797 if(INPUT_IS_SEEKABLE(this->input))
798 real_parse_index(this);
799
800 /* Simple stream selection case - 0/1 audio/video streams */
801 if (!this->video_stream)
802 this->video_stream = (this->num_video_streams == 1) ? &this->video_streams[0] : NULL;
803 if (!this->audio_stream)
804 this->audio_stream = (this->num_audio_streams == 1) ? &this->audio_streams[0] : NULL;
805
806 /* Last resort in the case of multiple audio/video streams:
807 * select the first streams found in the file */
808 if ((!this->video_stream && (this->num_video_streams > 1))
809 || (!this->audio_stream && (this->num_audio_streams > 1))) {
810 int len, offset;
811 off_t original_pos = 0;
812 char search_buffer[MAX_PREVIEW_SIZE];
813
814 /* Get data to search through for stream chunks */
815 if(INPUT_IS_SEEKABLE(this->input)) {
816 original_pos = this->input->get_current_pos(this->input);
817
818 if((len = this->input->read(this->input, search_buffer, MAX_PREVIEW_SIZE)) <= 0) {
819 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
820 "demux_real: failed to read header\n");
821 this->status = DEMUX_FINISHED;
822 return;
823 }
824
825 offset = 0;
826 } else if((this->input->get_capabilities(this->input) & INPUT_CAP_PREVIEW) != 0) {
827 if((len = this->input->get_optional_data(this->input, search_buffer, INPUT_OPTIONAL_DATA_PREVIEW)) <= 0) {
828 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
829 "demux_real: failed to read header\n");
830 this->status = DEMUX_FINISHED;
831 return;
832 }
833
834 /* Preview data starts at the beginning of the file */
835 offset = this->data_start + 18;
836 } else {
837 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
838 "demux_real: unable to search for correct stream\n");
839 this->status = DEMUX_FINISHED;
840 return;
841 }
842
843 while((offset < len) &&
844 ((!this->video_stream && (this->num_video_streams > 0)) ||
845 (!this->audio_stream && (this->num_audio_streams > 0)))) {
846 int i;
847
848 /* Check for end of the data chunk */
849 if (_x_is_fourcc(&search_buffer[offset], "INDX") || _x_is_fourcc(&search_buffer[offset], "DATA"))
850 break;
851
852 const int stream = _X_BE_16(&search_buffer[offset + 4]);
853
854 for(i = 0; !this->video_stream && (i < this->num_video_streams); i++) {
855 if(stream == this->video_streams[i].mdpr->stream_number) {
856 this->video_stream = &this->video_streams[i];
857 lprintf("selecting video stream: %d\n", stream);
858 }
859 }
860
861 for(i = 0; !this->audio_stream && (i < this->num_audio_streams); i++) {
862 if(stream == this->audio_streams[i].mdpr->stream_number) {
863 this->audio_stream = &this->audio_streams[i];
864 lprintf("selecting audio stream: %d\n", stream);
865 }
866 }
867
868 offset += _X_BE_16(&search_buffer[offset + 2]);
869 }
870
871 if(INPUT_IS_SEEKABLE(this->input))
872 this->input->seek(this->input, original_pos, SEEK_SET);
873 }
874
875 /* Let the user know if we haven't managed to detect what streams to play */
876 if((!this->video_stream && this->num_video_streams) ||
877 (!this->audio_stream && this->num_audio_streams)) {
878 xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
879 "demux_real: unable to determine which audio/video streams to play\n");
880 this->status = DEMUX_FINISHED;
881 return;
882 }
883
884 this->audio_id = this->audio_stream ? this->audio_stream->mdpr->stream_number : -1;
885 this->video_id = this->video_stream ? this->video_stream->mdpr->stream_number : -1;
886 this->pos1 = 18;
887 this->endpos1 = chunk_size;
888 this->pos2 = 18;
889 this->endpos2 = chunk_size;
890 this->startpos1 = this->input->get_current_pos (this->input) - 18;
891
892 /* noninterleaved file (1 DATA chunk per stream) ? */
893 if (INPUT_IS_SEEKABLE (this->input)) {
894 uint32_t need = (this->audio_stream ? 1 : 0) | (this->video_stream ? 2 : 0);
895 off_t here = this->startpos1;
896 off_t last_pos = here + 18;
897 this->input->seek (this->input, here, SEEK_SET);
898 while (need) {
899 uint8_t b[20];
900 uint32_t size;
901 if (this->input->read (this->input, b, 18) != 18)
902 break;
903 size = _X_BE_32 (b + 4);
904 if (_X_ME_32 (b) == ME_FOURCC('D','A','T','A')) {
905 int n = 32;
906 while (--n) {
907 int stream, psize;
908 if (this->input->read (this->input, b, 12) != 12)
909 break;
910 psize = _X_BE_16 (b + 2);
911 if (_X_BE_16 (b) < 2) {
912 stream = _X_BE_16 (b + 4);
913 if ((need & 1) && (stream == this->audio_id)) {
914 this->startpos1 = here;
915 this->endpos1 = size;
916 need &= ~1;
917 if (!need)
918 break;
919 } else if ((need & 2) && (stream == this->video_id)) {
920 this->startpos2 = here;
921 this->endpos2 = size;
922 need &= ~2;
923 if (!need)
924 break;
925 }
926 }
927 this->input->seek (this->input, psize - 12, SEEK_CUR);
928 }
929 }
930 here += size;
931 this->input->seek (this->input, here, SEEK_SET);
932 }
933 if (this->startpos1)
934 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
935 "demux_real: audio stream #%d found in DATA chunk @%"PRId64".\n",
936 this->audio_id, (int64_t)this->startpos1);
937 if (this->startpos2)
938 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
939 "demux_real: video stream #%d found in DATA chunk @%"PRId64".\n",
940 this->video_id, (int64_t)this->startpos2);
941 if (this->startpos1) {
942 this->input->seek (this->input, this->startpos1 + 18, SEEK_SET);
943 if (this->startpos2) {
944 if (this->startpos1 != this->startpos2) {
945 /* Noninterleaved file. Try cloning input. */
946 if (this->input->get_capabilities (this->input) & INPUT_CAP_CLONE) {
947 input_plugin_t *in2 = NULL;
948 if (this->input->get_optional_data (this->input, &in2, INPUT_OPTIONAL_DATA_CLONE) == INPUT_OPTIONAL_SUCCESS)
949 this->in2 = in2;
950 }
951 if (this->in2) {
952 this->in2->seek (this->in2, this->startpos2 + 18, SEEK_SET);
953 this->lasttime2 = 0;
954 }
955 }
956 }
957 } else {
958 if (this->startpos2) {
959 this->input->seek (this->input, this->startpos2 + 18, SEEK_SET);
960 this->startpos1 = this->startpos2;
961 this->endpos1 = this->endpos2;
962 } else {
963 /* should not happen */
964 this->input->seek (this->input, last_pos, SEEK_SET);
965 }
966 }
967 }
968
969 /* should not happen */
970 if (!this->endpos1)
971 this->endpos1 = 1;
972 if (!this->endpos2)
973 this->endpos2 = 1;
974
975 /* Send headers and set meta info */
976 if (this->video_stream) {
977 _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
978 _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC,
979 this->video_stream->fourcc);
980 _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_BITRATE,
981 this->video_stream->mdpr->avg_bit_rate);
982 } else _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0);
983
984 if (this->audio_stream) {
985 _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
986 _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC,
987 this->audio_stream->fourcc);
988 _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE,
989 this->audio_stream->mdpr->avg_bit_rate);
990 } else _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0);
991
992 /* send start buffers */
993 _x_demux_control_start(this->stream);
994
995 if(this->video_stream) {
996 static const uint8_t h[] = {
997 0x00,0x00,0x01,0xb0,0xf3,0x00,0x00,0x01,
998 0xb5,0x0e,0xe0,0x40,0xc0,0xcf,0x00,0x00,
999 0x01,0x00,0x00,0x00,0x01,0x20,0x00,0x84,
1000 0x40,0x07,0xa8,0x50,0x20,0xf0,0xa2,0x1f
1001 };
1002 const uint8_t *info = this->video_stream->mdpr->type_specific_data;
1003 uint32_t ilen = this->video_stream->mdpr->type_specific_len;
1004 buf_element_t *buf;
1005 /* Check for recognised codec*/
1006 if(!this->video_stream->buf_type)
1007 this->video_stream->buf_type = BUF_VIDEO_UNKNOWN;
1008 /* Send header */
1009 buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
1010 buf->content = buf->mem;
1011 if (!ilen && (this->video_stream->fourcc == ME_FOURCC ('m','p','4','v'))) {
1012 xine_bmiheader *bih;
1013 xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
1014 "demux_real: missing mp4v config, trying generic 320x240...\n");
1015 buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END;
1016 bih = (xine_bmiheader *)buf->content;
1017 memset (bih, 0, sizeof (xine_bmiheader));
1018 bih->biSize = sizeof (xine_bmiheader);
1019 bih->biWidth = 320;
1020 bih->biHeight = 240;
1021 buf->size = sizeof (xine_bmiheader);
1022 buf->type = this->video_stream->buf_type;
1023 this->video_fifo->put (this->video_fifo, buf);
1024 buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
1025 info = h;
1026 ilen = sizeof (h);
1027 }
1028 if (ilen > (uint32_t)buf->max_size)
1029 ilen = buf->max_size;
1030 if (ilen)
1031 memcpy (buf->content, info, ilen);
1032 buf->size = ilen;
1033 buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END;
1034 buf->extra_info->input_normpos = 0;
1035 buf->extra_info->input_time = 0;
1036 buf->type = this->video_stream->buf_type;
1037 this->video_fifo->put (this->video_fifo, buf);
1038
1039 /* Allocate fragment offset table */
1040 this->fragment_tab = calloc(FRAGMENT_TAB_SIZE, sizeof(uint32_t));
1041 this->fragment_tab_max = FRAGMENT_TAB_SIZE;
1042 }
1043
1044 if(this->audio_stream) {
1045 /* Check for recognised codec */
1046 if(!this->audio_stream->buf_type)
1047 this->audio_stream->buf_type = BUF_AUDIO_UNKNOWN;
1048
1049 /* Send headers */
1050 if(this->audio_fifo) {
1051 mdpr_t *const mdpr = this->audio_stream->mdpr;
1052
1053 buf_element_t *buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
1054
1055 buf->type = this->audio_stream->buf_type;
1056 buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END;
1057
1058 if (!mdpr->type_specific_len) {
1059 /* we dont have anything to tell, maybe it still works */
1060 buf->decoder_flags |= BUF_FLAG_STDHEADER;
1061 buf->size = 0;
1062 buf->decoder_info[0] = 0;
1063 buf->decoder_info[1] = 0;
1064 buf->decoder_info[2] = 0;
1065 buf->decoder_info[3] = 0;
1066 } else if (buf->type == BUF_AUDIO_AAC) {
1067 /* For AAC we send two header buffers, the first is a standard audio
1068 * header giving bits per sample, sample rate and number of channels.
1069 * The second is the codec initialisation data found at the end of
1070 * the type specific data for the audio stream */
1071 if (mdpr->type_specific_len >= 62) {
1072 uint16_t version = _X_BE_16 (mdpr->type_specific_data + 4);
1073 if (version != 5) {
1074 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
1075 "demux_real: unsupported audio header version for AAC: %d\n", version);
1076 buf->free_buffer (buf);
1077 goto unsupported;
1078 }
1079 buf->decoder_info[1] = _X_BE_16 (mdpr->type_specific_data + 54);
1080 buf->decoder_info[2] = _X_BE_16 (mdpr->type_specific_data + 58);
1081 buf->decoder_info[3] = _X_BE_16 (mdpr->type_specific_data + 60);
1082 buf->decoder_flags |= BUF_FLAG_STDHEADER;
1083 buf->content = NULL;
1084 buf->size = 0;
1085
1086 if (mdpr->type_specific_len >= 80) {
1087 uint32_t s;
1088 this->audio_fifo->put (this->audio_fifo, buf);
1089 buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
1090 s = _X_BE_32 (mdpr->type_specific_data + 74);
1091 if (s >= 1)
1092 s -= 1;
1093 if (s > mdpr->type_specific_len - 79)
1094 s = mdpr->type_specific_len - 79;
1095 buf->type = this->audio_stream->buf_type;
1096 buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END|BUF_FLAG_SPECIAL;
1097 buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG;
1098 buf->decoder_info[2] = s;
1099 buf->decoder_info_ptr[2] = buf->content;
1100 buf->size = 0;
1101 memcpy (buf->content, mdpr->type_specific_data + 79, s);
1102 }
1103 }
1104 } else {
1105 memcpy (buf->content, mdpr->type_specific_data, mdpr->type_specific_len);
1106 buf->size = mdpr->type_specific_len;
1107 }
1108
1109 this->audio_fifo->put (this->audio_fifo, buf);
1110 }
1111
1112 unsupported: ;
1113 }
1114 }
1115
1116
1117 /* very naive approach for parsing ram files. it will extract known
1118 * mrls directly so it should work for simple smil files too.
1119 * no attempt is made to support smil features:
1120 * http://service.real.com/help/library/guides/production/htmfiles/smil.htm
1121 */
demux_real_parse_references(demux_real_t * this)1122 static int demux_real_parse_references( demux_real_t *this) {
1123
1124 char *buf = NULL;
1125 int buf_size = 0;
1126 int buf_used = 0;
1127 int len, i, j;
1128 int alternative = 0;
1129 int comment = 0;
1130
1131
1132 lprintf("parsing references\n");
1133
1134 /* read file to memory.
1135 * warning: dumb code, but hopefuly ok since reference file is small */
1136 do {
1137 buf_size += 1024;
1138 buf = realloc(buf, buf_size+1);
1139
1140 len = this->input->read(this->input, &buf[buf_used], buf_size-buf_used);
1141
1142 if( len > 0 )
1143 buf_used += len;
1144
1145 /* 50k of reference file? no way. something must be wrong */
1146 if( buf_used > 50*1024 )
1147 break;
1148 } while( len > 0 );
1149
1150 if(buf_used)
1151 buf[buf_used] = '\0';
1152
1153 lprintf("received %d bytes [%s]\n", buf_used, buf);
1154
1155 if (!strncmp(buf,"http://",7))
1156 {
1157 i = 0;
1158 while (buf[i])
1159 {
1160 j = i;
1161 while (buf[i] && !isspace(buf[i]))
1162 ++i; /* skip non-space */
1163 len = buf[i];
1164 buf[i] = 0;
1165 if (strncmp (buf + j, "http://", 7) || (i - j) < 8)
1166 break; /* stop at the first non-http reference */
1167 lprintf("reference [%s] found\n", buf + j);
1168 _x_demux_send_mrl_reference (this->stream, 0, buf + j, NULL, 0, 0);
1169 buf[i] = (char) len;
1170 while (buf[i] && isspace(buf[i]))
1171 ++i; /* skip spaces */
1172 }
1173 }
1174 else for (i = 0; i < buf_used; ++i)
1175 {
1176 /* "--stop--" is used to have pnm alternative for old real clients
1177 * new real clients will stop processing the file and thus use
1178 * rtsp protocol.
1179 */
1180 if( !strncmp(&buf[i],"--stop--",8) )
1181 alternative++;
1182
1183 /* rpm files can contain comments which should be skipped */
1184 if( !strncmp(&buf[i],"<!--",4) )
1185 comment = 1;
1186
1187 if( !strncmp(&buf[i],"-->",3) )
1188 comment = 0;
1189
1190 if( (!strncmp(&buf[i],"pnm://",6) || !strncmp(&buf[i],"rtsp://",7)) &&
1191 !comment ) {
1192 for(j=i; buf[j] && buf[j] != '"' && !isspace(buf[j]); j++ )
1193 ;
1194 buf[j]='\0';
1195 lprintf("reference [%s] found\n", &buf[i]);
1196
1197 _x_demux_send_mrl_reference (this->stream, alternative,
1198 &buf[i], NULL, 0, 0);
1199
1200 i = j;
1201 }
1202 }
1203
1204 free(buf);
1205
1206 this->status = DEMUX_FINISHED;
1207 return this->status;
1208 }
1209
1210 /* redefine abs as macro to handle 64-bit diffs.
1211 i guess llabs may not be available everywhere */
1212 #define abs(x) ( ((x)<0) ? -(x) : (x) )
1213
1214 #define WRAP_THRESHOLD 220000
1215 #define PTS_AUDIO 0
1216 #define PTS_VIDEO 1
1217 #define PTS_BOTH 2
1218
check_newpts(demux_real_t * this,int64_t pts,int video,int preview)1219 static void check_newpts (demux_real_t *this, int64_t pts, int video, int preview) {
1220 const int64_t diff = pts - this->last_pts[video];
1221
1222 if (preview)
1223 return;
1224
1225 /* Metronom does not strictly follow audio pts. They usually are too coarse
1226 for seamless playback. Instead, it takes the latest discontinuity as a
1227 starting point. This can lead to terrible lags for our very long audio frames.
1228 So let's make sure audio has the last word here. */
1229 if (this->send_newpts > video) {
1230 _x_demux_control_newpts (this->stream, pts, BUF_FLAG_SEEK);
1231 this->send_newpts = video;
1232 this->last_pts[video] = pts;
1233 this->last_pts[1 - video] = 0;
1234 } else if (pts && (this->last_pts[video]) && (abs (diff) > WRAP_THRESHOLD)) {
1235 _x_demux_control_newpts (this->stream, pts, 0);
1236 this->send_newpts = 0;
1237 this->last_pts[1 - video] = 0;
1238 }
1239
1240 if (pts)
1241 this->last_pts[video] = pts;
1242 }
1243
real_get_reordered_pts(demux_real_t * this,uint8_t * hdr,uint32_t dts)1244 static uint32_t real_get_reordered_pts (demux_real_t *this, uint8_t *hdr, uint32_t dts) {
1245 int pict_type; /* I1/I2/P/B-frame */
1246 uint32_t t, pts;
1247 /* lower 13 bits of pts are stored within the frame */
1248 pict_type = hdr[0];
1249 t = ((((uint32_t)hdr[1] << 8) | hdr[2]) << 8) | hdr[3];
1250 switch (this->video_stream->buf_type) {
1251 case BUF_VIDEO_RV20:
1252 pict_type >>= 6;
1253 t >>= 10;
1254 break;
1255 case BUF_VIDEO_RV30:
1256 pict_type >>= 3;
1257 t >>= 7;
1258 break;
1259 case BUF_VIDEO_RV40:
1260 pict_type >>= 5;
1261 t >>= 6;
1262 break;
1263 default:
1264 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
1265 "demux_real: can't fix timestamp for buf type 0x%08x\n",
1266 this->video_stream->buf_type);
1267 return (dts);
1268 break;
1269 }
1270
1271 pict_type &= 3;
1272 t &= 0x1fff;
1273 pts = (dts & (~0x1fff)) | t;
1274 /* snap to dts +/- 4.095 seconds */
1275 if (dts + 0x1000 < pts) pts -= 0x2000;
1276 else if (dts > pts + 0x1000) pts += 0x2000;
1277 if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) {
1278 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1,
1279 "demux_real: video pts: %d.%03d:%04d -> %d.%03d (%d)\n",
1280 dts / 1000, dts % 1000, t, pts / 1000, pts % 1000, pict_type);
1281 }
1282 return (pts);
1283 }
1284
demux_real_flush(demux_real_t * this)1285 static void demux_real_flush (demux_real_t *this) {
1286 if (this->vbuf) {
1287 /* flush previous frame */
1288 this->vbuf->free_buffer (this->vbuf);
1289 this->vbuf = NULL;
1290 }
1291 }
1292
demux_real_send_chunk(demux_plugin_t * this_gen)1293 static int demux_real_send_chunk(demux_plugin_t *this_gen) {
1294
1295 demux_real_t *this = (demux_real_t *) this_gen;
1296
1297 uint32_t timestamp;
1298 uint32_t stream;
1299 uint32_t size;
1300 uint32_t flags;
1301
1302 int64_t pts;
1303 int keyframe, input_time = 0;
1304 int normpos;
1305 uint32_t bytes;
1306
1307 if(this->reference_mode)
1308 return demux_real_parse_references(this);
1309
1310 {
1311 uint8_t header[DATA_PACKET_HEADER_SIZE + 2];
1312 uint32_t version;
1313 /* load a header from wherever the stream happens to be pointing */
1314 if (this->input->read(this->input, header, DATA_PACKET_HEADER_SIZE) != DATA_PACKET_HEADER_SIZE) {
1315 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
1316 "demux_real: failed to read data packet header\n");
1317 goto fail0;
1318 }
1319 /* Check to see if we've gone past the end of the data chunk */
1320 if (_x_is_fourcc(&header[0], "INDX") || _x_is_fourcc(&header[0], "DATA")) {
1321 lprintf("finished reading data chunk\n");
1322 goto fail0;
1323 }
1324 bytes = DATA_PACKET_HEADER_SIZE;
1325 if (this->input == this->in1)
1326 normpos = (uint64_t)this->pos1 * 0xffff / this->endpos1;
1327 else
1328 normpos = (uint64_t)this->pos2 * 0xffff / this->endpos2;
1329 /* check version */
1330 version = _X_BE_16 (&header[0]);
1331 if (version > 1) {
1332 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
1333 "demux_real: unknown object version in data packet: 0x%04x\n", version);
1334 goto fail0;
1335 }
1336 /* read the packet information */
1337 stream = _X_BE_16 (&header[4]);
1338 size = _X_BE_16 (&header[2]);
1339 if (size < DATA_PACKET_HEADER_SIZE)
1340 goto fail0;
1341 size -= DATA_PACKET_HEADER_SIZE;
1342 timestamp = _X_BE_32 (&header[6]);
1343 pts = (int64_t)timestamp * 90;
1344 /* Data packet header with version 1 contains 1 extra byte */
1345 if (version == 0) {
1346 header[12] = 0;
1347 keyframe = header[11] & PN_KEYFRAME_FLAG;
1348 } else {
1349 if (this->input->read (this->input, header + DATA_PACKET_HEADER_SIZE, 1) != 1)
1350 goto fail0;
1351 keyframe = header[DATA_PACKET_HEADER_SIZE] & PN_KEYFRAME_FLAG;
1352 size--;
1353 bytes += 1;
1354 }
1355 header[13] = 0;
1356 flags = _X_BE_32 (header + 10);
1357 }
1358 lprintf ("packet of stream %d, 0x%X bytes @ %"PRIX64", pts = %"PRId64"%s\n",
1359 stream, size,
1360 this->input == this->in1 ? this->startpos1 + this->pos1 : this->startpos2 + this->pos2,
1361 pts, keyframe ? ", keyframe" : "");
1362
1363 if (this->video_stream && ((int)stream == this->video_id)) {
1364
1365 int vpkg_seqnum = -1;
1366 int vpkg_subseq = 0;
1367 buf_element_t *buf;
1368 uint32_t decoder_flags;
1369
1370 lprintf ("video chunk detected.\n");
1371
1372 pts = (int64_t) timestamp * 90;
1373
1374 if (this->video_stream->fourcc == ME_FOURCC ('m','p','4','v')) {
1375 int left = size;
1376 #ifdef DEBUG_MP4V
1377 int64_t here = this->input->get_current_pos (this->input);
1378 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
1379 "demux_real: mp4v @%" PRId64 ", %u bytes, time %u, flags 0x%08x.\n", here, size, timestamp, flags);
1380 #else
1381 (void)flags;
1382 #endif
1383 buf = this->vbuf;
1384 if (timestamp != this->vtime) {
1385 if (buf) {
1386 /* finish previous frame */
1387 buf->decoder_flags |= BUF_FLAG_FRAME_END;
1388 this->video_fifo->put (this->video_fifo, buf);
1389 this->vbuf = buf = NULL;
1390 }
1391 /* start new frame */
1392 this->vtime = timestamp;
1393 this->vkeyframe = keyframe ? BUF_FLAG_KEYFRAME : 0;
1394 }
1395 if (!buf) {
1396 buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, size);
1397 this->vbuf = buf;
1398 buf->size = 0;
1399 buf->type = this->video_stream->buf_type;
1400 buf->decoder_flags = BUF_FLAG_FRAME_START | this->vkeyframe;
1401 buf->pts = pts;
1402 if (pts) {
1403 check_newpts (this, pts, PTS_VIDEO, 0);
1404 pts = 0;
1405 }
1406 }
1407 while (left) {
1408 int part = buf->max_size - buf->size;
1409 if (part > left)
1410 part = left;
1411 if (this->input->read (this->input, buf->content + buf->size, part) != part) {
1412 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
1413 "demux_real: failed to read video");
1414 break;
1415 }
1416 buf->size += part;
1417 buf->extra_info->input_normpos = normpos;
1418 buf->extra_info->input_time = timestamp;
1419 buf->extra_info->total_time = this->duration;
1420 bytes += part;
1421 if (buf->size == buf->max_size) {
1422 this->video_fifo->put (this->video_fifo, buf);
1423 buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, size);
1424 buf->size = 0;
1425 buf->type = this->video_stream->buf_type;
1426 buf->decoder_flags = this->vkeyframe;
1427 this->vbuf = buf;
1428 }
1429 left -= part;
1430 }
1431 }
1432 else
1433
1434 /* sub-demuxer */
1435
1436 while (size > 2) {
1437
1438 /*
1439 * read packet header
1440 * bit 7: 1=last block in block chain
1441 * bit 6: 1=short header (only one block?)
1442 */
1443
1444 int vpkg_header, vpkg_length, vpkg_offset;
1445 uint8_t b[16], *p = b, *q = b;
1446 #define NEEDBYTES(n) { \
1447 int need = n - (q - p); \
1448 if (need > 0) { \
1449 if (this->input->read (this->input, q, need) != need) \
1450 goto fail0; \
1451 q += need; \
1452 } \
1453 }
1454 NEEDBYTES (2);
1455 vpkg_header = *p++;
1456 lprintf ("vpkg_hdr: %02x (size=%d)\n", vpkg_header, size);
1457
1458 if (0x40 == (vpkg_header & 0xc0)) {
1459
1460 /* seems to be a very short header (2 bytes), purpose of the second byte yet unknown */
1461 lprintf ("bummer == %02X\n", (unsigned int)*p);
1462 p++;
1463 vpkg_offset = 0;
1464 vpkg_length = size - 2;
1465
1466 } else {
1467
1468 if (0 == (vpkg_header & 0x40)) {
1469 /* sub-seqnum (bits 0-6: number of fragment. bit 7: ???) */
1470 vpkg_subseq = (*p++) & 0x7f;
1471 }
1472
1473 /* size of the complete packet. bit 14 is always one (same applies to the offset) */
1474 NEEDBYTES (5);
1475 vpkg_length = _X_BE_16 (p); p += 2;
1476 if (!(vpkg_length & 0xC000)) {
1477 vpkg_length <<= 16;
1478 vpkg_length |= _X_BE_16 (p); p += 2;
1479 } else
1480 vpkg_length &= 0x3fff;
1481
1482 /*
1483 * offset of the following data inside the complete packet
1484 * Note: if (hdr&0xC0)==0x80 then offset is relative to the
1485 * _end_ of the packet, so it's equal to fragment size!!!
1486 */
1487 NEEDBYTES (3);
1488 vpkg_offset = _X_BE_16 (p); p += 2;
1489 if (!(vpkg_offset & 0xC000)) {
1490 NEEDBYTES (3);
1491 vpkg_offset <<= 16;
1492 vpkg_offset |= _X_BE_16 (p); p += 2;
1493 } else
1494 vpkg_offset &= 0x3fff;
1495
1496 vpkg_seqnum = *p++;
1497 }
1498
1499 bytes += p - b;
1500 size -= p - b;
1501 #undef NEEDBYTES
1502
1503 /* not (yet) needed */
1504 (void)vpkg_subseq;
1505
1506 lprintf ("seq=%d, offset=%d, length=%d, size=%d, frag size=%d, flags=%02x\n",
1507 vpkg_seqnum, vpkg_offset, vpkg_length, size, this->fragment_size,
1508 vpkg_header);
1509
1510 if (vpkg_seqnum != this->old_seqnum) {
1511 lprintf ("new seqnum\n");
1512
1513 this->fragment_size = 0;
1514 this->old_seqnum = vpkg_seqnum;
1515 }
1516
1517 /* if we have a seekable stream then use the timestamp for the data
1518 * packet for more accurate seeking - if not then estimate time using
1519 * average bitrate */
1520 if(this->video_stream->index)
1521 input_time = timestamp;
1522 else
1523 input_time = (int)((int64_t) this->input->get_current_pos(this->input)
1524 * 8 * 1000 / this->avg_bitrate);
1525
1526 decoder_flags = keyframe ? BUF_FLAG_KEYFRAME : 0;
1527
1528 if (this->fragment_size == 0) {
1529 lprintf ("new packet starting\n");
1530
1531 /* send fragment offset table */
1532 if(this->fragment_count) {
1533 lprintf("sending fragment offset table\n");
1534
1535 buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
1536
1537 buf->decoder_flags = BUF_FLAG_SPECIAL | BUF_FLAG_FRAME_END;
1538 buf->decoder_info[1] = BUF_SPECIAL_RV_CHUNK_TABLE;
1539 buf->decoder_info[2] = this->fragment_count - 1;
1540 buf->decoder_info_ptr[2] = buf->content;
1541 buf->decoder_info[3] = 0;
1542 buf->size = 0;
1543 buf->type = this->video_stream->buf_type;
1544
1545 xine_fast_memcpy(buf->content, this->fragment_tab,
1546 this->fragment_count*8);
1547
1548 this->video_fifo->put(this->video_fifo, buf);
1549
1550 this->fragment_count = 0;
1551 }
1552
1553 decoder_flags |= BUF_FLAG_FRAME_START;
1554 } else {
1555 lprintf ("continuing packet \n");
1556 }
1557
1558 /* add entry to fragment offset table */
1559 this->fragment_tab[2*this->fragment_count] = 1;
1560 this->fragment_tab[2*this->fragment_count+1] = this->fragment_size;
1561 this->fragment_count++;
1562
1563 /*
1564 * calc size of fragment
1565 */
1566
1567 int fragment_size;
1568 switch(vpkg_header & 0xc0) {
1569 case 0x80:
1570 fragment_size = vpkg_offset;
1571 break;
1572 case 0x00:
1573 fragment_size = size;
1574 break;
1575 default:
1576 fragment_size = vpkg_length;
1577 break;
1578 }
1579 lprintf ("fragment size is %d\n", fragment_size);
1580
1581 /*
1582 * read fragment_size bytes of data
1583 */
1584
1585 int n = fragment_size;
1586 while(n) {
1587 buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
1588
1589 buf->size = MIN(n, buf->max_size);
1590
1591 buf->decoder_flags = decoder_flags;
1592 decoder_flags &= ~BUF_FLAG_FRAME_START;
1593
1594 buf->type = this->video_stream->buf_type;
1595
1596 if(this->input->read(this->input, buf->content, buf->size) < buf->size) {
1597 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
1598 "demux_real: failed to read video fragment");
1599 buf->free_buffer(buf);
1600 goto fail0;
1601 }
1602 bytes += buf->size;
1603
1604 /* RV30 and RV40 streams contain some fragments that shouldn't be passed
1605 * to the decoder. The purpose of these fragments is unknown, but
1606 * realplayer doesn't appear to pass them to the decoder either */
1607 if((n == fragment_size) &&
1608 (((buf->type == BUF_VIDEO_RV30) && (buf->content[0] & 0x20)) ||
1609 ((buf->type == BUF_VIDEO_RV40) && (buf->content[0] & 0x80)))) {
1610 lprintf("ignoring fragment\n");
1611
1612 /* Discard buffer and skip over rest of fragment */
1613 buf->free_buffer(buf);
1614 this->input->seek(this->input, n - buf->size, SEEK_CUR);
1615 this->fragment_count--;
1616
1617 break;
1618 }
1619
1620 /* if the video stream has b-frames fix the timestamps */
1621 if((this->video_stream->format >= 0x20200002) &&
1622 (buf->decoder_flags & BUF_FLAG_FRAME_START))
1623 pts = (int64_t)real_get_reordered_pts (this, buf->content, timestamp) * 90;
1624
1625 /* this test was moved from ffmpeg video decoder.
1626 * fixme: is pts only valid on frame start? */
1627 if (buf->decoder_flags & BUF_FLAG_FRAME_START) {
1628 buf->pts = pts;
1629 check_newpts (this, pts, PTS_VIDEO, 0);
1630 } else buf->pts = 0;
1631 pts = 0;
1632
1633 buf->extra_info->input_normpos = normpos;
1634 buf->extra_info->input_time = input_time;
1635 buf->extra_info->total_time = this->duration;
1636
1637 this->video_fifo->put(this->video_fifo, buf);
1638
1639 n -= buf->size;
1640 }
1641
1642 size -= fragment_size;
1643 lprintf ("size left %d\n", size);
1644
1645 this->fragment_size += fragment_size;
1646
1647 if (this->fragment_size >= vpkg_length) {
1648 lprintf ("fragment finished (%d/%d)\n", this->fragment_size, vpkg_length);
1649 this->fragment_size = 0;
1650 }
1651
1652 } /* while(size>2) */
1653
1654 } else if (this->audio_fifo && this->audio_stream && ((int)stream == this->audio_id)) {
1655
1656 lprintf ("audio chunk detected.\n");
1657
1658 if(this->audio_need_keyframe && !keyframe)
1659 goto discard;
1660 else
1661 this->audio_need_keyframe = 0;
1662
1663 /* speed up when not debugging */
1664 if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) {
1665 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1,
1666 "demux_real: audio pts: %d.%03d %s%s\n",
1667 timestamp / 1000, timestamp % 1000,
1668 keyframe ? "*" : " ",
1669 this->audio_stream->sub_packet_cnt ? " " : "s");
1670 }
1671
1672 /* cook audio frames are fairly long (almost 2 seconds). For obfuscation
1673 purposes, they are sent as multiple fragments in intentionally wrong order.
1674 The first sent fragment has the timestamp for the whole frame.
1675
1676 Sometimes, the remaining fragments all carry the same time, and appear
1677 immediately thereafter. This is easy.
1678
1679 Sometimes, the remaining fragments carry fake timestamps interpolated across
1680 the frame duration. Consequently, they will be muxed between the next few
1681 video frames. We get the complete frame ~2 seconds late. This is ugly.
1682 Let's be careful not to trap metronom into a big lag. */
1683 if (!this->audio_stream->sub_packet_cnt)
1684 this->audio_stream->audio_time = timestamp;
1685 else
1686 timestamp = this->audio_stream->audio_time;
1687 /* nasty kludge, maybe this is somewhere in mdpr? */
1688 if (this->audio_stream->buf_type == BUF_AUDIO_COOK)
1689 timestamp += 120;
1690 pts = (int64_t) timestamp * 90;
1691
1692 /* if we have a seekable stream then use the timestamp for the data
1693 * packet for more accurate seeking - if not then estimate time using
1694 * average bitrate */
1695 if(this->audio_stream->index)
1696 input_time = timestamp;
1697 else
1698 input_time = (int)((int64_t) this->input->get_current_pos(this->input)
1699 * 8 * 1000 / this->avg_bitrate);
1700
1701 check_newpts (this, pts, PTS_AUDIO, 0);
1702
1703 /* Each packet of AAC is made up of several AAC frames preceded by a
1704 * header defining the size of the frames in bits (!) */
1705 if(this->audio_stream->buf_type == BUF_AUDIO_AAC) {
1706 int i, frames, sizes[16];
1707 uint8_t b[32];
1708
1709 /* Upper 4 bits of second byte is frame count */
1710 if (this->input->read (this->input, b, 2) != 2)
1711 goto fail0;
1712 bytes += 2;
1713 frames = b[1] >> 4;
1714
1715 /* 2 bytes per frame size */
1716 if (this->input->read (this->input, b, 2 * frames) != 2 * frames)
1717 goto fail0;
1718 bytes += 2 * frames;
1719 for (i = 0; i < frames; i++)
1720 sizes[i] = (_X_BE_16 (b + 2 * i) + 7) >> 3;
1721
1722 for(i = 0; i < frames; i++) {
1723 if(_x_demux_read_send_data(this->audio_fifo, this->input, sizes[i], pts,
1724 this->audio_stream->buf_type, !i && keyframe ? BUF_FLAG_KEYFRAME : 0, normpos,
1725 input_time, this->duration, 0) < 0) {
1726
1727 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
1728 "demux_real: failed to read AAC frame\n");
1729
1730 goto fail0;
1731 }
1732 bytes += sizes[i];
1733 pts = 0; /* Only set pts on first frame */
1734 }
1735 } else if (this->audio_stream->intl) {
1736 /* reorder */
1737 uint8_t * buffer = this->audio_stream->frame_buffer;
1738 const int sps = this->audio_stream->sps;
1739 const int sph = this->audio_stream->h;
1740 const int cfs = this->audio_stream->cfs;
1741 const int w = this->audio_stream->w;
1742 const int spc = this->audio_stream->sub_packet_cnt;
1743 int x;
1744 const int fs = this->audio_stream->frame_size;
1745
1746 if (!buffer) {
1747 this->status = DEMUX_FINISHED;
1748 return this->status;
1749 }
1750
1751 switch (this->audio_stream->intl) {
1752 case ME_FOURCC('I','n','t','4'):
1753 for (x = 0; x < sph / 2; x++) {
1754 int pos = x * 2 * w + spc * cfs;
1755 if (pos + cfs > fs || this->input->read (this->input, buffer + pos, cfs) < cfs) {
1756 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
1757 "demux_real: failed to read audio chunk\n");
1758
1759 goto fail0;
1760 }
1761 bytes += cfs;
1762 }
1763 break;
1764 case ME_FOURCC('g','e','n','r'):
1765 for (x = 0; x < w / sps; x++) {
1766 int pos = sps * (sph * x + ((sph + 1) / 2) * (spc & 1) + (spc >> 1));
1767 if (pos + sps > fs || this->input->read (this->input, buffer + pos, sps) < sps) {
1768 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
1769 "demux_real: failed to read audio chunk\n");
1770
1771 goto fail0;
1772 }
1773 bytes += sps;
1774 }
1775 break;
1776 case ME_FOURCC('s','i','p','r'):
1777 {
1778 int pos = spc * w;
1779 if (pos + w > fs || this->input->read (this->input, buffer + pos, w) < w) {
1780 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
1781 "demux_real: failed to read audio chunk\n");
1782 goto fail0;
1783 }
1784 }
1785 bytes += w;
1786 if (spc == sph - 1)
1787 demux_real_sipro_swap ((char *)buffer, sph * w * 2 / 96);
1788 break;
1789 }
1790 this->audio_stream->sub_packet_cnt++;
1791 if ((int)this->audio_stream->sub_packet_cnt == sph) {
1792 this->audio_stream->sub_packet_cnt = 0;
1793 xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1,
1794 "demux_real: sending audio %d.%03d\n", input_time / 1000, input_time % 1000);
1795 _x_demux_send_data(this->audio_fifo, buffer, this->audio_stream->frame_size,
1796 pts, this->audio_stream->buf_type, keyframe ? BUF_FLAG_KEYFRAME : 0, normpos,
1797 input_time, this->duration, 0);
1798 }
1799 } else {
1800 if(_x_demux_read_send_data(this->audio_fifo, this->input, size, pts,
1801 this->audio_stream->buf_type, keyframe ? BUF_FLAG_KEYFRAME : 0, normpos,
1802 input_time, this->duration, 0) < 0) {
1803
1804 xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
1805 "demux_real: failed to read audio chunk\n");
1806
1807 goto fail0;
1808 }
1809 bytes += size;
1810
1811 /* FIXME: dp->flags = (flags & 0x2) ? 0x10 : 0; */
1812 }
1813
1814 } else {
1815
1816 /* discard */
1817 lprintf ("chunk not detected; discarding.\n");
1818
1819 discard:
1820 this->input->seek(this->input, size, SEEK_CUR);
1821 bytes += size;
1822
1823 }
1824
1825 /* Every good demuxer also is a muxer ;-) */
1826 if (this->input == this->in1) {
1827 this->lasttime1 = timestamp;
1828 this->pos1 += bytes;
1829 } else {
1830 this->lasttime2 = timestamp;
1831 this->pos2 += bytes;
1832 }
1833 if (this->in2) {
1834 if (this->lasttime1 > this->lasttime2)
1835 this->input = this->in2;
1836 else
1837 this->input = this->in1;
1838 }
1839
1840 #if 0
1841
1842 this->current_data_chunk_packet_count--;
1843
1844 /* check if it's time to reload */
1845 if (!this->current_data_chunk_packet_count &&
1846 this->next_data_chunk_offset) {
1847 unsigned char data_chunk_header[DATA_CHUNK_HEADER_SIZE];
1848
1849 /* seek to the next DATA chunk offset */
1850 this->input->seek(this->input, this->next_data_chunk_offset + PREAMBLE_SIZE, SEEK_SET);
1851
1852 /* load the rest of the DATA chunk header */
1853 if (this->input->read(this->input, data_chunk_header,
1854 DATA_CHUNK_HEADER_SIZE) != DATA_CHUNK_HEADER_SIZE) {
1855 this->status = DEMUX_FINISHED;
1856 return this->status;
1857 }
1858 lprintf ("**** found next DATA tag\n");
1859 this->current_data_chunk_packet_count = _X_BE_32(&data_chunk_header[2]);
1860 this->next_data_chunk_offset = _X_BE_32(&data_chunk_header[6]);
1861 }
1862
1863 if (!this->current_data_chunk_packet_count) {
1864 this->status = DEMUX_FINISHED;
1865 return this->status;
1866 }
1867
1868 #endif
1869
1870 return this->status;
1871
1872 fail0:
1873 if (this->vbuf) {
1874 /* finish last frame */
1875 this->vbuf->decoder_flags |= BUF_FLAG_FRAME_END;
1876 this->video_fifo->put (this->video_fifo, this->vbuf);
1877 this->vbuf = NULL;
1878 }
1879 if (this->input == this->in1) {
1880 this->lasttime1 = 0xffffffff;
1881 if (this->lasttime2 == 0xffffffff) {
1882 this->status = DEMUX_FINISHED;
1883 return this->status;
1884 }
1885 if (this->in2)
1886 this->input = this->in2;
1887 } else {
1888 this->lasttime2 = 0xffffffff;
1889 this->input = this->in1;
1890 if (this->lasttime1 == 0xffffffff) {
1891 this->status = DEMUX_FINISHED;
1892 return this->status;
1893 }
1894 }
1895
1896 return this->status;
1897 }
1898
demux_real_send_headers(demux_plugin_t * this_gen)1899 static void demux_real_send_headers(demux_plugin_t *this_gen) {
1900
1901 demux_real_t *this = (demux_real_t *) this_gen;
1902
1903 this->video_fifo = this->stream->video_fifo;
1904 this->audio_fifo = this->stream->audio_fifo;
1905
1906 this->status = DEMUX_OK;
1907
1908 this->last_pts[0] = 0;
1909 this->last_pts[1] = 0;
1910 this->send_newpts = PTS_BOTH;
1911
1912 this->avg_bitrate = 1;
1913
1914
1915
1916 /* send init info to decoders */
1917
1918 this->input->seek (this->input, 0, SEEK_SET);
1919
1920 _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0);
1921 _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0);
1922
1923 if( !this->reference_mode ) {
1924 real_parse_headers (this);
1925 } else {
1926 if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0)
1927 this->input->seek (this->input, 0, SEEK_SET);
1928 }
1929 }
1930
demux_real_find_time(real_index_entry_t * index,int n,uint32_t t)1931 static int demux_real_find_time (real_index_entry_t *index, int n, uint32_t t) {
1932 int b = 0, l, m = -1, e = n;
1933 if (e <= 0)
1934 return -1;
1935 do {
1936 l = m;
1937 m = (b + e) >> 1;
1938 if (t < index[m].timestamp)
1939 e = m;
1940 else
1941 b = m;
1942 } while (l != m);
1943 return m;
1944 }
1945
demux_real_find_offs(real_index_entry_t * index,int n,uint32_t offs)1946 static int demux_real_find_offs (real_index_entry_t *index, int n, uint32_t offs) {
1947 int b = 0, l, m = -1, e = n;
1948 if (e <= 0)
1949 return -1;
1950 do {
1951 l = m;
1952 m = (b + e) >> 1;
1953 if (offs < index[m].offset)
1954 e = m;
1955 else
1956 b = m;
1957 } while (l != m);
1958 return m;
1959 }
1960
demux_real_seek(demux_plugin_t * this_gen,off_t start_pos,int start_time,int playing)1961 static int demux_real_seek (demux_plugin_t *this_gen,
1962 off_t start_pos, int start_time, int playing) {
1963
1964 demux_real_t *this = (demux_real_t *) this_gen;
1965
1966 lprintf("seek start_pos=%d, start_time=%d, playing=%d\n",
1967 (int)start_pos, start_time, playing);
1968
1969 demux_real_flush (this);
1970
1971 this->input = this->in1;
1972
1973 do {
1974 int have;
1975
1976 if (!(this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE)) {
1977 if (playing || !this->input->seek_time)
1978 return this->status;
1979 /* RTSP supports only time based seek */
1980 if (start_pos && !start_time)
1981 start_time = (int64_t)this->duration * start_pos / 65535;
1982 this->input->seek_time (this->input, start_time, SEEK_SET);
1983 break;
1984 }
1985
1986 if (!start_pos && !start_time) {
1987 /* We can always return to the beginning. */
1988 this->lasttime1 = 0;
1989 this->pos1 = 18;
1990 this->pos2 = 18;
1991 this->in1->seek (this->in1, this->startpos1 + 18, SEEK_SET);
1992 if (this->in2) {
1993 this->lasttime2 = 0;
1994 this->in2->seek (this->in2, this->startpos2 + 18, SEEK_SET);
1995 }
1996 break;
1997 }
1998
1999 have = ((this->audio_stream && this->audio_stream->index) ? 1 : 0)
2000 | ((this->video_stream && this->video_stream->index) ? 2 : 0);
2001 if (!have)
2002 return this->status;
2003
2004 if (this->in2) {
2005 uint32_t pos1, pos2;
2006 int i1, i2;
2007 /* Noninterleaved seek. We need both indices. */
2008 if (have != 3)
2009 return this->status;
2010 if (start_time) {
2011 i1 = demux_real_find_time (this->audio_stream->index, this->audio_stream->index_entries, start_time);
2012 i2 = demux_real_find_time (this->video_stream->index, this->video_stream->index_entries, start_time);
2013 if ((i1 < 0) || (i2 < 0))
2014 return this->status;
2015 } else { /* start_pos */
2016 pos1 = (uint32_t)((double)start_pos / 65535.0 * this->endpos1) + this->startpos1;
2017 pos2 = (uint32_t)((double)start_pos / 65535.0 * this->endpos2) + this->startpos2;
2018 i1 = demux_real_find_offs (this->audio_stream->index, this->audio_stream->index_entries, pos1);
2019 i2 = demux_real_find_offs (this->video_stream->index, this->video_stream->index_entries, pos2);
2020 if ((i1 < 0) || (i2 < 0))
2021 return this->status;
2022 }
2023 pos1 = this->audio_stream->index[i1].offset;
2024 pos2 = this->video_stream->index[i2].offset;
2025 this->input->seek (this->in1, pos1, SEEK_SET);
2026 this->input->seek (this->in2, pos2, SEEK_SET);
2027 this->pos1 = pos1 - this->startpos1;
2028 this->pos2 = pos2 - this->startpos2;
2029 this->lasttime1 = 0;
2030 this->lasttime2 = 0;
2031 break;
2032 }
2033
2034 {
2035 real_index_entry_t *index, *other_index = NULL;
2036 int i, entries;
2037 start_pos = (off_t)((double) start_pos / 65535 * this->input->get_length (this->input));
2038 /* video index has priority over audio index */
2039 if (have & 2) {
2040 index = this->video_stream->index;
2041 entries = this->video_stream->index_entries;
2042 if (have & 1)
2043 other_index = this->audio_stream->index;
2044 } else {
2045 index = this->audio_stream->index;
2046 entries = this->audio_stream->index_entries;
2047 }
2048 if (start_pos)
2049 i = demux_real_find_offs (index, entries, start_pos);
2050 else /* start_time */
2051 i = demux_real_find_time (index, entries, start_time);
2052 if (i < 0)
2053 return this->status;
2054 /* make sure we don't skip past audio/video at start of file */
2055 if ((i == 0) && other_index && (other_index[0].offset < index[0].offset))
2056 index = other_index;
2057 this->input->seek (this->input, index[i].offset, SEEK_SET);
2058 this->pos1 = index[i].offset - this->startpos1;
2059 this->lasttime1 = 0;
2060 break;
2061 }
2062 } while (0);
2063
2064 this->send_newpts = PTS_BOTH;
2065 this->old_seqnum = -1;
2066 this->fragment_size = 0;
2067 this->fragment_count = 0;
2068 this->audio_need_keyframe = 1;
2069 if (this->audio_stream)
2070 this->audio_stream->sub_packet_cnt = 0;
2071
2072 if (playing)
2073 _x_demux_flush_engine (this->stream);
2074
2075 this->status = DEMUX_OK;
2076 return this->status;
2077 }
2078
demux_real_dispose(demux_plugin_t * this_gen)2079 static void demux_real_dispose (demux_plugin_t *this_gen) {
2080 demux_real_t *this = (demux_real_t *) this_gen;
2081 int i;
2082
2083 demux_real_flush (this);
2084
2085 if (this->in2)
2086 this->in2->dispose (this->in2);
2087
2088 for(i = 0; i < this->num_video_streams; i++) {
2089 real_free_mdpr(this->video_streams[i].mdpr);
2090 free(this->video_streams[i].index);
2091 }
2092
2093 for(i = 0; i < this->num_audio_streams; i++) {
2094 real_free_mdpr(this->audio_streams[i].mdpr);
2095 free(this->audio_streams[i].index);
2096 free(this->audio_streams[i].frame_buffer);
2097 }
2098
2099 free(this->fragment_tab);
2100 free(this);
2101 }
2102
demux_real_get_status(demux_plugin_t * this_gen)2103 static int demux_real_get_status (demux_plugin_t *this_gen) {
2104 demux_real_t *this = (demux_real_t *) this_gen;
2105
2106 return this->status;
2107 }
2108
demux_real_get_stream_length(demux_plugin_t * this_gen)2109 static int demux_real_get_stream_length (demux_plugin_t *this_gen) {
2110 demux_real_t *this = (demux_real_t *) this_gen;
2111
2112 /* duration is stored in the file as milliseconds */
2113 return this->duration;
2114 }
2115
demux_real_get_capabilities(demux_plugin_t * this_gen)2116 static uint32_t demux_real_get_capabilities (demux_plugin_t *this_gen) {
2117 (void)this_gen;
2118 return DEMUX_CAP_NOCAP;
2119 }
2120
demux_real_get_optional_data(demux_plugin_t * this_gen,void * data,int data_type)2121 static int demux_real_get_optional_data(demux_plugin_t *this_gen,
2122 void *data, int data_type) {
2123 (void)this_gen;
2124 (void)data;
2125 (void)data_type;
2126 return DEMUX_OPTIONAL_UNSUPPORTED;
2127 }
2128
2129 /* help function to discover stream type. returns:
2130 * -1 if couldn't read
2131 * 0 if not known.
2132 * 1 if normal stream.
2133 * 2 if reference stream.
2134 */
real_check_stream_type(input_plugin_t * input)2135 static int real_check_stream_type(input_plugin_t *input)
2136 {
2137 uint8_t buf[1024];
2138 off_t len = _x_demux_read_header(input, buf, sizeof(buf));
2139
2140 if ( len < 4 )
2141 return -1;
2142
2143 if ( memcmp(buf, "\x2eRMF", 4) == 0 )
2144 return 1;
2145
2146 #define my_strnstr(haystack, haystacklen, needle) \
2147 memmem(haystack, haystacklen, needle, sizeof(needle))
2148
2149 if( my_strnstr(buf, len, "pnm://") || my_strnstr(buf, len, "rtsp://") ||
2150 my_strnstr(buf, len, "<smil>") || !strncmp((char *)buf, "http://", MIN(7, len)) )
2151 return 2;
2152
2153 return 0;
2154 }
2155
open_plugin(demux_class_t * class_gen,xine_stream_t * stream,input_plugin_t * input)2156 static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
2157 input_plugin_t *input) {
2158
2159 demux_real_t *this;
2160 /* discover stream type */
2161 const int stream_type = real_check_stream_type(input);
2162
2163 if ( stream_type < 0 )
2164 return NULL;
2165
2166 switch (stream->content_detection_method) {
2167
2168 case METHOD_BY_CONTENT:
2169 if ( stream_type < 1 )
2170 return NULL;
2171
2172 lprintf ("by content accepted.\n");
2173 break;
2174
2175 case METHOD_BY_MRL:
2176 case METHOD_EXPLICIT:
2177 break;
2178
2179 default:
2180 return NULL;
2181 }
2182
2183 this = calloc (1, sizeof (demux_real_t));
2184 if (!this)
2185 return NULL;
2186
2187 this->status = 0;
2188 this->num_audio_streams = 0;
2189 this->num_video_streams = 0;
2190 this->audio_stream = NULL;
2191 this->video_stream = NULL;
2192 this->startpos1 = 0;
2193 this->startpos2 = 0;
2194 this->audio_need_keyframe = 0;
2195 this->current_data_chunk_packet_count = 0;
2196 this->last_pts[0] = 0;
2197 this->last_pts[1] = 0;
2198 this->send_newpts = 0;
2199 this->fragment_count = 0;
2200 this->fragment_tab = NULL;
2201 this->fragment_tab_max = 0;
2202 this->vbuf = NULL;
2203 this->vtime = 0;
2204 this->vkeyframe = 0;
2205 this->reference_mode = 0;
2206 this->in2 = NULL;
2207 this->lasttime1 = 0;
2208
2209 this->stream = stream;
2210 this->input =
2211 this->in1 = input;
2212
2213 this->lasttime2 = 0xffffffff;
2214
2215 if(stream_type == 2){
2216 this->reference_mode = 1;
2217 lprintf("reference stream detected\n");
2218 }
2219
2220 this->demux_plugin.send_headers = demux_real_send_headers;
2221 this->demux_plugin.send_chunk = demux_real_send_chunk;
2222 this->demux_plugin.seek = demux_real_seek;
2223 this->demux_plugin.dispose = demux_real_dispose;
2224 this->demux_plugin.get_status = demux_real_get_status;
2225 this->demux_plugin.get_stream_length = demux_real_get_stream_length;
2226 this->demux_plugin.get_capabilities = demux_real_get_capabilities;
2227 this->demux_plugin.get_optional_data = demux_real_get_optional_data;
2228 this->demux_plugin.demux_class = class_gen;
2229
2230 return &this->demux_plugin;
2231 }
2232
demux_real_init_class(xine_t * xine,const void * data)2233 void *demux_real_init_class (xine_t *xine, const void *data) {
2234 /* We explicitely dont need these here. */
2235 (void)xine;
2236 (void)data;
2237
2238 static const demux_class_t demux_real_class = {
2239 .open_plugin = open_plugin,
2240 .description = N_("RealMedia file demux plugin"),
2241 .identifier = "Real",
2242 .mimetypes =
2243 "audio/x-pn-realaudio: ra, rm, ram: Real Media file;"
2244 "audio/x-pn-realaudio-plugin: rpm: Real Media plugin file;"
2245 "audio/x-real-audio: ra, rm, ram: Real Media file;"
2246 "application/vnd.rn-realmedia: ra, rm, ram: Real Media file;",
2247 .extensions = "rm rmvb ram",
2248 .dispose = NULL,
2249 };
2250
2251 return (void *)&demux_real_class;
2252 }
2253