Beispiel #1
0
            private void OnContent(RTMPMessage msg)
            {
                if (ptsBase < 0 && msg.Timestamp > 0)
                {
                    ptsBase = msg.Timestamp;
                }
                switch (msg.GetPacketType())
                {
                case FLVPacketType.AACSequenceHeader:
                    OnAACHeader(msg);
                    break;

                case FLVPacketType.AACRawData:
                    OnAACBody(msg);
                    break;

                case FLVPacketType.AVCSequenceHeader:
                    OnAVCHeader(msg);
                    break;

                case FLVPacketType.AVCNALUnitKeyFrame:
                    OnAVCBody(msg, true);
                    break;

                case FLVPacketType.AVCNALUnitInterFrame:
                    OnAVCBody(msg, false);
                    break;

                default:
                    break;
                }
            }
Beispiel #2
0
        public RTMPMessage AddFragment(RTMPMessage message)
        {
            if (message.Header.MessageLength > Connection.IncomingChunkSize)
            {
                if (streamFragments.Count == 0)
                {
                    RemainingBytes  = message.Header.MessageLength - Connection.IncomingChunkSize;
                    MessageLength   = message.Header.MessageLength;
                    Timestamp       = message.Header.Timestamp;
                    MessageTypeID   = message.Header.MessageTypeID;
                    MessageStreamID = message.Header.MessageStreamID;
                }

                if (message.Header.MessageLength < 0)                 //followup
                {
                    RemainingBytes -= Connection.IncomingChunkSize;
                }

                streamFragments.Enqueue(message);

                if (RemainingBytes <= 0)                 //finished message
                {
                    return(ProcessFragments());
                }
            }
            else
            {
                RemainingBytes = 0;
                return(message);
            }
            return(null);
        }
Beispiel #3
0
        private void OnHeaderChanged(RTMPMessage msg)
        {
            var s = new MemoryStream();

            using (s) {
                using (var writer = new RTMPBinaryWriter(s, true)) {
                    writer.Write((byte)'F');
                    writer.Write((byte)'L');
                    writer.Write((byte)'V');
                    writer.Write((byte)1);
                    writer.Write((byte)5);
                    writer.WriteUInt32(9);
                    writer.WriteUInt32(0);
                }
                if (metadata != null)
                {
                    WriteMessage(s, metadata, 0xFFFFFFFF);
                }
                if (audioHeader != null)
                {
                    WriteMessage(s, audioHeader, 0xFFFFFFFF);
                }
                if (videoHeader != null)
                {
                    WriteMessage(s, videoHeader, 0xFFFFFFFF);
                }
            }
            streamIndex     = TargetChannel.GenerateStreamID();
            streamOrigin    = DateTime.Now;
            timestampOrigin = msg.Timestamp;
            var bytes = s.ToArray();

            ContentSink.OnContentHeader(new Content(streamIndex, TimeSpan.Zero, position, bytes, PCPChanPacketContinuation.None));
            position += bytes.Length;
        }
Beispiel #4
0
        public RTMPMessage AddFragment(RTMPMessage message)
        {
            if (message.Header.MessageLength > Connection.IncomingChunkSize)
            {
                if (streamFragments.Count == 0)
                {
                    RemainingBytes = message.Header.MessageLength - Connection.IncomingChunkSize;
                    MessageLength = message.Header.MessageLength;
                    Timestamp = message.Header.Timestamp;
                    MessageTypeID = message.Header.MessageTypeID;
                    MessageStreamID = message.Header.MessageStreamID;
                }

                if (message.Header.MessageLength < 0) //followup
                {
                    RemainingBytes -= Connection.IncomingChunkSize;
                }

                streamFragments.Enqueue(message);

                if (RemainingBytes <= 0) //finished message
                {
                    return ProcessFragments();
                }
            }
            else
            {
                RemainingBytes = 0;
                return message;
            }
            return null;
        }
