public MSF.AudioBlock ParseAudioBlock(int offset, Stream _stream) { _stream.Seek(offset, SeekOrigin.Begin); byte[] tmp = new byte[4]; MSF.AudioBlock ab = new MSF.AudioBlock(); _stream.Read(tmp, 0, 1); ab.AudioFrameNum = (uint)BitTools.MaskBits(tmp, 0, 8); ab.AudioBlockHeaderLength = ab.AudioFrameNum * 5 + 1; uint addr = (uint)offset + ab.AudioBlockHeaderLength + CRC_Size; for (int i = 0; i < ab.AudioFrameNum; i++) { //读音频参数集 MSF.AudioBlock.AudioFrame f = new MSF.AudioBlock.AudioFrame(); _stream.Read(tmp, 0, 2); f.RelativeStartAddr = addr; f.Length = (uint)BitTools.MaskBits(tmp, 0, 16); // skip 音频流编号 和 保留 _stream.Seek(1, SeekOrigin.Current); // 读相对时间 _stream.Read(tmp, 0, 2); f.RelativeTime = BitTools.MaskBits(tmp, 0, 16) * timeUint; // copy 音频流 //f._as = BitTools.CopyToNewStream(_stream, (long)f.RelativeStartAddr, (int)f.Length); BitTools.CopyFromStreamToBytesArray(_stream, (long)f.RelativeStartAddr, (int)f.Length, ref f._data); ab.aFrames.Add(f); //下一段音频地址 addr += f.Length; } return(ab); }
public MSF.VideoBlock ParseVideoBlock(int offset, Stream _stream) { _stream.Seek(offset, SeekOrigin.Begin); byte[] tmp = new byte[4]; MSF.VideoBlock vb = new MSF.VideoBlock(); _stream.Read(tmp, 0, 2); vb.VideoBlockHeaderLength = (uint)BitTools.MaskBits(tmp, 0, 12); //计算有多少个视频帧, 每个视频参数集 5byte vb.VideoFrameNum = vb.VideoBlockHeaderLength / 5; uint addr = (uint)offset + vb.VideoBlockHeaderLength + CRC_Size; for (int i = 0; i < vb.VideoFrameNum; i++) { MSF.VideoBlock.VideoFrame f = new MSF.VideoBlock.VideoFrame(); //本段视频的开始地址 f.RelativeStartAddr = addr; // 视频段长度 _stream.Read(tmp, 0, 2); f.Length = (uint)BitTools.MaskBits(tmp, 0, 16); // 帧类型,I帧 or P帧 _stream.Read(tmp, 0, 1); f.FrameMode = (uint)BitTools.MaskBits(tmp, 0, 3); if (vb.FirstIFrameIdx == -1 && f.FrameMode == 0) { vb.FirstIFrameIdx = i; } // 相对播放时间 if (BitTools.MaskBits(tmp, 7, 1) == 1) //相对时间提示 { _stream.Read(tmp, 0, 2); f.RelativeTime = BitTools.MaskBits(tmp, 0, 16) * timeUint; } // 本段视频流 //f._vs = BitTools.CopyToNewStream(_stream, (long)f.RelativeStartAddr, (int)f.Length); BitTools.CopyFromStreamToBytesArray(_stream, (long)f.RelativeStartAddr, (int)f.Length, ref f._data); vb.vFrames.Add(f); //下一段视频的开始地址 addr += f.Length; } ParseNALHeader(vb); return(vb); }
public MSFHeader ParseMSFHeader(int offset, Stream _stream) { _stream.Seek(offset, SeekOrigin.Begin); byte[] tmp = new byte[4]; MSFHeader msfHeader = new MSFHeader(); _stream.Read(tmp, 0, 1); msfHeader.Length = tmp[0]; _stream.Read(tmp, 0, 1); msfHeader.VideoBlockIndicator = (uint)BitTools.MaskBits(tmp, 1, 1); msfHeader.AudioBlockIndicator = (uint)BitTools.MaskBits(tmp, 2, 1); msfHeader.DataBlockIndicator = (uint)BitTools.MaskBits(tmp, 3, 1); msfHeader.ExtBlockIndicator = (uint)BitTools.MaskBits(tmp, 4, 1); // 起始播放时间 if (BitTools.MaskBits(tmp, 0, 1) == 1) { _stream.Read(tmp, 0, 4); msfHeader.PlayStartTime = BitTools.MaskBits(tmp, 0, 32) * timeUint; } // 视频段信息 if (msfHeader.VideoBlockIndicator == 1) { _stream.Read(tmp, 0, 3); msfHeader.VideoBlockLenth = (uint)BitTools.MaskBits(tmp, 0, 21); msfHeader.VideoBlockNum = (uint)BitTools.MaskBits(tmp, 21, 3); } //音频段信息 if (msfHeader.AudioBlockIndicator == 1) { _stream.Read(tmp, 0, 3); msfHeader.AudioBlockLenth = (uint)BitTools.MaskBits(tmp, 0, 21); msfHeader.AudioBlockNum = (uint)BitTools.MaskBits(tmp, 21, 3); } if (msfHeader.DataBlockIndicator == 1) { _stream.Seek(3, SeekOrigin.Current); } if (msfHeader.ExtBlockIndicator == 1) { _stream.Seek(3, SeekOrigin.Current); } // 跳过视频和音频参数集 return(msfHeader); }
public void ParseServiceMultiplexConfigTable(int offset, Stream _stream) { // 开始解析复用配置表 _stream.Seek(offset, SeekOrigin.Begin); _stream.Seek(3, SeekOrigin.Current); // 读取Multiplex frame number, (6 bit) byte[] tmp = new byte[4]; _stream.Read(tmp, 0, 1); _msConfigTable = new ContinualServiceConfigTable(); _msConfigTable.mpFameNum = (uint)BitTools.MaskBits(tmp, 2, 6); _msConfigTable.mfConfigTables = new List <MUXConfigTable>(); for (int i = 0; i < _msConfigTable.mpFameNum; i++) { //读取每个MF的信息配置表,RS, LDPC, mode MUXConfigTable mftmp = new MUXConfigTable(); _stream.Read(tmp, 0, 1); mftmp.RSCodec = (uint)BitTools.MaskBits(tmp, 6, 2); _stream.Read(tmp, 0, 2); mftmp.LDPC = (uint)BitTools.MaskBits(tmp, 2, 2); mftmp.mode = (uint)BitTools.MaskBits(tmp, 4, 2); mftmp.TS_num = (uint)BitTools.MaskBits(tmp, 10, 6); _msConfigTable.mfConfigTables.Add(mftmp); for (int j = 0; j < mftmp.TS_num; j++) { // skip 时隙号 和 保留,1 byte _stream.Seek(1, SeekOrigin.Current); } //读复用子帧数 _stream.Read(tmp, 0, 1); int subnumber = BitTools.MaskBits(tmp, 4, 4); for (int m = 0; m < subnumber; m++) { // skip 子帧号,。。。3 bytes _stream.Seek(3, SeekOrigin.Current); } } // skip CRC_32 _stream.Seek(CRC_Size, SeekOrigin.Current); }
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); }