135 lines
5.3 KiB
C#

//////////////////////////////////////////////////////////////////////////////////
// //
// 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
{
/// <summary>
/// The class that describes a basic MPEG2 section header.
/// </summary>
public class Mpeg2BasicHeader
{
/// <summary>
/// Get the table identification.
/// </summary>
public int TableID { get { return (tableID); } }
/// <summary>
/// Get the section length.
/// </summary>
public int SectionLength { get { return (sectionLength); } }
/// <summary>
/// Return true if the section is private data; false otherwise.
/// </summary>
public bool PrivateIndicator { get { return (privateIndicator); } }
/// <summary>
/// Return true if the sysntax indicator is set; false otherwise.
/// </summary>
public bool SyntaxIndicator { get { return (syntaxIndicator); } }
/// <summary>
/// Get the index of the next byte in the MPEG2 section following the header.
/// </summary>
/// <exception cref="InvalidOperationException">
/// The header has not been processed.
/// </exception>
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
/// <summary>
/// Initialize a new instance of the Mpeg2BasicHeader class.
/// </summary>
public Mpeg2BasicHeader() { }
/// <summary>
/// Parse the header.
/// </summary>
/// <param name="byteData">The MPEG2 section containing the header.</param>
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"));
}
}
/// <summary>
/// Validate the header fields.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">
/// A header field is not valid.
/// </exception>
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"));
}
/// <summary>
/// Log the header fields.
/// </summary>
public virtual void LogMessage() { }
}
}