private NALUnit[] ReadNALUnitArray(MemoryStream stream, int cnt) { return(Enumerable.Range(0, cnt) .Select(_ => { var len = stream.ReadUInt16BE(); return NALUnit.ReadFrom(stream, len); }) .ToArray()); }
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() ); }