Coder Social home page Coder Social logo

tsdecoder's Introduction

Cinegy Transport Stream Decoder Library

Use this library to decode MPEGTS (including DVB) transport streams - tested with various streams, from Multicast and File sources, with single- and multi-program streams.

How easy is it?

Assuming you have some data from a source as a byte array (e.g. from a UDP packet or from a file), just add them to the decoder!

	_tsDecoder.AddData(byteArrayData);
	

Once you start feeding in packets, the class will start to populate with data - allowing you to explore the Program Allocation Table, Service Descriptors, or even start grabbing the data from an individual elementary stream.

See all of this in action inside the Cinegy TS Analyser tool here: [GitHub] [https://github.com/cinegy/tsanalyser]

Getting the library

Just to make your life easier, we auto-build this using AppVeyor and push to NuGet - here is how we are doing right now:

Build status

You can check out the latest compiled binary from the master or pre-master code here:

AppVeyor TsDecoder Project Builder

Available on NuGet here:

NuGet

tsdecoder's People

Contributors

diefenthal avatar lewishub avatar lewk2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tsdecoder's Issues

Error xmlns="http://schemas.microsoft.com/developer/msbuild/2003"

i had fork this project and when i try to load it into Vs 2015 get i the information that this failed

C:\Users\Kay\Documents\GitHub\TsDecoder\Cinegy.TsDecoder\Cinegy.TsDecoder.csproj : error : Der MSBuild-XML-Namespace muss der Standard-XML-Namespace des Projekts sein. Wenn das Projekt im MSBuild 2003-Format erstellt wurde, fügen Sie dem -Element xmlns="http://schemas.microsoft.com/developer/msbuild/2003" hinzu. Wenn das Projekt im alten Format 1.0 oder 1.2 erstellt wurde, konvertieren Sie es in das MSBuild 2003-Format. C:\Users\Kay\Documents\GitHub\TsDecoder\Cinegy.TsDecoder\Cinegy.TsDecoder.csproj

C:\Users\Kay\Documents\GitHub\TsDecoder\Cinegy.TsDecoder.Tests\Cinegy.TsDecoder.Tests.csproj : error : Der MSBuild-XML-Namespace muss der Standard-XML-Namespace des Projekts sein. Wenn das Projekt im MSBuild 2003-Format erstellt wurde, fügen Sie dem -Element xmlns="http://schemas.microsoft.com/developer/msbuild/2003" hinzu. Wenn das Projekt im alten Format 1.0 oder 1.2 erstellt wurde, konvertieren Sie es in das MSBuild 2003-Format. C:\Users\Kay\Documents\GitHub\TsDecoder\Cinegy.TsDecoder.Tests\Cinegy.TsDecoder.Tests.csproj

ok for mixed after update to vs 2017
but not for users that use vs2015

Service name in Cyrillic.

System.ArgumentException: "'ISO-8859-5' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method."

MPTS transport stream consist of 25 services.

Missed Descriptors

I Missed some Descriptors

for that had i customized the descriptor class to

public Descriptor(byte[] stream, int start)
        {
            DescriptorTag = stream[start];
            DescriptorLength = stream[start + 1];
            Data = new byte[stream[start + 1]];
            Buffer.BlockCopy(stream, start + 2, Data, 0, stream[start + 1]);
        }
        public byte DescriptorTag { get; }
        public byte DescriptorLength { get; }
        public byte[] Data { get; set; }

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.AppendFormat("\r\n");
            sb.AppendFormat("DVB Descriptor\r\n");
            sb.AppendFormat("DescriptorTag : {0},(0x{1})\r\n", DescriptorTag.ToString(), DescriptorTag.ToString("x2"));
            sb.AppendFormat("DescriptorLength : {0},(0x{1})\r\n", DescriptorLength.ToString(), DescriptorLength.ToString("x2"));
            sb.AppendFormat("DescriptorData : {0}\r\n", Utils.ToHexString(Data));
            sb.AppendFormat("\r\n");
            return sb.ToString();
        }

so had i the Chance to log the data of the Descriptors
the dumps are here attached
Descriptor Dumps.zip

Bug in TsPacketFactory.GetTsPacketsFromData()

I've found a bug with the processing of adaption fields:

The AdaptationField.FieldSize is set correct, however the processing below it does not take account for the proper length of the adaption field as the adaptation_field_length refers to the size after the adaptation_field_length value:

from ISO-13818-1:

The adaptation_field_length is an 8-bit field specifying the number of bytes in the adaptation_field immediately following the adaptation_field_length

so this:

payloadSize -= tsPacket.AdaptationField.FieldSize;
payloadOffs += tsPacket.AdaptationField.FieldSize;

should be:

var adaptationFieldTotalSize = tsPacket.AdaptationField.FieldSize + sizeof(byte);
payloadSize -= adaptationFieldTotalSize;
payloadOffs += adaptationFieldTotalSize;