Beispiel #5
0
 private void OnAACHeader(RTMPMessage msg)
 {
     using (var s = new MemoryStream(msg.Body, false)) {
         s.Seek(2, SeekOrigin.Current);
         using (var bs = new BitReader(s, true)) {
             var type = bs.ReadBits(5);
             if (type == 31)
             {
                 type = bs.ReadBits(6) + 32;
             }
             var sampling_freq_idx     = bs.ReadBits(4);
             var sampling_freq         = sampling_freq_idx == 0x0F ? bs.ReadBits(24) : sampling_freq_idx;
             var channel_configuration = bs.ReadBits(4);
             this.adtsHeader = new ADTSHeader(
                 0xFFF,                 //sync
                 0,                     //ID
                 0,                     //Layer
                 true,                  //CRC Absent
                 type - 1,              //Profile
                 sampling_freq_idx,     //Sampling frequency index
                 0,                     //Private
                 channel_configuration, //Channel configuration
                 0,                     //Original/Copy
                 0,                     //home
                 0,                     //Copyright identification bit
                 0,                     //Copyright identification start
                 0,                     //frame length
                 0x7FF,                 //buffer fullness
                 0,                     //number of raw data blocks in frame
                 0                      //CRC
                 );
         }
     }
 }
Beispiel #6
0
 private void OnAVCHeader(RTMPMessage msg)
 {
     using (var data = new MemoryStream(msg.Body, 0, msg.Body.Length, false, true)) {
         data.Seek(5, SeekOrigin.Current);
         var configuratidn_version  = data.ReadByte();
         var avc_profile_indication = data.ReadByte();
         var profile_compatibility  = data.ReadByte();
         var avc_level_indcation    = data.ReadByte();
         this.nalSizeLen = (data.ReadByte() & 0x3) + 1;
         var sps_count = (data.ReadByte() & 0x1F);
         this.sps = ReadNALUnitArray(data, sps_count);
         var pps_count = data.ReadByte();
         this.pps = ReadNALUnitArray(data, pps_count);
         if (data.Position < data.Length &&
             (avc_profile_indication == 100 ||
              avc_profile_indication == 110 ||
              avc_profile_indication == 122 ||
              avc_profile_indication == 144))
         {
             var sps_ext_count = data.ReadByte();
             this.spsExt = ReadNALUnitArray(data, sps_ext_count);
         }
         else
         {
             this.spsExt = new NALUnit[0];
         }
     }
 }
        public static new RTMPMessage Decode(RTMPMessage msg)
        {
            msg.Body.MemoryReader.BaseStream.Position = 0;
            UserControlMessage_EventType eventType = (UserControlMessage_EventType)msg.Body.MemoryReader.ReadUShort();
            Type tmp = registered[eventType];

            return((RTMPUserControlMessage)tmp.GetConstructor(new Type[] { typeof(RTMPMessage) }).Invoke(new object[] { msg }));
        }
Beispiel #8
0
 private bool IsAACHeader(RTMPMessage msg)
 {
     return
         (msg.MessageType == RTMPMessageType.Audio &&
          msg.Body.Length > 1 &&
          (msg.Body[0] == 0xAF &&
           msg.Body[1] == 0x00));
 }
Beispiel #9
0
 public void OnVideo(RTMPMessage msg)
 {
     if (IsAVCHeader(msg))
     {
         videoHeader = msg;
         OnHeaderChanged(msg);
     }
     OnContentChanged(msg);
 }
Beispiel #10
0
 public void OnAudio(RTMPMessage msg)
 {
     if (IsAACHeader(msg))
     {
         audioHeader = msg;
         OnHeaderChanged(msg);
     }
     OnContentChanged(msg);
 }
Beispiel #11
0
 private bool IsAVCHeader(RTMPMessage msg)
 {
     return
         (msg.MessageType == RTMPMessageType.Video &&
          msg.Body.Length > 3 &&
          (msg.Body[0] == 0x17 &&
           msg.Body[1] == 0x00 &&
           msg.Body[2] == 0x00 &&
           msg.Body[3] == 0x00));
 }
