TsRemux.EbmlElement.ParseEbml C# (CSharp) Method

ParseEbml() public static method

public static ParseEbml ( Stream fs ) : EbmlElement
fs Stream
return EbmlElement
        public static EbmlElement ParseEbml(Stream fs)
        {
            Int64 pos = fs.Position;
            EbmlElement ebml = null;
            if (null == fs || fs.Length == 0)
                return null;
            int b = fs.ReadByte();
            if (b == -1)
                goto cleanup;
            int len = VintLength((byte)b);
            if ((fs.Length - fs.Position) < (Int64)len)
                goto cleanup;
            fs.Position -= 1;
            Int64 id = 0;
            for (int i = 0; i < len; i++)
            {
                id <<= 8;
                id |= (byte)fs.ReadByte();
            }
            b = fs.ReadByte();
            if (b == -1)
                goto cleanup;
            len = VintLength((byte)b);
            if ((fs.Length - fs.Position) < (Int64)len)
                goto cleanup;
            fs.Position -= 1;
            Int64 size = VintToInt64(fs);
            if ((fs.Length - fs.Position) < size)
                goto cleanup;
            ebml = new EbmlElement(id, size, fs.Position, fs);

            cleanup:
            fs.Position = pos;
            return ebml;
        }

Usage Example

Ejemplo n.º 1
0
        protected override void GetInitialValues()
        {
            fs.Seek(0, SeekOrigin.Begin);
            UInt32      header = 0xffffffff;
            EbmlElement mkv    = null;
            byte        b      = 0;

            for (int i = 0; i < Constants.DISK_BUFFER; i++)
            {
                int ib = fs.ReadByte();
                if (ib == -1)
                {
                    throw new FormatException("The specified file is too short");
                }
                b        = (byte)(ib & 0xff);
                header <<= 8;
                header  |= b;
                if (header == Constants.MKVSEGMENT_START)
                {
                    fs.Seek(-4, SeekOrigin.Current);
                    mkv = EbmlElement.ParseEbml(fs);
                    if (null == mkv)
                    {
                        throw new FormatException("Invalid/Corrupted MKV file");
                    }
                    break;
                }
            }
            EbmlElement[] clusts = mkv.Children;
            foreach (EbmlElement clust in clusts)
            {
                ReportProgress((int)(50 * clust.DataStream.Position / clust.DataStream.Length));
                if (clust.Id == Constants.MKVCLUSTER_START)
                {
                    Clusters.Add(GetClusterClock(clust), clust);
                }
                else if (clust.Id == Constants.MKVTRACKINFO_START)
                {
                    EbmlElement[]     tracks     = clust.Children;
                    ushort            id         = 0;
                    List <StreamInfo> mkvStreams = new List <StreamInfo>();
                    foreach (EbmlElement track in tracks)
                    {
                        if (track.Id == 0xae)
                        {
                            EbmlElement[] trackAttributes = track.Children;
                            string        codec           = null;
                            ushort        pid             = 0;
                            UInt64        uid             = 0;
                            byte[]        data            = null;
                            EbmlElement   elementaryInfo  = null;
                            foreach (EbmlElement trackAtt in trackAttributes)
                            {
                                switch (trackAtt.Id)
                                {
                                case 0xd7:     // Track number
                                    for (Int64 i = 0; i < trackAtt.Size; i++)
                                    {
                                        pid <<= 8;
                                        pid  |= (byte)fs.ReadByte();
                                    }
                                    break;

                                case 0x86:     // Codec ID
                                    byte[] cid = new byte[(int)trackAtt.Size];
                                    trackAtt.DataStream.Read(cid, 0, (int)trackAtt.Size);
                                    codec = Encoding.ASCII.GetString(cid);
                                    break;

                                case 0x63a2:     // Coded Private
                                    data = new byte[(int)trackAtt.Size];
                                    trackAtt.DataStream.Read(data, 0, (int)trackAtt.Size);
                                    break;

                                case 0x73c5:     // Track UID
                                    for (Int64 i = 0; i < trackAtt.Size; i++)
                                    {
                                        uid <<= 8;
                                        uid  |= (byte)fs.ReadByte();
                                    }
                                    break;

                                case 0xe0:     // Video elementary stream info
                                    elementaryInfo = trackAtt;
                                    break;

                                case 0xe1:     // Audio elementary stream info
                                    elementaryInfo = trackAtt;
                                    break;
                                }
                            }
                            if (codec == null || pid == 0)
                            {
                                throw new FormatException("Track info is invalid");
                            }
                            if (0 == string.Compare(codec, "V_MPEG2", true, CultureInfo.InvariantCulture) ||
                                0 == string.Compare(codec, "V_MPEG4/ISO/AVC", true, CultureInfo.InvariantCulture) ||
                                0 == string.Compare(codec, "V_MS/VFW/FOURCC", true, CultureInfo.InvariantCulture) ||
                                0 == string.Compare(codec, "A_AC3", true, CultureInfo.InvariantCulture) ||
                                0 == string.Compare(codec, "A_DTS", true, CultureInfo.InvariantCulture))
                            {
                                id++;
                                TrackInfo ti = new TrackInfo(id, codec, data, elementaryInfo);
                                TrackList.Add(id, ti);
                                StreamInfo si = null;
                                if (0 == string.Compare(codec, "V_MPEG2", true, CultureInfo.InvariantCulture))
                                {
                                    si = new StreamInfo(ElementaryStreamTypes.VIDEO_STREAM_MPEG2, id);
                                }
                                else if (0 == string.Compare(codec, "V_MPEG4/ISO/AVC", true, CultureInfo.InvariantCulture))
                                {
                                    si = new StreamInfo(ElementaryStreamTypes.VIDEO_STREAM_H264, id);
                                }
                                else if (0 == string.Compare(codec, "V_MS/VFW/FOURCC", true, CultureInfo.InvariantCulture))
                                {
                                    si = new StreamInfo(ElementaryStreamTypes.VIDEO_STREAM_VC1, id);
                                }
                                else if (0 == string.Compare(codec, "A_AC3", true, CultureInfo.InvariantCulture))
                                {
                                    si = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_AC3, id);
                                }
                                else if (0 == string.Compare(codec, "A_DTS", true, CultureInfo.InvariantCulture))
                                {
                                    si = new StreamInfo(ElementaryStreamTypes.AUDIO_STREAM_DTS, id);
                                }
                                mkvStreams.Add(si);
                            }
                        }
                    }
                    if (mkvStreams.Count > 0)
                    {
                        sis = mkvStreams.ToArray();
                    }
                }
            }
            GetTimeStamps();
            CurrentIndex = 0;
        }