Get SatelliteDeliverySystemDescriptor for Choosen TransportstreamId

Hello

is it possible to get the DeliverySystemDescriptors for Satellite Terrestrial Cable for the choosen TransportstreamID?

in the Tsdecoder had i added this Functions

public SatelliteDeliverySystemDescriptor GetSatelliteDeliverySystemDescriptorForTSID(int? transportstreamId)
{
if (transportstreamId == null) return null;
var networkInformationItem = _nitFactory?.NetworkInformationItems?.SingleOrDefault(i => i.TransportStreamId == transportstreamId);
var satellitedesc = networkInformationItem.Descriptors?.SingleOrDefault(
nd => nd as SatelliteDeliverySystemDescriptor != null) as
SatelliteDeliverySystemDescriptor;
return satellitedesc;
}
public CableDeliverySystemDescriptor GetCableDeliverySystemDescriptorForTSID(int? transportstreamId)
{
if (transportstreamId == null) return null;
var networkInformationItem = _nitFactory?.NetworkInformationItems?.SingleOrDefault(i => i.TransportStreamId == transportstreamId);
var cabledeliverySystemDesc = networkInformationItem.Descriptors?.SingleOrDefault(
nd => nd as CableDeliverySystemDescriptor != null) as
CableDeliverySystemDescriptor;
return cabledeliverySystemDesc;
}
public TerrestrialDeliverySystemDescriptor GetTerrestrialDeliverySystemDescriptorForTSID(int? transportstreamId)
{
if (transportstreamId == null) return null;
var networkInformationItem = _nitFactory?.NetworkInformationItems?.SingleOrDefault(i => i.TransportStreamId == transportstreamId);
var terrestrialSystemDesc = networkInformationItem.Descriptors?.SingleOrDefault(
nd => nd as TerrestrialDeliverySystemDescriptor != null) as
TerrestrialDeliverySystemDescriptor;
return terrestrialSystemDesc;
}
but the problem is to get the TransportstreamId from sdt or pat to use this Functions

Logical Channel Number Descriptor (LCNDescriptor 0x83)

/// <summary>
    /// A Logical Channel Number Descriptor 0x83 <see cref="Descriptor"/>.
    /// </summary>
    /// <remarks>
    /// For details please refer to the original documentation,
    /// e.g. <i>ETSI EN 300 468 V1.15.1 (2016-03)</i> or alternate versions.
    /// </remarks>
    public class LcnDescriptor :Descriptor
    {
        public class LogicalchannelnumberItem
        {
            private ushort serviceID;
            private bool visibleServiceFlag;
            private byte reserved;
            private ushort logicalChannelNumber;

            public ushort ServiceID { get { return this.serviceID; } set { this.serviceID = value; } }
            public bool VisibleServiceFlag { get { return this.visibleServiceFlag; } set { this.visibleServiceFlag = value; } }
            public byte Reserved { get { return this.reserved; } set { this.reserved = value; } }
            public ushort LogicalChannelNumber { get { return this.logicalChannelNumber; } set { this.logicalChannelNumber = value; } }
        }

        private ArrayList logicalChannelNumbers = new ArrayList();
        

        public LcnDescriptor(byte[] stream, int start)
            : base(stream, start)
        {
           
            for (int idx = start + 2; idx < start + this.DescriptorLength - 1; idx += 4)
            {
                LogicalchannelnumberItem lcnItem = new LogicalchannelnumberItem();
                lcnItem.ServiceID = (ushort)((stream[idx] << 8) | (stream[idx + 1]));
                lcnItem.VisibleServiceFlag = (((stream[idx + 2] >> 7) & 0x01)) != 0; ;
                lcnItem.Reserved = (byte)(stream[idx + 2] >> 2 & 0x1F);
                lcnItem.LogicalChannelNumber = (ushort)(((stream[idx + 2] & 0x02) << 8) | (stream[idx + 3]));
                this.logicalChannelNumbers.Add(lcnItem);
            }

        }
        public ArrayList LogicalChannelNumbers { get { return this.logicalChannelNumbers; } }
    }

Index out of range Exceptions in Short and ExtendedEventDescriptors

had Index out of range Exceptions in ShortEventDescriptor and ExtendedEventDescriptors
so had i look into the code and Played with them with thr result that it can be fixed

can you confirm it with this changes that it working for you too