Beispiel #12
0
        public static new RTMPAMF0Message Decode(RTMPMessage msg)
        {
            msg.Body.MemoryReader.BaseStream.Position = 0;
            msg.Body.MemoryReader.ReadByte();                   // should be 02;
            short  len     = msg.Body.MemoryReader.ReadShort(); //strlen
            String command = msg.Body.ReadString(len);
            Type   tmp     = registered[command];

            return((RTMPAMF0Message)tmp.GetConstructor(new Type[] { typeof(RTMPMessage) }).Invoke(new object[] { msg }));
        }
Beispiel #13
0
        public RTMPMessageHeader(RTMPMessage parentMessage)
        {
            ParentMessage = parentMessage;
            Connection = parentMessage.Connection;

            Format = RTMPMessageFormat.Undefined;
            ChunkStreamID = RTMPMessageChunkStreamID.Undefined;
            Timestamp = 0;
            MessageLength = -1;
            MessageTypeID = RTMPMessageTypeID.AMF0;
            MessageStreamID = -1;
        }
Beispiel #14
0
        public RTMPMessageHeader(RTMPMessage parentMessage)
        {
            ParentMessage = parentMessage;
            Connection    = parentMessage.Connection;

            Format          = RTMPMessageFormat.Undefined;
            ChunkStreamID   = RTMPMessageChunkStreamID.Undefined;
            Timestamp       = 0;
            MessageLength   = -1;
            MessageTypeID   = RTMPMessageTypeID.AMF0;
            MessageStreamID = -1;
        }
Beispiel #15
0
 private void OnContentChanged(RTMPMessage content)
 {
     if (streamIndex < 0)
     {
         OnHeaderChanged(content);
     }
     WriteMessage(bodyBuffer, content, timestampOrigin);
     if (bodyBuffer.Length >= 7500 ||
         flushTimer.ElapsedMilliseconds >= 100)
     {
         FlushContents();
     }
 }
Beispiel #16
0
        private void WriteMessage(Stream stream, RTMPMessage msg, long time_origin)
        {
            var timestamp = Math.Max(0, msg.Timestamp - time_origin);

            using (var writer = new RTMPBinaryWriter(stream, true)) {
                writer.Write((byte)msg.MessageType);
                writer.WriteUInt24(msg.Body.Length);
                writer.WriteUInt24((int)timestamp & 0xFFFFFF);
                writer.Write((byte)((timestamp >> 24) & 0xFF));
                writer.WriteUInt24(0);
                writer.Write(msg.Body, 0, msg.Body.Length);
                writer.Write(msg.Body.Length + 11);
            }
        }
Beispiel #17
0
 private void OnContentChanged(RTMPMessage content)
 {
     if (streamIndex < 0)
     {
         OnHeaderChanged(content);
         return;
     }
     WriteMessage(bodyBuffer, content, timestampOrigin);
     if (bodyBuffer.Length > 0)
     {
         ContentSink.OnContent(new Content(streamIndex, DateTime.Now - streamOrigin, position, bodyBuffer.ToArray(), PCPChanPacketContinuation.None));
         position += bodyBuffer.Length;
         bodyBuffer.SetLength(0);
     }
 }
Beispiel #18
0
            private void OnAACBody(RTMPMessage msg)
            {
                var pts         = msg.Timestamp - Math.Max(0, ptsBase);
                var raw_length  = msg.Body.Length - 2;
                var header      = new ADTSHeader(adtsHeader, raw_length + adtsHeader.Bytesize);
                var pes_payload = new MemoryStream();

                using (pes_payload) {
                    ADTSHeader.WriteTo(pes_payload, header);
                    pes_payload.Write(msg.Body, 2, raw_length);
                }
                var pes        = new PESPacket(0xC0, TSTimeStamp.FromMilliseconds(pts), null, pes_payload.ToArray());
                var pes_packet = new MemoryStream();

                using (pes_packet) {
                    PESPacket.WriteTo(pes_packet, pes);
                }
                writer.WriteTSPackets(
                    AudioPID,
                    true,
                    null,
                    pes_packet.ToArray()
                    );
            }
        private PCPChanPacketContinuation GetContentFlags(RTMPMessage content)
        {
            var pkttype = content.GetPacketType();

            switch (pkttype)
            {
            case FLVPacketType.AudioData:
            case FLVPacketType.AACRawData:
                return(PCPChanPacketContinuation.AudioFrame);

            case FLVPacketType.AACSequenceHeader:
                return(PCPChanPacketContinuation.None);

            case FLVPacketType.AVCNALUnitInterFrame:
                return(PCPChanPacketContinuation.IntraFrame);

            case FLVPacketType.AVCEOS:
            case FLVPacketType.AVCNALUnitKeyFrame:
            case FLVPacketType.AVCSequenceHeader:
            case FLVPacketType.VideoData:
            default:
                return(PCPChanPacketContinuation.None);
            }
        }
