public List <Nalu> ToRTP(PSFragment ps) { if (ps.IsFrameStart) { _header = ps.Header; } if (_header == null) { return(new List <Nalu>()); } List <Nalu> nList = new List <Nalu>(); if (ps.Data.Length < MTU && ps.IsFrameStart && ps.IsFrameEnd) { nList.Add(new Nalu(_header, ps.Data)); } else { List <byte[]> slices = SplitPayload(ps.Data); NaluHeader indicator = new NaluHeader(false, _header.NRI, NaluTypes.FU_A); for (int i = 0; i < slices.Count; i++) { bool start = (i == 0) && ps.IsFrameStart; bool end = (i == slices.Count - 1 && ps.IsFrameEnd); FuHeader fuh = new FuHeader(start, end, _header.Type); nList.Add(new FragUnitA(indicator, fuh, slices[i]).ToNalu()); } } return(nList); }
private void decodeE0(byte[] buffer, int index) //视频流 { int length = readUshort(buffer, 4); //PES packet length:16 位字段,指出了PES 分组中跟在该字段后的字节数目。值为0 表示PES 分组长度要么没有规定要么没有限制。这种情况只允许出现在有效负载包含来源于传输流分组中某个视频基本流的字节的PES 分组中。 if (length != buffer.Length - 6) { return; } int start = 8 + buffer[8]; index = start + 1; int startcodeLen = getStreamStartCode(buffer, index); if (startcodeLen == 4 || startcodeLen == 3) { Nalu nal = Nalu.Parse(BytesHelper.SubBytes(buffer, index + startcodeLen)); //标记上一个包是一帧的结束。 if (_lastFg != null) { _lastFg.IsFrameEnd = true; toFireUnpacked(); } //因为有header值,因此此包是一帧开始 _lastFg = new PSFragment(nal.Header, nal.Payload); } else { toFireUnpacked(); _lastFg = new PSFragment(null, BytesHelper.SubBytes(buffer, index)); } }
private void toFireUnpacked() { if (_lastFg != null) { onUnpacked(_lastFg); } _lastFg = null; }
private void onUnpacked(PSFragment psf) { Unpacked?.Invoke(this, psf); }