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