Ejemplo n.º 1
0
        private MediaStreamSample GetAudioSample()
        {
            if (aIdx > (aNum - 1))
            {
                // next second
                abuffer = null;
                aNum    = 0;
                aIdx    = 0;
            }

            if (abuffer == null)
            {
                int i = -1; //第几秒数据?
                abuffer = m_demux2.GetCurrentBuffer(curChannelIdx, MediaStreamType.Audio, out i);
                if (abuffer != null)
                {
                    if (i == 1) //第一秒数据
                    {
                        // 因为播放器的timestamp必须从0 开始
                        atimestamp_base = abuffer.msfHeader.PlayStartTime;
                    }
                    aNum = (int)abuffer.audioBlock.AudioFrameNum;
                    atimestamp_offset = abuffer.msfHeader.PlayStartTime - atimestamp_base;
                }
                else
                {
                    MediaStreamSample sample = new MediaStreamSample(this.audioStreamDescription, null, 0, 0, 0, emptyDict);
                    return(sample);
                }
            }

            MemoryStream stream = new MemoryStream();//abuffer.audioBlock.aFrames[aIdx]._as as MemoryStream;
            //LATM 封装,第一个字节是length, 跳过第一个字节, 相应的长度应该减1
            int len = (int)abuffer.audioBlock.aFrames[aIdx].Length - 1;

            stream.Write(abuffer.audioBlock.aFrames[aIdx]._data, 1, len);

            long timestamp = atimestamp_offset + abuffer.audioBlock.aFrames[aIdx].RelativeTime;  // 以100 纳秒为单位

            MediaStreamSample mediaStreamSample = new MediaStreamSample
                                                  (
                this.audioStreamDescription,
                stream,
                0,
                len,
                timestamp,
                emptyDict
                                                  );

            aIdx++;

            return(mediaStreamSample);
        }
Ejemplo n.º 2
0
        private void AdjustTimeStampOf1stSecond(MSF msf)
        {
            int ifIdx = msf.videoBlock.FirstIFrameIdx;

            if (ifIdx == 0)
            {
                return;
            }

            msf.videoBlock.FirstIFrameIdx = 0;
            long ts_base = msf.videoBlock.vFrames[ifIdx].RelativeTime;

            // Remove other non-I frame
            for (int i = 0; i < ifIdx; i++)
            {
                msf.videoBlock.vFrames.RemoveAt(0);
            }
            msf.videoBlock.VideoFrameNum = msf.videoBlock.VideoFrameNum - (uint)ifIdx;

            foreach (var v in msf.videoBlock.vFrames)
            {
                v.RelativeTime -= ts_base;
            }

            // 处理audio, 使其同步
            // 首先查找和Video I 帧大概同步的audio 帧
            long offset = msf.audioBlock.aFrames[1].RelativeTime - msf.audioBlock.aFrames[0].RelativeTime;

            long ts_base_audio = 0;
            int  idx_audio     = 0;

            for (int m = 0; m < msf.audioBlock.AudioFrameNum; m++)
            {
                if (Math.Abs(msf.audioBlock.aFrames[m].RelativeTime - ts_base) < offset)
                {
                    ts_base_audio = msf.audioBlock.aFrames[m].RelativeTime;
                    idx_audio     = m;
                    break;
                }
            }

            // remove other frames;
            for (int i = 0; i < idx_audio; i++)
            {
                msf.audioBlock.aFrames.RemoveAt(0);
            }
            msf.audioBlock.AudioFrameNum -= (uint)idx_audio;

            foreach (var v in msf.audioBlock.aFrames)
            {
                v.RelativeTime -= ts_base_audio;
            }
        }
Ejemplo n.º 3
0
 private void AdjustTimeStampBase(MSF msf, int idx)
 {
     if (idx > 0)
     {
         msf.msfHeader.PlayStartTime = msf.msfHeader.PlayStartTime - FistTSBase;
         foreach (var v in msf.audioBlock.aFrames)
         {
             v.RelativeTime += msf.msfHeader.PlayStartTime;
         }
         foreach (var v in msf.videoBlock.vFrames)
         {
             v.RelativeTime += msf.msfHeader.PlayStartTime;
         }
     }
     else if (idx == 0)
     {
         long offset = msf.videoBlock.vFrames[1].RelativeTime - msf.videoBlock.vFrames[0].RelativeTime;
         FistTSBase += msf.videoBlock.vFrames[(int)msf.videoBlock.VideoFrameNum - 1].RelativeTime + offset;
         FistTSBase += msf.msfHeader.PlayStartTime;
         msf.msfHeader.PlayStartTime = 0;
     }
 }
