Esempio n. 1
0
        public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188)
        {
            //将1078一帧的数据拆分成一小段一小段的PES包
            byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize);
            TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer);

            //TSHeader + Adaptation + PES1
            //TSHeader + PES2
            //TSHeader + Adaptation + PESN
            try
            {
                int        totalLength = 0;
                TS_Package package     = new TS_Package();
                package.Header = new TS_Header();
                //ts header 4
                totalLength               += 4;
                package.Header.PID         = 256;
                package.Header.PackageType = PackageType.Data_Start;
                string key = jt1078Package.GetKey();
                if (VideoCounter.TryGetValue(key, out byte counter))
                {
                    if (counter > 0xf)
                    {
                        counter = 0;
                    }
                }
                else
                {
                    VideoCounter.Add(key, counter);
                }
                package.Header.ContinuityCounter = counter;
                counter++;
                package.Header.PayloadUnitStartIndicator = 1;
                package.Header.Adaptation       = new TS_AdaptationInfo();
                package.Payload                 = new PES_Package();
                package.Payload.StreamId        = 0xe0;
                package.Payload.PESPacketLength = 0;
                //PESStartCode + StreamId+ Flag1 + PTS_DTS_Flag + PESPacketLength
                //3 + 1 + 1 + 1 + 2
                totalLength += (3 + 1 + 1 + 1 + 2);
                package.Payload.PTS_DTS_Flag = PTS_DTS_Flags.all;
                long timestamp = (long)jt1078Package.Timestamp;
                if (jt1078Package.Label3.DataType == JT1078DataType.视频I帧)
                {
                    //ts header adaptation
                    //PCRIncluded + Timestamp
                    //1 + 6
                    totalLength += (1 + 6);
                    package.Header.Adaptation.PCRIncluded = PCRInclude.包含;
                    package.Header.Adaptation.Timestamp   = timestamp;
                    package.Payload.DTS = timestamp * H264DefaultHZ;
                    package.Payload.PTS = package.Payload.DTS + jt1078Package.LastIFrameInterval * H264DefaultHZ;
                }
                else if (jt1078Package.Label3.DataType == JT1078DataType.视频P帧)
                {
                    //ts header adaptation
                    //PCRIncluded
                    //1
                    totalLength += 1;
                    package.Header.Adaptation.PCRIncluded = PCRInclude.包含;
                    package.Payload.DTS = timestamp * H264DefaultHZ;
                    package.Payload.PTS = package.Payload.DTS + jt1078Package.LastFrameInterval * H264DefaultHZ;
                }
                //Flag1 + PTS_DTS_Flag + DTS + PTS
                //1 + 1 + 5 + 5 = 12
                totalLength += 12;
                totalLength += TSConstants.FiexdESPackageHeaderLength;
                //根据计算剩余的长度进行是否需要填充第一包
                var remainingLength = FiexdTSLength - totalLength;
                int index           = 0;
                //情况1:1078的第一包不够剩余(remainingLength)字节
                //情况2:1078的第一包比剩余(remainingLength)字节多
                //情况3: 1078的第一包等于剩余(remainingLength)字节
                //填充大小
                int fullSize = jt1078Package.Bodies.Length - remainingLength;
                package.Payload.Payload = new ES_Package();
                if (fullSize < 0)
                {
                    //这个很重要,需要控制
                    package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载;
                    //还差一点
                    fullSize = Math.Abs(fullSize);
                    package.Header.Adaptation.FillSize = (byte)fullSize;
                    package.Payload.Payload.NALUs      = new List <byte[]>()
                    {
                        jt1078Package.Bodies
                    };
                    package.ToBuffer(ref messagePackReader);
                }
                else if (fullSize == 0)
                {
                    //这个很重要,需要控制
                    package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载;
                    //刚刚好
                    package.Header.Adaptation.FillSize = 0;
                    package.Payload.Payload.NALUs      = new List <byte[]>()
                    {
                        jt1078Package.Bodies
                    };
                    package.ToBuffer(ref messagePackReader);
                }
                else
                {
                    //这个很重要,需要控制
                    package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载;
                    //太多了,需要拆分
                    package.Header.Adaptation.FillSize = 0;
                    package.Payload.Payload.NALUs      = new List <byte[]>();
                    ReadOnlySpan <byte> dataReader = jt1078Package.Bodies;
                    package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray());
                    index += remainingLength;
                    package.ToBuffer(ref messagePackReader);
                    while (index != jt1078Package.Bodies.Length)
                    {
                        if (counter > 0xf)
                        {
                            counter = 0;
                        }
                        int segmentFullSize = jt1078Package.Bodies.Length - index;
                        if (segmentFullSize >= FiexdSegmentPESLength)
                        {
                            CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, FiexdSegmentPESLength).ToArray(), counter);
                            index += FiexdSegmentPESLength;
                        }
                        else
                        {
                            var nalu = dataReader.Slice(index, segmentFullSize).ToArray();
                            //当等于183字节的时候
                            //12698D08E8DBDBCDF6C6FA19DD88490E908D687D1755BE87DF82754BE2D245270569310B3030A4904DF1883ED09A68CA1C79BC4B97642B5BC095A55E56868D05370D3BC8B7B60B4642A486B6852656C01FFADACEF4BD4320E8BE9C54D44177A433CC37493FA1D8ACD0164E92454D03B6EC0617B133AEF43B599BF85632AB9B5FF671F0DDAA07E8F279F5639BA88E3FFFFCE1D3351FAF43DF23BCEB7E3B2CAB3EABAED23B25097B7F51FF38E8D0EBAB589CEC42B0440EB8
                            //if (jt1078Package.Label3.DataType == JT1078DataType.视频P帧)
                            //{
                            //    string hex = dataReader.Slice(index, segmentFullSize).ToArray().ToHexString();
                            //}
                            CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, segmentFullSize).ToArray(), counter);
                            index += segmentFullSize;
                        }
                        counter++;
                    }
                }
                VideoCounter[key] = counter;
                return(messagePackReader.FlushAndGetArray());
            }
            finally
            {
                TSArrayPool.Return(buffer);
            }
        }