Beispiel #20
0
 public void OnVideo(RTMPMessage msg)
 {
     OnContent(msg);
 }
Beispiel #21
0
 public void OnAudio(RTMPMessage msg)
 {
     OnContent(msg);
 }
 public RTMPAcknowledgement(RTMPMessage msg) : base(msg)
 {
     BytesSoFar = msg.Body.MemoryReader.ReadUInt();
 }
Beispiel #23
0
 public RTMPMessageBody(RTMPMessage message)
 {
     ParentMessage = message;
     MemoryWriter  = new RTMPLib.Internal.BinaryWriter(ms);
 }
Beispiel #24
0
 public RTMPMessageBody(RTMPMessage message)
 {
     ParentMessage = message;
     MemoryWriter = new RTMPLib.Internal.BinaryWriter(ms);
 }
Beispiel #25
0
 public RTMPSetChunkSize(RTMPMessage msg)
     : base(msg)
 {
     ChunkSize = msg.Body.MemoryReader.ReadUInt();
 }
Beispiel #26
0
 public RTMPAudioMessage(RTMPMessage msg) : base(msg)
 {
     Format = msg.Body.MemoryReader.ReadByte();
     Data   = msg.Body.MemoryReader.ReadBytes(msg.Header.MessageLength - 1);
 }
Beispiel #27
0
 public RTMPSetChunkSize(RTMPMessage msg)
     : base(msg)
 {
     ChunkSize = msg.Body.MemoryReader.ReadUInt();
 }
Beispiel #28
0
 public static new RTMPAMF0Message Decode(RTMPMessage msg)
 {
     msg.Body.MemoryReader.BaseStream.Position = 0;
     msg.Body.MemoryReader.ReadByte(); // should be 02;
     short len = msg.Body.MemoryReader.ReadShort();//strlen
     String command = msg.Body.ReadString(len);
     Type tmp = registered[command];
     return (RTMPAMF0Message)tmp.GetConstructor(new Type[] { typeof(RTMPMessage) }).Invoke(new object[] { msg });
 }
Beispiel #29
0
        public static FLVPacketType GetPacketType(this RTMPMessage msg)
        {
            switch (msg.MessageType)
            {
            case RTMPMessageType.Audio:
                if (msg.Body.Length < 2)
                {
                    return(FLVPacketType.AudioData);
                }
                switch ((msg.Body[0] & 0xF0) >> 4)
                {
                case 10:
                    if (msg.Body[1] == 0)
                    {
                        return(FLVPacketType.AACSequenceHeader);
                    }
                    else
                    {
                        return(FLVPacketType.AACRawData);
                    }

                default:
                    return(FLVPacketType.AudioData);
                }

            case RTMPMessageType.Video:
                if (msg.Body.Length < 2)
                {
                    return(FLVPacketType.VideoData);
                }
                switch (msg.Body[0] & 0x0F)
                {
                case 7:
                    switch (msg.Body[1])
                    {
                    case 0:
                        return(FLVPacketType.AVCSequenceHeader);

                    case 1:
                        switch ((msg.Body[0] & 0xF0) >> 4)
                        {
                        case 1:
                        case 4:
                            return(FLVPacketType.AVCNALUnitKeyFrame);

                        default:
                            return(FLVPacketType.AVCNALUnitInterFrame);
                        }

                    case 2:
                        return(FLVPacketType.AVCEOS);

                    default:
                        return(FLVPacketType.VideoData);
                    }

                default:
                    return(FLVPacketType.VideoData);
                }

            default:
                return(FLVPacketType.Unknown);
            }
        }
 public RTMPUserControlMessage(RTMPMessage msg)
     : base(msg)
 {
     Body.MemoryReader.BaseStream.Position = 0;
     EventType = (UserControlMessage_EventType)Body.MemoryReader.ReadUShort();
 }
 public static new RTMPMessage Decode(RTMPMessage msg)
 {
     msg.Body.MemoryReader.BaseStream.Position = 0;
     UserControlMessage_EventType eventType = (UserControlMessage_EventType)msg.Body.MemoryReader.ReadUShort();
     Type tmp = registered[eventType];
     return (RTMPUserControlMessage)tmp.GetConstructor(new Type[] { typeof(RTMPMessage) }).Invoke(new object[] { msg });
 }
