public void Setup() { var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "JT1078_1.txt")); foreach (var line in lines) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); Package = JT1078Serializer.Merge(package); } H264NALUs = h264Decoder.ParseNALU(Package); SPSNALu = H264NALUs.FirstOrDefault(f => f.NALUHeader.NalUnitType == 7); SPSNALu.RawData = h264Decoder.DiscardEmulationPreventionBytes(SPSNALu.RawData); }
/// <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); } }
public void Setup() { var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "JT1078_1.txt")); foreach (var line in lines) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); Package = JT1078Serializer.Merge(package); } H264NALUs = h264Decoder.ParseNALU(Package); SPSNALu = H264NALUs.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS); SPSNALu.RawData = h264Decoder.DiscardEmulationPreventionBytes(SPSNALu.RawData); List <JT1078Package> packages = new List <JT1078Package>(); var lines3 = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_3.txt")); int mergeBodyLength = 0; foreach (var line in lines3) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); mergeBodyLength += package.DataBodyLength; var packageMerge = JT1078Serializer.Merge(package); if (packageMerge != null) { packages.Add(packageMerge); } } List <H264NALU> nalus = new List <H264NALU>(); bool segmentFlag = false; foreach (var package in packages) { if (segmentFlag) { break; } List <H264NALU> h264NALUs = h264Decoder.ParseNALU(package); foreach (var nalu in h264NALUs) { if (nalu.Slice) { //H264 NALU slice first_mb_in_slice nalus.Add(nalu); } else { if (nalus.Count > 0) { FMp4H264NALUs = new List <H264NALU>(nalus); segmentFlag = true; nalus.Clear(); } nalus.Add(nalu); } } } }
private void CreateVideoTagOtherFrame(ref FlvMessagePackWriter flvMessagePackWriter, uint previousTagSize, H264NALU nALU) { //flv body PreviousTagSize flvMessagePackWriter.WriteUInt32(previousTagSize); //flv body video tag //flv body tag header FlvTags flvTags = new FlvTags(); flvTags.Type = TagType.Video; flvTags.Timestamp = nALU.LastIFrameInterval; flvTags.TimestampExt = 0; flvTags.StreamId = 0; //flv body tag body flvTags.VideoTagsData = new VideoTags(); if (nALU.NALUHeader.NalUnitType == 5) { flvTags.VideoTagsData.FrameType = FrameType.KeyFrame; } else { flvTags.VideoTagsData.FrameType = FrameType.InterFrame; } flvTags.VideoTagsData.VideoData = new AvcVideoPacke(); flvTags.VideoTagsData.VideoData.AvcPacketType = AvcPacketType.Raw; flvTags.VideoTagsData.VideoData.CompositionTime = nALU.LastIFrameInterval; flvTags.VideoTagsData.VideoData.Data = nALU.RawData; flvMessagePackWriter.WriteFlvTag(flvTags); }
public byte[] CreateFlvFrame(List <H264NALU> nALUs, int minimumLength = 65535) { byte[] buffer = FlvArrayPool.Rent(minimumLength); try { FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); int currentMarkPosition = 0; int nextMarkPosition = 0; H264NALU sps = null, pps = null; SPSInfo spsInfo = new SPSInfo(); foreach (var naln in nALUs) { string key = naln.GetKey(); if (sps != null && pps != null) { if (VideoSPSDict.TryGetValue(key, out var spsInfoCache)) { if (spsInfoCache.height != spsInfo.height && spsInfoCache.width != spsInfo.width) { if (FlvFrameInfoDict.TryGetValue(key, out FlvFrameInfo flvFrameInfo)) { CreateFlvKeyFrame(ref flvMessagePackWriter, key, sps.RawData, pps.RawData, spsInfo, flvFrameInfo.PreviousTagSize); FlvFirstFrameCache.TryRemove(key, out _); FlvFirstFrameCache.TryAdd(key, flvMessagePackWriter.FlushAndGetArray()); VideoSPSDict.TryUpdate(key, spsInfo, spsInfo); flvFrameInfo.LastFrameInterval = 0; FlvFrameInfoDict.TryUpdate(key, flvFrameInfo, flvFrameInfo); } } sps = null; pps = null; } else { CreateFlvKeyFrame(ref flvMessagePackWriter, key, sps.RawData, pps.RawData, spsInfo, 0); FlvFirstFrameCache.TryAdd(key, flvMessagePackWriter.FlushAndGetArray()); VideoSPSDict.TryAdd(key, spsInfo); sps = null; pps = null; } } //7 8 6 5 1 1 1 1 7 8 6 5 1 1 1 1 1 7 8 6 5 1 1 1 1 1 switch (naln.NALUHeader.NalUnitType) { case 5: // IDR case 1: // I/P/B if (FlvFrameInfoDict.TryGetValue(key, out FlvFrameInfo flvFrameInfo)) { currentMarkPosition = flvMessagePackWriter.GetCurrentPosition(); CreateVideoTagOtherFrame(ref flvMessagePackWriter, flvFrameInfo, naln); nextMarkPosition = flvMessagePackWriter.GetCurrentPosition(); uint tmpPreviousTagSize = (uint)(nextMarkPosition - currentMarkPosition - PreviousTagSizeFixedLength); flvFrameInfo.PreviousTagSize = tmpPreviousTagSize; flvFrameInfo.LastFrameInterval += naln.LastFrameInterval; FlvFrameInfoDict.TryUpdate(key, flvFrameInfo, flvFrameInfo); } break; case 7: // sps sps = naln; var rawData = H264Decoder.DiscardEmulationPreventionBytes(naln.RawData); ExpGolombReader h264GolombReader = new ExpGolombReader(rawData); spsInfo = h264GolombReader.ReadSPS(); break; case 8: // pps pps = naln; break; case 6: //SEI break; default: break; } } return(flvMessagePackWriter.FlushAndGetArray()); } finally { FlvArrayPool.Return(buffer); } }