static void Start(string[] args) { InputFile = TestInputs.HlsStream; StartTime = 0; DecodeDurationLimit = 20; IsBenchmarking = false; SaveWaveFile = true; SaveSnapshots = true; Container = new MediaContainer(InputFile); Container.Initialize(); TestNormalDecoding(); //TestMultipleSeeks(); Container.Dispose(); Terminal.WriteLine("All Tests Done!"); Terminal.ReadKey(true, true); }
public void Open(IMediaInputStream stream, Uri streamUri, HardwareDeviceInfo ha) { if (stream != null || streamUri != null) { Close(); try { // TODO: Sometimes when the stream can't be read, the sample player stays as if it were trying to open // until the interrupt timeout occurs but and the Real-Time Clock continues. Strange behavior. Investigate more. // Signal the initial state var source = stream != null ? stream.StreamUri : streamUri; State.ResetAll(); State.UpdateSource(source); // Create a default stream container configuration object var containerConfig = new ContainerConfiguration(); // Convert the URI object to something the Media Container understands (Uri to String) var mediaSource = source.IsWellFormedOriginalString() ? source.OriginalString : Uri.EscapeUriString(source.OriginalString); // When opening via URL (and not via custom input stream), fix up the protocols and stuff if (stream == null) { try { // the async protocol prefix allows for increased performance for local files. // or anything that is file-system related if (source.IsFile || source.IsUnc) { // Set the default protocol Prefix // The async protocol prefix by default does not ssem to provide // any performance improvements. Just leaving it for future reference below. // containerConfig.ProtocolPrefix = "async" mediaSource = source.LocalPath; } } catch { /* Ignore exception and continue */ } // Support device URLs // GDI GRAB: Example URI: device://gdigrab?desktop if (string.IsNullOrWhiteSpace(source.Scheme) == false && (source.Scheme == "format" || source.Scheme == "device") && string.IsNullOrWhiteSpace(source.Host) == false && string.IsNullOrWhiteSpace(containerConfig.ForcedInputFormat) && string.IsNullOrWhiteSpace(source.Query) == false) { // Update the Input format and container input URL // It is also possible to set some input options as follows: // Example: streamOptions.PrivateOptions["framerate"] = "20" containerConfig.ForcedInputFormat = source.Host; mediaSource = Uri.UnescapeDataString(source.Query).TrimStart('?'); //this.LogInfo(Aspects.EngineCommand, // $"Media URI will be updated. Input Format: {source.Host}, Input Argument: {mediaSource}"); } } // Instantiate the public container using either a URL (default) or a custom input stream. Container = stream == null ? new MediaContainer(mediaSource, containerConfig, this) : new MediaContainer(stream, containerConfig, this); // Initialize the container Container.Initialize(); Container.MediaOptions.VideoHardwareDevice = ha; // Side-load subtitles if requested // Get the main container open Container.Open(); State.InitializeBufferingStatistics(); Workers = new MediaWorkerSet(this); Workers.Start(); } catch { try { Workers?.Dispose(); } catch { /* Ignore any exceptions and continue */ } try { Container?.Dispose(); } catch { /* Ignore any exceptions and continue */ } Container = null; throw; } } else { Close(); } }
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; }