public static RtspClientSharp.RawFrames.Video.RawH264Frame CopyFrame(RtspClientSharp.RawFrames.Video.RawH264Frame frame) { RtspClientSharp.RawFrames.Video.RawH264Frame duplicate = null; if (frame is RtspClientSharp.RawFrames.Video.RawH264IFrame iFrame) { duplicate = new RtspClientSharp.RawFrames.Video.RawH264IFrame(iFrame.Timestamp, SaveBuffer(iFrame.FrameSegment), SaveBuffer(iFrame.SpsPpsSegment)); } else if (frame is RtspClientSharp.RawFrames.Video.RawH264PFrame pFrame) { duplicate = new RtspClientSharp.RawFrames.Video.RawH264PFrame(pFrame.Timestamp, SaveBuffer(pFrame.FrameSegment)); } return(duplicate); }
private void HandleFrame(RtspClientSharp.RawFrames.Video.RawH264Frame frame) { bool isIFrame = false; if (frame is RtspClientSharp.RawFrames.Video.RawH264IFrame iframe) { isIFrame = true; if (parser != null) { OnFrames?.Invoke(this, new FrameSetEvent { StartTimestamp = lastTimestamp, EndTimestamp = iframe.Timestamp, StreamInfo = parser, RawFrames = samples.ToArray() }); samples.Clear(); } lastTimestamp = iframe.Timestamp; parser = new MP4.SpsParser(iframe.SpsPpsSegment.ToArray()); OnFrameInfo?.Invoke(this, new InfoEvent { StartTimestamp = lastTimestamp, StreamInfo = parser }); } if (parser != null) { byte[] sample = frame.FrameSegment.ToArray(); byte[][] parts; if (isIFrame) { // Apparently, I frame should also be preceded by SPS and PPS, even though they're also in the header. parts = new byte[][] { parser.Sps, parser.Pps, sample }; } else { // Check it has a start marker (as we use it to update it to a length marker) parts = new byte[][] { sample }; } samples.Add(AppendDataWithStartMarker(parts)); } }