Example #1
0
bool VideoDecoder::seek(const Audio::Timestamp &time) {
	if (!isSeekable())
		return false;

	// Stop all tracks so they can be seeked
	if (isPlaying())
		stopAudio();

	// Do the actual seeking
	if (!seekIntern(time))
		return false;

	// Seek any external track too
	for (TrackListIterator it = _externalTracks.begin(); it != _externalTracks.end(); it++)
		if (!(*it)->seek(time))
			return false;

	_lastTimeChange = time;

	// Now that we've seeked, start all tracks again
	// Also reset our start time
	if (isPlaying()) {
		startAudio();
		_startTime = g_system->getMillis() - (time.msecs() / _playbackRate).toInt();
	}

	resetPauseStartTime();
	findNextVideoTrack();
	_needsUpdate = true;
	return true;
}
Example #2
0
const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
	if (!_nextVideoTrack)
		return 0;

	const Graphics::Surface *frame = _nextVideoTrack->decodeNextFrame();

	if (!_setStartTime) {
		_startTime = g_system->getMillis();
		_setStartTime = true;
	}

	_nextVideoTrack = findNextVideoTrack();
	_needUpdate = false;

	// Update audio buffers too
	// (needs to be done after we find the next track)
	updateAudioBuffer();

	// We have to initialize the scaled surface
	if (frame && (_scaleFactorX != 1 || _scaleFactorY != 1)) {
		if (!_scaledSurface) {
			_scaledSurface = new Graphics::Surface();
			_scaledSurface->create(_width, _height, getPixelFormat());
		}

		scaleSurface(frame, _scaledSurface, _scaleFactorX, _scaleFactorY);
		return _scaledSurface;
	}

	return frame;
}
Example #3
0
void QuickTimeDecoder::init() {
	Audio::QuickTimeAudioDecoder::init();

	// Initialize all the audio tracks
	for (uint32 i = 0; i < _audioTracks.size(); i++)
		addTrack(new AudioTrackHandler(this, _audioTracks[i]));

	// Initialize all the video tracks
	const Common::Array<Common::QuickTimeParser::Track *> &tracks = Common::QuickTimeParser::_tracks;
	for (uint32 i = 0; i < tracks.size(); i++) {
		if (tracks[i]->codecType == CODEC_TYPE_VIDEO) {
			for (uint32 j = 0; j < tracks[i]->sampleDescs.size(); j++)
				((VideoSampleDesc *)tracks[i]->sampleDescs[j])->initCodec();

			addTrack(new VideoTrackHandler(this, tracks[i]));
		}
	}

	// Prepare the first video track
	VideoTrackHandler *nextVideoTrack = (VideoTrackHandler *)findNextVideoTrack();

	if (nextVideoTrack) {
		if (_scaleFactorX != 1 || _scaleFactorY != 1) {
			// We have to take the scale into consideration when setting width/height
			_width = (nextVideoTrack->getScaledWidth() / _scaleFactorX).toInt();
			_height = (nextVideoTrack->getScaledHeight() / _scaleFactorY).toInt();
		} else {
			_width = nextVideoTrack->getWidth();
			_height = nextVideoTrack->getHeight();
		}
	}
}
Example #4
0
const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
	if (!_nextVideoTrack)
		return 0;

	const Graphics::Surface *frame = _nextVideoTrack->decodeNextFrame();

	if (!_setStartTime) {
		_startTime = g_system->getMillis();
		_setStartTime = true;
	}

	_nextVideoTrack = findNextVideoTrack();
	_needUpdate = false;

	// Update audio buffers too
	// (needs to be done after we find the next track)
	updateAudioBuffer();

	if (_scaledSurface) {
		scaleSurface(frame, _scaledSurface, _scaleFactorX, _scaleFactorY);
		return _scaledSurface;
	}

	return frame;
}
Example #5
0
const Graphics::Surface *AVIDecoder::decodeNextFrame() {
	AVIVideoTrack *track = nullptr;
	bool isReversed = false;
	int frameNum = 0;

	// Check whether the video is playing in revese
	for (int idx = _videoTracks.size() - 1; idx >= 0; --idx) {
		track = static_cast<AVIVideoTrack *>(_videoTracks[idx].track);
		isReversed |= track->isReversed();
	}

	if (isReversed) {
		// For reverse mode we need to keep seeking to just before the
		// desired frame prior to actually decoding a frame
		frameNum = getCurFrame();
		seekIntern(track->getFrameTime(frameNum));
	}

	// Decode the next frame
	const Graphics::Surface *frame = VideoDecoder::decodeNextFrame();

	if (isReversed) {
		// In reverse mode, set next frame to be the prior frame number
		for (int idx = _videoTracks.size() - 1; idx >= 0; --idx) {
			track = static_cast<AVIVideoTrack *>(_videoTracks[idx].track);
			track->setCurFrame(frameNum - 1);
			findNextVideoTrack();
		}
	}

	return frame;
}
Example #6
0
void QuickTimeDecoder::init() {
	Audio::QuickTimeAudioDecoder::init();

	_startTime = 0;
	_setStartTime = false;

	// Initialize all the audio tracks
	if (!_audioTracks.empty()) {
		_audioHandles.resize(_audioTracks.size());

		for (uint32 i = 0; i < _audioTracks.size(); i++)
			_handlers.push_back(new AudioTrackHandler(this, _audioTracks[i]));
	}

	// Initialize all the video tracks
	for (uint32 i = 0; i < _tracks.size(); i++) {
		if (_tracks[i]->codecType == CODEC_TYPE_VIDEO) {
			for (uint32 j = 0; j < _tracks[i]->sampleDescs.size(); j++)
				((VideoSampleDesc *)_tracks[i]->sampleDescs[j])->initCodec();

			_handlers.push_back(new VideoTrackHandler(this, _tracks[i]));
		}
	}

	// Prepare the first video track
	_nextVideoTrack = findNextVideoTrack();

	if (_nextVideoTrack) {
		// Initialize the scaled surface
		if (_scaleFactorX != 1 || _scaleFactorY != 1) {
			// We have to initialize the scaled surface
			_scaledSurface = new Graphics::Surface();
			_scaledSurface->create((_nextVideoTrack->getWidth() / _scaleFactorX).toInt(),
					(_nextVideoTrack->getHeight() / _scaleFactorY).toInt(), getPixelFormat());
			_width = _scaledSurface->w;
			_height = _scaledSurface->h;
		} else {
			_width = _nextVideoTrack->getWidth().toInt();
			_height = _nextVideoTrack->getHeight().toInt();
		}

		_needUpdate = true;
	} else {
		_needUpdate = false;
	}

	// Now start any audio
	if (!_audioTracks.empty()) {
		startAudio();
		_audioStartOffset = Audio::Timestamp(0);
	}
}
Example #7
0
uint32 VideoDecoder::getTimeToNextFrame() const {
	if (endOfVideo() || _needsUpdate)
		return 0;

	const VideoTrack *track = findNextVideoTrack();

	if (!track)
		return 0;

	uint32 elapsedTime = getTime();
	uint32 nextFrameStartTime = track->getNextFrameStartTime();

	if (nextFrameStartTime <= elapsedTime)
		return 0;

	return nextFrameStartTime - elapsedTime;
}
Example #8
0
bool VideoDecoder::setReverse(bool reverse) {
	// Can only reverse video-only videos
	if (reverse && hasAudio())
		return false;

	// Attempt to make sure all the tracks are in the requested direction
	for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) {
		if ((*it)->getTrackType() == Track::kTrackTypeVideo && ((VideoTrack *)*it)->isReversed() != reverse) {
			if (!((VideoTrack *)*it)->setReverse(reverse))
				return false;

			_needsUpdate = true; // force an update
		}
	}

	findNextVideoTrack();
	return true;
}
Example #9
0
const Graphics::Surface *VideoDecoder::decodeNextFrame() {
	_needsUpdate = false;

	readNextPacket();
	VideoTrack *track = findNextVideoTrack();

	if (!track)
		return 0;

	const Graphics::Surface *frame = track->decodeNextFrame();

	if (track->hasDirtyPalette()) {
		_palette = track->getPalette();
		_dirtyPalette = true;
	}

	return frame;
}
Example #10
0
void QuickTimeDecoder::seekToTime(const Audio::Timestamp &time) {
	stopAudio();
	_audioStartOffset = time;

	// Sets all tracks to this time
	for (uint32 i = 0; i < _handlers.size(); i++)
		_handlers[i]->seekToTime(time);

	startAudio();

	// Reset our start time
	_startTime = g_system->getMillis() - time.msecs();
	_setStartTime = true;
	resetPauseStartTime();

	// Reset the next video track too
	_nextVideoTrack = findNextVideoTrack();
	_needUpdate = _nextVideoTrack != 0;
}
Example #11
0
bool VideoDecoder::rewind() {
	if (!isRewindable())
		return false;

	// Stop all tracks so they can be rewound
	if (isPlaying())
		stopAudio();

	for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
		if (!(*it)->rewind())
			return false;

	// Now that we've rewound, start all tracks again
	if (isPlaying())
		startAudio();

	_lastTimeChange = 0;
	_startTime = g_system->getMillis();
	resetPauseStartTime();
	findNextVideoTrack();
	return true;
}
Example #12
0
const Graphics::Surface *VideoDecoder::decodeNextFrame() {
	_needsUpdate = false;

	readNextPacket();

	// If we have no next video track at this point, there shouldn't be
	// any frame available for us to display.
	if (!_nextVideoTrack)
		return 0;

	const Graphics::Surface *frame = _nextVideoTrack->decodeNextFrame();

	if (_nextVideoTrack->hasDirtyPalette()) {
		_palette = _nextVideoTrack->getPalette();
		_dirtyPalette = true;
	}

	// Look for the next video track here for the next decode.
	findNextVideoTrack();

	return frame;
}