bool QuickTimeParser::parseFile(const String &filename) { if (!_resFork->open(filename) || !_resFork->hasDataFork()) return false; _foundMOOV = false; _disposeFileHandle = DisposeAfterUse::YES; Atom atom = { 0, 0, 0 }; if (_resFork->hasResFork()) { // Search for a 'moov' resource MacResIDArray idArray = _resFork->getResIDArray(MKTAG('m', 'o', 'o', 'v')); if (!idArray.empty()) _fd = _resFork->getResource(MKTAG('m', 'o', 'o', 'v'), idArray[0]); if (_fd) { atom.size = _fd->size(); if (readDefault(atom) < 0 || !_foundMOOV) return false; } delete _fd; } _fd = _resFork->getDataFork(); atom.size = _fd->size(); if (readDefault(atom) < 0 || !_foundMOOV) return false; init(); return true; }
int QuickTimeParser::readMOOV(Atom atom) { if (readDefault(atom) < 0) return -1; // We parsed the 'moov' atom, so we don't need anything else _foundMOOV = true; return 1; }
int QuickTimeParser::readTRAK(Atom atom) { Track *track = new Track(); track->codecType = CODEC_TYPE_MOV_OTHER; track->startTime = 0; // XXX: check _tracks.push_back(track); return readDefault(atom); }
int QuickTimeDecoder::readTRAK(MOVatom atom) { MOVStreamContext *sc = new MOVStreamContext(); if (!sc) return -1; sc->codec_type = CODEC_TYPE_MOV_OTHER; sc->start_time = 0; // XXX: check _streams[_numStreams++] = sc; return readDefault(atom); }
int QuickTimeParser::readCMOV(Atom atom) { #ifdef USE_ZLIB // Read in the dcom atom _fd->readUint32BE(); if (_fd->readUint32BE() != MKTAG('d', 'c', 'o', 'm')) return -1; if (_fd->readUint32BE() != MKTAG('z', 'l', 'i', 'b')) { warning("Unknown cmov compression type"); return -1; } // Read in the cmvd atom uint32 compressedSize = _fd->readUint32BE() - 12; if (_fd->readUint32BE() != MKTAG('c', 'm', 'v', 'd')) return -1; uint32 uncompressedSize = _fd->readUint32BE(); // Read in data byte *compressedData = (byte *)malloc(compressedSize); _fd->read(compressedData, compressedSize); // Create uncompressed stream byte *uncompressedData = (byte *)malloc(uncompressedSize); // Uncompress the data unsigned long dstLen = uncompressedSize; if (!uncompress(uncompressedData, &dstLen, compressedData, compressedSize)) { warning ("Could not uncompress cmov chunk"); free(compressedData); free(uncompressedData); return -1; } // Load data into a new MemoryReadStream and assign _fd to be that SeekableReadStream *oldStream = _fd; _fd = new MemoryReadStream(uncompressedData, uncompressedSize, DisposeAfterUse::YES); // Read the contents of the uncompressed data Atom a = { MKTAG('m', 'o', 'o', 'v'), 0, uncompressedSize }; int err = readDefault(a); // Assign the file handle back to the original handle free(compressedData); delete _fd; _fd = oldStream; return err; #else warning ("zlib not found, cannot read QuickTime cmov atom"); return -1; #endif }
bool QuickTimeDecoder::loadFile(const Common::String &filename) { if (!_resFork->open(filename) || !_resFork->hasDataFork()) return false; _foundMOOV = false; _numStreams = 0; _videoStreamIndex = _audioStreamIndex = -1; _startTime = 0; MOVatom atom = { 0, 0, 0xffffffff }; if (_resFork->hasResFork()) { // Search for a 'moov' resource Common::MacResIDArray idArray = _resFork->getResIDArray(MKID_BE('moov')); if (!idArray.empty()) _fd = _resFork->getResource(MKID_BE('moov'), idArray[0]); if (_fd) { atom.size = _fd->size(); if (readDefault(atom) < 0 || !_foundMOOV) return false; } delete _fd; atom.type = 0; atom.offset = 0; atom.size = 0xffffffff; } _fd = _resFork->getDataFork(); if (readDefault(atom) < 0 || !_foundMOOV) return false; init(); return true; }
bool QuickTimeParser::parseStream(SeekableReadStream *stream, DisposeAfterUse::Flag disposeFileHandle) { _fd = stream; _foundMOOV = false; _disposeFileHandle = disposeFileHandle; Atom atom = { 0, 0, 0xffffffff }; if (readDefault(atom) < 0 || !_foundMOOV) { close(); return false; } init(); return true; }
bool QuickTimeDecoder::loadStream(Common::SeekableReadStream *stream) { _fd = stream; _foundMOOV = false; _numStreams = 0; _videoStreamIndex = _audioStreamIndex = -1; _startTime = 0; MOVatom atom = { 0, 0, 0xffffffff }; if (readDefault(atom) < 0 || !_foundMOOV) { _fd = 0; return false; } init(); return true; }
int QuickTimeParser::readWAVE(Atom atom) { if (_tracks.empty()) return 0; Track *track = _tracks.back(); if (atom.size > (1 << 30)) return -1; if (track->sampleDescs[0]->getCodecTag() == MKTAG('Q', 'D', 'M', '2')) // Read extra data for QDM2 track->extraData = _fd->readStream(atom.size - 8); else if (atom.size > 8) return readDefault(atom); else _fd->skip(atom.size); return 0; }
int QuickTimeParser::readSTSD(Atom atom) { Track *track = _tracks.back(); _fd->readByte(); // version _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags uint32 entryCount = _fd->readUint32BE(); track->sampleDescs.resize(entryCount); for (uint32 i = 0; i < entryCount; i++) { // Parsing Sample description table Atom a = { 0, 0, 0 }; uint32 start_pos = _fd->pos(); int size = _fd->readUint32BE(); // size uint32 format = _fd->readUint32BE(); // data format _fd->readUint32BE(); // reserved _fd->readUint16BE(); // reserved _fd->readUint16BE(); // index track->sampleDescs[i] = readSampleDesc(track, format); debug(0, "size=%d 4CC= %s codec_type=%d", size, tag2str(format), track->codecType); if (!track->sampleDescs[i]) { // other codec type, just skip (rtp, mp4s, tmcd ...) _fd->seek(size - (_fd->pos() - start_pos), SEEK_CUR); } // this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) a.size = size - (_fd->pos() - start_pos); if (a.size > 8) readDefault(a); else if (a.size > 0) _fd->seek(a.size, SEEK_CUR); } return 0; }
int QuickTimeParser::readWAVE(Atom atom) { if (_tracks.empty()) return 0; Track *track = _tracks.back(); if (atom.size > (1 << 30)) return -1; // We should only get here within an stsd atom if (track->sampleDescs.empty()) return -1; SampleDesc *sampleDesc = track->sampleDescs.back(); if (sampleDesc->getCodecTag() == MKTAG('Q', 'D', 'M', '2')) // Read extra data for QDM2 sampleDesc->_extraData = _fd->readStream(atom.size); else if (atom.size > 8) return readDefault(atom); else _fd->skip(atom.size); return 0; }