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; } }
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); }
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; }
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; }
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 ); } } }
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 })); }
private bool IsAACHeader(RTMPMessage msg) { return (msg.MessageType == RTMPMessageType.Audio && msg.Body.Length > 1 && (msg.Body[0] == 0xAF && msg.Body[1] == 0x00)); }
public void OnVideo(RTMPMessage msg) { if (IsAVCHeader(msg)) { videoHeader = msg; OnHeaderChanged(msg); } OnContentChanged(msg); }
public void OnAudio(RTMPMessage msg) { if (IsAACHeader(msg)) { audioHeader = msg; OnHeaderChanged(msg); } OnContentChanged(msg); }
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)); }
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 })); }
public RTMPMessageHeader(RTMPMessage parentMessage) { ParentMessage = parentMessage; Connection = parentMessage.Connection; Format = RTMPMessageFormat.Undefined; ChunkStreamID = RTMPMessageChunkStreamID.Undefined; Timestamp = 0; MessageLength = -1; MessageTypeID = RTMPMessageTypeID.AMF0; MessageStreamID = -1; }
private void OnContentChanged(RTMPMessage content) { if (streamIndex < 0) { OnHeaderChanged(content); } WriteMessage(bodyBuffer, content, timestampOrigin); if (bodyBuffer.Length >= 7500 || flushTimer.ElapsedMilliseconds >= 100) { FlushContents(); } }
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); } }
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); } }
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); } }
public void OnVideo(RTMPMessage msg) { OnContent(msg); }
public void OnAudio(RTMPMessage msg) { OnContent(msg); }
public RTMPAcknowledgement(RTMPMessage msg) : base(msg) { BytesSoFar = msg.Body.MemoryReader.ReadUInt(); }
public RTMPMessageBody(RTMPMessage message) { ParentMessage = message; MemoryWriter = new RTMPLib.Internal.BinaryWriter(ms); }
public RTMPSetChunkSize(RTMPMessage msg) : base(msg) { ChunkSize = msg.Body.MemoryReader.ReadUInt(); }
public RTMPAudioMessage(RTMPMessage msg) : base(msg) { Format = msg.Body.MemoryReader.ReadByte(); Data = msg.Body.MemoryReader.ReadBytes(msg.Header.MessageLength - 1); }
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 }); }
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 }); }
public static bool IsKeyFrame(this RTMPMessage msg) { return(msg.GetPacketType() != FLVPacketType.AVCNALUnitInterFrame); }
public RTMPAMF0Message(RTMPMessage rawMessage) : base(rawMessage) { }
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() ); }