Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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);
}
Exemple #4
0
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);
}
Exemple #5
0
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
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}
Exemple #10
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;
}
Exemple #11
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;
}