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