public void AddBlock(VideoPacket NewBlock)
        {
            //	need to insert at the correct time
            var Blocks = this.Blocks;

            System.Func <int, VideoPacket> GetAt = (Index) =>
            {
                return(Blocks[Index]);
            };
            System.Func <VideoPacket, BinaryChop.CompareDirection> Compare = (OtherBlock) =>
            {
                //return OtherBlock.GetLineIndexDirection(NewBlock.StartLine);
                return(OtherBlock.GetTimeDirection(NewBlock.GetStartTime()));
            };
            int?Match;
            int?NearestPrev;

            if (Blocks.Count == 0)
            {
                Match       = null;
                NearestPrev = -1;
            }
            else
            {
                BinaryChop.Search(0, Blocks.Count - 1, GetAt, Compare, out NearestPrev, out Match);
                if (Match.HasValue)
                {
                    throw new System.Exception("Block already exists in stream");
                }
            }
            Blocks.Insert(NearestPrev.Value + 1, NewBlock);
        }
        public VideoPacket?GetNearestStreamDataLessThanEqual(PopTimeline.TimeUnit Time)
        {
            var Blocks = this.Blocks;

            if (Blocks.Count == 0)
            {
                return(null);
            }

            System.Func <int, VideoPacket> GetAt = (Index) =>
            {
                return(Blocks[Index]);
            };
            System.Func <VideoPacket, BinaryChop.CompareDirection> Compare = (OtherBlock) =>
            {
                return(OtherBlock.GetTimeDirection(Time));
            };
            int?Match;
            int?Nearest;

            BinaryChop.Search(0, Blocks.Count - 1, GetAt, Compare, out Nearest, out Match);

            //	nothing at/before this time
            if (Nearest.Value < 0)
            {
                return(null);
            }

            return(GetAt(Nearest.Value));
        }
    public override List <PopTimeline.StreamDataItem> GetStreamData(PopTimeline.DataStreamMeta _StreamMeta, PopTimeline.TimeUnit MinTime, PopTimeline.TimeUnit MaxTime)
    {
        var StreamMeta  = (VideoStreamMeta)_StreamMeta;
        var BlockStream = VideoStreams[StreamMeta.StreamIndex];
        var Data        = new List <PopTimeline.StreamDataItem>();
        var Blocks      = BlockStream.Blocks;

        if (Blocks.Count == 0)
        {
            return(Data);
        }

        //	find start with binary chop.
        //	find TAIL and work backwards as nearestprev will be last time, but if we do min we can start out of range
        System.Func <int, VideoPacket> GetAt = (Index) =>
        {
            return(Blocks[Index]);
        };
        System.Func <VideoPacket, BinaryChop.CompareDirection> Compare = (OtherBlock) =>
        {
            return(OtherBlock.GetTimeDirection(MaxTime));
        };
        int?MaxMatch;
        int?MaxNearestPrev;

        BinaryChop.Search(0, Blocks.Count - 1, GetAt, Compare, out MaxNearestPrev, out MaxMatch);
        int Last = MaxNearestPrev.Value;

        //	go earlier
        for (int b = Last; b >= 0; b--)
        {
            var Block      = Blocks[b];
            var CompareDir = Block.GetTimeDirection(MinTime);
            //	if min time is AFTER block, block is before min
            if (CompareDir == BinaryChop.CompareDirection.After)
            {
                break;
            }
            Data.Insert(0, Block);
        }

        return(Data);
    }
        void GetStreamDataIndex(PopTimeline.TimeUnit Time, out int?Match, out int?Nearest)
        {
            var Blocks = this.Blocks;

            if (Blocks.Count == 0)
            {
                Match   = null;
                Nearest = null;
                return;
            }

            System.Func <int, VideoPacket> GetAt = (Index) =>
            {
                return(Blocks[Index]);
            };
            System.Func <VideoPacket, BinaryChop.CompareDirection> Compare = (OtherBlock) =>
            {
                return(OtherBlock.GetTimeDirection(Time));
            };
            BinaryChop.Search(0, Blocks.Count - 1, GetAt, Compare, out Nearest, out Match);
        }
        public VideoPacket?GetNearestStreamDataGreaterThanEqual(PopTimeline.TimeUnit Time)
        {
            var Blocks = this.Blocks;

            if (Blocks.Count == 0)
            {
                return(null);
            }

            System.Func <int, VideoPacket> GetAt = (Index) =>
            {
                return(Blocks[Index]);
            };
            System.Func <VideoPacket, BinaryChop.CompareDirection> Compare = (OtherBlock) =>
            {
                return(OtherBlock.GetTimeDirection(Time));
            };
            int?Match;
            int?Nearest;

            BinaryChop.Search(0, Blocks.Count - 1, GetAt, Compare, out Nearest, out Match);

            if (Match.HasValue)
            {
                return(GetAt(Match.Value));
            }

            //	next must the one after prev
            var Next = Nearest.Value + 1;

            if (Next >= Blocks.Count)
            {
                return(null);
            }

            return(GetAt(Next));
        }