Пример #1
0
        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;
        }