public ReaderBase(MkvMediaFile file, TrackEntry track) { clusters = file.clusters; this.track = track; trackNumber = track.trackNumber; strippedHeaders = track.strippedHeaderBytes(); strippedHeaderBytes = strippedHeaders?.Length ?? 0; seekIndex = file.segment.buildSeekIndex(trackNumber); stream = file.stream; loadCluster(0); }
static IEnumerable <sSeekPos> listBlobsInClusters(ClustersCache cache, ulong trackNumber, int idx, int count = 3) { int endIdx = Math.Min(idx + count, cache.file.segment.cluster.Length); for ( ; idx < endIdx; idx++) { lock (cache.syncRoot) cache.file.loadCluster(idx, tempCluster); foreach (var sp in listBlobsInCluster(tempCluster, trackNumber, idx)) { yield return(sp); } } }
public static MkvSeekPosition find(ClustersCache cache, TimeSpan where, ulong trackNumber) { ulong searchingTime = cache.timeScaler.convertBack(where); int idx = Array.BinarySearch(cache.file.segment.cluster, new ClusterPlaceholder(searchingTime), clusterCompare); if (idx < 0) { idx = (~idx) - 1; } if (idx < 0) { return(new MkvSeekPosition(TimeSpan.Zero, 0, 0)); } if (null == tempCluster) { tempCluster = new ReusableCluster(); } Logger.logDebug("FindSeekPosition.find, looking for {0}, scaled {1}, starting from {2}", where, searchingTime, idx); // Create a new reusable one ReusableCluster rc = new ReusableCluster(); sSeekPos? blob = listBlobsInClusters(cache, trackNumber, idx) .Where(sp => sp.time <= searchingTime) .Select(nullable) .LastOrDefault(); if (!blob.HasValue) { throw new ApplicationException("Seek failed, might be trying to seek past the end"); } TimeSpan time = cache.timeScaler.convert((long)blob.Value.time); return(new MkvSeekPosition(time, blob.Value.cluster, blob.Value.blob)); }
public MkvMediaFile(Stream stream) { this.stream = stream; segment = Segment.read(stream); videoTrack = new VideoTrack(this, segment.findVideoTrack()); audioTrack = new AudioTrack(this, segment.findAudioTrack()); var in4 = segment.info[0]; if (in4.duration.HasValue) { double nano = in4.duration.Value * in4.timestampScale; long ticks = (long)(nano * 0.01); duration = TimeSpan.FromTicks(ticks); } else { throw new ArgumentException("THe MKV lacks the duration field"); } clusters = new ClustersCache(this); }