Beispiel #32
0
 public static bool IsKeyFrame(this RTMPMessage msg)
 {
     return(msg.GetPacketType() != FLVPacketType.AVCNALUnitInterFrame);
 }
Beispiel #33
0
 public RTMPAMF0Message(RTMPMessage rawMessage)
     : base(rawMessage)
 {
 }
Beispiel #34
0
            private void OnAVCBody(RTMPMessage msg, bool keyframe)
            {
                var pts = msg.Timestamp - Math.Max(0, ptsBase);
                var cts = msg.Body.Skip(2).Take(3).Aggregate(0, (r, v) => (r << 8) | v);

                if (cts >= 0x800000)
                {
                    cts = 0x1000000 - cts;
                }
                var dts = pts;

                pts = pts + cts;
                var access_unit_delimiter = false;
                var idr           = false;
                var nalbytestream = new MemoryStream();
                int units         = 0;

                using (nalbytestream)
                    using (var body = new MemoryStream(msg.Body, 0, msg.Body.Length)) {
                        body.Seek(5, SeekOrigin.Begin);
                        while (body.Position < body.Length)
                        {
                            var len  = body.ReadBytes(nalSizeLen).Aggregate(0, (r, v) => (r << 8) | v);
                            var nalu = NALUnit.ReadFrom(body, len);
                            if (nalu.NALUnitType == 9)
                            {
                                access_unit_delimiter = true;
                            }
                            if (!access_unit_delimiter)
                            {
                                NALUnit.WriteToByteStream(nalbytestream, NALUnit.AccessUnitDelimiter);
                                access_unit_delimiter = true;
                            }
                            if (nalu.NALUnitType == 5)
                            {
                                idr = true;
                                foreach (var unit in sps)
                                {
                                    NALUnit.WriteToByteStream(nalbytestream, unit);
                                }
                                foreach (var unit in pps)
                                {
                                    NALUnit.WriteToByteStream(nalbytestream, unit);
                                }
                                foreach (var unit in spsExt)
                                {
                                    NALUnit.WriteToByteStream(nalbytestream, unit);
                                }
                            }
                            NALUnit.WriteToByteStream(nalbytestream, nalu);
                            units += 1;
                        }
                    }
                var pes = new PESPacket(
                    0xE0,
                    TSTimeStamp.FromMilliseconds(pts),
                    TSTimeStamp.FromMilliseconds(dts),
                    nalbytestream.ToArray()
                    );
                var pes_packet = new MemoryStream();

                using (pes_packet) {
                    PESPacket.WriteTo(pes_packet, pes);
                }
                writer.WriteTSPackets(
                    VideoPID,
                    msg.IsKeyFrame() || idr,
                    idr ? (TSTimeStamp?)TSTimeStamp.FromMilliseconds(dts) : null,
                    pes_packet.ToArray()
                    );
            }
Beispiel #35
0
 public RTMPAMF0Message(RTMPMessage rawMessage)
     : base(rawMessage)
 {
 }
 public RTMPUserControlMessage(RTMPMessage msg)
     : base(msg)
 {
     Body.MemoryReader.BaseStream.Position = 0;
     EventType = (UserControlMessage_EventType)Body.MemoryReader.ReadUShort();
 }
 public RTMPAcknowledgement(RTMPMessage msg)
     : base(msg)
 {
     BytesSoFar = msg.Body.MemoryReader.ReadUInt();
 }