Esempio n. 1
0
        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);
        }
Esempio n. 2
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);
                }
            }
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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);
        }