private void SeekToTimestampInternal(double timestamp, out double newTimestamp) { var oldTimestamp = currentTimestamp; reader.FrameQueue.Clear(); reader.AudioQueue.Clear(); previousFrames.Clear(); reader.SeekToTimestamp(timestamp); synchronization = null; while (reader.ReadNextPacket() && (reader.FrameQueue.Count == 0 || Math.Abs(reader.FrameQueue.Peek().Timestamp - oldTimestamp) < Math.Abs(reader.FrameQueue.Peek().Timestamp - timestamp))) { reader.FrameQueue.Clear(); reader.AudioQueue.Clear(); } if (TryEnsureFrameQueueNotEmpty()) { currentFrame = reader.FrameQueue.Dequeue(); newTimestamp = currentFrame.Timestamp; } else { // should never happen currentFrame = new MovieFrame { RgbaData = new byte[GraphicsHelper.AlignedSize(reader.Width, reader.Height)], Timestamp = timestamp }; newTimestamp = Movie.Duration; } }
public void GoToEnd() { SeekToTimestamp(Movie.Duration); while (reader.ReadNextPacket()) { while (reader.FrameQueue.Any()) { currentFrame = reader.FrameQueue.Dequeue(); } } State = MoviePlaybackState.End; currentTimestamp = Movie.Duration; }
public StandardMoviePlayback(IMovie movie) : base(ResourceVolatility.Volatile) { Movie = movie; reader = movie.Read(); videoSpeed = 1.0; frameImage = new MoviePlaybackImage(); currentFrame = new MovieFrame { RgbaData = new byte[GraphicsHelper.AlignedSize(reader.Width, reader.Height)], Timestamp = 0 }; }
public void OnUpdate(FrameTime frameTime) { switch (State) { case MoviePlaybackState.Stopped: break; case MoviePlaybackState.Playing: if (!synchronization.HasValue) { synchronization = new Synchronization { RealTime = frameTime.TotalSeconds, MovieFrameTimestamp = currentTimestamp }; } var realTimePassed = frameTime.TotalSeconds - synchronization.Value.RealTime; var signedSpeed = playingReversed ? -videoSpeed : videoSpeed; currentTimestamp = Math.Max(0, realTimePassed * signedSpeed + synchronization.Value.MovieFrameTimestamp); if (playingReversed) { while (currentFrame.Timestamp > currentTimestamp) { if (previousFrames.Count == 0 && !TryFillFrameStack(currentTimestamp)) { ReverseDirection(); return; } currentFrame = previousFrames.Pop(); } } else { var continueGettingNext = true; do { if (!TryEnsureFrameQueueNotEmpty()) { if (currentTimestamp >= Movie.Duration) { State = MoviePlaybackState.End; } return; } var nextFrame = reader.FrameQueue.Peek(); if (nextFrame.Timestamp <= currentTimestamp) { currentFrame = reader.FrameQueue.Dequeue(); } else { continueGettingNext = false; } } while (continueGettingNext); } break; case MoviePlaybackState.Paused: break; case MoviePlaybackState.End: break; default: throw new ArgumentOutOfRangeException(); } if (currentFrame.RgbaData != frameImage.RgbaData) { // todo: size to frame? frameImage.Update(new IntSize2(reader.Width, reader.Height), currentFrame.RgbaData); } }