1 /*
2  * Copyright (C) 2001-2020 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  * Quicktime File Demuxer by Mike Melanson (melanson@pcisys.net)
21  *  based on a Quicktime parsing experiment entitled 'lazyqt'
22  *
23  * Atom finder, trak builder rewrite, multiaudio and ISO fragment
24  *  media file support by Torsten Jager (t.jager@gmx.de)
25  *
26  * Ideally, more documentation is forthcoming, but in the meantime:
27  * functional flow:
28  *  create_qt_info
29  *  open_qt_file
30  *   parse_moov_atom
31  *    parse_mvhd_atom
32  *    parse_trak_atom
33  *    build_frame_table
34  *  free_qt_info
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 #include <zlib.h>
48 
49 #define LOG_MODULE "demux_qt"
50 #include "group_video.h"
51 
52 #include <xine/xine_internal.h>
53 #include <xine/xineutils.h>
54 #include <xine/demux.h>
55 #include <xine/buffer.h>
56 #include "bswap.h"
57 
58 #include "qtpalette.h"
59 
60 typedef unsigned int qt_atom;
61 
62 #define QT_ATOM BE_FOURCC
63 /* top level atoms */
64 #define FREE_ATOM QT_ATOM('f', 'r', 'e', 'e')
65 #define JUNK_ATOM QT_ATOM('j', 'u', 'n', 'k')
66 #define MDAT_ATOM QT_ATOM('m', 'd', 'a', 't')
67 #define MOOV_ATOM QT_ATOM('m', 'o', 'o', 'v')
68 #define PNOT_ATOM QT_ATOM('p', 'n', 'o', 't')
69 #define SKIP_ATOM QT_ATOM('s', 'k', 'i', 'p')
70 #define WIDE_ATOM QT_ATOM('w', 'i', 'd', 'e')
71 #define PICT_ATOM QT_ATOM('P', 'I', 'C', 'T')
72 #define FTYP_ATOM QT_ATOM('f', 't', 'y', 'p')
73 /*
74 #define SIDX_ATOM QT_ATOM('s', 'i', 'd', 'x')
75 */
76 
77 #define CMOV_ATOM QT_ATOM('c', 'm', 'o', 'v')
78 
79 #define MVHD_ATOM QT_ATOM('m', 'v', 'h', 'd')
80 
81 #define VMHD_ATOM QT_ATOM('v', 'm', 'h', 'd')
82 #define SMHD_ATOM QT_ATOM('s', 'm', 'h', 'd')
83 
84 #define TRAK_ATOM QT_ATOM('t', 'r', 'a', 'k')
85 #define TKHD_ATOM QT_ATOM('t', 'k', 'h', 'd')
86 #define MDHD_ATOM QT_ATOM('m', 'd', 'h', 'd')
87 #define ELST_ATOM QT_ATOM('e', 'l', 's', 't')
88 
89 /* atoms in a sample table */
90 #define STSD_ATOM QT_ATOM('s', 't', 's', 'd')
91 #define STSZ_ATOM QT_ATOM('s', 't', 's', 'z')
92 #define STZ2_ATOM QT_ATOM('s', 't', 'z', '2')
93 #define STSC_ATOM QT_ATOM('s', 't', 's', 'c')
94 #define STCO_ATOM QT_ATOM('s', 't', 'c', 'o')
95 #define STTS_ATOM QT_ATOM('s', 't', 't', 's')
96 #define CTTS_ATOM QT_ATOM('c', 't', 't', 's')
97 #define STSS_ATOM QT_ATOM('s', 't', 's', 's')
98 #define CO64_ATOM QT_ATOM('c', 'o', '6', '4')
99 
100 #define ESDS_ATOM QT_ATOM('e', 's', 'd', 's')
101 #define WAVE_ATOM QT_ATOM('w', 'a', 'v', 'e')
102 #define FRMA_ATOM QT_ATOM('f', 'r', 'm', 'a')
103 #define AVCC_ATOM QT_ATOM('a', 'v', 'c', 'C')
104 #define HVCC_ATOM QT_ATOM('h', 'v', 'c', 'C')
105 #define ENDA_ATOM QT_ATOM('e', 'n', 'd', 'a')
106 
107 #define IMA4_FOURCC ME_FOURCC('i', 'm', 'a', '4')
108 #define MAC3_FOURCC ME_FOURCC('M', 'A', 'C', '3')
109 #define MAC6_FOURCC ME_FOURCC('M', 'A', 'C', '6')
110 #define ULAW_FOURCC ME_FOURCC('u', 'l', 'a', 'w')
111 #define ALAW_FOURCC ME_FOURCC('a', 'l', 'a', 'w')
112 #define MP4A_FOURCC ME_FOURCC('m', 'p', '4', 'a')
113 #define SAMR_FOURCC ME_FOURCC('s', 'a', 'm', 'r')
114 #define ALAC_FOURCC ME_FOURCC('a', 'l', 'a', 'c')
115 #define DRMS_FOURCC ME_FOURCC('d', 'r', 'm', 's')
116 #define TWOS_FOURCC ME_FOURCC('t', 'w', 'o', 's')
117 #define SOWT_FOURCC ME_FOURCC('s', 'o', 'w', 't')
118 #define RAW_FOURCC  ME_FOURCC('r', 'a', 'w', ' ')
119 #define IN24_FOURCC ME_FOURCC('i', 'n', '2', '4')
120 #define NI42_FOURCC ME_FOURCC('4', '2', 'n', 'i')
121 #define AVC1_FOURCC ME_FOURCC('a', 'v', 'c', '1')
122 #define HVC1_FOURCC ME_FOURCC('h', 'v', 'c', '1')
123 #define HEV1_FOURCC ME_FOURCC('h', 'e', 'v', '1')
124 #define HEVC_FOURCC ME_FOURCC('h', 'e', 'v', 'c')
125 #define AC_3_FOURCC ME_FOURCC('a', 'c', '-', '3')
126 #define EAC3_FOURCC ME_FOURCC('e', 'c', '-', '3')
127 #define QCLP_FOURCC ME_FOURCC('Q', 'c', 'l', 'p')
128 
129 #define UDTA_ATOM QT_ATOM('u', 'd', 't', 'a')
130 #define META_ATOM QT_ATOM('m', 'e', 't', 'a')
131 #define HDLR_ATOM QT_ATOM('h', 'd', 'l', 'r')
132 #define ILST_ATOM QT_ATOM('i', 'l', 's', 't')
133 #define NAM_ATOM QT_ATOM(0xA9, 'n', 'a', 'm')
134 #define CPY_ATOM QT_ATOM(0xA9, 'c', 'p', 'y')
135 #define DES_ATOM QT_ATOM(0xA9, 'd', 'e', 's')
136 #define CMT_ATOM QT_ATOM(0xA9, 'c', 'm', 't')
137 #define ALB_ATOM QT_ATOM(0xA9, 'a', 'l', 'b')
138 #define GEN_ATOM QT_ATOM(0xA9, 'g', 'e', 'n')
139 #define ART_ATOM QT_ATOM(0xA9, 'A', 'R', 'T')
140 #define TOO_ATOM QT_ATOM(0xA9, 't', 'o', 'o')
141 #define WRT_ATOM QT_ATOM(0xA9, 'w', 'r', 't')
142 #define DAY_ATOM QT_ATOM(0xA9, 'd', 'a', 'y')
143 
144 #define RMRA_ATOM QT_ATOM('r', 'm', 'r', 'a')
145 #define RMDA_ATOM QT_ATOM('r', 'm', 'd', 'a')
146 #define RDRF_ATOM QT_ATOM('r', 'd', 'r', 'f')
147 #define RMDR_ATOM QT_ATOM('r', 'm', 'd', 'r')
148 #define RMVC_ATOM QT_ATOM('r', 'm', 'v', 'c')
149 #define QTIM_ATOM QT_ATOM('q', 't', 'i', 'm')
150 #define URL__ATOM QT_ATOM('u', 'r', 'l', ' ')
151 #define DATA_ATOM QT_ATOM('d', 'a', 't', 'a')
152 
153 /* fragment stuff */
154 #define MVEX_ATOM QT_ATOM('m', 'v', 'e', 'x')
155 #define MEHD_ATOM QT_ATOM('m', 'e', 'h', 'd')
156 #define TREX_ATOM QT_ATOM('t', 'r', 'e', 'x')
157 #define MOOF_ATOM QT_ATOM('m', 'o', 'o', 'f')
158 #define MFHD_ATOM QT_ATOM('m', 'v', 'h', 'd')
159 #define TRAF_ATOM QT_ATOM('t', 'r', 'a', 'f')
160 #define TFHD_ATOM QT_ATOM('t', 'f', 'h', 'd')
161 #define TRUN_ATOM QT_ATOM('t', 'r', 'u', 'n')
162 
163 /* placeholder for cutting and pasting
164 #define _ATOM QT_ATOM('', '', '', '')
165 */
166 
167 /* TJ. I have not seen more than 20Mb yet... */
168 #define MAX_MOOV_SIZE (128 << 20)
169 
170 #define ATOM_PREAMBLE_SIZE 8
171 #define PALETTE_COUNT 256
172 
173 #define MAX_PTS_DIFF 100000
174 
175 #ifdef ARCH_X86
176 #  define HAVE_FAST_FLOAT
177 #endif
178 
179 typedef struct {
180 #ifdef HAVE_FAST_FLOAT
181   double   mul;
182 #else
183   int32_t num;
184   int32_t den;
185 #endif
186 } scale_int_t;
187 
scale_int_init(scale_int_t * scale,uint32_t num,uint32_t den)188 static void scale_int_init (scale_int_t *scale, uint32_t num, uint32_t den) {
189   if (!den)
190     den = 1;
191 #ifdef HAVE_FAST_FLOAT
192   scale->mul = (double)num / (double)den;
193 #else
194   scale->num = num;
195   scale->den = den;
196 #endif
197 }
198 
scale_int_do(scale_int_t * scale,int64_t * v)199 static void scale_int_do (scale_int_t *scale, int64_t *v) {
200 #ifdef HAVE_FAST_FLOAT
201   *v = (double)(*v) * scale->mul;
202 #else
203   *v = *v * scale->num / scale->den;
204 #endif
205 }
206 
207 /**
208  * @brief Network bandwidth, cribbed from src/input/input_mms.c
209  */
210 static const uint32_t bandwidths[] = {
211    14400,  19200,  28800,  33600,   34430,    57600,
212   115200, 262200, 393216, 524300, 1544000, 10485800
213 };
214 
215 /* these are things that can go wrong */
216 typedef enum {
217   QT_OK,
218   QT_FILE_READ_ERROR,
219   QT_NO_MEMORY,
220   QT_NOT_A_VALID_FILE,
221   QT_NO_MOOV_ATOM,
222   QT_NO_ZLIB,
223   QT_ZLIB_ERROR,
224   QT_HEADER_TROUBLE,
225   QT_DRM_NOT_SUPPORTED
226 } qt_error;
227 
228 /* there are other types but these are the ones we usually care about */
229 typedef enum {
230 
231   MEDIA_AUDIO,
232   MEDIA_VIDEO,
233   MEDIA_OTHER
234 
235 } media_type;
236 
237 #ifdef SIDX_ATOM
238 typedef struct {
239   int64_t offset;
240   int64_t pts;
241 } fragment_info_t;
242 
243 typedef struct {
244   int num_fragments;
245   fragment_info_t fragments[1];
246 } fragment_index_t;
247 #endif
248 
249 /* TJ. Cinematic movies reach > 200000 frames easily, so we better save space here.
250  * offset / file size should well fit into 48 bits :-) */
251 typedef struct {
252   union {
253     int64_t offset;
254     uint8_t bytes[8];
255   } _ffs;
256   unsigned int size;
257   /* pts actually is dts for reordered video. Edit list and frame
258      duration code relies on that, so keep the offset separately
259      until sending to video fifo.
260      Value is small enough for plain int. */
261   int ptsoffs;
262   int64_t pts;
263 } qt_frame;
264 #define QTF_OFFSET(f)     ((f)._ffs.offset & ~((uint64_t)0xffff << 48))
265 #ifdef WORDS_BIGENDIAN
266 #  define QTF_KEYFRAME(f) ((f)._ffs.bytes[0])
267 #  define QTF_MEDIA_ID(f) ((f)._ffs.bytes[1])
268 #else
269 #  define QTF_KEYFRAME(f) ((f)._ffs.bytes[7])
270 #  define QTF_MEDIA_ID(f) ((f)._ffs.bytes[6])
271 #endif
272 
273 typedef struct {
274   int64_t track_duration;
275   int64_t media_time;
276 } edit_list_table_t;
277 
278 typedef struct {
279   unsigned int first_chunk;
280   unsigned int samples_per_chunk;
281   unsigned int media_id;
282 } sample_to_chunk_table_t;
283 
284 typedef struct {
285   char *url;
286   int64_t data_rate;
287   int qtim_version;
288 } reference_t;
289 
290 typedef struct {
291   /* the media id that corresponds to this trak */
292   uint8_t       *properties_atom;
293   uint8_t       *decoder_config;
294   unsigned int   media_id;
295   unsigned int   codec_fourcc;
296   unsigned int   codec_buftype;
297   unsigned int   properties_atom_size;
298   unsigned int   decoder_config_len;
299   /* formattag-like field that specifies codec in mp4 files */
300   int            object_type_id;
301   char           codec_str[20];
302   union {
303     struct {
304       unsigned int width;
305       unsigned int height;
306       int          depth;
307       int          edit_list_compensation;  /* special trick for edit lists */
308 
309       int palette_count;
310       palette_entry_t palette[PALETTE_COUNT];
311     } video;
312     struct {
313       xine_waveformatex *wave;
314       unsigned int wave_size;
315 
316       unsigned int sample_rate;
317       unsigned int channels;
318       unsigned int bits;
319       unsigned int vbr;
320 
321       /* special audio parameters */
322       unsigned int samples_per_packet;
323       unsigned int bytes_per_packet;
324       unsigned int bytes_per_frame;
325       unsigned int bytes_per_sample;
326       unsigned int samples_per_frame;
327     } audio;
328   } s;
329 } properties_t;
330 
331 typedef struct {
332   /* trak description */
333   media_type type;
334   int id;
335 
336   /* internal frame table corresponding to this trak */
337   qt_frame    *frames;
338   unsigned int frame_count;
339   unsigned int current_frame;
340 
341   /* this is the current properties atom in use */
342   properties_t *properties;
343   /* one or more properties atoms for this trak */
344   properties_t *stsd_atoms;
345   unsigned int  stsd_atoms_count;
346 
347   /* trak timescale */
348   int timescale;
349   int ptsoffs_mul;
350   scale_int_t si;
351 
352   /* flags that indicate how a trak is supposed to be used */
353   unsigned int flags;
354 
355   /* temporary tables for loading a chunk */
356   /* edit list table */
357   edit_list_table_t       *edit_list_table;
358   /* chunk offsets */
359   uint8_t                 *chunk_offset_table32;
360   uint8_t                 *chunk_offset_table64;
361   /* sample sizes */
362   uint8_t                 *sample_size_table;
363   /* sync samples, a.k.a., keyframes */
364   uint8_t                 *sync_sample_table;
365   xine_keyframes_entry_t  *keyframes_list;
366   /* sample to chunk table */
367   sample_to_chunk_table_t *sample_to_chunk_table;
368   /* time to sample table */
369   uint8_t                 *time_to_sample_table;
370   /* pts to dts timeoffset to sample table */
371   uint8_t                 *timeoffs_to_sample_table;
372   /* and the sizes thereof */
373   unsigned int edit_list_count;
374   unsigned int chunk_offset_count;
375   unsigned int samples;
376   unsigned int sample_size;
377   unsigned int sample_size_count;
378   unsigned int sample_size_bytes;
379   unsigned int sample_size_shift;
380   unsigned int sync_sample_count;
381   unsigned int keyframes_used;
382   unsigned int keyframes_size;
383   unsigned int sample_to_chunk_count;
384   unsigned int time_to_sample_count;
385   unsigned int timeoffs_to_sample_count;
386 
387   /* what to add to output buffer type */
388   int audio_index;
389 
390   int lang;
391 
392   /* fragment defaults */
393   int default_sample_description_index;
394   int default_sample_duration;
395   int default_sample_size;
396   int default_sample_flags;
397   /* fragment seamless dts */
398   int64_t fragment_dts;
399   int delay_index;
400   /* fragment frame array size */
401   int fragment_frames;
402 } qt_trak;
403 
404 typedef struct {
405   int          compressed_header;  /* 1 if there was a compressed moov; just FYI */
406 
407   unsigned int creation_time;  /* in ms since Jan-01-1904 */
408   unsigned int modification_time;
409   unsigned int timescale;  /* base clock frequency is Hz */
410   unsigned int duration;
411   int32_t      msecs;
412   uint32_t     normpos_mul;
413   uint32_t     normpos_shift;
414 
415   int64_t      moov_first_offset;
416 
417   unsigned int trak_count;
418   qt_trak     *traks;
419 
420 #define MAX_AUDIO_TRAKS 8
421   int          audio_trak_count;
422   int          audio_traks[MAX_AUDIO_TRAKS];
423 
424   /* the trak numbers that won their respective frame count competitions */
425   int          video_trak;
426   int          audio_trak;
427   int          seek_flag;  /* this is set to indicate that a seek has just occurred */
428 
429   /* fragment mode */
430   int          fragment_count;
431   size_t       fragbuf_size;
432   uint8_t     *fragment_buf;
433   off_t        fragment_next;
434 
435   char        *artist;
436   char        *name;
437   char        *album;
438   char        *genre;
439   char        *copyright;
440   char        *description;
441   char        *comment;
442   char        *composer;
443   char        *year;
444 
445   /* a QT movie may contain a number of references pointing to URLs */
446   reference_t *references;
447   unsigned int reference_count;
448   int          chosen_reference;
449 
450   /* need to know base MRL to construct URLs from relative paths */
451   char        *base_mrl;
452 
453   qt_error     last_error;
454 } qt_info;
455 
456 typedef struct {
457   demux_plugin_t       demux_plugin;
458 
459   xine_stream_t       *stream;
460 
461   config_values_t     *config;
462 
463   fifo_buffer_t       *video_fifo;
464   fifo_buffer_t       *audio_fifo;
465 
466   input_plugin_t      *input;
467 
468   int                  status;
469 
470   qt_info              qt;
471   xine_bmiheader       bih;
472 
473 #ifdef QT_OFFSET_SEEK
474   off_t                data_start;
475   off_t                data_size;
476 #endif
477 
478   int64_t              bandwidth;
479 } demux_qt_t;
480 
481 
482 /**********************************************************************
483  * lazyqt special debugging functions
484  **********************************************************************/
485 
486 /* define DEBUG_ATOM_LOAD as 1 to get a verbose parsing of the relevant
487  * atoms */
488 #define DEBUG_ATOM_LOAD 0
489 
490 /* define DEBUG_EDIT_LIST as 1 to get a detailed look at how the demuxer is
491  * handling edit lists */
492 #define DEBUG_EDIT_LIST 0
493 
494 /* define DEBUG_FRAME_TABLE as 1 to dump the complete frame table that the
495  * demuxer plans to use during file playback */
496 #define DEBUG_FRAME_TABLE 0
497 
498 /* define DEBUG_VIDEO_DEMUX as 1 to see details about the video chunks the
499  * demuxer is sending off to the video decoder */
500 #define DEBUG_VIDEO_DEMUX 0
501 
502 /* define DEBUG_AUDIO_DEMUX as 1 to see details about the audio chunks the
503  * demuxer is sending off to the audio decoder */
504 #define DEBUG_AUDIO_DEMUX 0
505 
506 /* define DEBUG_META_LOAD as 1 to see details about the metadata chunks the
507  * demuxer is reading from the file */
508 #define DEBUG_META_LOAD 0
509 
510 /* Define DEBUG_DUMP_MOOV as 1 to dump the raw moov atom to disk. This is
511  * particularly useful in debugging a file with a compressed moov (cmov)
512  * atom. The atom will be dumped to the filename specified as
513  * RAW_MOOV_FILENAME. */
514 #define DEBUG_DUMP_MOOV 0
515 #define RAW_MOOV_FILENAME "moovatom.raw"
516 
517 #if DEBUG_ATOM_LOAD
518 #define debug_atom_load printf
519 #else
debug_atom_load(const char * format,...)520 static inline void XINE_FORMAT_PRINTF (1, 2) debug_atom_load (const char *format, ...) {(void)format;}
521 #endif
522 
523 #if DEBUG_EDIT_LIST
524 #define debug_edit_list printf
525 #else
debug_edit_list(const char * format,...)526 static inline void XINE_FORMAT_PRINTF (1, 2) debug_edit_list (const char *format, ...) {(void)format;}
527 #endif
528 
529 #if DEBUG_FRAME_TABLE
530 #define debug_frame_table printf
531 #else
debug_frame_table(const char * format,...)532 static inline void XINE_FORMAT_PRINTF (1, 2) debug_frame_table (const char *format, ...) {(void)format;}
533 #endif
534 
535 #if DEBUG_VIDEO_DEMUX
536 #define debug_video_demux printf
537 #else
debug_video_demux(const char * format,...)538 static inline void XINE_FORMAT_PRINTF (1, 2) debug_video_demux (const char *format, ...) {(void)format;}
539 #endif
540 
541 #if DEBUG_AUDIO_DEMUX
542 #define debug_audio_demux printf
543 #else
debug_audio_demux(const char * format,...)544 static inline void XINE_FORMAT_PRINTF (1, 2) debug_audio_demux (const char *format, ...) {(void)format;}
545 #endif
546 
547 #if DEBUG_META_LOAD
548 #define debug_meta_load printf
549 #else
debug_meta_load(const char * format,...)550 static inline void XINE_FORMAT_PRINTF (1, 2) debug_meta_load (const char *format, ...) {(void)format;}
551 #endif
552 
dump_moov_atom(uint8_t * moov_atom,int moov_atom_size)553 static inline void dump_moov_atom (uint8_t *moov_atom, int moov_atom_size) {
554 #if DEBUG_DUMP_MOOV
555 
556   FILE *f;
557 
558   f = fopen(RAW_MOOV_FILENAME, "wb");
559   if (!f) {
560     perror(RAW_MOOV_FILENAME);
561     return;
562   }
563 
564   if (fwrite(moov_atom, moov_atom_size, 1, f) != 1)
565     printf ("  qt debug: could not write moov atom to disk\n");
566 
567   fclose(f);
568 
569 #else
570   (void)moov_atom;
571   (void)moov_atom_size;
572 #endif
573 }
574 
575 /**********************************************************************
576  * lazyqt functions
577  **********************************************************************/
578 
reset_qt_info(demux_qt_t * this)579 static void reset_qt_info (demux_qt_t *this) {
580 #ifndef HAVE_ZERO_SAFE_MEM
581   this->qt.compressed_header = 0;
582   this->qt.creation_time     = 0;
583   this->qt.modification_time = 0;
584   this->qt.duration          = 0;
585   this->qt.normpos_mul       = 0;
586   this->qt.normpos_shift     = 0;
587   this->qt.trak_count        = 0;
588   this->qt.traks             = NULL;
589   this->qt.artist            = NULL;
590   this->qt.name              = NULL;
591   this->qt.album             = NULL;
592   this->qt.genre             = NULL;
593   this->qt.copyright         = NULL;
594   this->qt.description       = NULL;
595   this->qt.comment           = NULL;
596   this->qt.composer          = NULL;
597   this->qt.year              = NULL;
598   this->qt.references        = NULL;
599   this->qt.reference_count   = 0;
600   this->qt.base_mrl          = NULL;
601   this->qt.fragbuf_size      = 0;
602   this->qt.fragment_buf      = NULL;
603   this->qt.fragment_next     = 0;
604 #else
605   memset (&this->qt, 0, sizeof (this->qt));
606 #endif
607   this->qt.last_error        = QT_OK;
608   this->qt.timescale         = 1;
609   this->qt.msecs             = 1;
610   this->qt.video_trak        = -1;
611   this->qt.audio_trak        = -1;
612   this->qt.chosen_reference  = -1;
613   this->qt.fragment_count    = -1;
614 }
615 
616 /* create a qt_info structure */
create_qt_info(demux_qt_t * this)617 static qt_info *create_qt_info (demux_qt_t *this) {
618   reset_qt_info (this);
619   return &this->qt;
620 }
621 
622 /* release a qt_info structure and associated data */
free_qt_info(demux_qt_t * this)623 static void free_qt_info (demux_qt_t *this) {
624   if (this->qt.traks) {
625     unsigned int i;
626     for (i = 0; i < this->qt.trak_count; i++) {
627       free (this->qt.traks[i].frames);
628       free (this->qt.traks[i].edit_list_table);
629       free (this->qt.traks[i].sample_to_chunk_table);
630       if (this->qt.traks[i].type == MEDIA_AUDIO) {
631         unsigned int j;
632         for (j = 0; j < this->qt.traks[i].stsd_atoms_count; j++)
633           free (this->qt.traks[i].stsd_atoms[j].s.audio.wave);
634       }
635       free (this->qt.traks[i].stsd_atoms);
636     }
637     free (this->qt.traks);
638   }
639   if (this->qt.references) {
640     unsigned int i;
641     for (i = 0; i < this->qt.reference_count; i++)
642       free (this->qt.references[i].url);
643     free (this->qt.references);
644   }
645   free (this->qt.fragment_buf);
646   free (this->qt.base_mrl);
647   free (this->qt.artist);
648   free (this->qt.name);
649   free (this->qt.album);
650   free (this->qt.genre);
651   free (this->qt.copyright);
652   free (this->qt.description);
653   free (this->qt.comment);
654   free (this->qt.composer);
655   free (this->qt.year);
656   reset_qt_info (this);
657 }
658 
659 /* fetch interesting information from the movie header atom */
parse_mvhd_atom(demux_qt_t * this,uint8_t * mvhd_atom)660 static void parse_mvhd_atom (demux_qt_t *this, uint8_t *mvhd_atom) {
661 
662   this->qt.creation_time     = _X_BE_32 (mvhd_atom + 0x0c);
663   this->qt.modification_time = _X_BE_32 (mvhd_atom + 0x10);
664   this->qt.timescale         = _X_BE_32 (mvhd_atom + 0x14);
665   this->qt.duration          = _X_BE_32 (mvhd_atom + 0x18);
666 
667   if (this->qt.timescale == 0)
668     this->qt.timescale = 1;
669 
670   debug_atom_load("  qt: timescale = %d, duration = %d (%d seconds)\n",
671     this->qt.timescale, this->qt.duration,
672     this->qt.duration / this->qt.timescale);
673 }
674 
675 /* helper function from mplayer's parse_mp4.c */
mp4_read_descr_len(uint8_t * s,uint32_t * length)676 static int mp4_read_descr_len (uint8_t *s, uint32_t *length) {
677   uint8_t b;
678   uint8_t numBytes = 0;
679 
680   *length = 0;
681 
682   do {
683     b = *s++;
684     numBytes++;
685     *length = (*length << 7) | (b & 0x7F);
686   } while ((b & 0x80) && numBytes < 4);
687 
688   return numBytes;
689 }
690 
691 #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
692 #  define WRITE_BE_32(v,p) { \
693   uint8_t *wp = (uint8_t *)(p); \
694   int32_t n = __builtin_bswap32 ((int32_t)(v)); \
695   __builtin_memcpy (wp, &n, 4); \
696 }
697 #else
698 #  define WRITE_BE_32(v,p) { \
699   uint8_t *wp = (uint8_t *)(p); \
700   uint32_t wv = (v); \
701   wp[0] = wv >> 24; \
702   wp[1] = wv >> 16; \
703   wp[2] = wv >> 8; \
704   wp[3] = wv; \
705 }
706 #endif
707 
708 /* find sub atoms somewhere inside this atom */
find_embedded_atoms(uint8_t * atom,const uint32_t * types,uint8_t ** found,uint32_t * sizes)709 static void find_embedded_atoms (uint8_t *atom,
710   const uint32_t *types, uint8_t **found, uint32_t *sizes) {
711   uint8_t *here;
712   uint32_t atomsize, v, n;
713   uint8_t *end;
714   if (!atom || !types || !found)
715     return;
716   for (n = 0; types[n]; n++)
717     found[n] = NULL, sizes[n] = 0;
718   atomsize = _X_BE_32 (atom);
719   if (atomsize < 16)
720     return;
721   end = atom + atomsize;
722   atomsize -= 16;
723   here = atom + 16;
724   v = _X_BE_32 (here - 4);
725   while (1) {
726     for (n = 0; types[n]; n++) {
727       if (v == types[n]) {
728         uint32_t fsize = _X_BE_32 (here - 8);
729         if (fsize == 0) {
730           found[n] = here - 8;
731           sizes[n] = atomsize + 8;
732           return;
733         }
734         if ((fsize < 8) || (fsize - 8 > atomsize))
735           break;
736         found[n] = here - 8;
737         sizes[n] = fsize;
738         atomsize -= fsize - 8;
739         if (atomsize < 8)
740           return;
741         here += fsize - 1;
742         v = _X_BE_32 (here - 4);
743         atomsize += 1;
744         break;
745       }
746     }
747     if (!atomsize)
748       break;
749     if (here >= end)
750       break;
751     v = (v << 8) | *here++;
752     atomsize -= 1;
753   }
754 }
755 
atom_scan(uint8_t * atom,int depth,const uint32_t * types,uint8_t ** found,unsigned int * sizes)756 static int atom_scan (     /** << return value: # of missing atoms. */
757   uint8_t        *atom,    /** << the atom to parse. */
758   int             depth,   /** << how many levels of hierarchy to examine. */
759   const uint32_t *types,   /** << zero terminated list of interesting atom types. */
760   uint8_t       **found,   /** << list of atom pointers to fill in. */
761   unsigned int   *sizes) { /** << list of atom sizes to fill in. */
762   static const uint8_t containers[] =
763     /* look into these from "trak". */
764     "edtsmdiaminfdinfstbl"
765     /* look into these from "moov" (intentionally hide "trak"). */
766     "udtametailstiprosinfrmrarmdardrfrmvc";
767   unsigned int atomtype, atomsize, subsize = 0;
768   unsigned int i = 8, n, left;
769 
770   if (!atom || !types || !found)
771     return 0;
772   if (depth > 0) {
773     for (n = 0; types[n]; n++) {
774       found[n] = NULL;
775       sizes[n] = 0;
776     }
777     left = n;
778     depth = -depth;
779   } else {
780     for (left = n = 0; types[n]; n++)
781       if (!(found[n]))
782         left++;
783   }
784 
785   atomsize = _X_BE_32 (atom);
786   atomtype = _X_BE_32 (&atom[4]);
787   if (atomtype == META_ATOM) {
788     if ((atomsize < 12) || (atom[8] != 0))
789       return left;
790     i = 12;
791   }
792 
793   for (; i + 8 <= atomsize; i += subsize) {
794     unsigned int j;
795     uint32_t subtype = _X_BE_32 (&atom[i + 4]);
796     subsize          = _X_BE_32 (&atom[i]);
797     if (subsize == 0) {
798       subsize = atomsize - i;
799       WRITE_BE_32 (subsize, &atom[i]);
800     }
801     if ((subsize < 8) || (i + subsize > atomsize))
802       break;
803     for (n = 0; types[n]; n++) {
804       if (found[n])
805         continue;
806       if (!(subtype ^ types[n])) {
807 #if DEBUG_ATOM_LOAD
808         xine_hexdump (atom + i, subsize);
809 #endif
810         found[n] = atom + i;
811         sizes[n] = subsize;
812         if (!(--left))
813           return 0;
814         break;
815       }
816     }
817     if (depth > -2)
818       continue;
819     for (j = 0; j < sizeof (containers) - 1; j += 4) {
820       if (!memcmp (atom + i + 4, containers + j, 4)) {
821         if (!(left = atom_scan (atom + i, depth + 1, types, found, sizes)))
822           return 0;
823         break;
824       }
825     }
826   }
827 
828   return left;
829 }
830 
831 /*
832  * This function traverses through a trak atom searching for the sample
833  * table atoms, which it loads into an internal trak structure.
834  */
parse_trak_atom(qt_trak * trak,uint8_t * trak_atom)835 static qt_error parse_trak_atom (qt_trak *trak, uint8_t *trak_atom) {
836   uint8_t *atom;
837   int j;
838   unsigned int atomsize;
839   qt_error last_error = QT_OK;
840 
841   static const uint32_t types_trak[] = {
842     VMHD_ATOM, SMHD_ATOM, TKHD_ATOM, ELST_ATOM,
843     MDHD_ATOM, STSD_ATOM, STSZ_ATOM, STSS_ATOM,
844     STCO_ATOM, CO64_ATOM, STSC_ATOM, STTS_ATOM,
845     CTTS_ATOM, STZ2_ATOM, 0};
846   unsigned int sizes[14];
847   uint8_t *atoms[14];
848 
849   /* initialize trak structure */
850 #ifdef HAVE_ZERO_SAFE_MEM
851   memset (trak, 0, sizeof (*trak));
852 #else
853   trak->edit_list_count = 0;
854   trak->edit_list_table = NULL;
855   trak->chunk_offset_count = 0;
856   trak->chunk_offset_table32 = NULL;
857   trak->chunk_offset_table64 = NULL;
858   trak->samples = 0;
859   trak->sample_size = 0;
860   trak->sample_size_count = 0;
861   trak->sample_size_bytes = 0;
862   trak->sample_size_shift = 0;
863   trak->sample_size_table = NULL;
864   trak->sync_sample_count = 0;
865   trak->sync_sample_table = NULL;
866   trak->keyframes_list = NULL;
867   trak->keyframes_size = 0;
868   trak->keyframes_used = 0;
869   trak->sample_to_chunk_count = 0;
870   trak->sample_to_chunk_table = NULL;
871   trak->time_to_sample_count = 0;
872   trak->time_to_sample_table = NULL;
873   trak->timeoffs_to_sample_count = 0;
874   trak->timeoffs_to_sample_table = NULL;
875   trak->frames = NULL;
876   trak->frame_count = 0;
877   trak->current_frame = 0;
878   trak->flags = 0;
879   trak->stsd_atoms_count = 0;
880   trak->stsd_atoms = NULL;
881 #endif
882   trak->id = -1;
883   trak->timescale = 1;
884   trak->delay_index = -1;
885 
886   /* default type */
887   trak->type = MEDIA_OTHER;
888 
889   /* search for media type atoms */
890   atom_scan (trak_atom, 5, types_trak, atoms, sizes);
891 
892   if (atoms[0]) /* VMHD_ATOM */
893     trak->type = MEDIA_VIDEO;
894   else if (atoms[1]) /* SMHD_ATOM */
895     trak->type = MEDIA_AUDIO;
896 
897   debug_atom_load("  qt: parsing %s trak atom\n",
898     (trak->type == MEDIA_VIDEO) ? "video" :
899       (trak->type == MEDIA_AUDIO) ? "audio" : "other");
900 
901   /* search for the useful atoms */
902   atom     = atoms[2]; /* TKHD_ATOM */
903   atomsize = sizes[2];
904   if (atomsize >= 12) {
905     trak->flags = _X_BE_24(&atom[9]);
906     if (atom[8] == 1) {
907       if (atomsize >= 32)
908         trak->id = _X_BE_32 (&atom[28]);
909     } else {
910       if (atomsize >= 24)
911         trak->id = _X_BE_32 (&atom[20]);
912     }
913   }
914 
915   atom     = atoms[3]; /* ELST_ATOM */
916   atomsize = sizes[3];
917   if (atomsize >= 16) {
918     trak->edit_list_count = _X_BE_32 (&atom[12]);
919     debug_atom_load ("    qt elst atom (edit list atom): %d entries\n", trak->edit_list_count);
920     if (atom[8] == 1) {
921       unsigned int j;
922       if (trak->edit_list_count > (atomsize - 16) / 20)
923         trak->edit_list_count = (atomsize - 16) / 20;
924       trak->edit_list_table = calloc (trak->edit_list_count + 1, sizeof (edit_list_table_t));
925       if (!trak->edit_list_table) {
926         last_error = QT_NO_MEMORY;
927         goto free_trak;
928       }
929       for (j = 0; j < trak->edit_list_count; j++) {
930         trak->edit_list_table[j].track_duration = _X_BE_64 (&atom[16 + j * 20 + 0]);
931         trak->edit_list_table[j].media_time     = _X_BE_64 (&atom[16 + j * 20 + 8]);
932         debug_atom_load ("      %d: track duration = %"PRId64", media time = %"PRId64"\n",
933           j, trak->edit_list_table[j].track_duration, trak->edit_list_table[j].media_time);
934       }
935     } else {
936       unsigned int j;
937       if (trak->edit_list_count > (atomsize - 16) / 12)
938         trak->edit_list_count = (atomsize - 16) / 12;
939       /* dont bail on zero items */
940       trak->edit_list_table = calloc (trak->edit_list_count + 1, sizeof (edit_list_table_t));
941       if (!trak->edit_list_table) {
942         last_error = QT_NO_MEMORY;
943         goto free_trak;
944       }
945       /* load the edit list table */
946       for (j = 0; j < trak->edit_list_count; j++) {
947         trak->edit_list_table[j].track_duration = _X_BE_32 (&atom[16 + j * 12 + 0]);
948         trak->edit_list_table[j].media_time     = _X_BE_32 (&atom[16 + j * 12 + 4]);
949         if (trak->edit_list_table[j].media_time == 0xffffffff)
950           trak->edit_list_table[j].media_time = -1ll;
951         debug_atom_load ("      %d: track duration = %"PRId64", media time = %"PRId64"\n",
952           j, trak->edit_list_table[j].track_duration, trak->edit_list_table[j].media_time);
953       }
954     }
955   }
956 
957   atom     = atoms[4]; /* MDHD_ATOM */
958   atomsize = sizes[4];
959   if (atomsize >= 12) {
960     const int version = atom[8];
961     debug_atom_load ("demux_qt: mdhd atom\n");
962     if (version == 0) {
963       if (atomsize >= 30) {
964         trak->timescale = _X_BE_32 (&atom[20]) & 0x7fffffff;
965         trak->lang      = _X_BE_16 (&atom[28]);
966       }
967     } else if (version == 1) {
968       if (atomsize >= 42) {
969         trak->timescale = _X_BE_32 (&atom[28]) & 0x7fffffff;
970         trak->lang      = _X_BE_16 (&atom[40]);
971       }
972     }
973   }
974   if (trak->timescale == 0)
975     trak->timescale = 1;
976   scale_int_init (&trak->si, 90000, trak->timescale);
977 
978   atom     = atoms[5]; /* STSD_ATOM */
979   atomsize = sizes[5];
980   if (atomsize >= 16) {
981     uint8_t *item;
982     unsigned int k;
983     debug_atom_load ("demux_qt: stsd atom\n");
984     /* Allocate space for our prop array, plus a copy of the STSD atom.
985      * It is usually small (< 200 bytes).
986      * All decoder config pointers will use that buf, no need to allocate separately. */
987     k = _X_BE_32 (&atom[12]);
988     if (!k) {
989       last_error = QT_HEADER_TROUBLE;
990       goto free_trak;
991     }
992     /* safety */
993     if (k > 32)
994       k = 32;
995     item = malloc (k * sizeof (properties_t) + atomsize);
996     if (!item) {
997       last_error = QT_NO_MEMORY;
998       goto free_trak;
999     }
1000     memset (item, 0, k * sizeof (properties_t));
1001     trak->stsd_atoms = (properties_t *)item;
1002     trak->stsd_atoms_count = k;
1003     item += k * sizeof (properties_t);
1004     memcpy (item, atom, atomsize);
1005     atomsize -= 16;
1006     item += 16;
1007     /* use first properties atom for now */
1008     trak->properties = trak->stsd_atoms;
1009 
1010     k = 0;
1011     while (k < trak->stsd_atoms_count) {
1012       static const uint32_t stsd_types[] = {ESDS_ATOM, AVCC_ATOM, HVCC_ATOM, 0};
1013       uint32_t stsd_sizes[3];
1014       uint8_t *stsd_atoms[3];
1015       properties_t *p;
1016       uint32_t isize;
1017 
1018       if (atomsize < 8)
1019         break;
1020       p = trak->stsd_atoms + k;
1021       isize = _X_BE_32 (item);
1022       if (!isize)
1023         isize = atomsize;
1024       if (isize < 8) {
1025         last_error = QT_HEADER_TROUBLE;
1026         goto free_trak;
1027       }
1028       if (isize > atomsize)
1029         isize = atomsize;
1030       p->properties_atom      = item;
1031       p->properties_atom_size = isize;
1032 #ifndef HAVE_ZERO_SAFE_MEM
1033       p->decoder_config_len   = 0;
1034       p->decoder_config       = NULL;
1035 #endif
1036       p->media_id             = k + 1;
1037       p->codec_fourcc         = _X_ME_32 (item + 4);
1038       _x_tag32_me2str (p->codec_str, p->codec_fourcc);
1039       p->object_type_id = -1;
1040 
1041       /* look for generic decoder config */
1042       find_embedded_atoms (item, stsd_types, stsd_atoms, stsd_sizes);
1043       do {
1044         unsigned int j, subsize = stsd_sizes[0], len;
1045         uint8_t *subatom = stsd_atoms[0]; /* ESDS_ATOM */
1046         if (subsize < 13)
1047           break;
1048         debug_atom_load ("    qt/mpeg-4 esds atom\n");
1049         j = 12;
1050         if (subatom[j++] == 0x03) {
1051           j += mp4_read_descr_len (subatom + j, &len);
1052           j++;
1053         }
1054         j += 2;
1055         if (subatom[j++] != 0x04)
1056           break;
1057         j += mp4_read_descr_len (subatom + j, &len);
1058         p->object_type_id = subatom[j++];
1059         debug_atom_load ("      object type id is %d\n", p->object_type_id);
1060         j += 12;
1061         if (subatom[j++] != 0x05)
1062           break;
1063         j += mp4_read_descr_len (subatom + j, &len);
1064         debug_atom_load ("      decoder config is %d (0x%X) bytes long\n", len, len);
1065         if (len > isize - j)
1066           len = isize - j;
1067         p->decoder_config = subatom + j;
1068         p->decoder_config_len = len;
1069       } while (0);
1070 
1071       if (trak->type == MEDIA_VIDEO) do {
1072         /* for palette traversal */
1073         int color_depth;
1074         int color_greyscale;
1075 
1076         if (isize < 0x24)
1077           break;
1078 
1079         /* look for decoder config */
1080         do {
1081           if (stsd_sizes[1] > 8) { /* AVCC_ATOM */
1082             debug_atom_load ("    avcC atom\n");
1083             p->decoder_config_len = stsd_sizes[1] - 8;
1084             p->decoder_config = stsd_atoms[1] + 8;
1085             break;
1086           }
1087           if (stsd_sizes[2] > 8) { /* HVCC_ATOM */
1088             debug_atom_load ("    hvcC atom\n");
1089             p->decoder_config_len = stsd_sizes[2] - 8;
1090             p->decoder_config = stsd_atoms[2] + 8;
1091             break;
1092           }
1093         } while (0);
1094 
1095         /* initialize to sane values */
1096         p->s.video.width  = _X_BE_16 (item + 0x20);
1097         p->s.video.height = _X_BE_16 (item + 0x22);
1098         if (!p->s.video.width)
1099           p->s.video.height = 0;
1100         else if (!p->s.video.height)
1101           p->s.video.width = 0;
1102         p->s.video.depth = 0;
1103         /* assume no palette at first */
1104         p->s.video.palette_count = 0;
1105         /* fetch video parameters */
1106 
1107         k++;
1108         debug_atom_load("    video properties atom #%d [%s], %d x %d\n",
1109           k, p->codec_str, p->s.video.width, p->s.video.height);
1110 
1111         if (isize < 0x54)
1112           break;
1113 
1114         /* figure out the palette situation */
1115         color_depth = item[0x53];
1116         p->s.video.depth = color_depth;
1117         color_greyscale = color_depth & 0x20;
1118         color_depth &= 0x1F;
1119 
1120         /* if the depth is 2, 4, or 8 bpp, file is palettized */
1121         if ((isize >= 0x56) && ((color_depth == 2) || (color_depth == 4) || (color_depth == 8))) {
1122           int color_flag;
1123           color_flag = _X_BE_16 (item + 0x54);
1124 
1125           if (color_greyscale) {
1126 
1127             int color_index, color_dec;
1128             p->s.video.palette_count = 1 << color_depth;
1129 
1130             /* compute the greyscale palette */
1131             color_index = 255;
1132             color_dec = 256 / (p->s.video.palette_count - 1);
1133             for (j = 0; j < p->s.video.palette_count; j++) {
1134               p->s.video.palette[j].r = color_index;
1135               p->s.video.palette[j].g = color_index;
1136               p->s.video.palette[j].b = color_index;
1137               color_index -= color_dec;
1138               if (color_index < 0)
1139                 color_index = 0;
1140             }
1141 
1142           } else if (color_flag & 0x08) {
1143 
1144             const uint8_t *color_table;
1145             /* if flag bit 3 is set, load the default palette */
1146             p->s.video.palette_count = 1 << color_depth;
1147 
1148             if (color_depth == 2)
1149               color_table = qt_default_palette_4;
1150             else if (color_depth == 4)
1151               color_table = qt_default_palette_16;
1152             else
1153               color_table = qt_default_palette_256;
1154 
1155             for (j = 0; j < p->s.video.palette_count; j++) {
1156               p->s.video.palette[j].r = color_table[j * 4 + 0];
1157               p->s.video.palette[j].g = color_table[j * 4 + 1];
1158               p->s.video.palette[j].b = color_table[j * 4 + 2];
1159             }
1160 
1161           } else {
1162 
1163             /* load the palette from the file */
1164             if (isize >= 0x5e) {
1165               int color_start = _X_BE_32 (item + 0x56);
1166               int color_count = _X_BE_16 (item + 0x5a);
1167               int color_end   = _X_BE_16 (item + 0x5c);
1168               color_end++;
1169               if (color_end > PALETTE_COUNT)
1170                 color_end = PALETTE_COUNT;
1171               p->s.video.palette_count = color_end;
1172               if (color_end > (int)((isize - 0x5e) >> 3))
1173                 color_end = (isize - 0x5e) >> 3;
1174               if (color_count & 0x8000) {
1175                 int j;
1176                 for (j = color_start; j < color_end; j++) {
1177                   p->s.video.palette[j].r = item[0x5e + j * 8 + 2];
1178                   p->s.video.palette[j].g = item[0x5e + j * 8 + 4];
1179                   p->s.video.palette[j].b = item[0x5e + j * 8 + 6];
1180                 }
1181               } else {
1182                 int j;
1183                 for (j = color_start; j < color_end; j++) {
1184                   int color_index = _X_BE_16 (item + 0x5e + j * 8);
1185                   if (color_index < p->s.video.palette_count) {
1186                     p->s.video.palette[color_index].r = item[0x5e + j * 8 + 2];
1187                     p->s.video.palette[color_index].g = item[0x5e + j * 8 + 4];
1188                     p->s.video.palette[color_index].b = item[0x5e + j * 8 + 6];
1189                   }
1190                 }
1191               }
1192             }
1193           }
1194         }
1195 #ifdef DEBUG_ATOM_LOAD
1196         debug_atom_load("      %d RGB colours\n",
1197           p->s.video.palette_count);
1198         for (j = 0; j < p->s.video.palette_count; j++)
1199           debug_atom_load("        %d: %3d %3d %3d\n",
1200             j,
1201             p->s.video.palette[j].r,
1202             p->s.video.palette[j].g,
1203             p->s.video.palette[j].b);
1204 #endif
1205       } while (0);
1206 
1207       else if (trak->type == MEDIA_AUDIO) do {
1208 
1209 #ifndef HAVE_ZERO_SAFE_MEM
1210         p->s.audio.wave_size = 0;
1211         p->s.audio.wave = NULL;
1212 #endif
1213         if (isize < 0x22)
1214           break;
1215 
1216         /* fetch audio parameters, assume uncompressed */
1217         p->s.audio.sample_rate        = _X_BE_16 (item + 0x20);
1218         p->s.audio.channels           =
1219         p->s.audio.samples_per_frame  =
1220         p->s.audio.samples_per_packet = item[0x19];
1221         p->s.audio.bits               = item[0x1b];
1222         p->s.audio.bytes_per_sample   =
1223         p->s.audio.bytes_per_packet   = p->s.audio.bits / 8;
1224         p->s.audio.bytes_per_frame    = p->s.audio.bytes_per_sample * p->s.audio.samples_per_frame;
1225 
1226         /* 24-bit audio doesn't always declare itself properly, and can be big- or little-endian */
1227         if ((p->codec_fourcc == IN24_FOURCC) && (isize >= 0x52)) {
1228           p->s.audio.bits = 24;
1229           if (_X_BE_32 (item + 0x4c) == ENDA_ATOM && item[0x51])
1230             p->codec_fourcc = NI42_FOURCC;
1231         }
1232         p->codec_buftype = _x_formattag_to_buf_audio (p->codec_fourcc);
1233 
1234         /* see if the trak deserves a promotion to VBR */
1235         p->s.audio.vbr = (_X_BE_16 (item + 0x1c) == 0xFFFE) ? 1 : 0;
1236         /* in mp4 files the audio fourcc is always 'mp4a' - the codec is
1237          * specified by the object type id field in the esds atom */
1238         if (p->codec_fourcc == MP4A_FOURCC) {
1239           p->s.audio.vbr = 1;
1240           if (p->object_type_id == 221) {
1241             p->codec_buftype = BUF_AUDIO_VORBIS;
1242             memcpy (p->codec_str, "vorbis", 7);
1243           } else if (p->object_type_id == 107) {
1244             p->codec_buftype = BUF_AUDIO_MPEG;
1245             memcpy (p->codec_str, "mp3", 4);
1246           }
1247         }
1248         /* if this is MP4 audio, mark the trak as VBR */
1249         else if ((p->codec_fourcc == SAMR_FOURCC) ||
1250                  (p->codec_fourcc == AC_3_FOURCC) ||
1251                  (p->codec_fourcc == EAC3_FOURCC) ||
1252                  (p->codec_fourcc == QCLP_FOURCC)) {
1253           p->s.audio.vbr = 1;
1254         }
1255 
1256         else if (p->codec_fourcc == ALAC_FOURCC) {
1257           p->s.audio.vbr = 1;
1258           if (isize >= 0x24 + 36) {
1259             /* further, FFmpeg's ALAC decoder requires 36 out-of-band bytes */
1260             p->decoder_config_len = 36;
1261             p->decoder_config = item + 0x24;
1262           }
1263         }
1264 
1265         /* special case time: A lot of CBR audio codecs stored in the
1266          * early days lacked the extra header; compensate */
1267         else if (p->codec_fourcc == IMA4_FOURCC) {
1268           p->s.audio.samples_per_packet = 64;
1269           p->s.audio.bytes_per_packet   = 34;
1270           p->s.audio.bytes_per_frame    = 34 * p->s.audio.channels;
1271           p->s.audio.bytes_per_sample   = 2;
1272           p->s.audio.samples_per_frame  = 64 * p->s.audio.channels;
1273         } else if (p->codec_fourcc == MAC3_FOURCC) {
1274           p->s.audio.samples_per_packet = 3;
1275           p->s.audio.bytes_per_packet   = 1;
1276           p->s.audio.bytes_per_frame    = 1 * p->s.audio.channels;
1277           p->s.audio.bytes_per_sample   = 1;
1278           p->s.audio.samples_per_frame  = 3 * p->s.audio.channels;
1279         } else if (p->codec_fourcc == MAC6_FOURCC) {
1280           p->s.audio.samples_per_packet = 6;
1281           p->s.audio.bytes_per_packet   = 1;
1282           p->s.audio.bytes_per_frame    = 1 * p->s.audio.channels;
1283           p->s.audio.bytes_per_sample   = 1;
1284           p->s.audio.samples_per_frame  = 6 * p->s.audio.channels;
1285         } else if (p->codec_fourcc == ALAW_FOURCC) {
1286           p->s.audio.samples_per_packet = 1;
1287           p->s.audio.bytes_per_packet   = 1;
1288           p->s.audio.bytes_per_frame    = 1 * p->s.audio.channels;
1289           p->s.audio.bytes_per_sample   = 2;
1290           p->s.audio.samples_per_frame  = 2 * p->s.audio.channels;
1291         } else if (p->codec_fourcc == ULAW_FOURCC) {
1292           p->s.audio.samples_per_packet = 1;
1293           p->s.audio.bytes_per_packet   = 1;
1294           p->s.audio.bytes_per_frame    = 1 * p->s.audio.channels;
1295           p->s.audio.bytes_per_sample   = 2;
1296           p->s.audio.samples_per_frame  = 2 * p->s.audio.channels;
1297         }
1298 
1299         else if (p->codec_fourcc == DRMS_FOURCC) {
1300           last_error = QT_DRM_NOT_SUPPORTED;
1301           goto free_trak;
1302         }
1303 
1304         /* it's time to dig a little deeper to determine the real audio
1305          * properties; if a the stsd compressor atom has 0x24 bytes, it
1306          * appears to be a handler for uncompressed data; if there are an
1307          * extra 0x10 bytes, there are some more useful decoding params;
1308          * further, do not do load these parameters if the audio is just
1309          * PCM ('raw ', 'twos', 'sowt' or 'in24') */
1310         if ((isize >= 0x34) &&
1311             (p->codec_fourcc != AC_3_FOURCC) &&
1312             (p->codec_fourcc != EAC3_FOURCC) &&
1313             (p->codec_fourcc != TWOS_FOURCC) &&
1314             (p->codec_fourcc != SOWT_FOURCC) &&
1315             (p->codec_fourcc != RAW_FOURCC)  &&
1316             (p->codec_fourcc != IN24_FOURCC) &&
1317             (p->codec_fourcc != NI42_FOURCC)) {
1318 
1319           if (_X_BE_32 (item + 0x24))
1320             p->s.audio.samples_per_packet = _X_BE_32 (item + 0x24);
1321           if (_X_BE_32 (item + 0x28))
1322             p->s.audio.bytes_per_packet   = _X_BE_32 (item + 0x28);
1323           if (_X_BE_32 (item + 0x2c))
1324             p->s.audio.bytes_per_frame    = _X_BE_32 (item + 0x2c);
1325           if (_X_BE_32 (item + 0x30))
1326             p->s.audio.bytes_per_sample   = _X_BE_32 (item + 0x30);
1327           if (p->s.audio.bytes_per_packet)
1328             p->s.audio.samples_per_frame =
1329               (p->s.audio.bytes_per_frame /
1330                p->s.audio.bytes_per_packet) *
1331                p->s.audio.samples_per_packet;
1332         }
1333 
1334         /* div by 0 safety */
1335         if (!p->s.audio.samples_per_frame)
1336           p->s.audio.samples_per_frame = 1;
1337 
1338         /* check for a MS-style WAVE format header */
1339         if ((isize >= 0x50) &&
1340           (_X_BE_32 (item + 0x38) == WAVE_ATOM) &&
1341           (_X_BE_32 (item + 0x40) == FRMA_ATOM) &&
1342           (_X_ME_32 (item + 0x4c) == p->codec_fourcc)) {
1343           unsigned int wave_size = _X_BE_32 (item + 0x48);
1344 
1345           if ((wave_size >= sizeof (xine_waveformatex) + 8) &&
1346               (isize >= (0x50 + wave_size - 8))) {
1347             wave_size -= 8;
1348             p->s.audio.wave_size = wave_size;
1349             p->s.audio.wave = malloc (wave_size);
1350             if (!p->s.audio.wave) {
1351               last_error = QT_NO_MEMORY;
1352               goto free_trak;
1353             }
1354             memcpy (p->s.audio.wave, item + 0x50, wave_size);
1355             _x_waveformatex_le2me (p->s.audio.wave);
1356           }
1357         }
1358 
1359         k++;
1360         debug_atom_load("    audio properties atom #%d [%s], %d Hz, %d bits, %d channels, %s\n",
1361           k, p->codec_str, p->s.audio.sample_rate, p->s.audio.bits, p->s.audio.channels,
1362           (p->s.audio.vbr) ? "vbr, " : "");
1363         if (isize > 0x28) {
1364           debug_atom_load("      %d samples/packet, %d bytes/packet, %d bytes/frame\n",
1365             p->s.audio.samples_per_packet,
1366             p->s.audio.bytes_per_packet,
1367             p->s.audio.bytes_per_frame);
1368           debug_atom_load("      %d bytes/sample (%d samples/frame)\n",
1369             p->s.audio.bytes_per_sample,
1370             p->s.audio.samples_per_frame);
1371         }
1372 
1373       } while (0);
1374 
1375       else { /* MEDIA_OTHER */
1376         k++;
1377       }
1378 
1379       /* forward to the next atom */
1380       item += isize;
1381       atomsize -= isize;
1382     }
1383     trak->stsd_atoms_count = k;
1384     if (!k)
1385       goto free_trak;
1386   }
1387 
1388   atom     = atoms[6]; /* STSZ_ATOM */
1389   atomsize = sizes[6];
1390   if (atomsize >= 20) {
1391     trak->sample_size       = _X_BE_32(&atom[12]);
1392     /* load table only if sample size is 0 */
1393     /* there may be 0 items + moof fragments later */
1394     if (trak->sample_size == 0) {
1395       trak->sample_size_count = _X_BE_32(&atom[16]);
1396       trak->samples = trak->sample_size_count;
1397       if (trak->sample_size_count > (atomsize - 20) / 4)
1398         trak->sample_size_count = (atomsize - 20) / 4;
1399       debug_atom_load ("    qt stsz atom (sample size atom): sample size = %d, %d entries\n",
1400         trak->sample_size, trak->sample_size_count);
1401       trak->sample_size_table = atom + 20;
1402       trak->sample_size_bytes = 4;
1403       trak->sample_size_shift = 0;
1404     }
1405   } else {
1406     atom     = atoms[13]; /* STZ2_ATOM */
1407     atomsize = sizes[13];
1408     if (atomsize >= 20) {
1409       trak->sample_size_count = _X_BE_32 (&atom[16]);
1410       trak->sample_size_table = atom + 20;
1411       if (atom[15] == 16) {
1412         trak->sample_size_bytes = 2;
1413         trak->sample_size_shift = 16;
1414         if (trak->sample_size_count > (atomsize - 20) / 2)
1415           trak->sample_size_count = (atomsize - 20) / 2;
1416       } else if (atom[15] == 8) {
1417         trak->sample_size_bytes = 1;
1418         trak->sample_size_shift = 24;
1419         if (trak->sample_size_count > (atomsize - 20))
1420           trak->sample_size_count = atomsize - 20;
1421       } else {
1422         /* There is also a 4bit mode but i never saw all <= 15 byte frames. */
1423         trak->sample_size_count = 0;
1424         trak->sample_size_table = NULL;
1425       }
1426     }
1427   }
1428 
1429   atom     = atoms[7]; /* STSS_ATOM */
1430   atomsize = sizes[7];
1431   if (atomsize >= 16) {
1432     trak->sync_sample_count = _X_BE_32 (&atom[12]);
1433     if (trak->sync_sample_count > (atomsize - 16) / 4)
1434       trak->sync_sample_count = (atomsize - 16) / 4;
1435     debug_atom_load ("    qt stss atom (sample sync atom): %d sync samples\n",
1436       trak->sync_sample_count);
1437     trak->sync_sample_table = atom + 16;
1438   }
1439 
1440   atom     = atoms[8]; /* STCO_ATOM */
1441   atomsize = sizes[8];
1442   if (atomsize >= 16) {
1443     trak->chunk_offset_count = _X_BE_32 (&atom[12]);
1444     debug_atom_load ("    qt stco atom (32-bit chunk offset atom): %d chunk offsets\n",
1445       trak->chunk_offset_count);
1446     if (trak->chunk_offset_count > (atomsize - 16) / 4)
1447       trak->chunk_offset_count = (atomsize - 16) / 4;
1448     trak->chunk_offset_table32 = atom + 16;
1449   } else {
1450     atom     = atoms[9]; /* CO64_ATOM */
1451     atomsize = sizes[9];
1452     if (atomsize >= 16) {
1453       trak->chunk_offset_count = _X_BE_32 (&atom[12]);
1454       if (trak->chunk_offset_count > (atomsize - 16) / 8)
1455         trak->chunk_offset_count = (atomsize - 16) / 8;
1456       debug_atom_load ("    qt co64 atom (64-bit chunk offset atom): %d chunk offsets\n",
1457         trak->chunk_offset_count);
1458       trak->chunk_offset_table64 = atom + 16;
1459     }
1460   }
1461 
1462   atom     = atoms[10]; /* STSC_ATOM */
1463   atomsize = sizes[10];
1464   if (atomsize >= 16) {
1465     unsigned int j;
1466     trak->sample_to_chunk_count = _X_BE_32 (&atom[12]);
1467     if (trak->sample_to_chunk_count > (atomsize - 16) / 12)
1468       trak->sample_to_chunk_count = (atomsize - 16) / 12;
1469     debug_atom_load ("    qt stsc atom (sample-to-chunk atom): %d entries\n",
1470       trak->sample_to_chunk_count);
1471     trak->sample_to_chunk_table = calloc (trak->sample_to_chunk_count + 1, sizeof (sample_to_chunk_table_t));
1472     if (!trak->sample_to_chunk_table) {
1473       last_error = QT_NO_MEMORY;
1474       goto free_trak;
1475     }
1476     /* load the sample to chunk table */
1477     for (j = 0; j < trak->sample_to_chunk_count; j++) {
1478       trak->sample_to_chunk_table[j].first_chunk       = _X_BE_32 (&atom[16 + j * 12 + 0]);
1479       trak->sample_to_chunk_table[j].samples_per_chunk = _X_BE_32 (&atom[16 + j * 12 + 4]);
1480       trak->sample_to_chunk_table[j].media_id          = _X_BE_32 (&atom[16 + j * 12 + 8]);
1481       debug_atom_load ("      %d: %d samples/chunk starting at chunk %d (%d) for media id %d\n",
1482         j, trak->sample_to_chunk_table[j].samples_per_chunk,
1483         trak->sample_to_chunk_table[j].first_chunk,
1484         trak->sample_to_chunk_table[j].first_chunk - 1,
1485         trak->sample_to_chunk_table[j].media_id);
1486     }
1487   }
1488 
1489   atom     = atoms[11]; /* STTS_ATOM */
1490   atomsize = sizes[11];
1491   if (atomsize >= 16) {
1492     trak->time_to_sample_count = _X_BE_32 (&atom[12]);
1493     debug_atom_load ("    qt stts atom (time-to-sample atom): %d entries\n",
1494       trak->time_to_sample_count);
1495     if (trak->time_to_sample_count > (atomsize - 16) / 8)
1496       trak->time_to_sample_count = (atomsize - 16) / 8;
1497     trak->time_to_sample_table = atom + 16;
1498   }
1499 
1500   atom     = atoms[12]; /* CTTS_ATOM */
1501   atomsize = sizes[12];
1502   if (atomsize >= 16) {
1503     /* TJ. this has the same format as stts. If present, duration here
1504        means (pts - dts), while the corresponding stts defines dts. */
1505     trak->timeoffs_to_sample_count = _X_BE_32 (&atom[12]);
1506     debug_atom_load ("    qt ctts atom (timeoffset-to-sample atom): %d entries\n",
1507       trak->timeoffs_to_sample_count);
1508     if (trak->timeoffs_to_sample_count > (atomsize - 16) / 8)
1509       trak->timeoffs_to_sample_count = (atomsize - 16) / 8;
1510     trak->timeoffs_to_sample_table = atom + 16;
1511   }
1512 
1513   return QT_OK;
1514 
1515   /* jump here to make sure everything is free'd and avoid leaking memory */
1516 free_trak:
1517   free(trak->edit_list_table);
1518   free(trak->sample_to_chunk_table);
1519   free(trak->stsd_atoms);
1520   return last_error;
1521 }
1522 
1523 /* Traverse through a reference atom and extract the URL and data rate. */
parse_reference_atom(demux_qt_t * this,uint8_t * ref_atom,char * base_mrl)1524 static qt_error parse_reference_atom (demux_qt_t *this, uint8_t *ref_atom, char *base_mrl) {
1525 
1526   unsigned int sizes[4];
1527   reference_t ref;
1528   uint8_t *atoms[4] = { NULL, NULL, NULL, NULL };
1529   static const uint32_t types_ref[] = { URL__ATOM, RMDR_ATOM, QTIM_ATOM, 0 };
1530   /* initialize reference atom */
1531   ref.url = NULL;
1532   ref.data_rate = 0;
1533   ref.qtim_version = 0;
1534 
1535   atom_scan (ref_atom, 4, types_ref, atoms, sizes);
1536 
1537   if (sizes[0] > 12) {
1538     size_t string_size = _X_BE_32 (&atoms[0][8]);
1539     size_t url_offset = 0;
1540     int http = 0;
1541 
1542     if (12 + string_size > sizes[0])
1543       return QT_NOT_A_VALID_FILE;
1544 
1545     /* if the URL starts with "http://", copy it */
1546     if (string_size >= 7 &&
1547         memcmp (&atoms[0][12], "http://", 7) &&
1548         memcmp (&atoms[0][12], "rtsp://", 7) &&
1549         base_mrl) {
1550       /* We need a "qt" prefix hack for Apple trailers */
1551       http = !strncasecmp (base_mrl, "http://", 7);
1552       url_offset = strlen(base_mrl) + 2 * http;
1553     }
1554     if (url_offset >= 0x80000000)
1555       return QT_NOT_A_VALID_FILE;
1556 
1557     /* otherwise, append relative URL to base MRL */
1558     string_size += url_offset;
1559     ref.url = calloc (1, string_size + 1);
1560     if (url_offset)
1561       sprintf (ref.url, "%s%s", http ? "qt" : "", base_mrl);
1562     memcpy (ref.url + url_offset, &atoms[0][12], _X_BE_32 (&atoms[0][8]));
1563     ref.url[string_size] = '\0';
1564     debug_atom_load ("    qt rdrf URL reference:\n      %s\n", ref.url);
1565   }
1566 
1567   if (sizes[1] >= 16) {
1568     /* load the data rate */
1569     ref.data_rate = _X_BE_32 (&atoms[1][12]);
1570     ref.data_rate *= 10;
1571     debug_atom_load ("    qt rmdr data rate = %"PRId64"\n", ref.data_rate);
1572   }
1573 
1574   if (sizes[2] >= 10) {
1575     ref.qtim_version = _X_BE_16 (&atoms[2][8]);
1576     debug_atom_load ("      qtim version = %04X\n", ref.qtim_version);
1577   }
1578 
1579   if (ref.url) {
1580     this->qt.references = realloc (this->qt.references, (this->qt.reference_count + 1) * sizeof (reference_t));
1581     if (this->qt.references)
1582       this->qt.references[this->qt.reference_count++] = ref;
1583   }
1584 
1585   return QT_OK;
1586 }
1587 
qt_normpos_init(demux_qt_t * this)1588 static void qt_normpos_init (demux_qt_t *this) {
1589   uint32_t n = this->qt.msecs, dbits = 32, sbits;
1590   while (!(n & 0x80000000))
1591     dbits--, n <<= 1;
1592   /* _mul setup limit:    sbits <= 64 - 16
1593    * mbits = 16 + sbits - dbits;
1594    * _mul usage limit:    mbits <= 64 - dbits
1595    *                      16 + sbits - dbits <= 64 - dbits
1596    *                      sbits <= 48
1597    * usage simplifiction: mbits <= 32
1598    *                      16 + sbits - dbits <= 32
1599    *                      sbits <= 16 + dbits
1600    */
1601   sbits = 16 + dbits - 1; /* safety */
1602   this->qt.normpos_shift = sbits;
1603   this->qt.normpos_mul   = ((uint64_t)0xffff << sbits) / (uint32_t)this->qt.msecs;
1604 }
1605 
qt_msec_2_normpos(demux_qt_t * this,int32_t msec)1606 static int32_t qt_msec_2_normpos (demux_qt_t *this, int32_t msec) {
1607   return ((uint64_t)msec * this->qt.normpos_mul) >> this->qt.normpos_shift;
1608 }
1609 
qt_pts_2_msecs(int64_t pts)1610 static int32_t qt_pts_2_msecs (int64_t pts) {
1611 #ifdef ARCH_X86_32
1612   return (pts * (int32_t)((((uint32_t)1 << 31) + 22) / 45)) >> 32;
1613 #else
1614   return pts / 90;
1615 #endif
1616 }
1617 
1618 #define KEYFRAMES_SIZE 1024
qt_keyframes_size(qt_trak * trak,uint32_t n)1619 static void qt_keyframes_size (qt_trak *trak, uint32_t n) {
1620   xine_keyframes_entry_t *e = trak->keyframes_list;
1621   n = (n + KEYFRAMES_SIZE - 1) & ~(KEYFRAMES_SIZE - 1);
1622   if (n > trak->keyframes_size) {
1623     e = realloc (e, n * sizeof (*e));
1624     if (!e)
1625       return;
1626     trak->keyframes_list = e;
1627     trak->keyframes_size = n;
1628   }
1629 }
1630 
qt_keyframes_simple_add(qt_trak * trak,qt_frame * f)1631 static void qt_keyframes_simple_add (qt_trak *trak, qt_frame *f) {
1632   if (trak->keyframes_used < trak->keyframes_size) {
1633     xine_keyframes_entry_t *e = trak->keyframes_list;
1634     e += trak->keyframes_used++;
1635     e->msecs = qt_pts_2_msecs (f->pts);
1636   }
1637 }
1638 
build_frame_table(qt_trak * trak,unsigned int global_timescale)1639 static qt_error build_frame_table (qt_trak *trak, unsigned int global_timescale) {
1640 
1641   if ((trak->type != MEDIA_VIDEO) &&
1642       (trak->type != MEDIA_AUDIO))
1643     return QT_OK;
1644 
1645   /* Simplified ptsoffs conversion, no rounding error cumulation. */
1646   trak->ptsoffs_mul = 90000 * (1 << 12) / trak->timescale;
1647 
1648   /* Sample to chunk sanity test. */
1649   if (trak->sample_to_chunk_count) {
1650     unsigned int i;
1651     sample_to_chunk_table_t *e = trak->sample_to_chunk_table + trak->sample_to_chunk_count;
1652     /* add convenience tail, table is large enough. */
1653     e[0].first_chunk = trak->chunk_offset_count + 1;
1654     for (i = trak->sample_to_chunk_count; i; i--) {
1655       e--;
1656       if (e[0].first_chunk == 0)
1657         e[0].first_chunk = 1;
1658       if (e[0].first_chunk > e[1].first_chunk)
1659         e[0].first_chunk = e[1].first_chunk;
1660       if (e[0].media_id > trak->stsd_atoms_count) {
1661         printf ("QT: help! media ID out of range! (%u > %u)\n",
1662           e[0].media_id, trak->stsd_atoms_count);
1663         e[0].media_id = 0;
1664       }
1665     }
1666   }
1667 
1668   /* AUDIO and OTHER frame types follow the same rules; VIDEO and vbr audio
1669    * frame types follow a different set */
1670   if ((trak->type == MEDIA_VIDEO) ||
1671       ((trak->type == MEDIA_AUDIO) && (trak->properties->s.audio.vbr))) {
1672     /* maintain counters for each of the subtracks within the trak */
1673     int *media_id_counts = NULL;
1674     qt_frame *frame;
1675     unsigned int samples_per_frame;
1676 
1677     /* test for legacy compressed audio */
1678     if ((trak->type == MEDIA_AUDIO) &&
1679         (trak->properties->s.audio.samples_per_frame > 1) &&
1680         (trak->time_to_sample_count == 1) &&
1681         (_X_BE_32 (&trak->time_to_sample_table[4]) == 1))
1682       /* Oh dear. Old style. */
1683       samples_per_frame = trak->properties->s.audio.samples_per_frame;
1684     else
1685       samples_per_frame = 1;
1686 
1687     /* figure out # of samples */
1688     trak->frame_count = 0;
1689     {
1690       unsigned int u;
1691       int n = trak->chunk_offset_count;
1692       if (!n)
1693         return QT_OK;
1694       if (!trak->sample_to_chunk_count)
1695         return QT_OK;
1696       for (u = 0; u + 1 < trak->sample_to_chunk_count; u++) {
1697         int j, s = trak->sample_to_chunk_table[u].samples_per_chunk;
1698         if ((samples_per_frame != 1) && (s % samples_per_frame))
1699           return QT_OK; /* unaligned chunk, should not happen */
1700         j = trak->sample_to_chunk_table[u + 1].first_chunk -
1701             trak->sample_to_chunk_table[u].first_chunk;
1702         if (j > n)
1703           j = n;
1704         trak->frame_count += j * s;
1705         n -= j;
1706       }
1707       trak->frame_count += n * trak->sample_to_chunk_table[u].samples_per_chunk;
1708     }
1709     trak->frame_count = (trak->frame_count + samples_per_frame - 1) / samples_per_frame;
1710     if (!trak->frame_count)
1711       return QT_OK;
1712 
1713     /* 1 more for convenient end marker. */
1714     trak->frames = malloc ((trak->frame_count + 1) * sizeof (qt_frame));
1715     if (!trak->frames)
1716       return QT_NO_MEMORY;
1717     frame = trak->frames;
1718     frame->pts = 0;
1719     trak->current_frame = 0;
1720 
1721     media_id_counts = calloc (trak->stsd_atoms_count + 1, sizeof (int));
1722     if (!media_id_counts) {
1723       free (trak->frames);
1724       trak->frames = NULL;
1725       return QT_NO_MEMORY;
1726     }
1727 
1728     {
1729       unsigned int u;
1730       /* initialize more accounting variables */
1731       /* file position */
1732       const uint8_t *o      = trak->chunk_offset_table32 ?
1733                               trak->chunk_offset_table32 : trak->chunk_offset_table64;
1734       uint64_t offset_value = 0;
1735       /* size */
1736       const uint8_t *s    = trak->sample_size_table;
1737       uint32_t size_left  = trak->sample_size_count;
1738       uint32_t size_value = trak->sample_size;
1739       /* sample duration */
1740       const uint8_t *p            = trak->time_to_sample_table;
1741       uint32_t duration_left      = trak->time_to_sample_count;
1742       uint32_t duration_countdown = 0;
1743       uint32_t duration_value     = 1;
1744       int64_t  pts_value          = 0;
1745       /* used by reordered video */
1746       const uint8_t *q           = trak->timeoffs_to_sample_table;
1747       uint32_t ptsoffs_left      = trak->timeoffs_to_sample_count;
1748       uint32_t ptsoffs_countdown = 0;
1749       int32_t  ptsoffs_value     = 0;
1750 
1751       if (samples_per_frame != 1) {
1752         /* Old style demuxing. Tweak our frame builder.
1753          * Treating whole chunks as frames would be faster, but unfortunately
1754          * some ffmpeg decoders dont like multiple frames in one go. */
1755         size_left = 0;
1756         size_value = trak->properties->s.audio.bytes_per_frame;
1757         duration_left = 0;
1758         duration_value = samples_per_frame;
1759         ptsoffs_left = 0;
1760         trak->samples = _X_BE_32 (trak->time_to_sample_table) / samples_per_frame;
1761       }
1762 
1763       /* iterate through each start chunk in the stsc table */
1764       for (u = 0; u < trak->sample_to_chunk_count; u++) {
1765         unsigned int keyframe_default = trak->sync_sample_table ? 0 : 1;
1766         unsigned int media_id         = trak->sample_to_chunk_table[u].media_id;
1767         int _samples_per_chunk        = trak->sample_to_chunk_table[u].samples_per_chunk;
1768         unsigned int sn;
1769         /* Iterate from the first chunk of the current table entry to
1770          * the first chunk of the next table entry.
1771          * Entries are 1 based.
1772          * If the first chunk is in the last table entry, iterate to the
1773          * final chunk number (the number of offsets in stco table). */
1774         sn = trak->sample_to_chunk_table[u + 1].first_chunk
1775            - trak->sample_to_chunk_table[u].first_chunk;
1776         /* iterate through each sample in a chunk */
1777         while (sn--) {
1778 
1779           int samples_per_chunk = _samples_per_chunk;
1780 
1781           if (trak->chunk_offset_table32)
1782             offset_value = _X_BE_32 (o), o += 4;
1783           else
1784             offset_value = _X_BE_64 (o), o += 8;
1785 
1786           while (samples_per_chunk > 0) {
1787 
1788             /* figure out the offset and size.
1789              * far most files use 4 byte sizes, optimize for them.
1790              * for others, moov buffer is safety padded. */
1791             if (size_left) {
1792               size_value = _X_BE_32 (s);
1793               s += trak->sample_size_bytes;
1794               size_value >>= trak->sample_size_shift;
1795               size_left--;
1796             }
1797             frame->_ffs.offset = offset_value;
1798             frame->size = size_value;
1799             offset_value += size_value;
1800 
1801             /* media id accounting */
1802             QTF_MEDIA_ID(frame[0]) = media_id;
1803             media_id_counts[media_id] += 1;
1804 
1805             /* if there is no stss (sample sync) table, make all of the frames
1806              * keyframes; otherwise, clear the keyframe bits for now */
1807             QTF_KEYFRAME(frame[0]) = keyframe_default;
1808 
1809             /* figure out the pts situation */
1810             if (!duration_countdown && duration_left) {
1811               duration_countdown = _X_BE_32 (p); p += 4;
1812               duration_value     = _X_BE_32 (p); p += 4;
1813               duration_left--;
1814             }
1815             frame->pts = pts_value;
1816             pts_value += duration_value;
1817             duration_countdown--;
1818 
1819             /* offset pts for reordered video */
1820             if (!ptsoffs_countdown && ptsoffs_left) {
1821               unsigned int v;
1822               ptsoffs_countdown = _X_BE_32 (q); q += 4;
1823               v                 = _X_BE_32 (q); q += 4;
1824               /* TJ. this is 32 bit signed. */
1825               ptsoffs_value = v;
1826               if ((sizeof (int) > 4) && (ptsoffs_value & 0x80000000))
1827                 ptsoffs_value |= ~0xffffffffL;
1828               ptsoffs_left--;
1829             }
1830             frame->ptsoffs = ptsoffs_value;
1831             ptsoffs_countdown--;
1832 
1833             if (!trak->edit_list_count) {
1834               scale_int_do (&trak->si, &frame->pts);
1835               frame->ptsoffs = (frame->ptsoffs * trak->ptsoffs_mul) >> 12;
1836             }
1837 
1838             frame++;
1839             samples_per_chunk -= samples_per_frame;
1840           }
1841         }
1842       }
1843       /* provide append time for fragments */
1844       trak->fragment_dts = pts_value;
1845       /* convenience frame */
1846       frame->pts = pts_value;
1847       if (!trak->edit_list_count)
1848         scale_int_do (&trak->si, &frame->pts);
1849     }
1850 
1851     /* was the last chunk incomplete? */
1852     if (trak->samples && (trak->samples < trak->frame_count))
1853       trak->frame_count = trak->samples;
1854 
1855     /* fill in the keyframe information */
1856     qt_keyframes_size (trak, trak->sync_sample_count);
1857     if (!trak->edit_list_count && (trak->keyframes_size >= trak->sync_sample_count)) {
1858       unsigned int u;
1859       uint8_t *p = trak->sync_sample_table;
1860       for (u = 0; u < trak->sync_sample_count; u++) {
1861         unsigned int fr = _X_BE_32 (p); p += 4;
1862         if ((fr > 0) && (fr <= trak->frame_count)) {
1863           QTF_KEYFRAME(trak->frames[fr - 1]) = 1;
1864           /* we already have xine pts, register them */
1865           qt_keyframes_simple_add (trak, trak->frames + fr - 1);
1866         }
1867       }
1868     } else {
1869       unsigned int u;
1870       uint8_t *p = trak->sync_sample_table;
1871       for (u = 0; u < trak->sync_sample_count; u++) {
1872         unsigned int fr = _X_BE_32 (p); p += 4;
1873         if ((fr > 0) && (fr <= trak->frame_count))
1874           QTF_KEYFRAME(trak->frames[fr - 1]) = 1;
1875       }
1876     }
1877 
1878     /* decide which video properties atom to use */
1879     {
1880       unsigned int u;
1881       int atom_to_use = 0;
1882       for (u = 1; u < trak->stsd_atoms_count; u++)
1883         if (media_id_counts[u + 1] > media_id_counts[u])
1884           atom_to_use = u;
1885       trak->properties = &trak->stsd_atoms[atom_to_use];
1886     }
1887     free(media_id_counts);
1888 
1889   } else { /* trak->type == MEDIA_AUDIO */
1890 
1891     unsigned int u;
1892     int64_t pts_value = 0;
1893     const uint8_t *p = trak->chunk_offset_table32 ?
1894                        trak->chunk_offset_table32 : trak->chunk_offset_table64;
1895     /* in this case, the total number of frames is equal to the number of chunks */
1896     trak->frame_count = trak->chunk_offset_count;
1897     trak->frames = malloc ((trak->frame_count + 1) * sizeof (qt_frame));
1898     if (!trak->frames)
1899       return QT_NO_MEMORY;
1900     trak->frames[0].pts = 0;
1901 
1902     /* iterate through each start chunk in the stsc table */
1903     for (u = 0; u < trak->sample_to_chunk_count; u++) {
1904       uint32_t media_id = trak->sample_to_chunk_table[u].media_id;
1905       /* the chunk size is actually the audio frame count */
1906       uint32_t duration = trak->sample_to_chunk_table[u].samples_per_chunk;
1907       uint32_t fsize    = (duration * trak->properties->s.audio.channels)
1908                         / trak->properties->s.audio.samples_per_frame
1909                         * trak->properties->s.audio.bytes_per_frame;
1910       /* iterate through each sample in a chunk and fill in size and
1911        * pts information */
1912       qt_frame *af = trak->frames + trak->sample_to_chunk_table[u].first_chunk - 1;
1913       /* Iterate from the first chunk of the current table entry to
1914        * the first chunk of the next table entry.
1915        * Entries are 1 based.
1916        * If the first chunk is in the last table entry, iterate to the
1917        * final chunk number (the number of offsets in stco table) */
1918       unsigned int sn = trak->sample_to_chunk_table[u + 1].first_chunk
1919                       - trak->sample_to_chunk_table[u].first_chunk;
1920       while (sn--) {
1921 
1922         /* figure out the pts for this chunk */
1923         af->pts = pts_value;
1924         if (!trak->edit_list_count) {
1925           scale_int_do (&trak->si, &af->pts);
1926         }
1927         pts_value += duration;
1928         af->ptsoffs = 0;
1929 
1930         if (trak->chunk_offset_table32)
1931           af->_ffs.offset = _X_BE_32 (p), p += 4;
1932         else
1933           af->_ffs.offset = _X_BE_64 (p), p += 8;
1934 
1935         /* fetch the alleged chunk size according to the QT header */
1936         af->size = fsize;
1937 
1938         /* media id accounting */
1939         QTF_MEDIA_ID(af[0]) = media_id;
1940         QTF_KEYFRAME(af[0]) = 0;
1941 
1942         af++;
1943       }
1944       /* convenience frame */
1945       af->pts = pts_value;
1946       if (!trak->edit_list_count) {
1947         scale_int_do (&trak->si, &af->pts);
1948       }
1949     }
1950     /* provide append time for fragments */
1951     trak->fragment_dts = pts_value;
1952   }
1953 
1954   if (trak->frame_count && trak->edit_list_count) {
1955     /* Fix up pts information w.r.t. the edit list table.
1956      * Supported: initial trak delay, gaps, and skipped intervals.
1957      * Not supported: repeating and reordering intervals.
1958      * Also, make xine timestamps right here and avoid an extra pass. */
1959     uint32_t edit_list_index;
1960     uint32_t use_keyframes = trak->sync_sample_count && (trak->keyframes_size >= trak->sync_sample_count);
1961     int64_t  edit_list_pts = 0, edit_list_duration = 0;
1962     qt_frame *sf = trak->frames, *tf = sf, *ef = sf + trak->frame_count;
1963     for (edit_list_index = 0; edit_list_index < trak->edit_list_count; edit_list_index++) {
1964       int64_t edit_list_media_time, offs = 0;
1965       /* snap to exact end of previous edit */
1966       edit_list_pts += edit_list_duration;
1967       /* duration is in global timescale units; convert to trak timescale */
1968       edit_list_media_time = trak->edit_list_table[edit_list_index].media_time;
1969       edit_list_duration = trak->edit_list_table[edit_list_index].track_duration;
1970       edit_list_duration *= trak->timescale;
1971       edit_list_duration /= global_timescale;
1972       /* insert delay */
1973       if (trak->edit_list_table[edit_list_index].media_time == -1ll)
1974         continue;
1975       /* extend last edit to end of trak, why?
1976        * anyway, add 1 second and catch ptsoffs. */
1977       if (edit_list_index == trak->edit_list_count - 1)
1978         edit_list_duration = ef->pts - edit_list_pts + trak->timescale;
1979       /* skip interval */
1980       if (trak->sync_sample_count) {
1981         /* find edit start, and the nearest keyframe before. */
1982         qt_frame *f = sf;
1983         for (; sf < ef; sf++) {
1984           offs = sf->pts;
1985           offs += sf->ptsoffs;
1986           offs -= edit_list_media_time;
1987           if (QTF_KEYFRAME(sf[0]))
1988             f = sf;
1989           if (offs >= 0)
1990             break;
1991         }
1992         if (sf == ef)
1993           break;
1994         offs -= sf->ptsoffs;
1995         edit_list_pts += offs;
1996         /* insert decoder preroll area */
1997         for (; f < sf; f++) {
1998           if (f != tf)
1999             *tf = *f;
2000           tf->pts = edit_list_pts;
2001           scale_int_do (&trak->si, &tf->pts);
2002           tf->ptsoffs = (tf->ptsoffs * trak->ptsoffs_mul) >> 12;
2003           tf++;
2004         }
2005       } else {
2006         /* find edit start. */
2007         for (; sf < ef; sf++) {
2008           offs = sf->pts;
2009           offs += sf->ptsoffs;
2010           offs -= edit_list_media_time;
2011           if (offs >= 0)
2012             break;
2013         }
2014         if (sf == ef)
2015           break;
2016         offs -= sf->ptsoffs;
2017         edit_list_pts += offs;
2018       }
2019       /* avoid separate end of table test */
2020       if (edit_list_duration > ef[0].pts - sf[0].pts)
2021         edit_list_duration = ef[0].pts - sf[0].pts;
2022       /* ">= 0" is easier than "> 0" in 32bit mode */
2023       edit_list_duration -= 1;
2024       /* insert interval */
2025       if (sf == tf) {
2026         /* no frames skipped yet (usual case) */
2027         do {
2028           /* this _does_ fit, see above */
2029           uint32_t d = sf[1].pts - sf[0].pts;
2030           sf[0].pts = edit_list_pts;
2031           scale_int_do (&trak->si, &sf[0].pts);
2032           sf[0].ptsoffs = (sf[0].ptsoffs * trak->ptsoffs_mul) >> 12;
2033           if (QTF_KEYFRAME(sf[0]) & use_keyframes)
2034             qt_keyframes_simple_add (trak, sf);
2035           sf++;
2036           edit_list_pts += d;
2037           edit_list_duration -= d;
2038         } while (edit_list_duration >= 0);
2039         tf = sf;
2040       } else {
2041         /* shift out skipped frames */
2042         do {
2043           uint32_t d = sf[1].pts - sf[0].pts;
2044           tf[0] = sf[0];
2045           tf[0].pts = edit_list_pts;
2046           scale_int_do (&trak->si, &tf[0].pts);
2047           tf[0].ptsoffs = (tf[0].ptsoffs * trak->ptsoffs_mul) >> 12;
2048           if (QTF_KEYFRAME(tf[0]) & use_keyframes)
2049             qt_keyframes_simple_add (trak, tf);
2050           sf++;
2051           tf++;
2052           edit_list_pts += d;
2053           edit_list_duration -= d;
2054         } while (edit_list_duration >= 0);
2055       }
2056       edit_list_duration += 1;
2057       edit_list_pts -= offs;
2058     }
2059     trak->fragment_dts = edit_list_pts;
2060     /* convenience frame */
2061     tf->pts            = edit_list_pts;
2062     scale_int_do (&trak->si, &tf[0].pts);
2063     trak->frame_count  = tf - trak->frames;
2064   }
2065 #ifdef DEBUG_EDIT_LIST
2066   {
2067     unsigned int u;
2068     qt_frame *f = trak->frames;
2069     for (u = 0; u <= trak->frame_count; u++) {
2070       debug_edit_list ("  final pts for sample %u = %"PRId64"\n", u, f->pts);
2071       f++;
2072     }
2073   }
2074 #endif
2075 
2076   return QT_OK;
2077 }
2078 
2079 /************************************************************************
2080 * Fragment stuff                                                        *
2081 ************************************************************************/
2082 
2083 #ifdef SIDX_ATOM
load_fragment_index(input_plugin_t * input,const uint8_t * head,uint32_t hsize,uint32_t timescale)2084 static fragment_index_t *load_fragment_index (input_plugin_t *input, const uint8_t *head, uint32_t hsize, uint32_t timescale) {
2085   uint32_t inum;
2086 
2087   {
2088     uint8_t fullhead[32];
2089     uint32_t isize;
2090     int n = 32 - hsize;
2091     if (hsize)
2092       memcpy (fullhead, head, hsize);
2093     if (n > 0) {
2094       if (input->read (input, fullhead + hsize, n) != n)
2095         return NULL;
2096     }
2097     isize = _X_BE_32 (fullhead);
2098     if (isize < 32)
2099       return NULL;
2100     inum  = _X_BE_32 (fullhead + 28);
2101     if (inum > (isize - 32) / 12)
2102       inum = (isize - 32) / 12;
2103   }
2104 
2105   {
2106     int64_t pos, pts;
2107     fragment_index_t *idx;
2108     fragment_info_t  *inf;
2109     uint8_t *tab = malloc (sizeof (*idx) + inum * sizeof (idx->fragments[0]));
2110     if (!tab)
2111       return NULL;
2112     idx = (fragment_index_t *)tab;
2113     tab += sizeof (*idx) + inum * sizeof (idx->fragments[0]) - inum * 12;
2114     if (input->read (input, tab, inum * 12) != (int32_t)inum * 12) {
2115       free (idx);
2116       return NULL;
2117     }
2118     idx->num_fragments = inum;
2119     pos = input->get_current_pos (input);
2120     pts = 0;
2121     inf = &idx->fragments[0];
2122     while (inum--) {
2123       inf->offset = pos;
2124       pos += _X_BE_32 (tab);
2125       inf->pts = pts * 90000 / timescale;
2126       pts += _X_BE_32 (tab + 8);
2127       inf++;
2128       tab += 12;
2129     }
2130     inf->offset = pos;
2131     inf->pts    = pts * 90000 / timescale;
2132     return idx;
2133   }
2134 }
2135 
report_fragment_index(xine_t * xine,fragment_index_t * idx)2136 static void report_fragment_index (xine_t *xine, fragment_index_t *idx) {
2137   if (idx) {
2138     unsigned int v, s, m;
2139     v = idx->fragments[idx->num_fragments].pts / 90000;
2140     s = v % 60;
2141     v /= 60;
2142     m = v % 60;
2143     v /= 60;
2144     xprintf (xine, XINE_VERBOSITY_DEBUG,
2145       "demux_qt: found index of %u fragments, %"PRId64" bytes, %0u:%02u:%02u.\n",
2146       (unsigned int)idx->num_fragments, idx->fragments[idx->num_fragments].offset,
2147       v, m, s);
2148   }
2149 }
2150 #endif
2151 
find_trak_by_id(demux_qt_t * this,int id)2152 static qt_trak *find_trak_by_id (demux_qt_t *this, int id) {
2153   unsigned int i;
2154 
2155   for (i = 0; i < this->qt.trak_count; i++) {
2156     if (this->qt.traks[i].id == id)
2157       return &(this->qt.traks[i]);
2158   }
2159   return NULL;
2160 }
2161 
parse_mvex_atom(demux_qt_t * this,uint8_t * mvex_atom,unsigned int bufsize)2162 static int parse_mvex_atom (demux_qt_t *this, uint8_t *mvex_atom, unsigned int bufsize) {
2163   unsigned int i, mvex_size;
2164   uint32_t traknum = 0, subtype, subsize = 0;
2165   qt_trak *trak;
2166 
2167   /* limit to atom size */
2168   if (bufsize < 8)
2169     return 0;
2170   mvex_size = _X_BE_32 (mvex_atom);
2171   if (bufsize < mvex_size)
2172     mvex_size = bufsize;
2173   /* scan subatoms */
2174   for (i = 8; i + 8 <= mvex_size; i += subsize) {
2175     subsize = _X_BE_32 (&mvex_atom[i]);
2176     subtype = _X_BE_32 (&mvex_atom[i + 4]);
2177     if (subsize == 0)
2178       subsize = mvex_size - i;
2179     if ((subsize < 8) || (i + subsize > mvex_size))
2180       break;
2181     switch (subtype) {
2182       case MEHD_ATOM:
2183         break;
2184       case TREX_ATOM:
2185         if (subsize < 8 + 24)
2186           break;
2187         traknum = _X_BE_32 (&mvex_atom[i + 8 + 4]);
2188         trak = find_trak_by_id (this, traknum);
2189         if (!trak)
2190           break;
2191         trak->default_sample_description_index = _X_BE_32 (&mvex_atom[i + 8 + 8]);
2192         trak->default_sample_duration          = _X_BE_32 (&mvex_atom[i + 8 + 12]);
2193         trak->default_sample_size              = _X_BE_32 (&mvex_atom[i + 8 + 16]);
2194         trak->default_sample_flags             = _X_BE_32 (&mvex_atom[i + 8 + 20]);
2195         if (!trak->frame_count) {
2196           trak->fragment_dts = 0;
2197           /* No frames defined yet. Apply initial delay if present.
2198            * There are 2 ways for an edit list to do that:
2199            * 1. A gap descriptor with media_time == -1. This is easy.
2200            * 2. A regular interval descriptor with media_time _before_
2201            *    first frame pts (dts + ptsoffs). We can only flag that here,
2202            *    and apply later when we saw that frame.
2203            */
2204           if (trak->edit_list_count) {
2205             unsigned int n = 0;
2206             if (trak->edit_list_table[0].media_time == -1ll) {
2207               /* Gap. Duration is in global timescale units; convert to trak timescale. */
2208               int64_t d;
2209               d = trak->edit_list_table[0].track_duration;
2210               if (d > 0) {
2211                 d *= trak->timescale;
2212                 d /= this->qt.timescale;
2213                 trak->fragment_dts = d;
2214               }
2215               n = 1;
2216             }
2217             if ((trak->edit_list_count > n) && (trak->edit_list_table[n].media_time != -1ll)) {
2218               /* Interval. Flag for parse_traf_atom (). */
2219               trak->delay_index = n;
2220             }
2221           }
2222         }
2223         trak->fragment_frames = trak->frame_count;
2224         this->qt.fragment_count = 0;
2225         break;
2226       default: ;
2227     }
2228   }
2229 
2230   return 1;
2231 }
2232 
parse_traf_atom(demux_qt_t * this,uint8_t * traf_atom,unsigned int trafsize,off_t moofpos)2233 static int parse_traf_atom (demux_qt_t *this, uint8_t *traf_atom, unsigned int trafsize, off_t moofpos) {
2234   unsigned int i, done = 0;
2235   uint32_t subtype, subsize = 0;
2236   uint32_t sample_description_index = 0;
2237   uint32_t default_sample_duration = 0;
2238   uint32_t default_sample_size = 0;
2239   uint32_t default_sample_flags = 0;
2240   off_t base_data_offset = 0, data_pos = 0;
2241   qt_trak *trak = NULL;
2242 
2243   for (i = 8; i + 8 <= trafsize; i += subsize) {
2244     subsize = _X_BE_32 (&traf_atom[i]);
2245     subtype = _X_BE_32 (&traf_atom[i + 4]);
2246     if (subsize == 0)
2247       subsize = trafsize - i;
2248     if ((subsize < 8) || (i + subsize > trafsize))
2249       break;
2250     switch (subtype) {
2251 
2252       case TFHD_ATOM: {
2253         uint32_t tfhd_flags;
2254         uint8_t *p;
2255         if (subsize < 8 + 8)
2256           break;
2257         p = traf_atom + i + 8;
2258         tfhd_flags = _X_BE_32 (p); p += 4;
2259         trak = find_trak_by_id (this, _X_BE_32 (p)); p += 4;
2260         {
2261           unsigned int n;
2262           n = ((tfhd_flags << 3) & 8)
2263             + ((tfhd_flags << 1) & 4)
2264             + ((tfhd_flags >> 1) & 4)
2265             + ((tfhd_flags >> 2) & 4)
2266             + ((tfhd_flags >> 3) & 4)
2267             + 8 + 8;
2268           if (subsize < n)
2269             trak = NULL;
2270         }
2271         if (!trak)
2272           break;
2273         if (tfhd_flags & 1)
2274           base_data_offset = _X_BE_64 (p), p += 8;
2275         else
2276           base_data_offset = moofpos;
2277         data_pos = base_data_offset;
2278         if (tfhd_flags & 2)
2279           sample_description_index = _X_BE_32 (p), p += 4;
2280         else
2281           sample_description_index = trak->default_sample_description_index;
2282         if (tfhd_flags & 8)
2283           default_sample_duration = _X_BE_32 (p), p += 4;
2284         else
2285           default_sample_duration = trak->default_sample_duration;
2286         if (tfhd_flags & 0x10)
2287           default_sample_size = _X_BE_32 (p), p += 4;
2288         else
2289           default_sample_size = trak->default_sample_size;
2290         if (tfhd_flags & 0x20)
2291           default_sample_flags = _X_BE_32 (p), p += 4;
2292         else
2293           default_sample_flags = trak->default_sample_flags;
2294         break;
2295       }
2296 
2297       case TRUN_ATOM: {
2298         uint32_t trun_flags;
2299         uint32_t samples;
2300         uint32_t sample_duration, sample_size;
2301         uint32_t first_sample_flags, sample_flags;
2302         int64_t  sample_dts;
2303         uint8_t *p;
2304         qt_frame *frame;
2305         /* get head */
2306         if (!trak)
2307           break;
2308         if (subsize < 8 + 8)
2309           break;
2310         p = traf_atom + i + 8;
2311         trun_flags = _X_BE_32 (p); p += 4;
2312         samples    = _X_BE_32 (p); p += 4;
2313         {
2314           unsigned int n;
2315           n = ((trun_flags << 2) & 4)
2316             + ( trun_flags       & 4)
2317             + 8 + 8;
2318           if (subsize < n)
2319             break;
2320         }
2321         if (trun_flags & 1) {
2322           uint32_t o = _X_BE_32 (p);
2323           p += 4;
2324           data_pos = base_data_offset + (off_t)((int32_t)o);
2325         }
2326         if (trun_flags & 4)
2327           first_sample_flags = _X_BE_32 (p), p += 4;
2328         else
2329           first_sample_flags = default_sample_flags;
2330         /* truncation paranoia */
2331         {
2332           unsigned int n;
2333           n = ((trun_flags >> 6) & 4)
2334             + ((trun_flags >> 7) & 4)
2335             + ((trun_flags >> 8) & 4)
2336             + ((trun_flags >> 9) & 4);
2337           if (n) {
2338             n = (i + subsize - (p - traf_atom)) / n;
2339             if (samples > n) samples = n;
2340           }
2341         }
2342         if (!samples)
2343           break;
2344         /* enlarge frame table in steps of 64k frames, to avoid a flood of reallocations */
2345         frame = trak->frames;
2346         {
2347           unsigned int n = trak->frame_count + samples;
2348           if (n + 1 > (unsigned int)trak->fragment_frames) {
2349             n = (n + 1 + 0xffff) & ~0xffff;
2350             frame = realloc (trak->frames, n * sizeof (*frame));
2351             if (!frame)
2352               break;
2353             trak->fragment_frames = n;
2354             trak->frames = frame;
2355           }
2356         }
2357         frame += trak->frame_count;
2358         /* add pending delay. first frame dts is always 0, so just test ptsoffs.
2359          * this happens at most once, so keep it away from main loop. */
2360         if (trak->delay_index >= 0) {
2361           uint32_t n = 0;
2362           int64_t  t;
2363           if (trun_flags & 0x800) {
2364             n = ((trun_flags >> 6) & 4)
2365               + ((trun_flags >> 7) & 4)
2366               + ((trun_flags >> 8) & 4);
2367             n = _X_BE_32 (p + n);
2368           }
2369           t = trak->edit_list_table[trak->delay_index].media_time;
2370           if (t > (int)n) {
2371             /* this actually means skipping framees, and makes not much sense in fragment mode. */
2372             t = (int)n;
2373           }
2374           trak->fragment_dts -= t;
2375           trak->delay_index = -1;
2376         }
2377         /* get defaults */
2378         sample_dts      = trak->fragment_dts;
2379         sample_duration = default_sample_duration;
2380         sample_size     = default_sample_size;
2381         sample_flags    = first_sample_flags;
2382         /* prepare for keyframes */
2383         if (trak->type == MEDIA_VIDEO)
2384           qt_keyframes_size (trak, trak->keyframes_used + samples);
2385         /* add frames */
2386         trak->frame_count += samples;
2387         switch ((trun_flags & 0xf00) >> 8) {
2388           case 0xf:
2389             do {
2390               frame->pts = sample_dts;
2391               scale_int_do (&trak->si, &frame->pts);
2392               sample_duration = _X_BE_32 (p), p += 4;
2393               sample_dts += sample_duration;
2394               frame[0]._ffs.offset = data_pos;
2395               sample_size = _X_BE_32 (p), p += 4;
2396               frame->size = sample_size;
2397               data_pos += sample_size;
2398               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2399               sample_flags = _X_BE_32 (p), p += 4;
2400               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2401               {
2402                 uint32_t o = _X_BE_32 (p);
2403                 p += 4;
2404                 frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12;
2405               }
2406               if (QTF_KEYFRAME(frame[0]))
2407                 qt_keyframes_simple_add (trak, frame);
2408               frame++;
2409             } while (--samples);
2410             break;
2411           case 0xe:
2412             do {
2413               frame->pts = sample_dts;
2414               scale_int_do (&trak->si, &frame->pts);
2415               sample_dts += sample_duration;
2416               frame[0]._ffs.offset = data_pos;
2417               sample_size = _X_BE_32 (p), p += 4;
2418               frame->size = sample_size;
2419               data_pos += sample_size;
2420               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2421               sample_flags = _X_BE_32 (p), p += 4;
2422               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2423               {
2424                 uint32_t o = _X_BE_32 (p);
2425                 p += 4;
2426                 frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12;
2427               }
2428               if (QTF_KEYFRAME(frame[0]))
2429                 qt_keyframes_simple_add (trak, frame);
2430               frame++;
2431             } while (--samples);
2432             break;
2433           case 0xd:
2434             do {
2435               frame->pts = sample_dts;
2436               scale_int_do (&trak->si, &frame->pts);
2437               sample_duration = _X_BE_32 (p), p += 4;
2438               sample_dts += sample_duration;
2439               frame[0]._ffs.offset = data_pos;
2440               frame->size = sample_size;
2441               data_pos += sample_size;
2442               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2443               sample_flags = _X_BE_32 (p), p += 4;
2444               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2445               {
2446                 uint32_t o = _X_BE_32 (p);
2447                 p += 4;
2448                 frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12;
2449               }
2450               if (QTF_KEYFRAME(frame[0]))
2451                 qt_keyframes_simple_add (trak, frame);
2452               frame++;
2453             } while (--samples);
2454             break;
2455           case 0xc:
2456             do {
2457               frame->pts = sample_dts;
2458               scale_int_do (&trak->si, &frame->pts);
2459               sample_dts += sample_duration;
2460               frame[0]._ffs.offset = data_pos;
2461               frame->size = sample_size;
2462               data_pos += sample_size;
2463               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2464               sample_flags = _X_BE_32 (p), p += 4;
2465               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2466               {
2467                 uint32_t o = _X_BE_32 (p);
2468                 p += 4;
2469                 frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12;
2470               }
2471               if (QTF_KEYFRAME(frame[0]))
2472                 qt_keyframes_simple_add (trak, frame);
2473               frame++;
2474             } while (--samples);
2475             break;
2476           case 0xb:
2477             do {
2478               frame->pts = sample_dts;
2479               scale_int_do (&trak->si, &frame->pts);
2480               sample_duration = _X_BE_32 (p), p += 4;
2481               sample_dts += sample_duration;
2482               frame[0]._ffs.offset = data_pos;
2483               sample_size = _X_BE_32 (p), p += 4;
2484               frame->size = sample_size;
2485               data_pos += sample_size;
2486               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2487               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2488               sample_flags = default_sample_flags;
2489               {
2490                 uint32_t o = _X_BE_32 (p);
2491                 p += 4;
2492                 frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12;
2493               }
2494               if (QTF_KEYFRAME(frame[0]))
2495                 qt_keyframes_simple_add (trak, frame);
2496               frame++;
2497             } while (--samples);
2498             break;
2499           case 0xa:
2500             do {
2501               frame->pts = sample_dts;
2502               scale_int_do (&trak->si, &frame->pts);
2503               sample_dts += sample_duration;
2504               frame[0]._ffs.offset = data_pos;
2505               sample_size = _X_BE_32 (p), p += 4;
2506               frame->size = sample_size;
2507               data_pos += sample_size;
2508               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2509               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2510               sample_flags = default_sample_flags;
2511               {
2512                 uint32_t o = _X_BE_32 (p);
2513                 p += 4;
2514                 frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12;
2515               }
2516               if (QTF_KEYFRAME(frame[0]))
2517                 qt_keyframes_simple_add (trak, frame);
2518               frame++;
2519             } while (--samples);
2520             break;
2521           case 0x9:
2522             do {
2523               frame->pts = sample_dts;
2524               scale_int_do (&trak->si, &frame->pts);
2525               sample_duration = _X_BE_32 (p), p += 4;
2526               sample_dts += sample_duration;
2527               frame[0]._ffs.offset = data_pos;
2528               frame->size = sample_size;
2529               data_pos += sample_size;
2530               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2531               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2532               sample_flags = default_sample_flags;
2533               {
2534                 uint32_t o = _X_BE_32 (p);
2535                 p += 4;
2536                 frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12;
2537               }
2538               if (QTF_KEYFRAME(frame[0]))
2539                 qt_keyframes_simple_add (trak, frame);
2540               frame++;
2541             } while (--samples);
2542             break;
2543           case 0x8:
2544             do {
2545               frame->pts = sample_dts;
2546               scale_int_do (&trak->si, &frame->pts);
2547               sample_dts += sample_duration;
2548               frame[0]._ffs.offset = data_pos;
2549               frame->size = sample_size;
2550               data_pos += sample_size;
2551               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2552               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2553               sample_flags = default_sample_flags;
2554               {
2555                 uint32_t o = _X_BE_32 (p);
2556                 p += 4;
2557                 frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12;
2558               }
2559               if (QTF_KEYFRAME(frame[0]))
2560                 qt_keyframes_simple_add (trak, frame);
2561               frame++;
2562             } while (--samples);
2563             break;
2564           case 0x7:
2565             do {
2566               frame->pts = sample_dts;
2567               scale_int_do (&trak->si, &frame->pts);
2568               sample_duration = _X_BE_32 (p), p += 4;
2569               sample_dts += sample_duration;
2570               frame[0]._ffs.offset = data_pos;
2571               sample_size = _X_BE_32 (p), p += 4;
2572               frame->size = sample_size;
2573               data_pos += sample_size;
2574               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2575               sample_flags = _X_BE_32 (p), p += 4;
2576               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2577               frame->ptsoffs = 0;
2578               if (QTF_KEYFRAME(frame[0]))
2579                 qt_keyframes_simple_add (trak, frame);
2580               frame++;
2581             } while (--samples);
2582             break;
2583           case 0x6:
2584             do {
2585               frame->pts = sample_dts;
2586               scale_int_do (&trak->si, &frame->pts);
2587               sample_dts += sample_duration;
2588               frame[0]._ffs.offset = data_pos;
2589               sample_size = _X_BE_32 (p), p += 4;
2590               frame->size = sample_size;
2591               data_pos += sample_size;
2592               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2593               sample_flags = _X_BE_32 (p), p += 4;
2594               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2595               frame->ptsoffs = 0;
2596               if (QTF_KEYFRAME(frame[0]))
2597                 qt_keyframes_simple_add (trak, frame);
2598               frame++;
2599             } while (--samples);
2600             break;
2601           case 0x5:
2602             do {
2603               frame->pts = sample_dts;
2604               scale_int_do (&trak->si, &frame->pts);
2605               sample_duration = _X_BE_32 (p), p += 4;
2606               sample_dts += sample_duration;
2607               frame[0]._ffs.offset = data_pos;
2608               frame->size = sample_size;
2609               data_pos += sample_size;
2610               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2611               sample_flags = _X_BE_32 (p), p += 4;
2612               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2613               frame->ptsoffs = 0;
2614               if (QTF_KEYFRAME(frame[0]))
2615                 qt_keyframes_simple_add (trak, frame);
2616               frame++;
2617             } while (--samples);
2618             break;
2619           case 0x4:
2620             do {
2621               frame->pts = sample_dts;
2622               scale_int_do (&trak->si, &frame->pts);
2623               sample_dts += sample_duration;
2624               frame[0]._ffs.offset = data_pos;
2625               frame->size = sample_size;
2626               data_pos += sample_size;
2627               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2628               sample_flags = _X_BE_32 (p), p += 4;
2629               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2630               frame->ptsoffs = 0;
2631               if (QTF_KEYFRAME(frame[0]))
2632                 qt_keyframes_simple_add (trak, frame);
2633               frame++;
2634             } while (--samples);
2635             break;
2636           case 0x3:
2637             do {
2638               frame->pts = sample_dts;
2639               scale_int_do (&trak->si, &frame->pts);
2640               sample_duration = _X_BE_32 (p), p += 4;
2641               sample_dts += sample_duration;
2642               frame[0]._ffs.offset = data_pos;
2643               sample_size = _X_BE_32 (p), p += 4;
2644               frame->size = sample_size;
2645               data_pos += sample_size;
2646               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2647               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2648               sample_flags = default_sample_flags;
2649               frame->ptsoffs = 0;
2650               if (QTF_KEYFRAME(frame[0]))
2651                 qt_keyframes_simple_add (trak, frame);
2652               frame++;
2653             } while (--samples);
2654             break;
2655           case 0x2:
2656             do {
2657               frame->pts = sample_dts;
2658               scale_int_do (&trak->si, &frame->pts);
2659               sample_dts += sample_duration;
2660               frame[0]._ffs.offset = data_pos;
2661               sample_size = _X_BE_32 (p), p += 4;
2662               frame->size = sample_size;
2663               data_pos += sample_size;
2664               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2665               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2666               sample_flags = default_sample_flags;
2667               frame->ptsoffs = 0;
2668               if (QTF_KEYFRAME(frame[0]))
2669                 qt_keyframes_simple_add (trak, frame);
2670               frame++;
2671             } while (--samples);
2672             break;
2673           case 0x1:
2674             do {
2675               frame->pts = sample_dts;
2676               scale_int_do (&trak->si, &frame->pts);
2677               sample_duration = _X_BE_32 (p), p += 4;
2678               sample_dts += sample_duration;
2679               frame[0]._ffs.offset = data_pos;
2680               frame->size = sample_size;
2681               data_pos += sample_size;
2682               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2683               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2684               sample_flags = default_sample_flags;
2685               frame->ptsoffs = 0;
2686               if (QTF_KEYFRAME(frame[0]))
2687                 qt_keyframes_simple_add (trak, frame);
2688               frame++;
2689             } while (--samples);
2690             break;
2691           case 0x0:
2692             do {
2693               frame->pts = sample_dts;
2694               scale_int_do (&trak->si, &frame->pts);
2695               sample_dts += sample_duration;
2696               frame[0]._ffs.offset = data_pos;
2697               frame->size = sample_size;
2698               data_pos += sample_size;
2699               QTF_MEDIA_ID(frame[0]) = sample_description_index;
2700               QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000);
2701               sample_flags = default_sample_flags;
2702               frame->ptsoffs = 0;
2703               if (QTF_KEYFRAME(frame[0]))
2704                 qt_keyframes_simple_add (trak, frame);
2705               frame++;
2706             } while (--samples);
2707             break;
2708         }
2709         trak->fragment_dts = sample_dts;
2710         /* convenience frame */
2711         frame->pts = sample_dts;
2712         scale_int_do (&trak->si, &frame->pts);
2713         done++;
2714         break;
2715       }
2716 
2717       default: ;
2718     }
2719   }
2720   return done;
2721 }
2722 
parse_moof_atom(demux_qt_t * this,uint8_t * moof_atom,int moofsize,off_t moofpos)2723 static int parse_moof_atom (demux_qt_t *this, uint8_t *moof_atom, int moofsize, off_t moofpos) {
2724   int i, subtype, subsize = 0, done = 0;
2725 
2726   for (i = 8; i + 8 <= moofsize; i += subsize) {
2727     subsize = _X_BE_32 (&moof_atom[i]);
2728     subtype = _X_BE_32 (&moof_atom[i + 4]);
2729     if (subsize == 0)
2730       subsize = moofsize - i;
2731     if ((subsize < 8) || (i + subsize > moofsize))
2732       break;
2733     switch (subtype) {
2734       case MFHD_ATOM:
2735         /* TODO: check sequence # here */
2736         break;
2737       case TRAF_ATOM:
2738         if (parse_traf_atom (this, &moof_atom[i], subsize, moofpos))
2739           done++;
2740         break;
2741       default: ;
2742     }
2743   }
2744   return done;
2745 }
2746 
fragment_scan(demux_qt_t * this)2747 static int fragment_scan (demux_qt_t *this) {
2748   uint8_t hbuf[16];
2749   off_t pos, fsize;
2750   uint64_t atomsize;
2751   uint32_t caps, atomtype;
2752 
2753   /* prerequisites */
2754   if (this->qt.fragment_count < 0)
2755     return 0;
2756   caps = this->input->get_capabilities (this->input);
2757   fsize = this->input->get_length (this->input);
2758 
2759   if ((caps & INPUT_CAP_SEEKABLE) && (fsize > 0)) {
2760     /* Plain file, possibly being written right now.
2761      * Get all fragments known so far. */
2762 
2763     int frags = 0;
2764     for (pos = this->qt.fragment_next; pos < fsize; pos += atomsize) {
2765       if (this->input->seek (this->input, pos, SEEK_SET) != pos)
2766         break;
2767       if (this->input->read (this->input, hbuf, 16) != 16)
2768         break;
2769       atomsize = _X_BE_32 (hbuf);
2770       atomtype = _X_BE_32 (hbuf + 4);
2771       if (atomsize == 0)
2772         atomsize = fsize - pos;
2773       else if (atomsize == 1) {
2774         atomsize = _X_BE_64 (hbuf + 8);
2775         if (atomsize < 16)
2776           break;
2777       } else if (atomsize < 8)
2778         break;
2779       if (atomtype == MOOF_ATOM) {
2780         if (atomsize > (80 << 20))
2781           break;
2782         if (atomsize > this->qt.fragbuf_size) {
2783           size_t size2 = atomsize + (atomsize >> 1);
2784           uint8_t *b2 = realloc (this->qt.fragment_buf, size2);
2785           if (!b2)
2786             break;
2787           this->qt.fragment_buf = b2;
2788           this->qt.fragbuf_size = size2;
2789         }
2790         memcpy (this->qt.fragment_buf, hbuf, 16);
2791         if (atomsize > 16) {
2792           if (this->input->read (this->input, this->qt.fragment_buf + 16, atomsize - 16) != (off_t)atomsize - 16)
2793             break;
2794         }
2795         if (parse_moof_atom (this, this->qt.fragment_buf, atomsize, pos))
2796           frags++;
2797       }
2798     }
2799     this->qt.fragment_next = pos;
2800     this->qt.fragment_count += frags;
2801     return frags;
2802 
2803   } else {
2804     /* Stay patient, get 1 fragment only. */
2805 
2806     /* find next moof */
2807     pos = this->qt.fragment_next;
2808     if (pos == 0)
2809       pos = this->input->get_current_pos (this->input);
2810     while (1) {
2811       if (pos <= 0)
2812         return 0;
2813       if (this->input->seek (this->input, pos, SEEK_SET) != pos)
2814         return 0;
2815       if (this->input->read (this->input, hbuf, 8) != 8)
2816         return 0;
2817       atomsize = _X_BE_32 (hbuf);
2818       if (_X_BE_32 (hbuf + 4) == MOOF_ATOM)
2819         break;
2820       if (atomsize < 8) {
2821         if (atomsize != 1)
2822           return 0;
2823         if (this->input->read (this->input, hbuf + 8, 8) != 8)
2824           return 0;
2825         atomsize = _X_BE_64 (hbuf + 8);
2826         if (atomsize < 16)
2827           return 0;
2828       }
2829       pos += atomsize;
2830     }
2831     /* add it */
2832     if (atomsize < 16)
2833       return 0;
2834     if (atomsize > (80 << 20))
2835       return 0;
2836     if (atomsize > this->qt.fragbuf_size) {
2837       size_t size2 = atomsize + (atomsize >> 1);
2838       uint8_t *b2 = realloc (this->qt.fragment_buf, size2);
2839       if (!b2)
2840         return 0;
2841       this->qt.fragment_buf = b2;
2842       this->qt.fragbuf_size = size2;
2843     }
2844     memcpy (this->qt.fragment_buf, hbuf, 8);
2845     if (this->input->read (this->input, this->qt.fragment_buf + 8, atomsize - 8) != (off_t)atomsize - 8)
2846       return 0;
2847     if (!parse_moof_atom (this, this->qt.fragment_buf, atomsize, pos))
2848       return 0;
2849     this->qt.fragment_count += 1;
2850     pos += atomsize;
2851     /* next should be mdat. remember its end for next try.
2852      * dont actually skip it here, we will roughly do that by playing. */
2853     if (this->input->read (this->input, hbuf, 8) != 8)
2854       return 0;
2855     atomsize = _X_BE_32 (hbuf);
2856     if (_X_BE_32 (hbuf + 4) != MDAT_ATOM)
2857       return 0;
2858     if (atomsize < 8) {
2859       if (atomsize != 1)
2860         return 0;
2861       if (this->input->read (this->input, hbuf + 8, 8) != 8)
2862         return 0;
2863       atomsize = _X_BE_64 (hbuf + 8);
2864       if (atomsize < 16)
2865         return 0;
2866     }
2867     pos += atomsize;
2868     this->qt.fragment_next = pos;
2869     return 1;
2870   }
2871 }
2872 
2873 /************************************************************************
2874 * /Fragment stuff                                                       *
2875 ************************************************************************/
2876 
info_string_from_atom(uint8_t * atom,char ** target)2877 static void info_string_from_atom (uint8_t *atom, char **target) {
2878   uint32_t size, string_size, i;
2879 
2880   if (!atom)
2881     return;
2882   size = _X_BE_32 (atom);
2883   if ((size >= 24) && (_X_BE_32 (&atom[12]) == DATA_ATOM)) {
2884     if (_X_BE_32 (&atom[16]) != 1) /* # of portions */
2885       return;
2886     i = 24;
2887     string_size = _X_BE_32 (&atom[20]);
2888     if (string_size == 0)
2889       string_size = size - i;
2890   } else if (size >= 12) {
2891     i = 12;
2892     string_size = _X_BE_16 (&atom[8]);
2893   } else
2894     return;
2895   if (i + string_size > size)
2896     return;
2897   *target = realloc (*target, string_size + 1);
2898   if (*target == NULL)
2899     return;
2900   memcpy (*target, &atom[i], string_size);
2901   (*target)[string_size] = 0;
2902 }
2903 
2904 /* get real duration */
qt_update_duration(demux_qt_t * this)2905 static void qt_update_duration (demux_qt_t *this) {
2906   qt_trak *trak = this->qt.traks;
2907   uint32_t n;
2908   for (n = this->qt.trak_count; n; n--) {
2909     if (trak->frame_count) {
2910       int32_t msecs = qt_pts_2_msecs (trak->frames[trak->frame_count].pts);
2911       if (msecs > this->qt.msecs)
2912         this->qt.msecs = msecs;
2913     }
2914     trak++;
2915   }
2916   qt_normpos_init (this);
2917 }
2918 
2919 /*
2920  * This function takes a pointer to a qt_info structure and a pointer to
2921  * a buffer containing an uncompressed moov atom. When the function
2922  * finishes successfully, qt_info will have a list of qt_frame objects,
2923  * ordered by offset.
2924  */
parse_moov_atom(demux_qt_t * this,uint8_t * moov_atom)2925 static void parse_moov_atom (demux_qt_t *this, uint8_t *moov_atom) {
2926   unsigned int i;
2927   int error;
2928   unsigned int sizes[20];
2929   uint8_t *atoms[20];
2930   unsigned int max_video_frames = 0;
2931   unsigned int max_audio_frames = 0;
2932   uint8_t *mvex_atom;
2933   int mvex_size;
2934   static const uint32_t types_base[] = {
2935     MVHD_ATOM, MVEX_ATOM,
2936     TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM,
2937     TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM,
2938     TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM,
2939     TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM,
2940     TRAK_ATOM, 0
2941   };
2942   static const uint32_t types_meta[] = {
2943     NAM_ATOM, CPY_ATOM, DES_ATOM, CMT_ATOM,
2944     ART_ATOM, ALB_ATOM, GEN_ATOM, WRT_ATOM,
2945     DAY_ATOM, 0
2946   };
2947   static const uint32_t types_rmda[] = {
2948     RMDA_ATOM, RMDA_ATOM, RMDA_ATOM, RMDA_ATOM,
2949     RMDA_ATOM, RMDA_ATOM, RMDA_ATOM, RMDA_ATOM,
2950     0
2951   };
2952 
2953   /* make sure this is actually a moov atom (will also accept 'free' as
2954    * a special case) */
2955   if ((_X_BE_32(&moov_atom[4]) != MOOV_ATOM) &&
2956       (_X_BE_32(&moov_atom[4]) != FREE_ATOM)) {
2957     this->qt.last_error = QT_NO_MOOV_ATOM;
2958     return;
2959   }
2960 
2961   /* prowl through the moov atom looking for very specific targets */
2962   atom_scan (moov_atom, 1, types_base, atoms, sizes);
2963 
2964   if (atoms[0]) {
2965     parse_mvhd_atom (this, atoms[0]);
2966     if (this->qt.last_error != QT_OK)
2967       return;
2968   }
2969 
2970   mvex_atom = atoms[1];
2971   mvex_size = sizes[1];
2972 
2973   atoms[19] = NULL;
2974   {
2975     uint8_t **a = atoms + 2;
2976     while (*a)
2977       a++;
2978     this->qt.traks = malloc ((a - (atoms + 2)) * sizeof (qt_trak));
2979     if (!this->qt.traks) {
2980       this->qt.last_error = QT_NO_MEMORY;
2981       return;
2982     }
2983     a = atoms + 2;
2984     while (*a) {
2985       /* create a new trak structure */
2986       this->qt.last_error = parse_trak_atom (&this->qt.traks[this->qt.trak_count], *a);
2987       if (this->qt.last_error != QT_OK)
2988         return;
2989       this->qt.trak_count++;
2990       a++;
2991     }
2992   }
2993 
2994   atom_scan (moov_atom, 4, types_meta, atoms, sizes);
2995 
2996   info_string_from_atom (atoms[0], &this->qt.name);
2997   info_string_from_atom (atoms[1], &this->qt.copyright);
2998   info_string_from_atom (atoms[2], &this->qt.description);
2999   info_string_from_atom (atoms[3], &this->qt.comment);
3000   info_string_from_atom (atoms[4], &this->qt.artist);
3001   info_string_from_atom (atoms[5], &this->qt.album);
3002   info_string_from_atom (atoms[6], &this->qt.genre);
3003   info_string_from_atom (atoms[7], &this->qt.composer);
3004   info_string_from_atom (atoms[8], &this->qt.year);
3005 
3006   atom_scan (moov_atom, 2, types_rmda, atoms, sizes);
3007 
3008   atoms[8] = NULL;
3009   {
3010     uint8_t **a = atoms;
3011     while (*a) {
3012       parse_reference_atom (this, *a, this->qt.base_mrl);
3013       a++;
3014     }
3015   }
3016   debug_atom_load("  qt: finished parsing moov atom\n");
3017 
3018   /* build frame tables corresponding to each trak */
3019   debug_frame_table("  qt: preparing to build %d frame tables\n",
3020     this->qt.trak_count);
3021   for (i = 0; i < this->qt.trak_count; i++) {
3022     qt_trak *trak = &this->qt.traks[i];
3023     if (trak->type == MEDIA_VIDEO) {
3024       if (trak->properties) {
3025         xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
3026           "demux_qt: stream #%u: video [%s], %u x %u.\n",
3027           i, trak->properties->codec_str,
3028           trak->properties->s.video.width,
3029           trak->properties->s.video.height);
3030       } else {
3031         xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
3032           "demux_qt: stream #%u: video [unknown].\n", i);
3033       }
3034     } else if (trak->type == MEDIA_AUDIO) {
3035       if (trak->properties) {
3036         xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
3037           "demux_qt: stream #%u: audio [%s], %uch, %uHz, %ubit.\n",
3038           i, trak->properties->codec_str,
3039           trak->properties->s.audio.channels,
3040           trak->properties->s.audio.sample_rate,
3041           trak->properties->s.audio.bits);
3042       } else {
3043         xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
3044           "demux_qt: stream #%u: audio [unknown].\n", i);
3045       }
3046     } else {
3047       xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
3048         "demux_qt: stream #%u: other.\n", i);
3049     }
3050     debug_frame_table("    qt: building frame table #%d (%s)\n", i,
3051       (this->qt.traks[i].type == MEDIA_VIDEO) ? "video" : "audio");
3052     error = build_frame_table(&this->qt.traks[i], this->qt.timescale);
3053     if (error != QT_OK) {
3054       this->qt.last_error = error;
3055       return;
3056     }
3057     if (trak->frame_count) {
3058       xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
3059         "demux_qt:            start %" PRId64 "pts, %u frames.\n",
3060         trak->frames[0].pts + trak->frames[0].ptsoffs,
3061         trak->frame_count);
3062     }
3063   }
3064 
3065   /* must parse mvex _after_ building traks */
3066   if (mvex_atom) {
3067     parse_mvex_atom (this, mvex_atom, mvex_size);
3068     /* reassemble fragments, if any */
3069     fragment_scan (this);
3070   }
3071 
3072   qt_update_duration (this);
3073 
3074   for (i = 0; i < this->qt.trak_count; i++) {
3075     qt_trak *trak = this->qt.traks + i;
3076 #if DEBUG_DUMP_MOOV
3077     unsigned int j;
3078     /* dump the frame table in debug mode */
3079     for (j = 0; j < trak->frame_count; j++)
3080       debug_frame_table("      %d: %8X bytes @ %"PRIX64", %"PRId64" pts, media id %d%s\n",
3081         j,
3082         trak->frames[j].size,
3083         QTF_OFFSET(trak[0].frames[j]),
3084         trak->frames[j].pts,
3085         (int)QTF_MEDIA_ID(trak[0].frames[j]),
3086         (QTF_KEYFRAME(trak[0].frames[j])) ? " (keyframe)" : "");
3087 #endif
3088     /* decide which audio trak and which video trak has the most frames */
3089     if ((trak->type == MEDIA_VIDEO) &&
3090         (trak->frame_count > max_video_frames)) {
3091 
3092       this->qt.video_trak = i;
3093       max_video_frames = trak->frame_count;
3094 
3095       if (trak->keyframes_list) {
3096         xine_keyframes_entry_t *e = trak->keyframes_list;
3097         uint32_t n = trak->keyframes_used;
3098         while (n--) {
3099           e->normpos = qt_msec_2_normpos (this, e->msecs);
3100           e++;
3101         }
3102         _x_keyframes_set (this->stream, trak->keyframes_list, trak->keyframes_used);
3103       }
3104 
3105     } else if ((trak->type == MEDIA_AUDIO) &&
3106                (trak->frame_count > max_audio_frames)) {
3107 
3108       this->qt.audio_trak = i;
3109       max_audio_frames = trak->frame_count;
3110     }
3111 
3112     free (trak->keyframes_list);
3113     trak->keyframes_list = NULL;
3114     trak->keyframes_size = 0;
3115     trak->keyframes_used = 0;
3116   }
3117 
3118   /* check for references */
3119   if (this->qt.reference_count > 0) {
3120 
3121     /* init chosen reference to the first entry */
3122     this->qt.chosen_reference = 0;
3123 
3124     /* iterate through 1..n-1 reference entries and decide on the right one */
3125     for (i = 1; i < this->qt.reference_count; i++) {
3126 
3127       if (this->qt.references[i].qtim_version >
3128           this->qt.references[this->qt.chosen_reference].qtim_version)
3129         this->qt.chosen_reference = i;
3130       else if ((this->qt.references[i].data_rate <= this->bandwidth) &&
3131                (this->qt.references[i].data_rate >
3132                 this->qt.references[this->qt.chosen_reference].data_rate))
3133         this->qt.chosen_reference = i;
3134     }
3135 
3136     debug_atom_load("  qt: chosen reference is ref #%d, qtim version %04X, %"PRId64" bps\n      URL: %s\n",
3137       this->qt.chosen_reference,
3138       this->qt.references[this->qt.chosen_reference].qtim_version,
3139       this->qt.references[this->qt.chosen_reference].data_rate,
3140       this->qt.references[this->qt.chosen_reference].url);
3141   }
3142 }
3143 
load_moov_atom(input_plugin_t * input,uint8_t ** moov_atom,off_t * moov_atom_offset)3144 static qt_error load_moov_atom (input_plugin_t *input, uint8_t **moov_atom, off_t *moov_atom_offset) {
3145   uint8_t buf[MAX_PREVIEW_SIZE] = { 0, }, *p;
3146   uint64_t size = 0;
3147   uint32_t hsize;
3148   uint32_t type = 0;
3149   uint64_t pos  = 0;
3150   /* "moov" sometimes is wrongly marked as "free". Use that when there is no real one. */
3151   uint64_t free_pos = 0;
3152   uint64_t free_size = 0;
3153   /* Quick detect non-qt files: more than 1 unknown top level atom. */
3154   int unknown_atoms = 1;
3155 
3156   /* ffmpeg encodes .mp4 with "mdat" before "moov" because it does not know the table sizes needed before.
3157    * Some folks actually offer such files as is for streaming.
3158    * Thats why we distinctly use slow seek here as well. */
3159   if (input->get_capabilities (input) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)) {
3160 
3161     while (1) {
3162       hsize = 8;
3163       if (input->seek (input, pos, SEEK_SET) != (off_t)pos)
3164         break;
3165       if (input->read (input, buf, 8) != 8)
3166         break;
3167       size = _X_BE_32 (buf);
3168       if (size == 1) {
3169         hsize = 16;
3170         if (input->read (input, buf + 8, 8) != 8)
3171           return QT_FILE_READ_ERROR;
3172         size = _X_BE_64 (buf + 8);
3173         if (size < 16)
3174           break;
3175         if (size >= ((uint64_t)1 << 63))
3176           break;
3177       } else if (size < 8) {
3178         off_t len = input->get_length (input);
3179         size = len > (off_t)(pos + 8) ? len - pos : 8;
3180       }
3181       type = _X_BE_32 (buf + 4);
3182       if (type == MOOV_ATOM)
3183         break;
3184       if (type == FREE_ATOM) {
3185         if ((size - hsize >= 8) && (input->read (input, buf + hsize, 8) == 8)) {
3186           uint32_t stype = _X_BE_32 (buf + hsize + 4);
3187           hsize += 8;
3188           if ((stype == MVHD_ATOM) || (stype == CMOV_ATOM)) {
3189             free_pos = pos;
3190             free_size = size;
3191           }
3192         }
3193       }
3194       if ((type != FREE_ATOM) &&
3195           (type != JUNK_ATOM) &&
3196           (type != MDAT_ATOM) &&
3197           (type != PNOT_ATOM) &&
3198           (type != SKIP_ATOM) &&
3199           (type != WIDE_ATOM) &&
3200           (type != PICT_ATOM) &&
3201           (type != FTYP_ATOM)) {
3202         if (--unknown_atoms < 0)
3203           return QT_NOT_A_VALID_FILE;
3204       }
3205       pos += size;
3206     }
3207     p = buf;
3208     if ((type != MOOV_ATOM) && free_size) {
3209       type = MOOV_ATOM;
3210       pos  = free_pos;
3211       size = free_size;
3212       hsize = 0;
3213       if (input->seek (input, pos, SEEK_SET) != (off_t)pos)
3214         return QT_NO_MOOV_ATOM;
3215     }
3216     if (type != MOOV_ATOM)
3217       return QT_NOT_A_VALID_FILE;
3218 
3219   } else {
3220 
3221     int have = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW);
3222     if (have < 32)
3223       return QT_FILE_READ_ERROR;
3224     while (1) {
3225       hsize = 8;
3226       if (pos > (unsigned int)have - 8)
3227         break;
3228       p = buf + pos;
3229       size = _X_BE_32 (p);
3230       if (size == 1) {
3231         hsize = 16;
3232         if (pos > (unsigned int)have - 16)
3233           break;
3234         size = _X_BE_64 (p + 8);
3235         if (size < 16)
3236           return QT_NO_MOOV_ATOM;
3237         if (size >= ((uint64_t)1 << 63))
3238           return QT_NO_MOOV_ATOM;
3239       } else if (size < 8) {
3240         size = have - pos;
3241       }
3242       type = _X_BE_32 (p + 4);
3243       if (type == MOOV_ATOM)
3244         break;
3245       if (type == FREE_ATOM) {
3246         if (pos <= (unsigned int)have - hsize - 8) {
3247           uint32_t stype = _X_BE_32 (p + hsize + 4);
3248           hsize += 8;
3249           if ((stype == MVHD_ATOM) || (stype == CMOV_ATOM)) {
3250             free_pos = pos;
3251             free_size = size;
3252           }
3253         }
3254       }
3255       if ((type != FREE_ATOM) &&
3256           (type != JUNK_ATOM) &&
3257           (type != MDAT_ATOM) &&
3258           (type != PNOT_ATOM) &&
3259           (type != SKIP_ATOM) &&
3260           (type != WIDE_ATOM) &&
3261           (type != PICT_ATOM) &&
3262           (type != FTYP_ATOM)) {
3263         if (--unknown_atoms < 0)
3264           return QT_NOT_A_VALID_FILE;
3265       }
3266       pos += size;
3267     }
3268     if ((type != MOOV_ATOM) && free_size) {
3269       type = MOOV_ATOM;
3270       pos  = free_pos;
3271       size = free_size;
3272       hsize = 0;
3273     }
3274     if (type != MOOV_ATOM)
3275       return QT_NOT_A_VALID_FILE;
3276     if (input->seek (input, pos + hsize, SEEK_SET) != (off_t)pos + hsize)
3277       return QT_NO_MOOV_ATOM;
3278 
3279   }
3280   if (size >= MAX_MOOV_SIZE)
3281     return QT_NOT_A_VALID_FILE;
3282 
3283   *moov_atom_offset = pos;
3284   *moov_atom = malloc (size + 4);
3285   if (!*moov_atom)
3286     return QT_NO_MEMORY;
3287   if (hsize)
3288     memcpy (*moov_atom, p, hsize);
3289   if (input->read (input, *moov_atom + hsize, size - hsize) != (off_t)size - hsize) {
3290     free (*moov_atom);
3291     return QT_FILE_READ_ERROR;
3292   }
3293 
3294   return QT_OK;
3295 }
3296 
open_qt_file(demux_qt_t * this,uint8_t * moov_atom,off_t moov_atom_offset)3297 static qt_error open_qt_file (demux_qt_t *this, uint8_t *moov_atom, off_t moov_atom_offset) {
3298 
3299   uint32_t moov_atom_size;
3300 
3301   /* extract the base MRL if this is a http MRL */
3302   if (strncmp (this->input->get_mrl (this->input), "http://", 7) == 0) {
3303     char *slash;
3304     /* this will copy a few bytes too many, but no big deal */
3305     this->qt.base_mrl = strdup (this->input->get_mrl (this->input));
3306     /* terminate the string after the last slash character */
3307     slash = strrchr (this->qt.base_mrl, '/');
3308     if (slash)
3309       *(slash + 1) = '\0';
3310   }
3311 
3312   this->qt.moov_first_offset = moov_atom_offset;
3313   moov_atom_size = _X_BE_32 (moov_atom);
3314 
3315   /* check if moov is compressed */
3316   if ((moov_atom_size >= 0x28) && (_X_BE_32 (moov_atom + 12) == CMOV_ATOM)) do {
3317     uint8_t  *unzip_buffer;
3318     uint32_t  size2;
3319     this->qt.compressed_header = 1;
3320     this->qt.last_error        = QT_NO_MEMORY;
3321     size2                   = _X_BE_32 (moov_atom + 0x24);
3322     if (size2 > MAX_MOOV_SIZE)
3323       size2 = MAX_MOOV_SIZE;
3324     unzip_buffer = malloc (size2 + 4);
3325     if (unzip_buffer) {
3326       /* zlib stuff */
3327       z_stream z_state;
3328       int      z_ret_code1, z_ret_code2;
3329       this->qt.last_error  = QT_ZLIB_ERROR;
3330       z_state.next_in   = moov_atom + 0x28;
3331       z_state.avail_in  = moov_atom_size - 0x28;
3332       z_state.next_out  = unzip_buffer;
3333       z_state.avail_out = size2;
3334       z_state.zalloc    = NULL;
3335       z_state.zfree     = NULL;
3336       z_state.opaque    = NULL;
3337       z_ret_code1       = inflateInit (&z_state);
3338       if (Z_OK == z_ret_code1) {
3339         z_ret_code1 = inflate (&z_state, Z_NO_FLUSH);
3340         z_ret_code2 = inflateEnd (&z_state);
3341         if (((z_ret_code1 == Z_OK) || (z_ret_code1 == Z_STREAM_END)) && (Z_OK == z_ret_code2)) {
3342           /* replace the compressed moov atom with the decompressed atom */
3343           this->qt.last_error = QT_OK;
3344           free (moov_atom);
3345           moov_atom = unzip_buffer;
3346           moov_atom_size = _X_BE_32 (moov_atom);
3347           if (moov_atom_size > size2) {
3348             moov_atom_size = size2;
3349             WRITE_BE_32 (size2, moov_atom);
3350           }
3351           break;
3352         }
3353       }
3354       free (unzip_buffer);
3355     }
3356     free (moov_atom);
3357     return this->qt.last_error;
3358   } while (0);
3359 
3360   /* write moov atom to disk if debugging option is turned on */
3361   dump_moov_atom(moov_atom, moov_atom_size);
3362 
3363   /* take apart the moov atom */
3364   parse_moov_atom (this, moov_atom);
3365 
3366   free (moov_atom);
3367   return this->qt.last_error;
3368 }
3369 
3370 /**********************************************************************
3371  * xine demuxer functions
3372  **********************************************************************/
3373 
demux_qt_send_chunk(demux_plugin_t * this_gen)3374 static int demux_qt_send_chunk(demux_plugin_t *this_gen) {
3375 
3376   demux_qt_t *this = (demux_qt_t *) this_gen;
3377   buf_element_t *buf = NULL;
3378   unsigned int i;
3379   unsigned int remaining_sample_bytes;
3380   unsigned int frame_aligned_buf_size;
3381   int frame_duration;
3382   int first_buf;
3383   qt_trak *trak = NULL;
3384   off_t current_pos = this->input->get_current_pos (this->input);
3385 
3386   /* if this is DRM-protected content, finish playback before it even
3387    * tries to start */
3388   if (this->qt.last_error == QT_DRM_NOT_SUPPORTED) {
3389     this->status = DEMUX_FINISHED;
3390     return this->status;
3391   }
3392 
3393   /* check if it's time to send a reference up to the UI */
3394   if (this->qt.chosen_reference != -1) {
3395 
3396     _x_demux_send_mrl_reference (this->stream, 0,
3397                                  this->qt.references[this->qt.chosen_reference].url,
3398                                  NULL, 0, 0);
3399     this->status = DEMUX_FINISHED;
3400     return this->status;
3401   }
3402 
3403   /* Decide the trak from which to dispatch a frame. Policy: Dispatch
3404    * the frames in offset order as much as possible. If the pts difference
3405    * between the current frames from the audio and video traks is too
3406    * wide, make an exception. This exception deals with non-interleaved
3407    * Quicktime files. */
3408   do {
3409     int traks[MAX_AUDIO_TRAKS + 1];
3410     int trak_count = 0;
3411     int min_trak = -1, next_trak = -1;
3412     int64_t min_pts = 0, max_pts = 0; /* avoid warning */
3413     off_t next_pos = 0x7fffffffffffffffLL;
3414     int i;
3415 
3416     /* Step 1: list yet unfinished traks. */
3417     if (this->qt.video_trak >= 0) {
3418       trak = &this->qt.traks[this->qt.video_trak];
3419       if (trak->current_frame < trak->frame_count)
3420         traks[trak_count++] = this->qt.video_trak;
3421     }
3422     for (i = 0; i < this->qt.audio_trak_count; i++) {
3423       trak = &this->qt.traks[this->qt.audio_traks[i]];
3424       if (trak->current_frame < trak->frame_count)
3425         traks[trak_count++] = this->qt.audio_traks[i];
3426     }
3427 
3428     /* Step 2: handle trivial cases. */
3429     if (trak_count == 0) {
3430       if (fragment_scan (this)) {
3431         qt_update_duration (this);
3432         this->status = DEMUX_OK;
3433       } else
3434         this->status = DEMUX_FINISHED;
3435       return this->status;
3436     }
3437     if (trak_count == 1) {
3438       trak = &this->qt.traks[traks[0]];
3439       break;
3440     }
3441 
3442     /* Step 3: find
3443        * The minimum pts and the trak who has it.
3444        * The maximum pts.
3445        * The forward nearest to current position and the trak thereof. */
3446     for (i = 0; i < trak_count; i++) {
3447       int64_t pts;
3448       off_t pos;
3449       trak = &this->qt.traks[traks[i]];
3450       pts  = trak->frames[trak->current_frame].pts;
3451       if (i == 0) {
3452         min_pts  = max_pts = pts;
3453         min_trak = traks[i];
3454       } else if (pts < min_pts) {
3455         min_pts  = pts;
3456         min_trak = traks[i];
3457       } else if (pts > max_pts)
3458         max_pts  = pts;
3459       pos = QTF_OFFSET(trak->frames[trak->current_frame]);
3460       if ((pos >= current_pos) && (pos < next_pos)) {
3461         next_pos = pos;
3462         next_trak = traks[i];
3463       }
3464     }
3465 
3466     /* Step 4: after seek, or if the pts scissors opened too much, send minimum pts trak next.
3467        Otherwise, take next one by offset. */
3468     i = this->qt.seek_flag || (next_trak < 0) || (max_pts - min_pts > MAX_PTS_DIFF) ?
3469       min_trak : next_trak;
3470     trak = &this->qt.traks[i];
3471   } while (0);
3472 
3473   if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) {
3474     xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1,
3475       "demux_qt: sending trak %d dts %"PRId64" pos %"PRId64"\n",
3476       (int)(trak - this->qt.traks),
3477       trak->frames[trak->current_frame].pts,
3478       QTF_OFFSET(trak->frames[trak->current_frame]));
3479   }
3480 
3481   /* check if it is time to seek */
3482   if (this->qt.seek_flag) {
3483     this->qt.seek_flag = 0;
3484 
3485     /* send min pts of all used traks, usually audio (see demux_qt_seek ()). */
3486     _x_demux_control_newpts (this->stream,
3487         trak->frames[trak->current_frame].pts + trak->frames[trak->current_frame].ptsoffs, BUF_FLAG_SEEK);
3488   }
3489 
3490   if (trak->type == MEDIA_VIDEO) {
3491     i = trak->current_frame++;
3492 
3493     if (QTF_MEDIA_ID(trak->frames[i]) != trak->properties->media_id) {
3494       this->status = DEMUX_OK;
3495       return this->status;
3496     }
3497 
3498     remaining_sample_bytes = trak->frames[i].size;
3499     if ((off_t)QTF_OFFSET(trak->frames[i]) != current_pos) {
3500       if (this->input->seek (this->input, QTF_OFFSET(trak->frames[i]), SEEK_SET) < 0) {
3501         /* Do not stop demuxing. Maybe corrupt file or broken track. */
3502         return this->status;
3503       }
3504     }
3505 
3506     /* frame duration is the pts diff between this video frame and the next video frame
3507      * or the convenience frame at the end of list */
3508     frame_duration  = trak->frames[i + 1].pts;
3509     frame_duration -= trak->frames[i].pts;
3510 
3511     /* Due to the edit lists, some successive frames have the same pts
3512      * which would ordinarily cause frame_duration to be 0 which can
3513      * cause DIV-by-0 errors in the engine. Perform this little trick
3514      * to compensate. */
3515     if (!frame_duration) {
3516       frame_duration = 1;
3517       trak->properties->s.video.edit_list_compensation++;
3518     } else {
3519       frame_duration -= trak->properties->s.video.edit_list_compensation;
3520       trak->properties->s.video.edit_list_compensation = 0;
3521     }
3522 
3523     _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION,
3524                          frame_duration);
3525 
3526     debug_video_demux("  qt: sending off video frame %d from offset 0x%"PRIX64", %d bytes, media id %d, %"PRId64" pts\n",
3527       i,
3528       QTF_OFFSET(trak->frames[i]),
3529       trak->frames[i].size,
3530       (int)QTF_MEDIA_ID(trak->frames[i]),
3531       trak->frames[i].pts);
3532 
3533     while (remaining_sample_bytes) {
3534       buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, remaining_sample_bytes);
3535       buf->type = trak->properties->codec_buftype;
3536       buf->extra_info->input_time = qt_pts_2_msecs (trak->frames[i].pts);
3537       buf->extra_info->input_normpos = qt_msec_2_normpos (this, buf->extra_info->input_time);
3538       buf->pts = trak->frames[i].pts + (int64_t)trak->frames[i].ptsoffs;
3539 
3540       buf->decoder_flags |= BUF_FLAG_FRAMERATE;
3541       buf->decoder_info[0] = frame_duration;
3542 
3543       if (remaining_sample_bytes > (unsigned int)buf->max_size)
3544         buf->size = buf->max_size;
3545       else
3546         buf->size = remaining_sample_bytes;
3547       remaining_sample_bytes -= buf->size;
3548 
3549       if (this->input->read(this->input, buf->content, buf->size) !=
3550         buf->size) {
3551         buf->free_buffer(buf);
3552         trak->current_frame = trak->frame_count;
3553         break;
3554       }
3555 
3556       if (QTF_KEYFRAME(trak->frames[i]))
3557         buf->decoder_flags |= BUF_FLAG_KEYFRAME;
3558       if (!remaining_sample_bytes)
3559         buf->decoder_flags |= BUF_FLAG_FRAME_END;
3560 
3561       this->video_fifo->put(this->video_fifo, buf);
3562     }
3563 
3564   } else { /* trak->type == MEDIA_AUDIO */
3565     /* load an audio sample and packetize it */
3566     i = trak->current_frame++;
3567 
3568     if (QTF_MEDIA_ID(trak->frames[i]) != trak->properties->media_id) {
3569       this->status = DEMUX_OK;
3570       return this->status;
3571     }
3572 
3573     /* only go through with this procedure if audio_fifo exists */
3574     if (!this->audio_fifo)
3575       return this->status;
3576 
3577     remaining_sample_bytes = trak->frames[i].size;
3578 
3579     if ((off_t)QTF_OFFSET(trak->frames[i]) != current_pos) {
3580       if (this->input->seek (this->input, QTF_OFFSET(trak->frames[i]), SEEK_SET) < 0) {
3581         /* Do not stop demuxing. Maybe corrupt file or broken track. */
3582         return this->status;
3583       }
3584     }
3585 
3586     debug_audio_demux("  qt: sending off audio frame %d from offset 0x%"PRIX64", %d bytes, media id %d, %"PRId64" pts\n",
3587       i,
3588       QTF_OFFSET(trak->frames[i]),
3589       trak->frames[i].size,
3590       (int)QTF_MEDIA_ID(trak->frames[i]),
3591       trak->frames[i].pts);
3592 
3593     first_buf = 1;
3594     while (remaining_sample_bytes) {
3595       buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, remaining_sample_bytes);
3596       buf->type = trak->properties->codec_buftype;
3597       buf->extra_info->input_time = qt_pts_2_msecs (trak->frames[i].pts);
3598       buf->extra_info->input_normpos = qt_msec_2_normpos (this, buf->extra_info->input_time);
3599       /* The audio chunk is often broken up into multiple 8K buffers when
3600        * it is sent to the audio decoder. Only attach the proper timestamp
3601        * to the first buffer. This is for the linear PCM decoder which
3602        * turns around and sends out audio buffers as soon as they are
3603        * received. If 2 or more consecutive audio buffers are dispatched to
3604        * the audio out unit, the engine will compensate with pops. */
3605       if ((buf->type == BUF_AUDIO_LPCM_BE) ||
3606           (buf->type == BUF_AUDIO_LPCM_LE)) {
3607         if (first_buf) {
3608           buf->pts = trak->frames[i].pts;
3609           first_buf = 0;
3610         } else {
3611           buf->extra_info->input_time = 0;
3612           buf->pts = 0;
3613         }
3614       } else {
3615         buf->pts = trak->frames[i].pts;
3616       }
3617 
3618       /* 24-bit audio doesn't fit evenly into the default 8192-byte buffers */
3619       frame_aligned_buf_size = buf->max_size;
3620       if (trak->properties->s.audio.bits == 24)
3621         frame_aligned_buf_size = (frame_aligned_buf_size / 8184) * 8184;
3622 
3623       if (remaining_sample_bytes > frame_aligned_buf_size)
3624         buf->size = frame_aligned_buf_size;
3625       else
3626         buf->size = remaining_sample_bytes;
3627       remaining_sample_bytes -= buf->size;
3628 
3629       if (this->input->read(this->input, buf->content, buf->size) !=
3630         buf->size) {
3631         buf->free_buffer(buf);
3632         trak->current_frame = trak->frame_count;
3633         break;
3634       }
3635 
3636       /* Special case alert: If this is signed, 8-bit data, transform
3637        * the data to unsigned. */
3638       if ((trak->properties->s.audio.bits == 8) &&
3639           ((trak->properties->codec_fourcc == TWOS_FOURCC) ||
3640            (trak->properties->codec_fourcc == SOWT_FOURCC))) {
3641         int j;
3642         for (j = 0; j < buf->size; j++)
3643           buf->content[j] += 0x80;
3644       }
3645 
3646       if (!remaining_sample_bytes) {
3647         buf->decoder_flags |= BUF_FLAG_FRAME_END;
3648       }
3649 
3650       buf->type |= trak->audio_index;
3651       this->audio_fifo->put(this->audio_fifo, buf);
3652     }
3653   }
3654 
3655   return this->status;
3656 }
3657 
demux_qt_send_headers(demux_plugin_t * this_gen)3658 static void demux_qt_send_headers(demux_plugin_t *this_gen) {
3659 
3660   demux_qt_t *this = (demux_qt_t *) this_gen;
3661   buf_element_t *buf;
3662   qt_trak *video_trak = NULL;
3663   qt_trak *audio_trak = NULL;
3664   unsigned int audio_bitrate;
3665 
3666   unsigned int tnum;
3667   int audio_index = 0;
3668 
3669 #ifdef QT_OFFSET_SEEK
3670   /* for deciding data start and data size */
3671   int64_t first_video_offset = -1;
3672   int64_t  last_video_offset = -1;
3673   int64_t first_audio_offset = -1;
3674   int64_t  last_audio_offset = -1;
3675 #endif
3676 
3677   this->video_fifo = this->stream->video_fifo;
3678   this->audio_fifo = this->stream->audio_fifo;
3679 
3680   this->status = DEMUX_OK;
3681 
3682   /* figure out where the data begins and ends */
3683   if (this->qt.video_trak != -1) {
3684     video_trak = &this->qt.traks[this->qt.video_trak];
3685 #ifdef QT_OFFSET_SEEK
3686     first_video_offset = QTF_OFFSET(video_trak->frames[0]);
3687     last_video_offset = video_trak->frames[video_trak->frame_count - 1].size +
3688       QTF_OFFSET(video_trak->frames[video_trak->frame_count - 1]);
3689 #endif
3690   }
3691   if (this->qt.audio_trak != -1) {
3692     audio_trak = &this->qt.traks[this->qt.audio_trak];
3693 #ifdef QT_OFFSET_SEEK
3694     first_audio_offset = QTF_OFFSET(audio_trak->frames[0]);
3695     last_audio_offset = audio_trak->frames[audio_trak->frame_count - 1].size +
3696       QTF_OFFSET(audio_trak->frames[audio_trak->frame_count - 1]);
3697 #endif
3698   }
3699 
3700 #ifdef QT_OFFSET_SEEK
3701   if (first_video_offset < first_audio_offset)
3702     this->data_start = first_video_offset;
3703   else
3704     this->data_start = first_audio_offset;
3705 
3706   if (last_video_offset > last_audio_offset)
3707     this->data_size = last_video_offset - this->data_size;
3708   else
3709     this->data_size = last_audio_offset - this->data_size;
3710 #endif
3711 
3712   /* sort out the A/V information */
3713   if (this->qt.video_trak != -1) {
3714 
3715     this->bih.biSize = sizeof(this->bih);
3716     this->bih.biWidth = video_trak->properties->s.video.width;
3717     this->bih.biHeight = video_trak->properties->s.video.height;
3718     this->bih.biBitCount = video_trak->properties->s.video.depth;
3719 
3720     this->bih.biCompression = video_trak->properties->codec_fourcc;
3721     video_trak->properties->codec_buftype =
3722       _x_fourcc_to_buf_video(this->bih.biCompression);
3723 
3724     /* hack: workaround a fourcc clash! 'mpg4' is used by MS and Sorenson
3725      * mpeg4 codecs (they are not compatible).
3726      */
3727     if( video_trak->properties->codec_buftype == BUF_VIDEO_MSMPEG4_V1 )
3728       video_trak->properties->codec_buftype = BUF_VIDEO_MPEG4;
3729 
3730     if( !video_trak->properties->codec_buftype &&
3731          video_trak->properties->codec_fourcc )
3732     {
3733       video_trak->properties->codec_buftype = BUF_VIDEO_UNKNOWN;
3734       _x_report_video_fourcc (this->stream->xine, LOG_MODULE,
3735 			      video_trak->properties->codec_fourcc);
3736     }
3737 
3738     _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
3739     _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH,
3740                          this->bih.biWidth);
3741     _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT,
3742                          this->bih.biHeight);
3743     _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC,
3744                          video_trak->properties->codec_fourcc);
3745 
3746   } else {
3747 
3748     memset(&this->bih, 0, sizeof(this->bih));
3749     this->bih.biSize = sizeof(this->bih);
3750     _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0);
3751     _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, 0);
3752     _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, 0);
3753     _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, 0);
3754 
3755   }
3756 
3757   if (this->qt.audio_trak != -1) {
3758 
3759     _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
3760     _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS,
3761       audio_trak->properties->s.audio.channels);
3762     _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE,
3763       audio_trak->properties->s.audio.sample_rate);
3764     _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS,
3765       audio_trak->properties->s.audio.bits);
3766     _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC,
3767       audio_trak->properties->codec_fourcc);
3768 
3769   } else {
3770 
3771     _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0);
3772     _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, 0);
3773     _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, 0);
3774     _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, 0);
3775     _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, 0);
3776 
3777   }
3778 
3779   /* copy over the meta information like artist and title */
3780   if (this->qt.artist)
3781     _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->qt.artist);
3782   else if (this->qt.copyright)
3783     _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->qt.copyright);
3784   if (this->qt.name)
3785     _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->qt.name);
3786   else if (this->qt.description)
3787     _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->qt.description);
3788   if (this->qt.composer)
3789     _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, this->qt.composer);
3790   else if (this->qt.comment)
3791     _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, this->qt.comment);
3792   if (this->qt.album)
3793     _x_meta_info_set(this->stream, XINE_META_INFO_ALBUM, this->qt.album);
3794   if (this->qt.genre)
3795     _x_meta_info_set(this->stream, XINE_META_INFO_GENRE, this->qt.genre);
3796   if (this->qt.year)
3797     _x_meta_info_set(this->stream, XINE_META_INFO_YEAR, this->qt.year);
3798 
3799   /* send start buffers */
3800   _x_demux_control_start(this->stream);
3801 
3802   /* send init info to decoders */
3803   if (video_trak &&
3804       (video_trak->properties->codec_buftype)) {
3805     buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
3806     buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
3807 
3808     memcpy(buf->content, &this->bih, sizeof(this->bih));
3809     buf->size = sizeof(this->bih);
3810     buf->type = video_trak->properties->codec_buftype;
3811     this->video_fifo->put (this->video_fifo, buf);
3812 
3813     /* send header info to decoder. some mpeg4 streams need this */
3814     if (video_trak->properties->decoder_config) {
3815       buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
3816       buf->type = video_trak->properties->codec_buftype;
3817 
3818       if (video_trak->properties->codec_fourcc == AVC1_FOURCC ||
3819           video_trak->properties->codec_fourcc == HVC1_FOURCC ||
3820           video_trak->properties->codec_fourcc == HEV1_FOURCC ||
3821           video_trak->properties->codec_fourcc == HEVC_FOURCC) {
3822         buf->size = 0;
3823         buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER;
3824         buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG;
3825         buf->decoder_info[2] = video_trak->properties->decoder_config_len;
3826         buf->decoder_info_ptr[2] = video_trak->properties->decoder_config;
3827       } else {
3828         buf->size = video_trak->properties->decoder_config_len;
3829         buf->content = video_trak->properties->decoder_config;
3830       }
3831 
3832       this->video_fifo->put (this->video_fifo, buf);
3833     }
3834 
3835     /* send off the palette, if there is one */
3836     if (video_trak->properties->s.video.palette_count) {
3837       buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
3838       buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER;
3839       buf->decoder_info[1] = BUF_SPECIAL_PALETTE;
3840       buf->decoder_info[2] = video_trak->properties->s.video.palette_count;
3841       buf->decoder_info_ptr[2] = &video_trak->properties->s.video.palette;
3842       buf->size = 0;
3843       buf->type = video_trak->properties->codec_buftype;
3844       this->video_fifo->put (this->video_fifo, buf);
3845     }
3846 
3847     /* send stsd to the decoder */
3848     buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
3849     buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER;
3850     buf->decoder_info[1] = BUF_SPECIAL_STSD_ATOM;
3851     buf->decoder_info[2] = video_trak->properties->properties_atom_size - 4;
3852     buf->decoder_info_ptr[2] = video_trak->properties->properties_atom + 4;
3853     buf->size = 0;
3854     buf->type = video_trak->properties->codec_buftype;
3855     this->video_fifo->put (this->video_fifo, buf);
3856   }
3857 
3858   for (tnum = 0; tnum < this->qt.trak_count; tnum++) {
3859 
3860     audio_trak = &this->qt.traks[tnum];
3861     if (audio_trak->type != MEDIA_AUDIO)
3862       continue;
3863 
3864     if (!audio_trak->properties->codec_buftype &&
3865          audio_trak->properties->codec_fourcc) {
3866       audio_trak->properties->codec_buftype = BUF_AUDIO_UNKNOWN;
3867       _x_report_audio_format_tag (this->stream->xine, LOG_MODULE,
3868         audio_trak->properties->codec_fourcc);
3869     }
3870 
3871     if ((audio_trak->properties->codec_buftype == 0) ||
3872         (audio_index >= MAX_AUDIO_TRAKS) ||
3873         (this->audio_fifo == NULL))
3874       continue;
3875 
3876     this->qt.audio_traks[audio_index] = tnum;
3877     audio_trak->audio_index = audio_index;
3878 
3879     /* set the audio bitrate field (only for CBR audio) */
3880     if (!audio_trak->properties->s.audio.vbr) {
3881       audio_bitrate =
3882         audio_trak->properties->s.audio.sample_rate /
3883         audio_trak->properties->s.audio.samples_per_frame *
3884         audio_trak->properties->s.audio.bytes_per_frame *
3885         audio_trak->properties->s.audio.channels *
3886         8;
3887       _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE,
3888         audio_bitrate);
3889     }
3890 
3891     buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
3892     buf->type = audio_trak->properties->codec_buftype | audio_index;
3893     buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
3894     buf->decoder_info[0] = 0;
3895     buf->decoder_info[1] = audio_trak->properties->s.audio.sample_rate;
3896     buf->decoder_info[2] = audio_trak->properties->s.audio.bits;
3897     buf->decoder_info[3] = audio_trak->properties->s.audio.channels;
3898 
3899     if( audio_trak->properties->s.audio.wave_size ) {
3900       if (audio_trak->properties->s.audio.wave_size > (unsigned int)buf->max_size)
3901         buf->size = buf->max_size;
3902       else
3903         buf->size = audio_trak->properties->s.audio.wave_size;
3904       memcpy (buf->content, audio_trak->properties->s.audio.wave, buf->size);
3905     } else {
3906       buf->size = 0;
3907       buf->content = NULL;
3908     }
3909 
3910     this->audio_fifo->put (this->audio_fifo, buf);
3911 
3912     if (audio_trak->properties->decoder_config) {
3913       buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
3914       buf->type = audio_trak->properties->codec_buftype | audio_index;
3915       buf->size = 0;
3916       buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER;
3917       buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG;
3918       buf->decoder_info[2] = audio_trak->properties->decoder_config_len;
3919       buf->decoder_info_ptr[2] = audio_trak->properties->decoder_config;
3920       this->audio_fifo->put (this->audio_fifo, buf);
3921     }
3922 
3923     /* send stsd to the decoder */
3924     buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
3925     buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER;
3926     buf->decoder_info[1] = BUF_SPECIAL_STSD_ATOM;
3927     buf->decoder_info[2] = audio_trak->properties->properties_atom_size - 4;
3928     buf->decoder_info_ptr[2] = audio_trak->properties->properties_atom + 4;
3929     buf->size = 0;
3930     buf->type = audio_trak->properties->codec_buftype | audio_index;
3931     this->audio_fifo->put (this->audio_fifo, buf);
3932 
3933     this->qt.audio_trak_count = ++audio_index;
3934   }
3935 }
3936 
3937 /* support function that performs a binary seek on a trak; returns the
3938  * demux status */
binary_seek(demux_qt_t * this,qt_trak * trak,off_t start_pos,int start_time)3939 static int binary_seek (demux_qt_t *this, qt_trak *trak, off_t start_pos, int start_time) {
3940 
3941   int best_index;
3942   int left, middle, right;
3943 #ifdef QT_OFFSET_SEEK
3944   int found;
3945 #endif
3946 
3947   if (!trak->frame_count)
3948     return QT_OK;
3949 
3950 #ifdef QT_OFFSET_SEEK
3951   (void)this;
3952   /* perform a binary search on the trak, testing the offset
3953    * boundaries first; offset request has precedent over time request */
3954   if (start_pos) {
3955     if (start_pos <= (off_t)QTF_OFFSET(trak->frames[0]))
3956       best_index = 0;
3957     else if (start_pos >= (off_t)QTF_OFFSET(trak->frames[trak->frame_count - 1]))
3958       best_index = trak->frame_count - 1;
3959     else {
3960       left = 0;
3961       right = trak->frame_count - 1;
3962       found = 0;
3963 
3964       while (!found) {
3965 	middle = (left + right + 1) / 2;
3966         if ((start_pos >= (off_t)QTF_OFFSET(trak->frames[middle])) &&
3967             (start_pos < (off_t)QTF_OFFSET(trak->frames[middle + 1]))) {
3968           found = 1;
3969         } else if (start_pos < (off_t)QTF_OFFSET(trak->frames[middle])) {
3970           right = middle - 1;
3971         } else {
3972           left = middle;
3973         }
3974       }
3975 
3976       best_index = middle;
3977     }
3978   } else
3979 #else
3980   if (start_pos) {
3981     start_time = (uint64_t)(start_pos & 0xffff) * (uint32_t)this->qt.msecs / 0xffff;
3982   }
3983 #endif
3984   {
3985     int64_t pts = (int64_t)90 * start_time;
3986 
3987     if (pts <= trak->frames[0].pts)
3988       best_index = 0;
3989     else if (pts >= trak->frames[trak->frame_count - 1].pts)
3990       best_index = trak->frame_count - 1;
3991     else {
3992       left = 0;
3993       right = trak->frame_count - 1;
3994       do {
3995 	middle = (left + right + 1) / 2;
3996 	if (pts < trak->frames[middle].pts) {
3997 	  right = (middle - 1);
3998 	} else {
3999 	  left = middle;
4000 	}
4001       } while (left < right);
4002 
4003       best_index = left;
4004     }
4005   }
4006 
4007   trak->current_frame = best_index;
4008   return DEMUX_OK;
4009 }
4010 
demux_qt_seek(demux_plugin_t * this_gen,off_t start_pos,int start_time,int playing)4011 static int demux_qt_seek (demux_plugin_t *this_gen,
4012                           off_t start_pos, int start_time, int playing) {
4013 
4014   demux_qt_t *this = (demux_qt_t *) this_gen;
4015   qt_trak *video_trak = NULL;
4016   qt_trak *audio_trak = NULL;
4017   int i;
4018   int64_t keyframe_pts = -1;
4019 
4020 #ifdef QT_OFFSET_SEEK
4021   start_pos = (off_t) ( (double) start_pos / 65535 *
4022               this->data_size );
4023 #endif
4024 
4025   /* short-circuit any attempts to seek in a non-seekable stream, including
4026    * seeking in the forward direction; this may change later */
4027   if ((this->input->get_capabilities(this->input) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)) == 0) {
4028     this->qt.seek_flag = 1;
4029     this->status = DEMUX_OK;
4030     return this->status;
4031   }
4032 
4033   /* if there is a video trak, position it as close as possible to the
4034    * requested position */
4035   if (this->qt.video_trak != -1) {
4036     video_trak = &this->qt.traks[this->qt.video_trak];
4037     this->status = binary_seek (this, video_trak, start_pos, start_time);
4038     if (this->status != DEMUX_OK)
4039       return this->status;
4040     /* search back in the video trak for the nearest keyframe */
4041     while (video_trak->current_frame) {
4042       if (QTF_KEYFRAME(video_trak->frames[video_trak->current_frame])) {
4043         break;
4044       }
4045       video_trak->current_frame--;
4046     }
4047     keyframe_pts = video_trak->frames[video_trak->current_frame].pts;
4048   }
4049 
4050   /* seek all supported audio traks */
4051   for (i = 0; i < this->qt.audio_trak_count; i++) {
4052     audio_trak = &this->qt.traks[this->qt.audio_traks[i]];
4053     this->status = binary_seek (this, audio_trak, start_pos, start_time);
4054     if (this->status != DEMUX_OK)
4055       return this->status;
4056   }
4057 
4058   /* not done yet; now that the nearest keyframe has been found, seek
4059    * back to the first audio frame that has a pts less than or equal to
4060    * that of the keyframe; do not go through with this process there is
4061    * no video trak */
4062   if (keyframe_pts >= 0) for (i = 0; i < this->qt.audio_trak_count; i++) {
4063     audio_trak = &this->qt.traks[this->qt.audio_traks[i]];
4064     if (keyframe_pts > audio_trak->frames[audio_trak->frame_count - 1].pts) {
4065       /* whoops, this trak is too short, mark it finished */
4066       audio_trak->current_frame = audio_trak->frame_count;
4067     } else while (audio_trak->current_frame) {
4068       if (audio_trak->frames[audio_trak->current_frame].pts <= keyframe_pts) {
4069         break;
4070       }
4071       audio_trak->current_frame--;
4072     }
4073   }
4074 
4075   this->qt.seek_flag = 1;
4076   this->status = DEMUX_OK;
4077 
4078   /*
4079    * do only flush if already running (seeking).
4080    * otherwise decoder_config is flushed too.
4081    */
4082   if(playing)
4083     _x_demux_flush_engine(this->stream);
4084 
4085   return this->status;
4086 }
4087 
demux_qt_dispose(demux_plugin_t * this_gen)4088 static void demux_qt_dispose (demux_plugin_t *this_gen) {
4089   demux_qt_t *this = (demux_qt_t *) this_gen;
4090 
4091   free_qt_info (this);
4092   free(this);
4093 }
4094 
demux_qt_get_status(demux_plugin_t * this_gen)4095 static int demux_qt_get_status (demux_plugin_t *this_gen) {
4096   demux_qt_t *this = (demux_qt_t *) this_gen;
4097 
4098   return this->status;
4099 }
4100 
demux_qt_get_stream_length(demux_plugin_t * this_gen)4101 static int demux_qt_get_stream_length (demux_plugin_t *this_gen) {
4102   demux_qt_t *this = (demux_qt_t *) this_gen;
4103   return this->qt.msecs;
4104 }
4105 
demux_qt_get_capabilities(demux_plugin_t * this_gen)4106 static uint32_t demux_qt_get_capabilities(demux_plugin_t *this_gen) {
4107   demux_qt_t *this = (demux_qt_t *) this_gen;
4108   return DEMUX_CAP_AUDIOLANG | (this->qt.video_trak >= 0 ? DEMUX_CAP_VIDEO_TIME : 0);
4109 }
4110 
demux_qt_get_optional_data(demux_plugin_t * this_gen,void * data,int data_type)4111 static int demux_qt_get_optional_data(demux_plugin_t *this_gen,
4112 					void *data, int data_type) {
4113   demux_qt_t *this = (demux_qt_t *) this_gen;
4114 
4115   /* be a bit paranoid */
4116   if (this == NULL || this->stream == NULL)
4117     return DEMUX_OPTIONAL_UNSUPPORTED;
4118 
4119   switch (data_type) {
4120     case DEMUX_OPTIONAL_DATA_AUDIOLANG: {
4121       char *str   = data;
4122       int channel = *((int *)data);
4123       if ((channel < 0) || (channel >= this->qt.audio_trak_count)) {
4124         strcpy (str, "none");
4125       } else {
4126         int lang = this->qt.traks[this->qt.audio_traks[channel]].lang;
4127         if ((lang < 0x400) || (lang == 0x7fff)) {
4128           sprintf (str, "%d", channel);
4129         } else {
4130           int i;
4131           for (i = 10; i >= 0; i -= 5)
4132             *str++ = 0x60 | ((lang >> i) & 0x1f);
4133           *str = 0;
4134         }
4135         return DEMUX_OPTIONAL_SUCCESS;
4136       }
4137     }
4138     break;
4139     case DEMUX_OPTIONAL_DATA_VIDEO_TIME:
4140       if (data && (this->qt.video_trak >= 0)) {
4141         qt_trak *trak = &this->qt.traks[this->qt.video_trak];
4142         int32_t vtime = (trak->frames[trak->current_frame].pts + trak->frames[trak->current_frame].ptsoffs) / 90;
4143         memcpy (data, &vtime, sizeof (vtime));
4144         return DEMUX_OPTIONAL_SUCCESS;
4145       }
4146     break;
4147     default: ;
4148   }
4149   return DEMUX_OPTIONAL_UNSUPPORTED;
4150 }
4151 
open_plugin(demux_class_t * class_gen,xine_stream_t * stream,input_plugin_t * input)4152 static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
4153                                     input_plugin_t *input) {
4154 
4155   demux_qt_t      *this;
4156   xine_cfg_entry_t entry;
4157   uint8_t         *moov_atom = NULL;
4158   off_t            moov_atom_offset;
4159   qt_error         last_error;
4160 
4161   if ((input->get_capabilities(input) & INPUT_CAP_BLOCK)) {
4162     return NULL;
4163   }
4164 
4165   switch (stream->content_detection_method) {
4166     case METHOD_BY_CONTENT:
4167     case METHOD_BY_MRL:
4168     case METHOD_EXPLICIT:
4169       break;
4170     default:
4171       return NULL;
4172   }
4173 
4174   last_error = load_moov_atom (input, &moov_atom, &moov_atom_offset);
4175   if (last_error != QT_OK)
4176     return NULL;
4177 
4178   /* check that the next atom in the chunk contains alphanumeric characters
4179    * in the atom type field; if not, disqualify the file as a QT file */
4180   if (_X_BE_32 (moov_atom) < 16) {
4181     free (moov_atom);
4182     return NULL;
4183   }
4184   {
4185     int i;
4186     for (i = 12; i < 16; i++) {
4187       if (!isalnum (moov_atom[i])) {
4188         free (moov_atom);
4189         return NULL;
4190       }
4191     }
4192   }
4193 
4194   this = calloc (1, sizeof (demux_qt_t));
4195   if (!this) {
4196     free (moov_atom);
4197     return NULL;
4198   }
4199 
4200   this->stream = stream;
4201   this->input  = input;
4202 
4203   /* fetch bandwidth config */
4204   this->bandwidth = 0x7FFFFFFFFFFFFFFFLL;  /* assume infinite bandwidth */
4205   if (xine_config_lookup_entry (stream->xine, "media.network.bandwidth",
4206                                 &entry)) {
4207     if ((entry.num_value >= 0) && (entry.num_value <= 11))
4208       this->bandwidth = bandwidths[entry.num_value];
4209   }
4210 
4211   this->demux_plugin.send_headers      = demux_qt_send_headers;
4212   this->demux_plugin.send_chunk        = demux_qt_send_chunk;
4213   this->demux_plugin.seek              = demux_qt_seek;
4214   this->demux_plugin.dispose           = demux_qt_dispose;
4215   this->demux_plugin.get_status        = demux_qt_get_status;
4216   this->demux_plugin.get_stream_length = demux_qt_get_stream_length;
4217   this->demux_plugin.get_capabilities  = demux_qt_get_capabilities;
4218   this->demux_plugin.get_optional_data = demux_qt_get_optional_data;
4219   this->demux_plugin.demux_class       = class_gen;
4220 
4221   this->status = DEMUX_FINISHED;
4222 
4223   create_qt_info (this);
4224 
4225   last_error = open_qt_file (this, moov_atom, moov_atom_offset);
4226 
4227   switch (stream->content_detection_method) {
4228     case METHOD_BY_CONTENT:
4229       if (last_error == QT_DRM_NOT_SUPPORTED) {
4230         /* special consideration for DRM-protected files */
4231         _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "DRM-protected Quicktime file", NULL);
4232         break;
4233       }
4234       /* fall through */
4235     default:
4236       if (last_error != QT_OK) {
4237         free_qt_info (this);
4238         free (this);
4239         return NULL;
4240       }
4241   }
4242 
4243   if (this->qt.fragment_count > 0)
4244     xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
4245       _("demux_qt: added %d fragments\n"), this->qt.fragment_count);
4246 
4247   return &this->demux_plugin;
4248 }
4249 
demux_qt_init_class(xine_t * xine,const void * data)4250 void *demux_qt_init_class (xine_t *xine, const void *data) {
4251   (void)xine;
4252   (void)data;
4253 
4254   static const demux_class_t demux_qt_class = {
4255     .open_plugin     = open_plugin,
4256     .description     = N_("Apple Quicktime (MOV) and MPEG-4 demux plugin"),
4257     .identifier      = "MOV/MPEG-4",
4258     .mimetypes       =
4259       "video/quicktime: mov,qt: Quicktime animation;"
4260       "video/x-quicktime: mov,qt: Quicktime animation;"
4261       "audio/x-m4a: m4a,m4b: MPEG-4 audio;"
4262       "video/mp4: f4v,mp4,mpg4: MPEG-4 video;"
4263       "audio/mp4: f4a,mp4,mpg4: MPEG-4 audio;",
4264     .extensions      = "mov qt mp4 m4a m4b f4a f4v",
4265     .dispose         = NULL,
4266   };
4267 
4268   return (void *)&demux_qt_class;
4269 }
4270