/// <summary> /// Reads all the blocks of the specified media type from the source url. /// </summary> /// <param name="mediaSource">The subtitles URL.</param> /// <param name="sourceType">Type of the source.</param> /// <param name="parent">The parent.</param> /// <returns>A buffer containing all the blocks.</returns> internal static MediaBlockBuffer LoadBlocks(string mediaSource, MediaType sourceType, ILoggingHandler parent) { if (string.IsNullOrWhiteSpace(mediaSource)) { throw new ArgumentNullException(nameof(mediaSource)); } using (var tempContainer = new MediaContainer(mediaSource, null, parent)) { tempContainer.Initialize(); // Skip reading and decoding unused blocks tempContainer.MediaOptions.IsAudioDisabled = sourceType != MediaType.Audio; tempContainer.MediaOptions.IsVideoDisabled = sourceType != MediaType.Video; tempContainer.MediaOptions.IsSubtitleDisabled = sourceType != MediaType.Subtitle; // Open the container tempContainer.Open(); if (tempContainer.Components.Main == null || tempContainer.Components.MainMediaType != sourceType) { throw new MediaContainerException($"Could not find a stream of type '{sourceType}' to load blocks from"); } // read all the packets and decode them var outputFrames = new List <MediaFrame>(1024 * 8); while (true) { tempContainer.Read(); var frames = tempContainer.Decode(); foreach (var frame in frames) { if (frame.MediaType != sourceType) { continue; } outputFrames.Add(frame); } if (frames.Count <= 0 && tempContainer.IsAtEndOfStream) { break; } } // Build the result var result = new MediaBlockBuffer(outputFrames.Count, sourceType); foreach (var frame in outputFrames) { result.Add(frame, tempContainer); } tempContainer.Close(); return(result); } }
private static ConfiguredTaskAwaitable RunDecoderTask() { return(Task.Run(() => { if (DecompressDispatcher == null) { DecompressDispatcher = Dispatcher.CurrentDispatcher; } var decodedSeconds = 0d; while (true) { DecodingDone.Reset(); try { var decodedFrames = Container.Decode(); HandleDecoding(decodedFrames); if (decodedFrames.Count == 0) { // Alll decoding is done. Time to read DecodingDone.Set(); // no more frames can be decoded now. Let's wait for more packets to arrive. if (Container.IsStreamRealtime) { Thread.Sleep(1); } } else { decodedSeconds += decodedFrames .Where(f => f.MediaType == Container.Components.Main.MediaType) .Sum(f => f.Duration.TotalSeconds); if (Container.IsAtEndOfStream) { "End of file reached.".Warn(typeof(Program)); break; } else if (decodedSeconds >= DecodeDurationLimit) { ($"Decoder limit duration reached at {decodedFrames.Last().StartTime.TotalSeconds,8:0.00000} secs. " + $"Limit was: {DecodeDurationLimit,8:0.00000} seconds").Info(typeof(Program)); break; } } } finally { DecodingDone.Set(); } } ReadCancel = true; DecodingDone.Set(); $"Decoder task finished".Warn(typeof(Program)); DecodingFinished.Set(); }).ConfigureAwait(false)); }