From 6ffa9539bbfbfb1090b02cebc8a28283a8c69041 Mon Sep 17 00:00:00 2001 From: cvium Date: Tue, 11 Jan 2022 23:30:30 +0100 Subject: Refactor and add scheduled task --- .../Matroska/Extensions/EbmlReaderExtensions.cs | 257 ++++++++++----------- 1 file changed, 128 insertions(+), 129 deletions(-) (limited to 'src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs') diff --git a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs index 75d5aafe0..e068cac84 100644 --- a/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs +++ b/src/Jellyfin.MediaEncoding.Keyframes/Matroska/Extensions/EbmlReaderExtensions.cs @@ -3,176 +3,175 @@ using System.Buffers.Binary; using Jellyfin.MediaEncoding.Keyframes.Matroska.Models; using NEbml.Core; -namespace Jellyfin.MediaEncoding.Keyframes.Matroska.Extensions +namespace Jellyfin.MediaEncoding.Keyframes.Matroska.Extensions; + +/// +/// Extension methods for the class. +/// +internal static class EbmlReaderExtensions { /// - /// Extension methods for the class. + /// Traverses the current container to find the element with identifier. /// - internal static class EbmlReaderExtensions + /// An instance of . + /// The element identifier. + /// A value indicating whether the element was found. + internal static bool FindElement(this EbmlReader reader, ulong identifier) { - /// - /// Traverses the current container to find the element with identifier. - /// - /// An instance of . - /// The element identifier. - /// A value indicating whether the element was found. - internal static bool FindElement(this EbmlReader reader, ulong identifier) + while (reader.ReadNext()) { - while (reader.ReadNext()) + if (reader.ElementId.EncodedValue == identifier) { - if (reader.ElementId.EncodedValue == identifier) - { - return true; - } + return true; } - - return false; } - /// - /// Reads the current position in the file as an unsigned integer converted from binary. - /// - /// An instance of . - /// The unsigned integer. - internal static uint ReadUIntFromBinary(this EbmlReader reader) + return false; + } + + /// + /// Reads the current position in the file as an unsigned integer converted from binary. + /// + /// An instance of . + /// The unsigned integer. + internal static uint ReadUIntFromBinary(this EbmlReader reader) + { + var buffer = new byte[4]; + reader.ReadBinary(buffer, 0, 4); + return BinaryPrimitives.ReadUInt32BigEndian(buffer); + } + + /// + /// Reads from the start of the file to retrieve the SeekHead segment. + /// + /// An instance of . + /// Instance of . + internal static SeekHead ReadSeekHead(this EbmlReader reader) + { + reader = reader ?? throw new ArgumentNullException(nameof(reader)); + + if (reader.ElementPosition != 0) { - var buffer = new byte[4]; - reader.ReadBinary(buffer, 0, 4); - return BinaryPrimitives.ReadUInt32BigEndian(buffer); + throw new InvalidOperationException("File position must be at 0"); } - /// - /// Reads from the start of the file to retrieve the SeekHead segment. - /// - /// An instance of . - /// Instance of . - internal static SeekHead ReadSeekHead(this EbmlReader reader) + // Skip the header + if (!reader.FindElement(MatroskaConstants.SegmentContainer)) { - reader = reader ?? throw new ArgumentNullException(nameof(reader)); - - if (reader.ElementPosition != 0) - { - throw new InvalidOperationException("File position must be at 0"); - } - - // Skip the header - if (!reader.FindElement(MatroskaConstants.SegmentContainer)) - { - throw new InvalidOperationException("Expected a segment container"); - } + throw new InvalidOperationException("Expected a segment container"); + } - reader.EnterContainer(); + reader.EnterContainer(); - long? tracksPosition = null; - long? cuesPosition = null; - long? infoPosition = null; - // The first element should be a SeekHead otherwise we'll have to search manually - if (!reader.FindElement(MatroskaConstants.SeekHead)) - { - throw new InvalidOperationException("Expected a SeekHead"); - } + long? tracksPosition = null; + long? cuesPosition = null; + long? infoPosition = null; + // The first element should be a SeekHead otherwise we'll have to search manually + if (!reader.FindElement(MatroskaConstants.SeekHead)) + { + throw new InvalidOperationException("Expected a SeekHead"); + } + reader.EnterContainer(); + while (reader.FindElement(MatroskaConstants.Seek)) + { reader.EnterContainer(); - while (reader.FindElement(MatroskaConstants.Seek)) + reader.ReadNext(); + var type = (ulong)reader.ReadUIntFromBinary(); + switch (type) { - reader.EnterContainer(); - reader.ReadNext(); - var type = (ulong)reader.ReadUIntFromBinary(); - switch (type) - { - case MatroskaConstants.Tracks: - reader.ReadNext(); - tracksPosition = (long)reader.ReadUInt(); - break; - case MatroskaConstants.Cues: - reader.ReadNext(); - cuesPosition = (long)reader.ReadUInt(); - break; - case MatroskaConstants.Info: - reader.ReadNext(); - infoPosition = (long)reader.ReadUInt(); - break; - } - - reader.LeaveContainer(); - - if (tracksPosition.HasValue && cuesPosition.HasValue && infoPosition.HasValue) - { + case MatroskaConstants.Tracks: + reader.ReadNext(); + tracksPosition = (long)reader.ReadUInt(); + break; + case MatroskaConstants.Cues: + reader.ReadNext(); + cuesPosition = (long)reader.ReadUInt(); + break; + case MatroskaConstants.Info: + reader.ReadNext(); + infoPosition = (long)reader.ReadUInt(); break; - } } reader.LeaveContainer(); - if (!tracksPosition.HasValue || !cuesPosition.HasValue || !infoPosition.HasValue) + if (tracksPosition.HasValue && cuesPosition.HasValue && infoPosition.HasValue) { - throw new InvalidOperationException("SeekHead is missing or does not contain Info, Tracks and Cues positions"); + break; } - - return new SeekHead(infoPosition.Value, tracksPosition.Value, cuesPosition.Value); } - /// - /// Reads from SegmentContainer to retrieve the Info segment. - /// - /// An instance of . - /// The position of the info segment relative to the Segment container. - /// Instance of . - internal static Info ReadInfo(this EbmlReader reader, long position) + reader.LeaveContainer(); + + if (!tracksPosition.HasValue || !cuesPosition.HasValue || !infoPosition.HasValue) { - reader.ReadAt(position); + throw new InvalidOperationException("SeekHead is missing or does not contain Info, Tracks and Cues positions"); + } - double? duration = null; - reader.EnterContainer(); - // Mandatory element - reader.FindElement(MatroskaConstants.TimestampScale); - var timestampScale = reader.ReadUInt(); + return new SeekHead(infoPosition.Value, tracksPosition.Value, cuesPosition.Value); + } - if (reader.FindElement(MatroskaConstants.Duration)) - { - duration = reader.ReadFloat(); - } + /// + /// Reads from SegmentContainer to retrieve the Info segment. + /// + /// An instance of . + /// The position of the info segment relative to the Segment container. + /// Instance of . + internal static Info ReadInfo(this EbmlReader reader, long position) + { + reader.ReadAt(position); - reader.LeaveContainer(); + double? duration = null; + reader.EnterContainer(); + // Mandatory element + reader.FindElement(MatroskaConstants.TimestampScale); + var timestampScale = reader.ReadUInt(); - return new Info((long)timestampScale, duration); + if (reader.FindElement(MatroskaConstants.Duration)) + { + duration = reader.ReadFloat(); } - /// - /// Enters the Tracks segment and reads all tracks to find the specified type. - /// - /// Instance of . - /// The relative position of the tracks segment. - /// The track type identifier. - /// The first track number with the specified type. - /// Stream type is not found. - internal static ulong FindFirstTrackNumberByType(this EbmlReader reader, long tracksPosition, ulong type) - { - reader.ReadAt(tracksPosition); + reader.LeaveContainer(); + return new Info((long)timestampScale, duration); + } + + /// + /// Enters the Tracks segment and reads all tracks to find the specified type. + /// + /// Instance of . + /// The relative position of the tracks segment. + /// The track type identifier. + /// The first track number with the specified type. + /// Stream type is not found. + internal static ulong FindFirstTrackNumberByType(this EbmlReader reader, long tracksPosition, ulong type) + { + reader.ReadAt(tracksPosition); + + reader.EnterContainer(); + while (reader.FindElement(MatroskaConstants.TrackEntry)) + { reader.EnterContainer(); - while (reader.FindElement(MatroskaConstants.TrackEntry)) - { - reader.EnterContainer(); - // Mandatory element - reader.FindElement(MatroskaConstants.TrackNumber); - var trackNumber = reader.ReadUInt(); + // Mandatory element + reader.FindElement(MatroskaConstants.TrackNumber); + var trackNumber = reader.ReadUInt(); - // Mandatory element - reader.FindElement(MatroskaConstants.TrackType); - var trackType = reader.ReadUInt(); + // Mandatory element + reader.FindElement(MatroskaConstants.TrackType); + var trackType = reader.ReadUInt(); + reader.LeaveContainer(); + if (trackType == MatroskaConstants.TrackTypeVideo) + { reader.LeaveContainer(); - if (trackType == MatroskaConstants.TrackTypeVideo) - { - reader.LeaveContainer(); - return trackNumber; - } + return trackNumber; } + } - reader.LeaveContainer(); + reader.LeaveContainer(); - throw new InvalidOperationException($"No stream with type {type} found"); - } + throw new InvalidOperationException($"No stream with type {type} found"); } } -- cgit v1.2.3