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) { onStreamBuffer(); return; } int start = 8 + buffer[8]; index = start + 1; int startcodeLength = getStreamStartCode(buffer, index); if (startcodeLength == 4 || startcodeLength == 3) { int nalu = buffer[index + startcodeLength]; int nal = nalu & 0x1F; if (nal == 7 || nal == 8)//对应序列参数集SPS和图像参数集PPS { onUnpacked(Nalu.Parse(subBytes(buffer, index))); return;// getStreamBuffer(); } } setStreamBuffer(buffer, index); return; }
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)); } }
public static Nalu Parse(byte[] data) { int sIndex = getStartCodeLen(data); byte[] ndata = BytesHelper.SubBytes(data, sIndex); Nalu a = new Nalu(); a.Header = NaluHeader.Parse(ndata[0]); a.Payload = BytesHelper.SubBytes(ndata, 1); return(a); }
void onStreamBuffer() { if (_ms == null) { return; } byte[] buf = _ms.ToArray(); _ms.Close(); _ms = null; if (buf.Length > 0) { Nalu nalu = Nalu.Parse(buf); onUnpacked(nalu); } }
private static List <byte[]> SplitPayload(Nalu src) { List <byte[]> bList = new List <byte[]>(); int index = 0; int len = MTU - 1; while (index < src.PayloadLen) { if (index + len > src.PayloadLen) { len = src.PayloadLen - index; } bList.Add(BytesHelper.SubBytes(src.Payload, index, len)); index += len; } return(bList); }
public static List <Nalu> ToRTPPayload(Nalu src) { List <Nalu> nList = new List <Nalu>(); if (src.TotalBytes < MTU) { nList.Add(src); } else { List <byte[]> slices = SplitPayload(src); NaluHeader indicator = new NaluHeader(false, src.Header.NRI, NaluTypes.FU_A); for (int i = 0; i < slices.Count; i++) { bool start = i == 0; bool end = i == slices.Count - 1; FuHeader fuh = new FuHeader(start, end, src.Header.Type); nList.Add(new FragUnitA(indicator, fuh, slices[i]).ToNalu()); } } return(nList); }
private void onUnpacked(Nalu nalu) { Unpacked?.Invoke(this, nalu); }