예제 #1
0
void SmackerDecoder::readNextPacket() {
	SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0);

	if (videoTrack->endOfTrack())
		return;

	videoTrack->increaseCurFrame();

	uint i;
	uint32 chunkSize = 0;
	uint32 dataSizeUnpacked = 0;

	uint32 startPos = _fileStream->pos();

	// Check if we got a frame with palette data, and
	// call back the virtual setPalette function to set
	// the current palette
	if (_frameTypes[videoTrack->getCurFrame()] & 1)
		videoTrack->unpackPalette(_fileStream);

	// Load audio tracks
	for (i = 0; i < 7; ++i) {
		if (!(_frameTypes[videoTrack->getCurFrame()] & (2 << i)))
			continue;

		chunkSize = _fileStream->readUint32LE();
		chunkSize -= 4;    // subtract the first 4 bytes (chunk size)

		if (_header.audioInfo[i].compression == kCompressionNone) {
			dataSizeUnpacked = chunkSize;
		} else {
			dataSizeUnpacked = _fileStream->readUint32LE();
			chunkSize -= 4;    // subtract the next 4 bytes (unpacked data size)
		}

		handleAudioTrack(i, chunkSize, dataSizeUnpacked);
	}

	uint32 frameSize = _frameSizes[videoTrack->getCurFrame()] & ~3;
//	uint32 remainder =  _frameSizes[videoTrack->getCurFrame()] & 3;

	if (_fileStream->pos() - startPos > frameSize)
		error("Smacker actual frame size exceeds recorded frame size");

	uint32 frameDataSize = frameSize - (_fileStream->pos() - startPos);

	byte *frameData = (byte *)malloc(frameDataSize + 1);
	// Padding to keep the BigHuffmanTrees from reading past the data end
	frameData[frameDataSize] = 0x00;

	_fileStream->read(frameData, frameDataSize);

	Common::BitStream8LSB bs(new Common::MemoryReadStream(frameData, frameDataSize + 1, DisposeAfterUse::YES), true);
	videoTrack->decodeFrame(bs);

	_fileStream->seek(startPos + frameSize);
}
예제 #2
0
void NeverhoodSmackerDecoder::forceSeekToFrame(uint frame) {
	if (!isVideoLoaded())
		return;

	if (frame >= getFrameCount())
		error("Can't force Smacker seek to invalid frame %d", frame);

	if (_header.audioInfo[0].hasAudio)
		error("Can't force Smacker frame seek with audio");
	if (!rewind())
		error("Failed to rewind");

	SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0);
	uint32 offset = 0;
	for (uint32 i = 0; i < frame; i++) {
		videoTrack->increaseCurFrame();
		offset += _frameSizes[i] & ~3;
	}

	_fileStream->seek(offset, SEEK_CUR);
}