Ejemplo n.º 4
0
        private void AdjustTimeStampOf1stSecond(MSF msf)
        {
            int ifIdx = msf.videoBlock.FirstIFrameIdx;
            if (ifIdx == 0)
                return;

            msf.videoBlock.FirstIFrameIdx = 0;
            long ts_base = msf.videoBlock.vFrames[ifIdx].RelativeTime;

            // Remove other non-I frame
            for (int i = 0; i < ifIdx; i++)
            {
                msf.videoBlock.vFrames.RemoveAt(0);
            }
            msf.videoBlock.VideoFrameNum = msf.videoBlock.VideoFrameNum - (uint)ifIdx;

            foreach (var v in msf.videoBlock.vFrames)
            {
                v.RelativeTime -= ts_base;
            }

            // 处理audio, 使其同步
            // 首先查找和Video I 帧大概同步的audio 帧
            long offset = msf.audioBlock.aFrames[1].RelativeTime - msf.audioBlock.aFrames[0].RelativeTime;

            long ts_base_audio = 0;
            int idx_audio = 0;

            for (int m = 0; m < msf.audioBlock.AudioFrameNum; m++)
            {
                if (Math.Abs(msf.audioBlock.aFrames[m].RelativeTime - ts_base) < offset)
                {
                    ts_base_audio = msf.audioBlock.aFrames[m].RelativeTime;
                    idx_audio = m;
                    break;
                }
            }

            // remove other frames;
            for (int i = 0; i < idx_audio; i++)
            {
                msf.audioBlock.aFrames.RemoveAt(0);
            }
            msf.audioBlock.AudioFrameNum -= (uint)idx_audio;

            foreach (var v in msf.audioBlock.aFrames)
            {
                v.RelativeTime -= ts_base_audio;
            }
        }
Ejemplo n.º 5
0
        private void AdjustTimeStampBase(MSF msf, int idx)
        {
            if (idx > 0)
            {
                msf.msfHeader.PlayStartTime = msf.msfHeader.PlayStartTime - FistTSBase;
                foreach (var v in msf.audioBlock.aFrames)
                {
                    v.RelativeTime += msf.msfHeader.PlayStartTime;
                }
                foreach (var v in msf.videoBlock.vFrames)
                {
                    v.RelativeTime += msf.msfHeader.PlayStartTime;
                }
            }
            else if (idx == 0)
            {

                long offset = msf.videoBlock.vFrames[1].RelativeTime - msf.videoBlock.vFrames[0].RelativeTime;
                FistTSBase += msf.videoBlock.vFrames[(int)msf.videoBlock.VideoFrameNum - 1].RelativeTime + offset;
                FistTSBase += msf.msfHeader.PlayStartTime;
                msf.msfHeader.PlayStartTime = 0;
            }
        }
Ejemplo n.º 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;
        }
Ejemplo n.º 7
0
        private MediaStreamSample GetVideoSample()
        {
            if (vIdx == -1)
            {
                // the first frame requested,the first frame must be I frame,
                int i;
                if (msfVideoBuffer == null)
                {
                    msfVideoBuffer = this.m_demux2.GetCurrentBuffer(curChannelIdx, MediaStreamType.Video, out i);
                }

                vIdx = msfVideoBuffer.videoBlock.FirstIFrameIdx;
                fNum = (int)msfVideoBuffer.videoBlock.VideoFrameNum;

                // 因为播放器的timestamp必须从0 开始
                timestamp_base   = msfVideoBuffer.msfHeader.PlayStartTime + msfVideoBuffer.videoBlock.vFrames[vIdx].RelativeTime;
                timestamp_offset = msfVideoBuffer.msfHeader.PlayStartTime - timestamp_base;
            }
            else if (vIdx > (fNum - 1))
            {
                // next second
                msfVideoBuffer = null;
                fNum           = 0;
                vIdx           = 0;
            }

            if (msfVideoBuffer == null)
            {
                int i = -1; //第几秒数据?
                msfVideoBuffer = m_demux2.GetCurrentBuffer(curChannelIdx, MediaStreamType.Video, out i);
                if (msfVideoBuffer != null)
                {
                    fNum             = (int)msfVideoBuffer.videoBlock.VideoFrameNum;
                    timestamp_offset = msfVideoBuffer.msfHeader.PlayStartTime - timestamp_base;
                }
                else
                {
                    MediaStreamSample sample = new MediaStreamSample(this.videoStreamDescription, null, 0, 0, 0, emptyDict);
                    return(sample);
                }
            }

            MemoryStream vStream = new MemoryStream();//msfVideoBuffer.videoBlock.vFrames[vIdx]._vs as MemoryStream;
            int          len     = (int)msfVideoBuffer.videoBlock.vFrames[vIdx].Length;

            vStream.Write(msfVideoBuffer.videoBlock.vFrames[vIdx]._data, 0, len);
            // 以100 纳秒为单位
            long timestamp = (timestamp_offset + msfVideoBuffer.videoBlock.vFrames[vIdx].RelativeTime);
            MediaStreamSample mediaStreamSample = new MediaStreamSample
                                                  (
                this.videoStreamDescription,
                vStream,
                0,
                len,
                timestamp,
                emptyDict
                                                  );

            vIdx++;

            return(mediaStreamSample);
        }
