public void Test1() { Span <byte> buffer = new byte[1024]; FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); AVCDecoderConfigurationRecord aVCDecoderConfigurationRecord = new AVCDecoderConfigurationRecord(); aVCDecoderConfigurationRecord.AVCProfileIndication = 0x64; aVCDecoderConfigurationRecord.ProfileCompatibility = 0; aVCDecoderConfigurationRecord.AVCLevelIndication = 0x1F; aVCDecoderConfigurationRecord.NumOfPictureParameterSets = 1; aVCDecoderConfigurationRecord.SPSBuffer = new byte[] { 0x67, 0x64, 0x00, 0x1F, 0xAC, 0xD9, 0x40, 0x88, 0x1E, 0x68, 0x40, 0x00, 0x00, 0x03, 0x01, 0x80, 0x00, 0x00, 0x57, 0x83, 0xC6, 0x0C, 0x65, 0x80 }; aVCDecoderConfigurationRecord.PPSBuffer = new byte[] { 0x68, 0xEB, 0xE3, 0xCB, 0x22, 0xC0 }; flvMessagePackWriter.WriteAVCDecoderConfigurationRecord(aVCDecoderConfigurationRecord); var hexData = flvMessagePackWriter.FlushAndGetArray().ToHexString(); Assert.Equal("0164001FFFE100186764001FACD940881E6840000003018000005783C60C658001000668EBE3CB22C0", hexData); //0164001FFFE100186764001FACD940881E6840000003018000005783C60C658001000668EBE3CB22C0 //0164001FFFE100186764001FACD940881E6840000003018000005783C60C658001000668EBE3CB22C0 }
public static bool Read(DataStream stream, ref int width, ref int height) { AVCPacketType avcType = (AVCPacketType)stream.ReadByte(); // make sure, that this is header packet if (avcType != AVCPacketType.SequenceHeader) { return(false); } // read composition time stream.Read24Int(); AVCDecoderConfigurationRecord configuration = new AVCDecoderConfigurationRecord(stream); // do we have SPS? if ((configuration.NumOfSequenceParameterSets & 0x1F) == 0) { return(false); } // read SPS size ushort spsSize = stream.ReadUShort(); // read SPS itself byte[] spsBuffer = stream.ReadBytes(spsSize); ParseSPS(spsBuffer, out width, out height); return(true); }
public void WriteAVCDecoderConfigurationRecord(AVCDecoderConfigurationRecord configurationRecord) { WriteByte(configurationRecord.ConfigurationVersion); WriteByte(configurationRecord.AVCProfileIndication); WriteByte(configurationRecord.ProfileCompatibility); WriteByte(configurationRecord.AVCLevelIndication); //reserved(6bits)+LengthSizeMinusOne(2bits) WriteByte(0xFF); WriteByte((byte)configurationRecord.NumOfSequenceParameterSets); WriteUInt16((ushort)(configurationRecord.SPSBuffer.Length)); WriteArray(configurationRecord.SPSBuffer); WriteByte(configurationRecord.NumOfPictureParameterSets); WriteUInt16((ushort)(configurationRecord.PPSBuffer.Length)); WriteArray(configurationRecord.PPSBuffer); }
/// <summary> /// 编码首帧视频,即videoTag[0] /// <para> /// 注意:本方法已写入<see cref="previousTagSize"/> /// </para> /// </summary> /// <param name="sps"></param> /// <param name="pps"></param> /// <param name="sei"></param> /// <returns></returns> public byte[] EncoderFirstVideoTag(H264NALU sps, H264NALU pps, H264NALU sei) { byte[] buffer = FlvArrayPool.Rent(2048); try { FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); var rawData = h264Decoder.DiscardEmulationPreventionBytes(sps.RawData); ExpGolombReader h264GolombReader = new ExpGolombReader(rawData); SPSInfo spsInfo = h264GolombReader.ReadSPS(); //flv body video tag //flv body tag header FlvTags flvTags = new FlvTags { Type = TagType.Video, Timestamp = (uint)sps.Timestamp, TimestampExt = 0, StreamId = 0, //flv body tag body VideoTagsData = new VideoTags() }; flvTags.VideoTagsData.FrameType = FrameType.KeyFrame; flvTags.VideoTagsData.VideoData = new AvcVideoPacke { AvcPacketType = AvcPacketType.SequenceHeader, CompositionTime = 0 }; AVCDecoderConfigurationRecord aVCDecoderConfigurationRecord = new AVCDecoderConfigurationRecord { AVCProfileIndication = spsInfo.profileIdc, ProfileCompatibility = (byte)spsInfo.profileCompat, AVCLevelIndication = spsInfo.levelIdc, NumOfPictureParameterSets = 1, PPSBuffer = pps.RawData, SPSBuffer = sps.RawData }; flvTags.VideoTagsData.VideoData.AVCDecoderConfiguration = aVCDecoderConfigurationRecord; flvMessagePackWriter.WriteUInt32(previousTagSize); flvMessagePackWriter.WriteFlvTag(flvTags); var data = flvMessagePackWriter.FlushAndGetArray(); previousTagSize = (uint)(flvTags.DataSize + 11); return(data); } finally { FlvArrayPool.Return(buffer); } }
/// <summary> /// /// </summary> /// <param name="sps">NalUnitType->7</param> /// <param name="pps">NalUnitType->8</param> /// <returns></returns> public byte[] CreateFlvFirstFrame(H264NALU sps, H264NALU pps) { byte[] buffer = FlvArrayPool.Rent(65535); int currentMarkPosition = 0; int nextMarkPosition = 0; try { FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); //flv header flvMessagePackWriter.WriteArray(VideoFlvHeaderBuffer); //SPS -> 7 ExpGolombReader h264GolombReader = new ExpGolombReader(sps.RawData); var spsInfo = h264GolombReader.ReadSPS(); currentMarkPosition = flvMessagePackWriter.GetCurrentPosition(); //flv body script tag CreateScriptTagFrame(ref flvMessagePackWriter, spsInfo.width, spsInfo.height); nextMarkPosition = flvMessagePackWriter.GetCurrentPosition(); //flv body video tag uint scriptTagFramePreviousTagSize = (uint)(nextMarkPosition - currentMarkPosition - PreviousTagSizeFixedLength); AVCDecoderConfigurationRecord aVCDecoderConfigurationRecord = new AVCDecoderConfigurationRecord(); aVCDecoderConfigurationRecord.AVCProfileIndication = spsInfo.profileIdc; aVCDecoderConfigurationRecord.ProfileCompatibility = (byte)spsInfo.profileCompat; aVCDecoderConfigurationRecord.AVCLevelIndication = spsInfo.levelIdc; aVCDecoderConfigurationRecord.NumOfPictureParameterSets = 1; aVCDecoderConfigurationRecord.PPSBuffer = pps.RawData; aVCDecoderConfigurationRecord.SPSBuffer = sps.RawData; currentMarkPosition = flvMessagePackWriter.GetCurrentPosition(); CreateVideoTag0Frame(ref flvMessagePackWriter, scriptTagFramePreviousTagSize, aVCDecoderConfigurationRecord); nextMarkPosition = flvMessagePackWriter.GetCurrentPosition(); //flv body video tag 0 uint videoTag0PreviousTagSize = (uint)(nextMarkPosition - currentMarkPosition - PreviousTagSizeFixedLength); //cache PreviousTagSize PreviousTagSizeDict.AddOrUpdate(sps.GetKey(), videoTag0PreviousTagSize, (a, b) => videoTag0PreviousTagSize); return(flvMessagePackWriter.FlushAndGetArray()); } finally { FlvArrayPool.Return(buffer); } }
/// <summary> /// /// </summary> private void CreateFlvKeyFrame(ref FlvMessagePackWriter flvMessagePackWriter, string key, byte[] spsRawData, byte[] ppsRawData, SPSInfo spsInfo, uint previousTagSize = 0) { int currentMarkPosition = 0; int nextMarkPosition = 0; currentMarkPosition = flvMessagePackWriter.GetCurrentPosition(); //flv body script tag CreateScriptTagFrame(ref flvMessagePackWriter, spsInfo.width, spsInfo.height, previousTagSize); nextMarkPosition = flvMessagePackWriter.GetCurrentPosition(); //flv body video tag uint scriptTagFramePreviousTagSize = (uint)(nextMarkPosition - currentMarkPosition - PreviousTagSizeFixedLength); AVCDecoderConfigurationRecord aVCDecoderConfigurationRecord = new AVCDecoderConfigurationRecord(); aVCDecoderConfigurationRecord.AVCProfileIndication = spsInfo.profileIdc; aVCDecoderConfigurationRecord.ProfileCompatibility = (byte)spsInfo.profileCompat; aVCDecoderConfigurationRecord.AVCLevelIndication = spsInfo.levelIdc; aVCDecoderConfigurationRecord.NumOfPictureParameterSets = 1; aVCDecoderConfigurationRecord.PPSBuffer = ppsRawData; aVCDecoderConfigurationRecord.SPSBuffer = spsRawData; currentMarkPosition = flvMessagePackWriter.GetCurrentPosition(); CreateVideoTag0Frame(ref flvMessagePackWriter, scriptTagFramePreviousTagSize, aVCDecoderConfigurationRecord); nextMarkPosition = flvMessagePackWriter.GetCurrentPosition(); //flv body video tag 0 uint videoTag0PreviousTagSize = (uint)(nextMarkPosition - currentMarkPosition - PreviousTagSizeFixedLength); //cache PreviousTagSize FlvFrameInfoDict.AddOrUpdate(key, new FlvFrameInfo { PreviousTagSize = videoTag0PreviousTagSize }, (a, b) => { b.PreviousTagSize = videoTag0PreviousTagSize; return(b); }); }
private void CreateVideoTag0Frame(ref FlvMessagePackWriter flvMessagePackWriter, uint previousTagSize, AVCDecoderConfigurationRecord aVCDecoderConfigurationRecord) { //flv body PreviousTagSize ScriptTag flvMessagePackWriter.WriteUInt32(previousTagSize); //flv body video tag //flv body tag header FlvTags flvTags = new FlvTags(); flvTags.Type = TagType.Video; flvTags.Timestamp = 0; flvTags.TimestampExt = 0; flvTags.StreamId = 0; //flv body tag body flvTags.VideoTagsData = new VideoTags(); flvTags.VideoTagsData.FrameType = FrameType.KeyFrame; flvTags.VideoTagsData.VideoData = new AvcVideoPacke(); flvTags.VideoTagsData.VideoData.AvcPacketType = AvcPacketType.SequenceHeader; flvTags.VideoTagsData.VideoData.CompositionTime = 0; flvTags.VideoTagsData.VideoData.AVCDecoderConfiguration = aVCDecoderConfigurationRecord; flvMessagePackWriter.WriteFlvTag(flvTags); }