public MultiplexFrameHeader ParseMultiplexFrameHeader(int offset, Stream _stream) { _stream.Seek(offset, SeekOrigin.Begin); byte[] tmp = new byte[4]; int r = _stream.Read(tmp, 0, 4); // read the start code, if (r != 4) { return(null); } if (BitTools.FindBytePattern(tmp, frameStartCode) != 0) { return(null); // start code not match, return } MultiplexFrameHeader mfHeader = new MultiplexFrameHeader(); mfHeader.startAddr = 0x0; // parse frame header length 1 byte. _stream.Read(tmp, 0, 1); mfHeader.headerLength = tmp[0]; // 再读两个字节,协议版本号5 bit, 最低版本号5 bit, 复用帧标示 6 bit _stream.Read(tmp, 0, 2); mfHeader.MD_ID = (uint)BitTools.MaskBits(tmp, 10, 6); // 跳过4个字节, 包括从紧急广播提示-ESG更新序列号 _stream.Seek(4, SeekOrigin.Current); // 读一个字节,取出 subFrame number (4 bit) _stream.Read(tmp, 0, 1); mfHeader.subFrameNum = (uint)BitTools.MaskBits(tmp, 4, 4); //读取子帧长度 (3 byte) mfHeader.subFrameLength = new int[mfHeader.subFrameNum]; for (int i = 0; i < mfHeader.subFrameNum; i++) { _stream.Read(tmp, 0, 3); mfHeader.subFrameLength[i] = BitTools.MaskBits(tmp, 0, 24); } return(mfHeader); }
public bool ParseNALHeader(MSF.VideoBlock vb) { // Need to get the SPS and PPS of the stream, the first frame must be I frame, other frames cannot be played. if (vb.FirstIFrameIdx == -1) { return(false); } //有I帧 byte[] tmp = new byte[32]; byte[] NALStartCode = new byte[] { 0x00, 0x00, 0x01 }; List <byte[]> nals = new List <byte[]>(); Stream s = new MemoryStream(); //vb.vFrames[vb.FirstIFrameIdx]._vs; s.Write(vb.vFrames[vb.FirstIFrameIdx]._data, 0, (int)vb.vFrames[vb.FirstIFrameIdx].Length); s.Seek(0, SeekOrigin.Begin); s.Read(tmp, 0, 3); if (BitTools.FindBytePattern(tmp, NALStartCode) != 0) { return(false); } while (true) { long pos = s.Position; s.Read(tmp, 0, 32); int nextNALidx = BitTools.FindBytePattern(tmp, NALStartCode); if (nextNALidx == -1) { break; } byte[] nal = new byte[nextNALidx]; BitTools.CopyToBytesArray(tmp, nal, nextNALidx); nals.Add(nal); // rollback pos pos += nextNALidx + 3; //跳过下一个startcode s.Seek(pos, SeekOrigin.Begin); } s.Close(); vb.FirstIFrameInfo = new MSF.VideoBlock.NAL_SPS_PPS_SEI(); foreach (var v in nals) { switch (v[0]) { case 0x67: //SPS http://www.eefocus.com/czzheng/blog/11-09/230262_65ff0.html vb.FirstIFrameInfo.sps = new byte[v.Length - 1]; BitTools.CopyToBytesArray(v, 1, vb.FirstIFrameInfo.sps, v.Length - 1); break; case 0x68: //PPS vb.FirstIFrameInfo.pps = new byte[v.Length - 1]; BitTools.CopyToBytesArray(v, 1, vb.FirstIFrameInfo.pps, v.Length - 1); break; case 0x06: // SEI vb.FirstIFrameInfo.sei = new byte[v.Length - 1]; BitTools.CopyToBytesArray(v, 1, vb.FirstIFrameInfo.sei, v.Length - 1); break; default: break; } } return(true); }