Ejemplo n.º 1
0
        /// <summary>
        ///    Reads the file with a specified read style.
        /// </summary>
        /// <param name="propertiesStyle">
        ///    A <see cref="ReadStyle" /> value specifying at what level
        ///    of accuracy to read the media properties, or <see
        ///    cref="ReadStyle.None" /> to ignore the properties.
        /// </param>
        private void Read(ReadStyle propertiesStyle)
        {
            ulong offset = 0;

            while (offset < (ulong)Length)
            {
                EBMLElement element = new EBMLElement(this, offset);

                EBMLID     ebml_id     = (EBMLID)element.ID;
                MatroskaID matroska_id = (MatroskaID)element.ID;

                switch (ebml_id)
                {
                case EBMLID.EBMLHeader:
                    ReadHeader(element);
                    break;

                default:
                    break;
                }
                switch (matroska_id)
                {
                case MatroskaID.MatroskaSegment:
                    ReadSegment(element);
                    break;

                default:
                    break;
                }

                offset += element.Size;
            }
        }
Ejemplo n.º 2
0
        private void ReadSegment(EBMLElement element)
        {
            ulong i = 0;

            while (i < element.DataSize)
            {
                EBMLElement child = new EBMLElement(this, element.DataOffset + i);

                MatroskaID matroska_id = (MatroskaID)child.ID;

                switch (matroska_id)
                {
                case MatroskaID.MatroskaTracks:
                    ReadTracks(child);
                    break;

                case MatroskaID.MatroskaSegmentInfo:
                    ReadSegmentInfo(child);
                    break;

                case MatroskaID.MatroskaTags:
                    ReadTags(child);
                    break;

                case MatroskaID.MatroskaCluster:
                    // Get out of here when we reach the clusters for now.
                    return;

                default:
                    break;
                }

                i += child.Size;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Constructs a <see cref="Track" /> parsing from provided
        /// file data.
        /// Parsing will be done reading from _file at position references by
        /// parent element's data section.
        /// </summary>
        /// <param name="_file"><see cref="File" /> instance to read from.</param>
        /// <param name="element">Parent <see cref="EBMLElement" />.</param>
        public Track(File _file, EBMLElement element)
        {
            ulong i = 0;

            while (i < element.DataSize)
            {
                EBMLElement child = new EBMLElement(_file, element.DataOffset + i);

                MatroskaID matroska_id = (MatroskaID)child.ID;

                switch (matroska_id)
                {
                case MatroskaID.MatroskaTrackNumber:
                    track_number = child.ReadUInt();
                    break;

                case MatroskaID.MatroskaTrackUID:
                    track_uid = child.ReadUInt();
                    break;

                case MatroskaID.MatroskaCodecID:
                    track_codec_id = child.ReadString();
                    break;

                case MatroskaID.MatroskaCodecName:
                    track_codec_name = child.ReadString();
                    break;

                case MatroskaID.MatroskaTrackName:
                    track_name = child.ReadString();
                    break;

                case MatroskaID.MatroskaTrackLanguage:
                    track_language = child.ReadString();
                    break;

                case MatroskaID.MatroskaTrackFlagEnabled:
                    track_enabled = child.ReadBool();
                    break;

                case MatroskaID.MatroskaTrackFlagDefault:
                    track_default = child.ReadBool();
                    break;

                case MatroskaID.MatroskaCodecPrivate:
                    codec_data = child.ReadBytes();
                    break;

                default:
                    unknown_elems.Add(child);
                    break;
                }

                i += child.Size;
            }
        }
Ejemplo n.º 4
0
        private void ReadTrackEntry(EBMLElement element)
        {
            ulong i = 0;

            while (i < element.DataSize)
            {
                EBMLElement child = new EBMLElement(this, element.DataOffset + i);

                MatroskaID matroska_id = (MatroskaID)child.ID;

                switch (matroska_id)
                {
                case MatroskaID.MatroskaTrackType:
                {
                    TrackType track_type = (TrackType)child.ReadUInt();

                    switch (track_type)
                    {
                    case TrackType.Video:
                    {
                        VideoTrack track = new VideoTrack(this, element);

                        tracks.Add(track);
                        break;
                    }

                    case TrackType.Audio:
                    {
                        AudioTrack track = new AudioTrack(this, element);

                        tracks.Add(track);
                        break;
                    }

                    case TrackType.Subtitle:
                    {
                        SubtitleTrack track = new SubtitleTrack(this, element);

                        tracks.Add(track);
                        break;
                    }

                    default:
                        break;
                    }
                    break;
                }

                default:
                    break;
                }

                i += child.Size;
            }
        }
Ejemplo n.º 5
0
        private void ReadSimpleTag(EBMLElement element)
        {
            ulong i = 0;

#pragma warning disable 219 // Assigned, never read
            string tag_name = null, tag_language = null, tag_string = null;
#pragma warning restore 219

            while (i < element.DataSize)
            {
                EBMLElement child = new EBMLElement(this, element.DataOffset + i);

                MatroskaID matroska_id = (MatroskaID)child.ID;

                switch (matroska_id)
                {
                case MatroskaID.MatroskaTagName:
                    tag_name = child.ReadString();
                    break;

                case MatroskaID.MatroskaTagLanguage:
                    tag_language = child.ReadString();
                    break;

                case MatroskaID.MatroskaTagString:
                    tag_string = child.ReadString();
                    break;

                default:
                    break;
                }

                i += child.Size;
            }

            if (tag_name == "AUTHOR")
            {
                tag.Performers = new string [] { tag_string };
            }
            else if (tag_name == "TITLE")
            {
                tag.Title = tag_string;
            }
            else if (tag_name == "ALBUM")
            {
                tag.Album = tag_string;
            }
            else if (tag_name == "COMMENTS")
            {
                tag.Comment = tag_string;
            }
        }
Ejemplo n.º 6
0
 public SubtitleTrack(File _file, EBMLElement element) :
     base(_file, element)
 {
     foreach (EBMLElement elem in base.UnknownElements)
     {
         MatroskaID matroska_id = (MatroskaID)elem.ID;
         switch (matroska_id)
         {
         default:
             unknown_elems.Add(elem);
             break;
         }
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Create a new abstract <see cref="EBMLreader" /> with arbitrary attributes,
        /// without reading its information on the file.
        /// </summary>
        /// <param name="parent">The <see cref="EBMLreader" /> that contains the instance to be described.</param>
        /// <param name="position">Position in the file.</param>
        /// <param name="ebmlid">EBML ID of the element</param>
        /// <param name="size">Total size of the EBML, in bytes</param>
        public EBMLreader(EBMLreader parent, ulong position, MatroskaID ebmlid, ulong size = 0)
        {
            // Keep a reference to the file
            if (parent != null)
            {
                file = parent.file;
            }
            this.parent = parent;

            // Initialize attributes
            offset      = position;
            data_offset = offset;
            ebml_id     = (uint)ebmlid;
            ebml_size   = size;
        }
        /// <summary>
        /// Constructs a <see cref="SubtitleTrack" /> parsing from provided
        /// file data.
        /// Parsing will be done reading from _file at position references by
        /// parent element's data section.
        /// </summary>
        /// <param name="_file"><see cref="File" /> instance to read from.</param>
        /// <param name="element">Parent <see cref="EBMLElement" />.</param>
        public SubtitleTrack(File _file, EBMLElement element)
            : base(_file, element)
        {
            // Here we handle the unknown elements we know, and store the rest
            foreach (EBMLElement elem in base.UnknownElements)
            {
                MatroskaID matroska_id = (MatroskaID)elem.ID;

                switch (matroska_id)
                {
                default:
                    unknown_elems.Add(elem);
                    break;
                }
            }
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Create a UIDElement Stub
 /// </summary>
 /// <param name="type">Tag-type the UID represents</param>
 /// <param name="uid">UID of the element</param>
 public UIDElement(MatroskaID type, ulong uid)
 {
     UID = uid;
     if (type == MatroskaID.TagTrackUID ||
         type == MatroskaID.TagEditionUID ||
         type == MatroskaID.TagChapterUID ||
         type == MatroskaID.TagAttachmentUID
         )
     {
         UIDType = type;
     }
     else
     {
         UIDType = 0;
     }
 }
Ejemplo n.º 10
0
        private void ReadTracks(EBMLElement element)
        {
            ulong i = 0;

            while (i < element.DataSize)
            {
                EBMLElement child       = new EBMLElement(this, element.DataOffset + i);
                MatroskaID  matroska_id = (MatroskaID)child.ID;
                switch (matroska_id)
                {
                case MatroskaID.MatroskaTrackEntry:
                    ReadTrackEntry(child);
                    break;

                default:
                    break;
                }
                i += child.Size;
            }
        }
Ejemplo n.º 11
0
        private void ReadSegmentInfo(EBMLElement element)
        {
            ulong i = 0;

            while (i < element.DataSize)
            {
                EBMLElement child = new EBMLElement(this, element.DataOffset + i);

                MatroskaID matroska_id = (MatroskaID)child.ID;

                switch (matroska_id)
                {
                case MatroskaID.MatroskaDuration:
                    duration_unscaled = (UInt64)child.ReadDouble();
                    if (time_scale > 0)
                    {
                        duration = TimeSpan.FromSeconds(duration_unscaled * time_scale / 1000000000);
                    }
                    break;

                case MatroskaID.MatroskaTimeCodeScale:
                    time_scale = child.ReadUInt();
                    if (duration_unscaled > 0)
                    {
                        duration = TimeSpan.FromSeconds(duration_unscaled * time_scale / 1000000000);
                    }
                    break;

                case MatroskaID.MatroskaTitle:
                    title = child.ReadString();
                    break;

                default:
                    break;
                }

                i += child.Size;
            }
        }
Ejemplo n.º 12
0
        private bool ReadSeekHead(EBMLreader element, List <EBMLreader> segm_list)
        {
            MatroskaID ebml_id       = 0;
            ulong      ebml_position = 0;

            ulong i = 0;

            while (i < element.DataSize)
            {
                var ebml_seek   = new EBMLreader(element, element.DataOffset + i);
                var matroska_id = ebml_seek.ID;

                if (matroska_id != MatroskaID.Seek)
                {
                    return(false);                                                // corrupted SeekHead
                }
                ulong j = 0;
                while (j < ebml_seek.DataSize)
                {
                    var child = new EBMLreader(ebml_seek, ebml_seek.DataOffset + j);
                    matroska_id = child.ID;

                    switch (matroska_id)
                    {
                    case MatroskaID.SeekID:
                        ebml_id = (MatroskaID)child.ReadULong();
                        break;

                    case MatroskaID.SeekPosition:
                        ebml_position = child.ReadULong() + element.Offset;
                        break;
                    }

                    j += child.Size;
                }

                if (ebml_id > 0 && ebml_position > 0)
                {
                    // Create abstract EBML representation of the segment EBML
                    var ebml = new EBMLreader(element.Parent, ebml_position, ebml_id);

                    // Sort the seek-entries by increasing position order
                    int k;
                    for (k = segm_list.Count - 1; k >= 0; k--)
                    {
                        if (ebml_position > segm_list[k]
                            .Offset)
                        {
                            break;
                        }
                    }

                    segm_list.Insert(k + 1, ebml);

                    // Chained SeekHead recursive read
                    if (ebml_id == MatroskaID.SeekHead)
                    {
                        if (!ebml.Read())
                        {
                            return(false);                                      // Corrupted
                        }
                        ReadSeekHead(ebml, segm_list);
                    }
                }

                i += ebml_seek.Size;
            }

            return(true);
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Construct <see cref="EBMLelement" /> to contain data.
 /// </summary>
 /// <param name="ebmlid">EBML ID of the element to be created.</param>
 /// <param name="value">EBML data as an <see cref="ulong"/> value.</param>
 public EBMLelement(MatroskaID ebmlid, ulong value)
 {
     ID = ebmlid;
     SetData(value);
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Construct a <see cref="EBMLelement" /> to contain data.
 /// </summary>
 /// <param name="ebmlid">EBML ID of the element to be created.</param>
 /// <param name="data">EBML data of the element to be created.</param>
 public EBMLelement(MatroskaID ebmlid, ByteVector data)
 {
     ID   = ebmlid;
     Data = data;
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Construct a <see cref="EBMLelement" /> to contain children elements.
 /// </summary>
 /// <param name="ebmlid">EBML ID of the element to be created.</param>
 public EBMLelement(MatroskaID ebmlid)
 {
     ID       = ebmlid;
     Children = new List <EBMLelement>();
 }