////////////////////////////////////////////////////////////////////////////////// // // // Copyright © 2005-2020 nzsjb // // // // This Program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation; either version 2, or (at your option) // // any later version. // // // // This Program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with GNU Make; see the file COPYING. If not, write to // // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // http://www.gnu.org/copyleft/gpl.html // // // ////////////////////////////////////////////////////////////////////////////////// using System; namespace DVBServices { /// /// The class that describes a basic MPEG2 section header. /// public class Mpeg2BasicHeader { /// /// Get the table identification. /// public int TableID { get { return (tableID); } } /// /// Get the section length. /// public int SectionLength { get { return (sectionLength); } } /// /// Return true if the section is private data; false otherwise. /// public bool PrivateIndicator { get { return (privateIndicator); } } /// /// Return true if the sysntax indicator is set; false otherwise. /// public bool SyntaxIndicator { get { return (syntaxIndicator); } } /// /// Get the index of the next byte in the MPEG2 section following the header. /// /// /// The header has not been processed. /// public virtual int Index { get { if (lastIndex == -1) throw (new InvalidOperationException("Mpeg2BasicHeader: Index requested before block processed")); return (lastIndex); } } private int tableID; private int sectionLength; private bool privateIndicator; private bool syntaxIndicator; private int lastIndex = -1; private int dataLength; // MPEG basic header layout is as follows // // tableID byte uimsbf // // section syntax ind 1 bit bslbf // private indicator 1 bit bslbf // reserved 2 bits bslbf // section length 12 bits uimsbf /// /// Initialize a new instance of the Mpeg2BasicHeader class. /// public Mpeg2BasicHeader() { } /// /// Parse the header. /// /// The MPEG2 section containing the header. public virtual void Process(byte[] byteData) { lastIndex = 0; dataLength = byteData.Length; try { tableID = (int)byteData[lastIndex]; lastIndex++; syntaxIndicator = (byteData[lastIndex] & 0x80) != 0; privateIndicator = (byteData[lastIndex] & 0x40) != 0; sectionLength = ((byteData[lastIndex] & 0x0f) * 256) + (int)byteData[lastIndex + 1]; lastIndex += 2; Validate(); } catch (IndexOutOfRangeException) { throw (new ArgumentOutOfRangeException("MPEG2 basic header is short")); } } /// /// Validate the header fields. /// /// /// A header field is not valid. /// public virtual void Validate() { if (dataLength > 4096) throw (new ArgumentOutOfRangeException("MPEG2 Section data length wrong")); if (sectionLength < 1 || sectionLength > dataLength - 3) throw (new ArgumentOutOfRangeException("MPEG2 Section length wrong")); } /// /// Log the header fields. /// public virtual void LogMessage() { } } }