Esempio n. 1
0
const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame() {
	if (endOfTrack())
		return 0;

	const Graphics::Surface *frame = bufferNextFrame();

	if (_holdNextFrameStartTime) {
		// Don't set the next frame start time here; we just did a seek
		_holdNextFrameStartTime = false;
	} else if (_durationOverride >= 0) {
		// Use our own duration from the edit list calculation
		_nextFrameStartTime += _durationOverride;
		_durationOverride = -1;
	} else {
		_nextFrameStartTime += getFrameDuration();
	}

	// Update the edit list, if applicable
	// HACK: We're also accepting the time minus one because edit lists
	// aren't as accurate as one would hope.
	if (!endOfTrack() && getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1) {
		_curEdit++;

		if (!endOfTrack())
			enterNewEditList(true);
	}

	if (_scaledSurface) {
		_decoder->scaleSurface(frame, _scaledSurface, _parent->scaleFactorX, _parent->scaleFactorY);
		return _scaledSurface;
	}

	return frame;
}
Esempio n. 2
0
QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : TrackHandler(decoder, parent) {
	enterNewEditList(false);

	_holdNextFrameStartTime = false;
	_curFrame = -1;
	_durationOverride = -1;
	_scaledSurface = 0;
}
Esempio n. 3
0
QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : _decoder(decoder), _parent(parent) {
	_curEdit = 0;
	enterNewEditList(false);

	_holdNextFrameStartTime = false;
	_curFrame = -1;
	_durationOverride = -1;
	_scaledSurface = 0;
	_curPalette = 0;
	_dirtyPalette = false;
	_reversed = false;
}
Esempio n. 4
0
QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : TrackHandler(decoder, parent) {
	if (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1) {
		_scaledSurface = new Graphics::Surface();
		_scaledSurface->create(getWidth().toInt(), getHeight().toInt(), getPixelFormat());
	} else {
		_scaledSurface = 0;
	}

	enterNewEditList(false);

	_holdNextFrameStartTime = false;
	_curFrame = -1;
	_durationOverride = -1;

}
Esempio n. 5
0
void QuickTimeDecoder::VideoTrackHandler::seekToTime(Audio::Timestamp time) {
	// First, figure out what edit we're in
	time = time.convertToFramerate(_parent->timeScale);

	// Continue until we get to where we need to be
	for (_curEdit = 0; !endOfTrack(); _curEdit++)
		if ((uint32)time.totalNumberOfFrames() >= getCurEditTimeOffset() && (uint32)time.totalNumberOfFrames() < getCurEditTimeOffset() + getCurEditTrackDuration())
			break;

	// This track is done
	if (endOfTrack())
		return;

	enterNewEditList(false);

	// One extra check for the end of a track
	if (endOfTrack())
		return;

	// Now we're in the edit and need to figure out what frame we need
	while (getRateAdjustedFrameTime() < (uint32)time.totalNumberOfFrames()) {
		_curFrame++;
		if (_durationOverride >= 0) {
			_nextFrameStartTime += _durationOverride;
			_durationOverride = -1;
		} else {
			_nextFrameStartTime += getFrameDuration();
		}
	}

	// All that's left is to figure out what our starting time is going to be
	// Compare the starting point for the frame to where we need to be
	_holdNextFrameStartTime = getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames();

	// If we went past the time, go back a frame
	if (_holdNextFrameStartTime)
		_curFrame--;

	// Handle the keyframe here
	int32 destinationFrame = _curFrame + 1;

	assert(destinationFrame < (int32)_parent->frameCount);
	_curFrame = findKeyFrame(destinationFrame) - 1;
	while (_curFrame < destinationFrame - 1)
		bufferNextFrame();
}
Esempio n. 6
0
const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame() {
	if (endOfTrack())
		return 0;

	if (_reversed) {
		// Subtract one to place us on the frame before the current displayed frame.
		_curFrame--;

		// We have one "dummy" frame at the end to so the last frame is displayed
		// for the right amount of time.
		if (_curFrame < 0)
			return 0;

		// Decode from the last key frame to the frame before the one we need.
		// TODO: Probably would be wise to do some caching
		int targetFrame = _curFrame;
		_curFrame = findKeyFrame(targetFrame) - 1;
		while (_curFrame != targetFrame - 1)
			bufferNextFrame();
	}

	const Graphics::Surface *frame = bufferNextFrame();

	if (_reversed) {
		if (_holdNextFrameStartTime) {
			// Don't set the next frame start time here; we just did a seek
			_holdNextFrameStartTime = false;
		} else {
			// Just need to subtract the time
			_nextFrameStartTime -= getFrameDuration();
		}
	} else {
		if (_holdNextFrameStartTime) {
			// Don't set the next frame start time here; we just did a seek
			_holdNextFrameStartTime = false;
		} else if (_durationOverride >= 0) {
			// Use our own duration from the edit list calculation
			_nextFrameStartTime += _durationOverride;
			_durationOverride = -1;
		} else {
			_nextFrameStartTime += getFrameDuration();
		}

		// Update the edit list, if applicable
		// HACK: We're also accepting the time minus one because edit lists
		// aren't as accurate as one would hope.
		if (!atLastEdit() && getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1) {
			_curEdit++;

			if (!atLastEdit())
				enterNewEditList(true);
		}
	}

	if (frame && (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1)) {
		if (!_scaledSurface) {
			_scaledSurface = new Graphics::Surface();
			_scaledSurface->create(getScaledWidth().toInt(), getScaledHeight().toInt(), getPixelFormat());
		}

		_decoder->scaleSurface(frame, _scaledSurface, _parent->scaleFactorX, _parent->scaleFactorY);
		return _scaledSurface;
	}

	return frame;
}
Esempio n. 7
0
bool QuickTimeDecoder::VideoTrackHandler::seek(const Audio::Timestamp &requestedTime) {
	uint32 convertedFrames = requestedTime.convertToFramerate(_decoder->_timeScale).totalNumberOfFrames();
	for (_curEdit = 0; !atLastEdit(); _curEdit++)
		if (convertedFrames >= _parent->editList[_curEdit].timeOffset && convertedFrames < _parent->editList[_curEdit].timeOffset + _parent->editList[_curEdit].trackDuration)
			break;

	// If we did reach the end of the track, break out
	if (atLastEdit())
		return true;

	// If this track is in an empty edit, position us at the next non-empty
	// edit. There's nothing else to do after this.
	if (_parent->editList[_curEdit].mediaTime == -1) {
		while (!atLastEdit() && _parent->editList[_curEdit].mediaTime == -1)
			_curEdit++;

		if (!atLastEdit())
			enterNewEditList(true);

		return true;
	}

	enterNewEditList(false);

	// One extra check for the end of a track
	if (atLastEdit())
		return true;

	// Now we're in the edit and need to figure out what frame we need
	Audio::Timestamp time = requestedTime.convertToFramerate(_parent->timeScale);
	while (getRateAdjustedFrameTime() < (uint32)time.totalNumberOfFrames()) {
		_curFrame++;
		if (_durationOverride >= 0) {
			_nextFrameStartTime += _durationOverride;
			_durationOverride = -1;
		} else {
			_nextFrameStartTime += getFrameDuration();
		}
	}

	// All that's left is to figure out what our starting time is going to be
	// Compare the starting point for the frame to where we need to be
	_holdNextFrameStartTime = getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames();

	// If we went past the time, go back a frame. _curFrame before this point is at the frame
	// that should be displayed. This adjustment ensures it is on the frame before the one that
	// should be displayed.
	if (_holdNextFrameStartTime)
		_curFrame--;

	if (_reversed) {
		// Call setReverse again to update
		setReverse(true);
	} else {
		// Handle the keyframe here
		int32 destinationFrame = _curFrame + 1;

		assert(destinationFrame < (int32)_parent->frameCount);
		_curFrame = findKeyFrame(destinationFrame) - 1;
		while (_curFrame < destinationFrame - 1)
			bufferNextFrame();
	}

	return true;
}