public class ShortEventDescriptor : Descriptor
    {
        public ShortEventDescriptor(byte[] stream, int start) : base(stream, start)
        {
            int lastindex = start + 2;
            try
            {
                
                ISO639LanguageCode = Encoding.UTF8.GetString(stream, lastindex, 3);
                lastindex += ISO639LanguageCode.Length;

                EventNameLength = stream[lastindex];
                lastindex++;

                if (EventNameLength != 0)
                {
                    EventNameChar = new Text(stream, lastindex, EventNameLength);
                    lastindex += EventNameLength;
                    //Debug.WriteLine(EventNameChar);
                }

                TextLength = stream[lastindex];
                lastindex++;
                if (TextLength != 0)
                {
                    TextChar = new Text(stream, lastindex, TextLength);
                    lastindex += TextLength;
                    //Debug.WriteLine(TextChar);
                }
            }
            
            catch(IndexOutOfRangeException ex)
            { throw new ArgumentOutOfRangeException("Index was outside the bounds of the array."); }
        }

        public string ISO639LanguageCode { get; set; }
        public byte EventNameLength { get; set; }
        public Text EventNameChar { get; set; }
        public byte TextLength { get; set; }
        public Text TextChar { get; set; }
    }
public class ExtendedEventDescriptor : Descriptor
    {
        public class Item
        {
            public Item()
            {
            }

            public Item(Item item)
            {
                ItemDescriptionLength = item.ItemDescriptionLength;
                ItemDescriptionChar = new Text(item.ItemDescriptionChar);
                ItemLength = item.ItemLength;
                ItemChar = new Text(item.ItemChar);
            }

            public int ItemDescriptionLength { get; internal set; }
            public Text ItemDescriptionChar { get; internal set; }
            public int ItemLength { get; internal set; }
            public Text ItemChar { get; internal set; }
        }

        public ExtendedEventDescriptor(byte[] stream, int start) : base(stream, start)
        {
            int lastindex = start + 2;
            try
            {                
                DescriptorNumber = (byte)((stream[lastindex] >> 4) & 0x0F);
                LastDescriptorNumber = (byte)((stream[lastindex]) & 0x0F);
                lastindex++;
                ISO639LanguageCode = Encoding.UTF8.GetString(stream, lastindex, 3);
                lastindex += ISO639LanguageCode.Length;
                LengthOfItems = stream[lastindex];
                lastindex++;
                if(LengthOfItems!=0)
                {
                    var items = new List<Item>();
                    while (LengthOfItems!=0)
                    {
                        var item = new Item { ItemDescriptionLength = stream[lastindex] };
                        lastindex++;
                        if(item.ItemDescriptionLength!=0)
                        {
                            item.ItemDescriptionChar = new Text(stream, lastindex, item.ItemDescriptionLength);
                            lastindex+= item.ItemDescriptionLength;
                        }                        
                        item.ItemLength = stream[lastindex];
                        lastindex++;
                        if(item.ItemLength!=0)
                        {
                            item.ItemChar = new Text(stream, lastindex, item.ItemLength);
                            lastindex += item.ItemLength;
                        }
                        items.Add(item);
                        LengthOfItems -= (item.ItemDescriptionLength + item.ItemLength+2);                        
                    }
                    Items = items;
                }       
                
                TextLength = stream[lastindex];
                lastindex++;
                if (TextLength!=0)
                {
                    TextChar = new Text(stream, lastindex, TextLength);
                    lastindex = +TextLength;
                }               
            }
            catch (IndexOutOfRangeException ex)
            { throw new ArgumentOutOfRangeException("Index was outside the bounds of the array."); }
        }

        public byte DescriptorNumber { get; set; }
        public byte LastDescriptorNumber { get; set; }
        public string ISO639LanguageCode { get; set; }
        public int LengthOfItems { get; set; }
        public IEnumerable<Item> Items { get; set; }
        public byte TextLength { get; set; }
        public Text TextChar { get; set; }
    }

Feature Request TableIdentifier Support in AddPacket Method

i think that the TableIdentifier should be used too for table creation and not only the PID
with the TableIdentifier Support can more Tabels Like BAT, CAT, TOT, TDT can be used

`        public void AddPacket(TsPacket newPacket)
        {
            try
            {
                if (newPacket.TransportErrorIndicator)
                {
                    return;
                }

                switch (newPacket.Pid)
                {
                    case (short)PidType.PatPid: 
                        // PID 0x0 TID 0x0
                        _patFactory.AddPacket(newPacket);
                        // PID 0x0 TID 0x01
                        _catFactory.AddPacket(newPacket);
                        break;
                    case (short)PidType.SdtPid:
                        // PID 0x11 TID 0x42 /0x46
                        _sdtFactory.AddPacket(newPacket);
                        // PID 0x11 TID 0x4A 
                        _batFactory.AddPacket(newPacket);
                        break;
                    case (short)PidType.EitPid:
                        _eitFactory.AddPacket(newPacket);
                        break;
                    case 2048:
                        _sitFactory.AddPacket(newPacket);
                        break;
                    default:
                        CheckPmt(newPacket);
                        break;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception generated within AddPacket method: " + ex.Message);
            }
        }`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.