示例#1
0
        /// <summary>
        /// Demultiplex multiplexed packs together each streamId at a time + removing bad packs + fixing displaytimes
        /// </summary>
        /// <returns>List of complete packs each with a complete sub image</returns>
        public List <VobSubMergedPack> MergeVobSubPacks()
        {
            var  list         = new List <VobSubMergedPack>();
            var  pts          = new TimeSpan();
            var  ms           = new MemoryStream();
            int  streamId     = 0;
            bool continuation = false;

            float ticksPerMillisecond = 90.000F;
            //if (!IsPal)
            //    ticksPerMillisecond = 90.090F; TODO; What should this be for NTSC?

            // get unique streamIds
            var uniqueStreamIds = new List <int>();

            foreach (var p in VobSubPacks)
            {
                if (p.PacketizedElementaryStream != null &&
                    p.PacketizedElementaryStream.SubPictureStreamId.HasValue &&
                    !uniqueStreamIds.Contains(p.PacketizedElementaryStream.SubPictureStreamId.Value))
                {
                    uniqueStreamIds.Add(p.PacketizedElementaryStream.SubPictureStreamId.Value);
                }
            }

            IdxParagraph lastIdxParagraph = null;

            foreach (int uniqueStreamId in uniqueStreamIds) // packets must be merged in streamId order (so they don't get mixed)
            {
                foreach (var p in VobSubPacks)
                {
                    if (p.PacketizedElementaryStream != null && p.PacketizedElementaryStream.SubPictureStreamId.HasValue &&
                        p.PacketizedElementaryStream.SubPictureStreamId.Value == uniqueStreamId)
                    {
                        if (!continuation)
                        {
                            if (ms.Length > 0)
                            {
                                list.Add(new VobSubMergedPack(ms.ToArray(), pts, streamId, lastIdxParagraph));
                            }

                            ms  = new MemoryStream();
                            pts =
                                TimeSpan.FromMilliseconds(
                                    Convert.ToDouble(p.PacketizedElementaryStream.PresentationTimeStamp /
                                                     ticksPerMillisecond)); //90000F * 1000)); (PAL)
                            streamId = p.PacketizedElementaryStream.SubPictureStreamId.Value;
                        }
                        lastIdxParagraph = p.IdxLine;
                        continuation     = p.PacketizedElementaryStream.Length == PacketizedElementaryStreamMaximumLength;
                        ms.Write(p.PacketizedElementaryStream.DataBuffer, 0,
                                 p.PacketizedElementaryStream.DataBuffer.Length);
                    }
                }
                if (ms.Length > 0)
                {
                    list.Add(new VobSubMergedPack(ms.ToArray(), pts, streamId, lastIdxParagraph));
                    ms = new MemoryStream();
                }
            }

            // Remove any bad packs
            for (int i = list.Count - 1; i >= 0; i--)
            {
                VobSubMergedPack pack = list[i];
                if (pack.SubPicture == null || pack.SubPicture.ImageDisplayArea.Width <= 3 || pack.SubPicture.ImageDisplayArea.Height <= 2)
                {
                    list.RemoveAt(i);
                }
            }

            // Fix subs with no duration (completely normal) or negative duration or duration > 10 seconds
            for (int i = 0; i < list.Count; i++)
            {
                VobSubMergedPack pack = list[i];
                if (pack.SubPicture.Delay.TotalMilliseconds > 0)
                {
                    pack.EndTime = pack.StartTime.Add(pack.SubPicture.Delay);
                }

                if (pack.EndTime < pack.StartTime || pack.EndTime.TotalSeconds - pack.StartTime.TotalSeconds > 10.0)
                {
                    if (i + 1 < list.Count)
                    {
                        pack.EndTime = TimeSpan.FromMilliseconds(list[i].StartTime.TotalMilliseconds - 100);
                    }
                    else
                    {
                        pack.EndTime = TimeSpan.FromMilliseconds(pack.StartTime.TotalMilliseconds + 3000);
                    }
                }
            }

            return(list);
        }