예제 #1
0
        private void AddVideoParamaterSet(VideoSample sample)
        {
            var configpart = VideoParameter.Split(',');

            // Add SPS
            sample.BeginUnit();
            sample.AddUnitData(Convert.FromBase64String(configpart[0]));
            sample.EndUnit();
            // Add PPS
            sample.BeginUnit();
            sample.AddUnitData(Convert.FromBase64String(configpart[1]));
            sample.EndUnit();
        }
예제 #2
0
        private IRtspSample OnVideoPacket(long sampleTime, RtpPacket packet, bool discontinuity)
        {
            if (discontinuity)
            {
                // clear fragmented NAL unit
                _lastVideoSample = null;
            }

            var data = packet.PayloadData.ToArray();

            if (data.Length < 1)
            {
                return(null);
            }

            // Interleaved mode is not supported.
            var nalUnitFlags = data[0] & 0xe0;
            var nalUnitType  = data[0] & 0x1f;

            if (nalUnitType <= 23)
            {
                // NAL unit (one packet, one NAL)
                //Trace.WriteLine($"RtspHandler::OnVideoPacket(): NALType({nalUnitType}) Timestamp={packet.Timestamp} Length={data.Length}");
                var sample = new VideoSample(sampleTime, discontinuity, (nalUnitType == 5));
                if (sampleTime == 0)
                {
                    AddVideoParamaterSet(sample);
                }
                sample.BeginUnit();
                sample.AddUnitData(data);
                sample.EndUnit();
                sample.Commit();
                return(sample);
            }
            if (nalUnitType == 24)
            {
                // STAP-A (Single-time aggregation packet: one packet, multiple NALs)
                // TBD
                Debug.WriteLine("RtspHandler::OnVideoPacket(): STAP-A");
                return(null);
            }
            if (nalUnitType == 28)
            {
                // FU-A (Fragmentation Units: multiple packets, one NAL)
                //var fuIndicator = data[0];
                var fuHeader = data[1];
                if ((fuHeader & 0x80) != 0)  // check start bit
                // start of a fragmented NAL unit
                {
                    var fuNalUnitType = fuHeader & 0x1f;
                    //Trace.WriteLine($"RtspHandler::OnVideoPacket(): FU-A Start NALType({fuNalUnitType}) Timestamp={packet.Timestamp} Length={data.Length - 2}");
                    if (_lastVideoSample != null)
                    {
                        Debug.WriteLine("RtspHandler::OnVideoPacket(): Invalid fragmented NAL start.");
                    }
                    _lastVideoSample = new VideoSample(sampleTime, discontinuity, (fuNalUnitType == 5));
                    if (sampleTime == 0)
                    {
                        AddVideoParamaterSet(_lastVideoSample);
                    }
                    _lastVideoSample.BeginUnit();
                    _lastVideoSample.AddUnitData((byte)(nalUnitFlags | fuNalUnitType));
                    _lastVideoSample.AddUnitData(data.Skip(2));
                    return(null);
                }
                if (discontinuity)
                {
                    Debug.WriteLine("RtspHandler::OnVideoPacket(): Ignore middle-started fragmented NAL.");
                    return(null);
                }
                if ((fuHeader & 0x40) != 0)  // check end bit
                // end of a fragmented NAL unit
                //Trace.WriteLine($"RtspHandler::OnVideoPacket(): FU-A End Timestamp={packet.Timestamp} Length={data.Length - 2}");
                {
                    if (_lastVideoSample != null)
                    {
                        _lastVideoSample.AddUnitData(data.Skip(2));
                        _lastVideoSample.EndUnit();
                        _lastVideoSample.Commit();
                        var sample = _lastVideoSample;
                        _lastVideoSample = null;
                        return(sample);
                    }
                    else
                    {
                        Debug.WriteLine("RtspHandler::OnVideoPacket(): Invalid fragmented NAL end.");
                        return(null);
                    }
                }
                // following FU payload
                //Trace.WriteLine($"RtspHandler::OnVideoPacket(): FU-A Continue Timestamp={packet.Timestamp} Length={data.Length - 2}");
                if (_lastVideoSample != null)
                {
                    _lastVideoSample.AddUnitData(data.Skip(2));
                }
                else
                {
                    Debug.WriteLine("RtspHandler::OnVideoPacket(): Invalid fragmented NAL.");
                }
                return(null);
            }

            Debug.WriteLine($"RtspHandler::OnVideoPacket(): Unknown NALType({nalUnitType})");
            return(null);
        }