Esempio n. 2
0
        public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188)
        {
            //将1078一帧的数据拆分成一小段一小段的PES包
            byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize);
            TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer);

            //TSHeader + Adaptation + PES1
            //TSHeader + PES2
            //TSHeader + Adaptation + PESN
            try
            {
                int        totalLength = 0;
                TS_Package package     = new TS_Package();
                package.Header = new TS_Header();
                //ts header 4
                totalLength       += 4;
                package.Header.PID = 256;
                string key = jt1078Package.GetKey();
                if (VideoCounter.TryGetValue(key, out byte counter))
                {
                    if (counter > 0xf)
                    {
                        counter = 0;
                    }
                    package.Header.ContinuityCounter = counter++;
                    VideoCounter.TryUpdate(key, counter, counter);
                }
                else
                {
                    package.Header.ContinuityCounter = counter++;
                    VideoCounter.TryAdd(key, counter);
                }
                package.Header.PayloadUnitStartIndicator = 1;
                package.Header.Adaptation       = new TS_AdaptationInfo();
                package.Payload                 = new PES_Package();
                package.Payload.StreamId        = 0xe0;
                package.Payload.PESPacketLength = 0;
                //PESStartCode + StreamId + PESPacketLength
                //3 + 1 + 2
                totalLength += (3 + 1 + 2);
                package.Payload.PTS_DTS_Flag = PTS_DTS_Flags.all;
                if (jt1078Package.Label3.DataType == JT1078DataType.视频I帧)
                {
                    //ts header adaptation
                    //PCRIncluded + PCR
                    //1 + 5
                    totalLength += (1 + 5);
                    package.Header.Adaptation.PCRIncluded = PCRInclude.包含;
                    package.Header.Adaptation.PCR         = jt1078Package.LastIFrameInterval;
                    package.Payload.DTS = jt1078Package.LastIFrameInterval;
                    package.Payload.PTS = jt1078Package.LastIFrameInterval;
                }
                else
                {
                    //ts header adaptation
                    //PCRIncluded
                    //1
                    totalLength += 1;
                    package.Header.Adaptation.PCRIncluded = PCRInclude.包含;
                    package.Payload.DTS = jt1078Package.LastFrameInterval;
                    package.Payload.PTS = jt1078Package.LastFrameInterval;
                }
                //Flag1 + PTS_DTS_Flag + DTS + PTS
                //1 + 1 + 5 + 5
                totalLength += 12;
                //根据计算剩余的长度进行是否需要填充第一包
                var remainingLength = FiexdTSLength - totalLength;
                int index           = 0;
                //情况1:1078的第一包不够剩余(remainingLength)字节
                //情况2:1078的第一包比剩余(remainingLength)字节多
                //情况3: 1078的第一包等于剩余(remainingLength)字节
                //填充大小
                int fullSize = jt1078Package.Bodies.Length - remainingLength;
                package.Payload.Payload = new ES_Package();
                if (fullSize < 0)
                {
                    //这个很重要,需要控制
                    package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载;
                    //还差一点
                    fullSize = Math.Abs(fullSize);
                    package.Header.Adaptation.FillSize = (byte)fullSize;
                    package.Payload.Payload.NALUs      = new List <byte[]>()
                    {
                        jt1078Package.Bodies
                    };
                    package.ToBuffer(ref messagePackReader);
                }
                else if (fullSize == 0)
                {
                    //这个很重要,需要控制
                    package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载;
                    //刚刚好
                    package.Header.Adaptation.FillSize = 0;
                    package.Payload.Payload.NALUs      = new List <byte[]>()
                    {
                        jt1078Package.Bodies
                    };
                    package.ToBuffer(ref messagePackReader);
                }
                else
                {
                    //这个很重要,需要控制
                    package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载;
                    //太多了,需要拆分
                    package.Header.Adaptation.FillSize = 0;
                    package.Payload.Payload.NALUs      = new List <byte[]>();
                    ReadOnlySpan <byte> dataReader = jt1078Package.Bodies;
                    package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray());
                    index += remainingLength;
                    package.ToBuffer(ref messagePackReader);

                    while (index != jt1078Package.Bodies.Length)
                    {
                        if (counter > 0xf)
                        {
                            counter = 0;
                        }
                        int segmentFullSize = jt1078Package.Bodies.Length - index;
                        if (segmentFullSize >= FiexdSegmentPESLength)
                        {
                            CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, FiexdSegmentPESLength).ToArray(), counter++);
                        }
                        else
                        {
                            CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, segmentFullSize).ToArray(), counter++);
                            index += segmentFullSize;
                        }
                    }
                    VideoCounter.TryUpdate(key, counter, counter);
                }
                return(messagePackReader.FlushAndGetArray());
            }
            finally
            {
                TSArrayPool.Return(buffer);
            }
        }