/// <summary> /// Performs a seek operation to the specified position. /// </summary> /// <param name="position">The position.</param> private void Seek(TimeSpan position) { SeekingDone.Wait(); var startTime = DateTime.UtcNow; var resumeClock = Clock.IsRunning; Clock.Pause(); SeekingDone.Reset(); PacketReadingCycle.Wait(); FrameDecodingCycle.Wait(); BlockRenderingCycle.Wait(); // Clear Blocks and frames, reset the render times foreach (var t in Container.Components.MediaTypes) { Frames[t].Clear(); Blocks[t].Clear(); LastRenderTime[t] = TimeSpan.MinValue; } // Populate frame with after-seek operation var frames = Container.Seek(position); foreach (var frame in frames) { Frames[frame.MediaType].Push(frame); } // Resume the clock if it was running before the seek operation OnPropertyChanged(nameof(Position)); if (resumeClock) { Clock.Play(); } Container.Log(MediaLogMessageType.Debug, $"SEEK D: Elapsed: {startTime.DebugElapsedUtc()}"); RequestedSeekPosition = null; SeekingDone.Set(); }
public async Task CloseAsync() { Container?.Log(MediaLogMessageType.Debug, $"{nameof(CloseAsync)}: Entered"); Clock.Pause(); IsTaskCancellationPending = true; // Wait for cycles to complete. await Task.Run(() => { while (!BlockRenderingCycle.Wait(1)) { } while (!FrameDecodingCycle.Wait(1)) { } while (!PacketReadingCycle.Wait(1)) { } }); BlockRenderingTask?.Join(); FrameDecodingTask?.Join(); PacketReadingTask?.Join(); BlockRenderingTask = null; FrameDecodingTask = null; PacketReadingTask = null; foreach (var renderer in Renderers.Values) { renderer.Close(); } Renderers.Clear(); // Reset the clock Clock.Reset(); Container?.Log(MediaLogMessageType.Debug, $"{nameof(CloseAsync)}: Completed"); // Dispose the container if (Container != null) { Container.Dispose(); Container = null; } // Dispose the Blocks for all components foreach (var kvp in Blocks) { kvp.Value.Dispose(); } Blocks.Clear(); // Dispose the Frames for all components foreach (var kvp in Frames) { kvp.Value.Dispose(); } Frames.Clear(); // Clear the render times LastRenderTime.Clear(); // Update notification properties UpdateMediaProperties(); MediaState = MediaState.Close; }