xoreos  0.0.5
quicktime.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 /* Based on the Quicktime implementation in FFmpeg (<https://ffmpeg.org/)>,
26  * which is released under the terms of version 2 or later of the GNU
27  * Lesser General Public License.
28  *
29  * The original copyright note in libavformat/mov.c reads as follows:
30  *
31  * MOV demuxer
32  * Copyright (c) 2001 Fabrice Bellard
33  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
34  *
35  * first version by Francois Revol <revol@free.fr>
36  * seek function by Gael Chardon <gael.dev@4now.net>
37  *
38  * This file is part of FFmpeg.
39  *
40  * FFmpeg is free software; you can redistribute it and/or
41  * modify it under the terms of the GNU Lesser General Public
42  * License as published by the Free Software Foundation; either
43  * version 2.1 of the License, or (at your option) any later version.
44  *
45  * FFmpeg is distributed in the hope that it will be useful,
46  * but WITHOUT ANY WARRANTY; without even the implied warranty of
47  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
48  * Lesser General Public License for more details.
49  *
50  * You should have received a copy of the GNU Lesser General Public
51  * License along with FFmpeg; if not, write to the Free Software
52  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
53  */
54 
55 #include <cassert>
56 #include <cstring>
57 
58 #include "src/common/system.h"
59 #include "src/common/error.h"
62 
63 #include "src/video/quicktime.h"
64 #include "src/video/codecs/codec.h"
65 
66 #include "src/sound/audiostream.h"
67 
68 
69 // Audio codecs
70 #ifdef ENABLE_FAAD
71 #include "src/sound/decoders/aac.h"
72 #endif
74 #include "src/sound/decoders/pcm.h"
75 
76 // Video codecs
77 #ifdef ENABLE_XVIDCORE
78 #include "src/video/codecs/h263.h"
79 #endif
80 
81 namespace Video {
82 
84 // QuickTimeDecoder
86 
87 static const char *tag2str(uint32 tag) {
88  static char string[5];
89  string[0] = (tag >> 24) & 0xff;
90  string[1] = (tag >> 16) & 0xff;
91  string[2] = (tag >> 8) & 0xff;
92  string[3] = tag & 0xff;
93  string[4] = 0;
94  return string;
95 }
96 
98  _foundMOOV(false), _videoTrackIndex(-1) {
99 
100  assert(_fd);
101 
102  initParseTable();
103 
104  load();
105 }
106 
108 }
109 
111  Atom atom = { 0, 0, 0xffffffff };
112 
113  if (readDefault(atom) < 0 || !_foundMOOV)
114  throw Common::Exception("Not a valid QuickTime video");
115 
116  // Remove unknown/unhandled tracks
117  for (size_t i = 0; i < _tracks.size(); i++) {
118  if (_tracks[i]->codecType == CODEC_TYPE_MOV_OTHER) {
119  _tracks.erase(_tracks.begin() + i);
120  i--;
121  }
122  }
123 
124  // Adjust time scale and find the video track
125  for (size_t i = 0; i < _tracks.size(); i++) {
126  if (!_tracks[i]->timeScale)
127  _tracks[i]->timeScale = _timeScale;
128 
129  if (_tracks[i]->codecType == CODEC_TYPE_VIDEO && _videoTrackIndex < 0)
130  _videoTrackIndex = i;
131 
132  }
133 
134  // We only support playing if there is a video track
135  if (_videoTrackIndex < 0)
136  throw Common::Exception("No video tracks");
137 
138  // Initialize video codec, if present
139  for (size_t i = 0; i < _tracks[_videoTrackIndex]->sampleDescs.size(); i++)
140  dynamic_cast<VideoSampleDesc &>(*_tracks[_videoTrackIndex]->sampleDescs[i]).initCodec();
141 
142  // Add the video track
144 
145  // Initialize all the audio tracks, but ignore ones we can't process
146  for (uint32 i = 0; i < _tracks.size(); i++) {
147  if (_tracks[i]->codecType == CODEC_TYPE_AUDIO && static_cast<AudioSampleDesc *>(_tracks[i]->sampleDescs[0])->isAudioCodecSupported()) {
148  _audioTracks.push_back(new QuickTimeAudioTrack(this, _tracks[i]));
149  addTrack(new AudioTrackHandler(this, _audioTracks.back()));
150  break;
151  }
152  }
153 
154  initVideo();
155 }
156 
158  if (track->codecType == CODEC_TYPE_VIDEO) {
159  Common::ScopedPtr<VideoSampleDesc> entry(new VideoSampleDesc(track, format));
160 
161  _fd->readUint16BE(); // version
162  _fd->readUint16BE(); // revision level
163  _fd->readUint32BE(); // vendor
164  _fd->readUint32BE(); // temporal quality
165  _fd->readUint32BE(); // spacial quality
166 
167  uint16 width = _fd->readUint16BE(); // width
168  uint16 height = _fd->readUint16BE(); // height
169 
170  // The width is most likely invalid for entries after the first one
171  // so only set the overall width if it is not zero here.
172  if (width)
173  track->width = width;
174 
175  if (height)
176  track->height = height;
177 
178  _fd->readUint32BE(); // horiz resolution
179  _fd->readUint32BE(); // vert resolution
180  _fd->readUint32BE(); // data size, always 0
181  _fd->readUint16BE(); // frames per samples
182 
183  byte codecName[32];
184  _fd->read(codecName, 32); // codec name, pascal string (FIXME: true for mp4?)
185  if (codecName[0] <= 31) {
186  std::memcpy(entry->_codecName, &codecName[1], codecName[0]);
187  entry->_codecName[codecName[0]] = 0;
188  }
189 
190  entry->_bitsPerSample = _fd->readUint16BE(); // depth
191  entry->_colorTableId = _fd->readUint16BE(); // colortable id
192 
193  // figure out the palette situation
194  byte colorDepth = entry->_bitsPerSample & 0x1F;
195 
196  // if the depth is 2, 4, or 8 bpp, file is palettized
197  if (colorDepth == 2 || colorDepth == 4 || colorDepth == 8)
198  throw Common::Exception("No paletted video support");
199 
200  return entry.release();
201  } else if (track->codecType == CODEC_TYPE_AUDIO) {
202  Common::ScopedPtr<AudioSampleDesc> entry(new AudioSampleDesc(track, format));
203 
204  uint16 stsdVersion = _fd->readUint16BE();
205  _fd->readUint16BE(); // revision level
206  _fd->readUint32BE(); // vendor
207 
208  entry->_channels = _fd->readUint16BE(); // channel count
209  entry->_bitsPerSample = _fd->readUint16BE(); // sample size
210 
211  _fd->readUint16BE(); // compression id = 0
212  _fd->readUint16BE(); // packet size = 0
213 
214  entry->_sampleRate = (_fd->readUint32BE() >> 16);
215 
216  if (stsdVersion == 0) {
217  // Not used, except in special cases. See below.
218  entry->_samplesPerFrame = entry->_bytesPerFrame = 0;
219  } else if (stsdVersion == 1) {
220  // Read QT version 1 fields. In version 0 these dont exist.
221  entry->_samplesPerFrame = _fd->readUint32BE();
222  _fd->readUint32BE(); // bytes per packet
223  entry->_bytesPerFrame = _fd->readUint32BE();
224  _fd->readUint32BE(); // bytes per sample
225  } else {
226  warning("Unsupported QuickTime STSD audio version %d", stsdVersion);
227  return 0;
228  }
229 
230  // Version 0 videos (such as the Riven ones) don't have this set,
231  // but we need it later on. Add it in here.
232  if (format == MKTAG('i', 'm', 'a', '4')) {
233  entry->_samplesPerFrame = 64;
234  entry->_bytesPerFrame = 34 * entry->_channels;
235  }
236 
237  if (entry->_sampleRate == 0 && track->timeScale > 1)
238  entry->_sampleRate = track->timeScale;
239 
240  return entry.release();
241  }
242 
243  return 0;
244 }
245 
247  if (_videoTrackIndex < 0 || _tracks[_videoTrackIndex]->sampleDescs.empty())
248  return 0;
249 
250  return dynamic_cast<VideoSampleDesc &>(*_tracks[_videoTrackIndex]->sampleDescs[0])._videoCodec.get();
251 }
252 
254  _needCopy = static_cast<VideoTrackHandler &>(track).decodeNextFrame(*_surface);
255 }
256 
258  static const ParseTable p[] = {
259  { &QuickTimeDecoder::readDefault, MKTAG('d', 'i', 'n', 'f') },
260  { &QuickTimeDecoder::readLeaf, MKTAG('d', 'r', 'e', 'f') },
261  { &QuickTimeDecoder::readDefault, MKTAG('e', 'd', 't', 's') },
262  { &QuickTimeDecoder::readELST, MKTAG('e', 'l', 's', 't') },
263  { &QuickTimeDecoder::readHDLR, MKTAG('h', 'd', 'l', 'r') },
264  { &QuickTimeDecoder::readLeaf, MKTAG('m', 'd', 'a', 't') },
265  { &QuickTimeDecoder::readMDHD, MKTAG('m', 'd', 'h', 'd') },
266  { &QuickTimeDecoder::readDefault, MKTAG('m', 'd', 'i', 'a') },
267  { &QuickTimeDecoder::readDefault, MKTAG('m', 'i', 'n', 'f') },
268  { &QuickTimeDecoder::readMOOV, MKTAG('m', 'o', 'o', 'v') },
269  { &QuickTimeDecoder::readMVHD, MKTAG('m', 'v', 'h', 'd') },
270  { &QuickTimeDecoder::readLeaf, MKTAG('s', 'm', 'h', 'd') },
271  { &QuickTimeDecoder::readDefault, MKTAG('s', 't', 'b', 'l') },
272  { &QuickTimeDecoder::readSTCO, MKTAG('s', 't', 'c', 'o') },
273  { &QuickTimeDecoder::readSTSC, MKTAG('s', 't', 's', 'c') },
274  { &QuickTimeDecoder::readSTSD, MKTAG('s', 't', 's', 'd') },
275  { &QuickTimeDecoder::readSTSS, MKTAG('s', 't', 's', 's') },
276  { &QuickTimeDecoder::readSTSZ, MKTAG('s', 't', 's', 'z') },
277  { &QuickTimeDecoder::readSTTS, MKTAG('s', 't', 't', 's') },
278  { &QuickTimeDecoder::readTRAK, MKTAG('t', 'r', 'a', 'k') },
279  { &QuickTimeDecoder::readLeaf, MKTAG('u', 'd', 't', 'a') },
280  { &QuickTimeDecoder::readLeaf, MKTAG('v', 'm', 'h', 'd') },
281  { &QuickTimeDecoder::readDefault, MKTAG('w', 'a', 'v', 'e') },
282  { &QuickTimeDecoder::readESDS, MKTAG('e', 's', 'd', 's') },
283  { 0, 0 }
284  };
285 
286  _parseTable = p;
287 }
288 
290  uint32 total_size = 0;
291  Atom a;
292  int err = 0;
293 
294  a.offset = atom.offset;
295 
296  while (((total_size + 8) < atom.size) && !_fd->eos() && _fd->pos() < _fd->size() && !err) {
297  a.size = atom.size;
298  a.type = 0;
299 
300  if (atom.size >= 8) {
301  a.size = _fd->readUint32BE();
302  a.type = _fd->readUint32BE();
303 
304  // Some QuickTime videos with resource forks have mdat chunks
305  // that are of size 0. Adjust it so it's the correct size.
306  if (a.type == MKTAG('m', 'd', 'a', 't') && a.size == 0)
307  a.size = _fd->size();
308  }
309 
310  total_size += 8;
311  a.offset += 8;
312 
313  if (a.size == 1) { // 64 bit extended size
314  warning("64 bit extended size is not supported in QuickTime");
315  return -1;
316  }
317 
318  if (a.size == 0) {
319  a.size = atom.size - total_size;
320  if (a.size <= 8)
321  break;
322  }
323 
324  uint32 i = 0;
325 
326  for (; _parseTable[i].type != 0 && _parseTable[i].type != a.type; i++)
327  ; // Empty
328 
329  if (a.size < 8)
330  break;
331 
332  a.size -= 8;
333 
334  if (_parseTable[i].type == 0) {
335  // skip leaf atoms data
336  _fd->skip(a.size);
337  } else {
338  size_t start_pos = _fd->pos();
339  err = (this->*_parseTable[i].func)(a);
340 
341  size_t left = a.size - _fd->pos() + start_pos;
342 
343  if (left > 0) // skip garbage at atom end
344  _fd->skip(left);
345  }
346 
347  a.offset += a.size;
348  total_size += a.size;
349  }
350 
351  if (!err && total_size < atom.size)
352  _fd->seek(atom.size - total_size);
353 
354  return err;
355 }
356 
358  if (atom.size > 1)
359  _fd->seek(atom.size);
360 
361  return 0;
362 }
363 
365  if (readDefault(atom) < 0)
366  return -1;
367 
368  // We parsed the 'moov' atom, so we don't need anything else
369  _foundMOOV = true;
370  return 1;
371 }
372 
374  byte version = _fd->readByte(); // version
375  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
376 
377  if (version == 1) {
378  warning("QuickTime version 1");
379  _fd->readUint32BE(); _fd->readUint32BE();
380  _fd->readUint32BE(); _fd->readUint32BE();
381  } else {
382  _fd->readUint32BE(); // creation time
383  _fd->readUint32BE(); // modification time
384  }
385 
386  _timeScale = _fd->readUint32BE(); // time scale
387 
388  // We're just skipping *everything* else in this atom :P
389 
390  return 0;
391 }
392 
394  QuickTimeTrack *track = new QuickTimeTrack();
395 
396  if (!track)
397  return -1;
398 
400  track->startTime = 0; // XXX: check
401  _tracks.push_back(track);
402 
403  return readDefault(atom);
404 }
405 
406 // edit list atom
408  _fd->readByte(); // version
409  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
410  uint32 editCount = _fd->readUint32BE(); // entries
411 
412  for (uint32 i = 0; i < editCount; i++){
413  _fd->readUint32BE(); // Track duration
414  _fd->readUint32BE(); // Media time
415  _fd->readUint32BE(); // Media rate
416  }
417 
418  if (editCount != 1)
419  warning("Multiple edit list entries. Things may go awry");
420 
421  return 0;
422 }
423 
425  QuickTimeTrack *track = _tracks.back();
426 
427  _fd->readByte(); // version
428  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
429 
430  // component type
431  /* uint32 ctype = */ _fd->readUint32BE();
432  uint32 type = _fd->readUint32BE(); // component subtype
433 
434  if (type == MKTAG('v', 'i', 'd', 'e'))
435  track->codecType = CODEC_TYPE_VIDEO;
436  else if (type == MKTAG('s', 'o', 'u', 'n'))
437  track->codecType = CODEC_TYPE_AUDIO;
438 
439  _fd->readUint32BE(); // component manufacture
440  _fd->readUint32BE(); // component flags
441  _fd->readUint32BE(); // component flags mask
442 
443  if (atom.size <= 24)
444  return 0; // nothing left to read
445 
446  // .mov: PASCAL string
447  byte len = _fd->readByte();
448  _fd->skip(len);
449 
450  _fd->skip(atom.size - (_fd->pos() - atom.offset));
451 
452  return 0;
453 }
454 
456  QuickTimeTrack *track = _tracks.back();
457  byte version = _fd->readByte();
458 
459  if (version > 1)
460  return 1; // unsupported
461 
462  _fd->readByte(); _fd->readByte();
463  _fd->readByte(); // flags
464 
465  if (version == 1) {
466  _fd->readUint32BE(); _fd->readUint32BE();
467  _fd->readUint32BE(); _fd->readUint32BE();
468  } else {
469  _fd->readUint32BE(); // creation time
470  _fd->readUint32BE(); // modification time
471  }
472 
473  track->timeScale = _fd->readUint32BE();
474  track->duration = (version == 1) ? (_fd->readUint32BE(), _fd->readUint32BE()) : _fd->readUint32BE(); // duration
475 
476  _fd->readUint16BE(); // language
477  _fd->readUint16BE(); // quality
478 
479  return 0;
480 }
481 
483  QuickTimeTrack *track = _tracks.back();
484 
485  _fd->readByte(); // version
486  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
487 
488  uint32 entryCount = _fd->readUint32BE();
489  track->sampleDescs.reserve(entryCount);
490 
491  for (uint32 i = 0; i < entryCount; i++) { // Parsing Sample description table
492  Atom a = { 0, 0, 0 };
493  size_t start_pos = _fd->pos();
494  int size = _fd->readUint32BE(); // size
495  uint32 format = _fd->readUint32BE(); // data format
496 
497  _fd->readUint32BE(); // reserved
498  _fd->readUint16BE(); // reserved
499  _fd->readUint16BE(); // index
500 
501  track->sampleDescs.push_back(readSampleDesc(track, format));
502 
503  if (!track->sampleDescs[i]) {
504  // other codec type, just skip (rtp, mp4s, tmcd ...)
505  _fd->skip(size - (_fd->pos() - start_pos));
506  }
507 
508  // this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...)
509  a.size = size - (_fd->pos() - start_pos);
510  if (a.size > 8)
511  readDefault(a);
512  else if (a.size > 0)
513  _fd->skip(a.size);
514  }
515 
516  return 0;
517 }
518 
520  QuickTimeTrack *track = _tracks.back();
521 
522  _fd->readByte(); // version
523  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
524 
525  track->sampleToChunkCount = _fd->readUint32BE();
526 
527  track->sampleToChunk.reset(new SampleToChunkEntry[track->sampleToChunkCount]);
528 
529  if (!track->sampleToChunk)
530  return -1;
531 
532  for (uint32 i = 0; i < track->sampleToChunkCount; i++) {
533  track->sampleToChunk[i].first = _fd->readUint32BE() - 1;
534  track->sampleToChunk[i].count = _fd->readUint32BE();
535  track->sampleToChunk[i].id = _fd->readUint32BE();
536  //warning("Sample to Chunk[%d]: First = %d, Count = %d", i, track->sampleToChunk[i].first, track->sampleToChunk[i].count);
537  }
538 
539  return 0;
540 }
541 
543  QuickTimeTrack *track = _tracks.back();
544 
545  _fd->readByte(); // version
546  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
547 
548  track->keyframeCount = _fd->readUint32BE();
549  track->keyframes.reset(new uint32[track->keyframeCount]);
550 
551  if (!track->keyframes)
552  return -1;
553 
554  for (uint32 i = 0; i < track->keyframeCount; i++)
555  track->keyframes[i] = _fd->readUint32BE() - 1; // Adjust here, the frames are based on 1
556 
557  return 0;
558 }
559 
561  QuickTimeTrack *track = _tracks.back();
562 
563  _fd->readByte(); // version
564  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
565 
566  track->sampleSize = _fd->readUint32BE();
567  track->sampleCount = _fd->readUint32BE();
568 
569  if (track->sampleSize)
570  return 0; // there isn't any table following
571 
572  track->sampleSizes.reset(new uint32[track->sampleCount]);
573 
574  if (!track->sampleSizes)
575  return -1;
576 
577  for (uint32 i = 0; i < track->sampleCount; i++)
578  track->sampleSizes[i] = _fd->readUint32BE();
579 
580  return 0;
581 }
582 
584  QuickTimeTrack *track = _tracks.back();
585  uint32 totalSampleCount = 0;
586 
587  _fd->readByte(); // version
588  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
589 
590  track->timeToSampleCount = _fd->readUint32BE();
591  track->timeToSample.reset(new TimeToSampleEntry[track->timeToSampleCount]);
592 
593  for (int32 i = 0; i < track->timeToSampleCount; i++) {
594  track->timeToSample[i].count = _fd->readUint32BE();
595  track->timeToSample[i].duration = _fd->readUint32BE();
596 
597  totalSampleCount += track->timeToSample[i].count;
598  }
599 
600  track->frameCount = totalSampleCount;
601 
602  return 0;
603 }
604 
606  QuickTimeTrack *track = _tracks.back();
607 
608  _fd->readByte(); // version
609  _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
610 
611  track->chunkCount = _fd->readUint32BE();
612  track->chunkOffsets.reset(new uint32[track->chunkCount]);
613 
614  if (!track->chunkOffsets)
615  return -1;
616 
617  for (uint32 i = 0; i < track->chunkCount; i++)
618  track->chunkOffsets[i] = _fd->readUint32BE();
619 
620  return 0;
621 }
622 
623 enum {
628 };
629 
631  int length = 0;
632  int count = 4;
633 
634  while (count--) {
635  byte c = stream->readByte();
636  length = (length << 7) | (c & 0x7f);
637 
638  if (!(c & 0x80))
639  break;
640  }
641 
642  return length;
643 }
644 
645 static void readMP4Desc(Common::SeekableReadStream *stream, byte &tag, int &length) {
646  tag = stream->readByte();
647  length = readMP4DescLength(stream);
648 }
649 
651  if (_tracks.empty())
652  return 0;
653 
654  QuickTimeTrack *track = _tracks.back();
655 
656  // We should only get here within an stsd atom
657  if (track->sampleDescs.empty())
658  return -1;
659 
660  SampleDesc *sampleDesc = track->sampleDescs.back();
661 
662  _fd->readUint32BE(); // version + flags
663 
664  byte tag;
665  int length;
666 
667  readMP4Desc(_fd.get(), tag, length);
668  _fd->readUint16BE(); // id
669  if (tag == kMP4ESDescTag)
670  _fd->readByte(); // priority
671 
672  // Check if we've got the Config MPEG-4 header
673  readMP4Desc(_fd.get(), tag, length);
674  if (tag != kMP4DecConfigDescTag)
675  return 0;
676 
677  sampleDesc->_objectTypeMP4 = _fd->readByte();
678  _fd->readByte(); // stream type
679  _fd->readUint16BE(); _fd->readByte(); // buffer size
680  _fd->readUint32BE(); // max bitrate
681  _fd->readUint32BE(); // avg bitrate
682 
683  // Check if we've got the Specific MPEG-4 header
684  readMP4Desc(_fd.get(), tag, length);
685  if (tag != kMP4DecSpecificDescTag)
686  return 0;
687 
688  sampleDesc->_extraData.reset(_fd->readStream(length));
689 
690  return 0;
691 }
692 
694  _parentTrack = parentTrack;
695  _codecTag = codecTag;
696  _objectTypeMP4 = 0;
697 }
698 
699 QuickTimeDecoder::QuickTimeTrack::QuickTimeTrack() : chunkCount(0), timeToSampleCount(0), sampleToChunkCount(0),
700  sampleSize(0), sampleCount(0), keyframeCount(0), timeScale(0), width(0), height(0),
701  codecType(CODEC_TYPE_MOV_OTHER), frameCount(0), duration(0), startTime(0) {
702 
703 }
704 
706  _channels = 0;
707  _sampleRate = 0;
708  _samplesPerFrame = 0;
709  _bytesPerFrame = 0;
710  _bitsPerSample = 0;
711 }
712 
714  // Check if the codec is a supported codec
715  if (_codecTag == MKTAG('t', 'w', 'o', 's') ||
716  _codecTag == MKTAG('r', 'a', 'w', ' ') ||
717  _codecTag == MKTAG('i', 'm', 'a', '4'))
718  return true;
719 
720  if (_codecTag == MKTAG('m', 'p', '4', 'a')) {
721  Common::UString audioType;
722 
723  switch (_objectTypeMP4) {
724  case 0x40:
725 #ifdef ENABLE_FAAD
726  return true;
727 #else
728  audioType = "AAC";
729  break;
730 #endif
731  default:
732  audioType = "Unknown";
733  break;
734  }
735 
736  warning("No MPEG-4 audio (%s) support", audioType.c_str());
737  } else
738  warning("Audio Codec Not Supported: \'%s\'", tag2str(_codecTag));
739 
740  return false;
741 }
742 
744  switch (_codecTag) {
745  case MKTAG('t', 'w', 'o', 's'):
746  case MKTAG('r', 'a', 'w', ' '): {
747  uint16 flags = 0;
748  if (_codecTag == MKTAG('r', 'a', 'w', ' '))
749  flags |= Sound::FLAG_UNSIGNED;
750  if (_bitsPerSample == 16)
751  flags |= Sound::FLAG_16BITS;
752  return Sound::makePacketizedPCMStream(_sampleRate, flags, _channels);
753  }
754  case MKTAG('i', 'm', 'a', '4'):
755  return Sound::makePacketizedADPCMStream(Sound::kADPCMApple, _sampleRate, _channels, 34);
756  case MKTAG('m', 'p', '4', 'a'):
757  switch (_objectTypeMP4) {
758  case 0x40:
759  return Sound::makeAACStream(*_extraData);
760  }
761  break;
762  }
763 
764  return 0;
765 }
766 
768  static_cast<AudioTrackHandler &>(track).updateBuffer(endTime);
769 }
770 
772  std::memset(_codecName, 0, 32);
773  _colorTableId = 0;
774  _bitsPerSample = 0;
775 }
776 
778 }
779 
781  _videoCodec.reset();
782 
783  if (_codecTag == MKTAG('m', 'p', '4', 'v')) {
784  Common::UString videoType;
785 
786  // Parse the object type
787  switch (_objectTypeMP4) {
788  case 0x20:
789  videoType = "h.263";
790 
791  if (!_extraData) {
792  warning("Missing h.263 extra data; cannot decode");
793  break;
794  }
795 
796 #ifdef ENABLE_XVIDCORE
797  _videoCodec.reset(makeH263Codec(_parentTrack->width, _parentTrack->height, *_extraData));
798 #else
799  warning("H.263 decoding disabled when building without xvidcore");
800 #endif
801  break;
802 
803  default:
804  videoType = "Unknown";
805  break;
806  }
807 
808  if (!_videoCodec)
809  warning("MPEG-4 Video (%s) not yet supported", videoType.c_str());
810 
811  } else if (_codecTag == MKTAG('S', 'V', 'Q', '3')) {
812  // TODO: Sorenson Video 3
813  warning("Sorenson Video 3 not yet supported");
814  } else {
815  warning("Unsupported codec \'%s\'", tag2str(_codecTag));
816  }
817 }
818 
820  _decoder = decoder;
821  _parentTrack = parentTrack;
822  _curChunk = 0;
823  _samplesQueued = 0;
824 
825  AudioSampleDesc *entry = (AudioSampleDesc *)_parentTrack->sampleDescs[0];
826 
827  if (entry->getCodecTag() == MKTAG('r', 'a', 'w', ' ') || entry->getCodecTag() == MKTAG('t', 'w', 'o', 's'))
828  _parentTrack->sampleSize = (entry->_bitsPerSample / 8) * entry->_channels;
829 
830  // Create the new packetized audio stream
831  _stream.reset(static_cast<AudioSampleDesc *>(_parentTrack->sampleDescs[0])->createAudioStream());
832  _skipAACPrimer = true;
833 }
834 
836  if (allAudioQueued() || (length.totalNumberOfFrames() != 0 && Common::Timestamp(0, _samplesQueued, getRate()) >= length))
837  return;
838 
839  do {
840  // Normal audio
841  Common::ScopedPtr<Common::SeekableReadStream> stream(readAudioChunk(_curChunk));
842  Common::Timestamp chunkLength = getChunkLength(_curChunk, _skipAACPrimer);
843  _skipAACPrimer = false;
844  _curChunk++;
845 
846  // Queue up the packet
847  _stream->queuePacket(stream.release());
848  _samplesQueued += chunkLength.convertToFramerate(getRate()).totalNumberOfFrames();
849  } while (!allAudioQueued() && Common::Timestamp(0, _samplesQueued, getRate()) < length);
850 
851  if (allAudioQueued())
852  _stream->finish();
853 }
854 
856  return _parentTrack->timeToSampleCount == 1 && _parentTrack->timeToSample[0].duration == 1;
857 }
858 
860  AudioSampleDesc *entry = (AudioSampleDesc *)_parentTrack->sampleDescs[0];
862 
863  _decoder->_fd->seek(_parentTrack->chunkOffsets[chunk]);
864 
865  // First, we have to get the sample count
866  uint32 sampleCount = getAudioChunkSampleCount(chunk);
867  assert(sampleCount != 0);
868 
869  if (isOldDemuxing()) {
870  // Old-style audio demuxing
871 
872  // Then calculate the right sizes
873  while (sampleCount > 0) {
874  uint32 samples = 0, size = 0;
875 
876  if (entry->_samplesPerFrame >= 160) {
877  samples = entry->_samplesPerFrame;
878  size = entry->_bytesPerFrame;
879  } else if (entry->_samplesPerFrame > 1) {
880  samples = MIN<uint32>((1024 / entry->_samplesPerFrame) * entry->_samplesPerFrame, sampleCount);
881  size = (samples / entry->_samplesPerFrame) * entry->_bytesPerFrame;
882  } else {
883  samples = MIN<uint32>(1024, sampleCount);
884  size = samples * _parentTrack->sampleSize;
885  }
886 
887  // Now, we read in the data for this data and output it
888  Common::ScopedArray<byte> data(new byte[size]);
889  _decoder->_fd->read(data.get(), size);
890  wStream->write(data.get(), size);
891  sampleCount -= samples;
892  }
893  } else {
894  // New-style audio demuxing
895 
896  // Find our starting sample
897  uint32 startSample = 0;
898  for (uint32 i = 0; i < chunk; i++)
899  startSample += getAudioChunkSampleCount(i);
900 
901  for (uint32 i = 0; i < sampleCount; i++) {
902  uint32 size = (_parentTrack->sampleSize != 0) ? _parentTrack->sampleSize : _parentTrack->sampleSizes[i + startSample];
903 
904  // Now, we read in the data for this data and output it
905  Common::ScopedArray<byte> data(new byte[size]);
906  _decoder->_fd->read(data.get(), size);
907  wStream->write(data.get(), size);
908  }
909  }
910 
911  return new Common::MemoryReadStream(wStream->getData(), wStream->size(), true);
912 }
913 
915  uint32 sampleCount = 0;
916 
917  for (uint32 i = 0; i < _parentTrack->sampleToChunkCount; i++)
918  if (chunk >= _parentTrack->sampleToChunk[i].first)
919  sampleCount = _parentTrack->sampleToChunk[i].count;
920 
921  return sampleCount;
922 }
923 
925  uint32 chunkSampleCount = getAudioChunkSampleCount(chunk);
926 
927  if (isOldDemuxing())
928  return Common::Timestamp(0, chunkSampleCount, getRate());
929 
930  // AAC needs some extra handling, of course
931  return Common::Timestamp(0, getAACSampleTime(chunkSampleCount, skipAACPrimer), getRate());
932 }
933 
934 uint32 QuickTimeDecoder::QuickTimeAudioTrack::getAACSampleTime(uint32 totalSampleCount, bool skipAACPrimer) const{
935  uint32 curSample = 0;
936  uint32 time = 0;
937 
938  for (int32 i = 0; i < _parentTrack->timeToSampleCount; i++) {
939  uint32 sampleCount = _parentTrack->timeToSample[i].count;
940 
941  if (totalSampleCount < curSample + sampleCount) {
942  time += (totalSampleCount - curSample) * _parentTrack->timeToSample[i].duration;
943  break;
944  }
945 
946  time += _parentTrack->timeToSample[i].count * _parentTrack->timeToSample[i].duration;
947  curSample += sampleCount;
948  }
949 
950  // The first chunk of AAC contains "duration" samples that are used as a primer
951  // We need to subtract that number from the duration for the first chunk. See:
952  // http://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFAppenG/QTFFAppenG.html#//apple_ref/doc/uid/TP40000939-CH2-SW1
953  // The skipping of both the primer and the remainder are handled by the AAC code,
954  // whereas the timing of the remainder are handled by this time-to-sample chunk
955  // code already.
956  // We have to do this after each time we reinitialize the codec
957  if (skipAACPrimer) {
958  assert(_parentTrack->timeToSampleCount > 0);
959  time -= _parentTrack->timeToSample[0].duration;
960  }
961 
962  return time;
963 }
964 
965 QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, QuickTimeTrack *parent) : _decoder(decoder), _parent(parent), _curFrame(-1), _nextFrameStartTime(0) {
966 }
967 
969  return Common::Timestamp(0, _parent->duration, _decoder->_timeScale);
970 }
971 
973  return _parent->width;
974 }
975 
977  return _parent->height;
978 }
979 
981  return _parent->frameCount;
982 }
983 
985  if (endOfTrack())
986  return Common::Timestamp();
987 
988  return Common::Timestamp(0, _nextFrameStartTime, _parent->timeScale);
989 }
990 
992  _curFrame++;
993  _nextFrameStartTime += getFrameDuration();
994 
995  // Get the next packet
996  uint32 descId;
997  Common::ScopedPtr<Common::SeekableReadStream> frameData(getNextFramePacket(descId));
998 
999  if (!frameData || !descId || descId > _parent->sampleDescs.size())
1000  return false;
1001 
1002  // Find which video description entry we want
1003  VideoSampleDesc &entry = dynamic_cast<VideoSampleDesc &>(*_parent->sampleDescs[descId - 1]);
1004  if (!entry._videoCodec)
1005  return false;
1006 
1007  entry._videoCodec->decodeFrame(surface, *frameData);
1008  return true;
1009 }
1010 
1012  // First, we have to track down which chunk holds the sample and which sample in the chunk contains the frame we are looking for.
1013  int32 totalSampleCount = 0;
1014  int32 sampleInChunk = 0;
1015  int32 actualChunk = -1;
1016  uint32 sampleToChunkIndex = 0;
1017 
1018  for (uint32 i = 0; i < _parent->chunkCount; i++) {
1019  if (sampleToChunkIndex < _parent->sampleToChunkCount && i >= _parent->sampleToChunk[sampleToChunkIndex].first)
1020  sampleToChunkIndex++;
1021 
1022  totalSampleCount += _parent->sampleToChunk[sampleToChunkIndex - 1].count;
1023 
1024  if (totalSampleCount > _curFrame) {
1025  actualChunk = i;
1026  descId = _parent->sampleToChunk[sampleToChunkIndex - 1].id;
1027  sampleInChunk = _parent->sampleToChunk[sampleToChunkIndex - 1].count - totalSampleCount + _curFrame;
1028  break;
1029  }
1030  }
1031 
1032  if (actualChunk < 0)
1033  error("Could not find data for frame %d", _curFrame);
1034 
1035  // Next seek to that frame
1036  _decoder->_fd->seek(_parent->chunkOffsets[actualChunk]);
1037 
1038  // Then, if the chunk holds more than one frame, seek to where the frame we want is located
1039  for (int32 i = _curFrame - sampleInChunk; i < _curFrame; i++) {
1040  if (_parent->sampleSize != 0)
1041  _decoder->_fd->skip(_parent->sampleSize);
1042  else
1043  _decoder->_fd->skip(_parent->sampleSizes[i]);
1044  }
1045 
1046  // Finally, read in the raw data for the frame
1047  //printf("Frame Data[%d]: Offset = %d, Size = %d\n", _curFrame, stream->pos(), _parent->sampleSizes[_curFrame]);
1048 
1049  if (_parent->sampleSize != 0)
1050  return _decoder->_fd->readStream(_parent->sampleSize);
1051 
1052  return _decoder->_fd->readStream(_parent->sampleSizes[_curFrame]);
1053 }
1054 
1056  uint32 curFrameIndex = 0;
1057  for (int32 i = 0; i < _parent->timeToSampleCount; i++) {
1058  curFrameIndex += _parent->timeToSample[i].count;
1059  if ((uint32)_curFrame < curFrameIndex) {
1060  // Ok, now we have what duration this frame has.
1061  return _parent->timeToSample[i].duration;
1062  }
1063  }
1064 
1065  // This should never occur
1066  throw Common::Exception("Cannot find duration for frame %d", _curFrame);
1067 }
1068 
1069 
1071  : _decoder(decoder), _audioTrack(audioTrack) {
1072 }
1073 
1075  _audioTrack->queueAudio(endTime);
1076 }
1077 
1079  return _audioTrack;
1080 }
1081 
1083  return !_audioTrack->endOfStream();
1084 }
1085 
1086 } // End of namespace Video
int readELST(Atom atom)
Definition: quicktime.cpp:407
Common::ScopedPtr< Graphics::Surface > _surface
The video&#39;s surface.
Definition: decoder.h:393
PacketizedAudioStream * makePacketizedADPCMStream(ADPCMTypes type, int rate, int channels, uint32 blockAlign)
Creates a PacketizedAudioStream that will automatically queue packets as individual AudioStreams like...
Definition: adpcm.cpp:673
Common::ScopedArray< TimeToSampleEntry > timeToSample
Definition: quicktime.h:177
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
void checkAudioBuffer(AudioTrack &track, const Common::Timestamp &endTime)
Ensure that there is enough audio buffered in the given track to reach the given timestamp.
Definition: quicktime.cpp:767
AudioSampleDesc(QuickTimeTrack *parentTrack, uint32 codecTag)
Definition: quicktime.cpp:705
int64 totalNumberOfFrames() const
Return the time in frames described by this timestamp.
Definition: timestamp.h:209
PacketizedAudioStream * makePacketizedPCMStream(int rate, byte flags, int channels)
Creates a PacketizedAudioStream that will automatically queue packets as individual AudioStreams like...
Definition: pcm.cpp:171
An abstract representation of an audio track.
Definition: decoder.h:302
AudioTrackHandler(QuickTimeDecoder *decoder, QuickTimeAudioTrack *audioTrack)
Definition: quicktime.cpp:1070
A stream that dynamically grows as it&#39;s written to.
bool decodeNextFrame(Graphics::Surface &surface)
Definition: quicktime.cpp:991
Common::Timestamp getChunkLength(uint chunk, bool skipAACPrimer=false) const
Definition: quicktime.cpp:924
A class holding an UTF-8 string.
Definition: ustring.h:48
PacketizedAudioStream * makeAACStream(Common::SeekableReadStream &extraData)
Create a PacketizedAudioStream that decodes AAC sound.
Definition: aac.cpp:140
VideoSampleDesc(QuickTimeTrack *parentTrack, uint32 codecTag)
Definition: quicktime.cpp:771
void reset(PointerType o=0)
Resets the pointer with the new value.
Definition: scopedptr.h:87
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
Definition: scopedptr.h:103
int readMOOV(Atom atom)
Definition: quicktime.cpp:364
void addTrack(Track *track, bool isExternal=false)
Define a track to be used by this class.
Definition: decoder.cpp:152
bool _needCopy
Is new frame content available that needs to by copied?
Definition: decoder.h:391
Sound::PacketizedAudioStream * createAudioStream() const
Definition: quicktime.cpp:743
Common::ScopedPtr< Common::SeekableReadStream > _fd
Definition: quicktime.h:94
Common::ScopedArray< uint32 > chunkOffsets
Definition: quicktime.h:175
void updateBuffer(const Common::Timestamp &endTime)
Definition: quicktime.cpp:1074
Implementing the reading stream interfaces for plain memory blocks.
int readSTSD(Atom atom)
Definition: quicktime.cpp:482
int readSTTS(Atom atom)
Definition: quicktime.cpp:583
Sound::AudioStream * getAudioStream() const
Definition: quicktime.cpp:1078
Common::ScopedArray< SampleToChunkEntry > sampleToChunk
Definition: quicktime.h:179
Video codec base class.
Common::SeekableReadStream * readAudioChunk(uint chunk)
Definition: quicktime.cpp:859
unsigned samples (default: signed)
Definition: pcm.h:69
Decoding PCM (Pulse Code Modulation).
uint32 getAACSampleTime(uint32 totalSampleCount, bool skipAACPrimer=false) const
Definition: quicktime.cpp:934
static void readMP4Desc(Common::SeekableReadStream *stream, byte &tag, int &length)
Definition: quicktime.cpp:645
int readMVHD(Atom atom)
Definition: quicktime.cpp:373
SampleDesc(QuickTimeTrack *parentTrack, uint32 codecTag)
Definition: quicktime.cpp:693
uint32 getHeight() const
Get the height of this track.
Definition: quicktime.cpp:976
void initVideo()
Create a surface for video of these dimensions.
Definition: decoder.cpp:71
VideoTrackHandler(QuickTimeDecoder *decoder, QuickTimeTrack *parent)
Definition: quicktime.cpp:965
int readLeaf(Atom atom)
Definition: quicktime.cpp:357
int readMDHD(Atom atom)
Definition: quicktime.cpp:455
Basic exceptions to throw.
Decoding ADPCM (Adaptive Differential Pulse Code Modulation).
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
static const char * tag2str(uint32 tag)
Definition: quicktime.cpp:87
Common::PtrVector< SampleDesc > sampleDescs
Definition: quicktime.h:191
QuickTimeDecoder(Common::SeekableReadStream *stream)
Definition: quicktime.cpp:97
uint16_t uint16
Definition: types.h:202
#define UNUSED(x)
Definition: system.h:170
h.263 video codec.
int readSTSZ(Atom atom)
Definition: quicktime.cpp:560
Implementing the writing stream interfaces for memory blocks.
An AudioStream designed to work in terms of packets.
Definition: audiostream.h:271
Common::Timestamp getDuration() const
Get the duration of the track.
Definition: quicktime.cpp:968
void queueAudio(const Common::Timestamp &length=Common::Timestamp())
Definition: quicktime.cpp:835
Common::ScopedPtr< Codec > _videoCodec
Definition: quicktime.h:162
Simple memory based &#39;stream&#39;, which implements the ReadStream interface for a plain memory block...
Definition: memreadstream.h:66
uint32 getWidth() const
Get the width of this track.
Definition: quicktime.cpp:972
StackException Exception
Definition: error.h:59
An abstract representation of a video track.
Definition: decoder.h:226
Decoding AAC.
A scoped plain pointer, allowing pointer-y access and normal deletion.
Definition: scopedptr.h:120
SampleDesc * readSampleDesc(QuickTimeTrack *track, uint32 format)
Definition: quicktime.cpp:157
void warning(const char *s,...)
Definition: util.cpp:33
Common::ScopedArray< uint32 > sampleSizes
Definition: quicktime.h:182
Common::ScopedArray< uint32 > keyframes
Definition: quicktime.h:184
int readSTSS(Atom atom)
Definition: quicktime.cpp:542
Common::Timestamp getNextFrameStartTime() const
Get the start time of the next frame since the start of the video.
Definition: quicktime.cpp:984
int readTRAK(Atom atom)
Definition: quicktime.cpp:393
sound is 16 bits wide (default: 8bit)
Definition: pcm.h:72
Generic audio input stream.
Definition: audiostream.h:70
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
QuickTimeAudioTrack(QuickTimeDecoder *decoder, QuickTimeTrack *parentTrack)
Definition: quicktime.cpp:819
static int readMP4DescLength(Common::SeekableReadStream *stream)
Definition: quicktime.cpp:630
int readHDLR(Atom atom)
Definition: quicktime.cpp:424
Decoding Apple QuickTime videos.
void decodeNextTrackFrame(VideoTrack &track)
Decode enough data for the next frame.
Definition: quicktime.cpp:253
Common::PtrVector< QuickTimeTrack > _tracks
Definition: quicktime.h:277
uint32_t uint32
Definition: types.h:204
Common::ScopedPtr< Common::SeekableReadStream > _extraData
Definition: quicktime.h:127
Decoder for QuickTime videos.
Definition: quicktime.h:84
Low-level detection of architecture/system properties.
int readSTSC(Atom atom)
Definition: quicktime.cpp:519
Timestamps allow specifying points in time and measuring time intervals with a sub-millisecond granul...
Definition: timestamp.h:108
Codec * makeH263Codec(int width, int height, Common::SeekableReadStream &extraData)
Create a Codec capable of decoding h.263 frames.
Definition: h263.cpp:138
int readDefault(Atom atom)
Definition: quicktime.cpp:289
Common::PtrVector< QuickTimeAudioTrack > _audioTracks
Definition: quicktime.h:282
void NORETURN_PRE error(const char *s,...)
Definition: util.cpp:86
uint32 getAudioChunkSampleCount(uint chunk) const
Definition: quicktime.cpp:914
const ParseTable * _parseTable
Definition: quicktime.h:274
Common::SeekableReadStream * getNextFramePacket(uint32 &descId)
Definition: quicktime.cpp:1011
int(QuickTimeDecoder::* func)(Atom atom)
Definition: quicktime.h:103
Interface for a seekable & readable data stream.
Definition: readstream.h:265
Streaming audio.
byte readByte()
Read an unsigned byte from the stream and return it.
Definition: readstream.h:92
int readSTCO(Atom atom)
Definition: quicktime.cpp:605
Codec * findDefaultVideoCodec() const
Definition: quicktime.cpp:246
uint8 byte
Definition: types.h:209
Timestamp convertToFramerate(uint64 newFramerate) const
Return a timestamp which represents as closely as possible the point in time describes by this timest...
Definition: timestamp.cpp:98
int getFrameCount() const
Get the frame count of this track.
Definition: quicktime.cpp:980
unsigned int uint
Definition: types.h:211
int readESDS(Atom atom)
Definition: quicktime.cpp:650
int32_t int32
Definition: types.h:203