Ejemplo n.º 8
0
        private MediaStreamSample GetVideoSample()
        {
            if (vIdx == -1)
            {
                // the first frame requested,the first frame must be I frame,
                int i;
                if (msfVideoBuffer == null)
                    msfVideoBuffer = this.m_demux2.GetCurrentBuffer(curChannelIdx, MediaStreamType.Video, out i);

                vIdx = msfVideoBuffer.videoBlock.FirstIFrameIdx;
                fNum = (int)msfVideoBuffer.videoBlock.VideoFrameNum;

                // 因为播放器的timestamp必须从0 开始
                timestamp_base = msfVideoBuffer.msfHeader.PlayStartTime + msfVideoBuffer.videoBlock.vFrames[vIdx].RelativeTime;
                timestamp_offset = msfVideoBuffer.msfHeader.PlayStartTime - timestamp_base;
            }
            else if (vIdx > (fNum - 1))
            {
                // next second
                msfVideoBuffer = null;
                fNum = 0;
                vIdx = 0;
            }

            if (msfVideoBuffer == null)
            {
                int i = -1; //第几秒数据?
                msfVideoBuffer = m_demux2.GetCurrentBuffer(curChannelIdx, MediaStreamType.Video, out i);
                if (msfVideoBuffer != null)
                {
                    fNum = (int)msfVideoBuffer.videoBlock.VideoFrameNum;
                    timestamp_offset = msfVideoBuffer.msfHeader.PlayStartTime - timestamp_base;
                }
                else
                {
                    MediaStreamSample sample = new MediaStreamSample(this.videoStreamDescription, null, 0, 0, 0, emptyDict);
                    return sample;
                }
            }

            MemoryStream vStream = new MemoryStream();//msfVideoBuffer.videoBlock.vFrames[vIdx]._vs as MemoryStream;
            int len = (int)msfVideoBuffer.videoBlock.vFrames[vIdx].Length;
            vStream.Write(msfVideoBuffer.videoBlock.vFrames[vIdx]._data, 0, len);
            // 以100 纳秒为单位
            long timestamp = (timestamp_offset + msfVideoBuffer.videoBlock.vFrames[vIdx].RelativeTime);
            MediaStreamSample mediaStreamSample = new MediaStreamSample
                (
                this.videoStreamDescription,
                vStream,
                0,
                len,
                timestamp,
                emptyDict
                );
            vIdx++;

            return mediaStreamSample;
        }
Ejemplo n.º 9
0
        private MediaStreamSample GetAudioSample()
        {
            if (aIdx > (aNum - 1))
            {
                // next second
                abuffer = null;
                aNum = 0;
                aIdx = 0;
            }

            if (abuffer == null)
            {
                int i = -1; //第几秒数据?
                abuffer = m_demux2.GetCurrentBuffer(curChannelIdx, MediaStreamType.Audio, out i);
                if (abuffer != null)
                {
                    if (i == 1) //第一秒数据
                    {
                        // 因为播放器的timestamp必须从0 开始
                        atimestamp_base = abuffer.msfHeader.PlayStartTime;
                    }
                    aNum = (int)abuffer.audioBlock.AudioFrameNum;
                    atimestamp_offset = abuffer.msfHeader.PlayStartTime - atimestamp_base;
                }
                else
                {
                    MediaStreamSample sample = new MediaStreamSample(this.audioStreamDescription, null, 0, 0, 0, emptyDict);
                    return sample;
                }
            }

            MemoryStream stream = new MemoryStream();//abuffer.audioBlock.aFrames[aIdx]._as as MemoryStream;
            //LATM 封装,第一个字节是length, 跳过第一个字节, 相应的长度应该减1
            int len = (int)abuffer.audioBlock.aFrames[aIdx].Length - 1;
            stream.Write(abuffer.audioBlock.aFrames[aIdx]._data, 1, len);

            long timestamp = atimestamp_offset + abuffer.audioBlock.aFrames[aIdx].RelativeTime;  // 以100 纳秒为单位

            MediaStreamSample mediaStreamSample = new MediaStreamSample
                (
                this.audioStreamDescription,
                stream,
                0,
                len,
                timestamp,
                emptyDict
                );
            aIdx++;

            return mediaStreamSample;
        }