Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }