From a5976d95e5777bae5293aaf48d767a4901580469 Mon Sep 17 00:00:00 2001 From: "SmallChi(Koike)" <564952747@qq.com> Date: Mon, 29 Mar 2021 18:34:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=861078=E8=BD=ACfmp4=5F10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/JT1078.FMp4.Test/FMp4Box_Test.cs | 2 +- src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs | 11 +- src/JT1078.FMp4/Boxs/SampleDescriptionBox.cs | 8 +- src/JT1078.FMp4/Boxs/SampleTableBox.cs | 9 +- src/JT1078.FMp4/Boxs/SegmentIndexBox.cs | 103 +++++++++++--- src/JT1078.FMp4/Boxs/SyncSampleBox.cs | 37 ++++- src/JT1078.FMp4/Boxs/TrackRunBox.cs | 15 +- src/JT1078.FMp4/FMp4Encoder.cs | 138 ++++++++----------- src/JT1078.FMp4/JT1078.FMp4.xml | 85 +++++++++++- 9 files changed, 292 insertions(+), 116 deletions(-) diff --git a/src/JT1078.FMp4.Test/FMp4Box_Test.cs b/src/JT1078.FMp4.Test/FMp4Box_Test.cs index 1655bd6..1844585 100644 --- a/src/JT1078.FMp4.Test/FMp4Box_Test.cs +++ b/src/JT1078.FMp4.Test/FMp4Box_Test.cs @@ -172,7 +172,7 @@ namespace JT1078.FMp4.Test //stbl SampleTableBox sampleTableBox = new SampleTableBox(); //stbl->stsd - SampleDescriptionBox sampleDescriptionBox = new SampleDescriptionBox(HandlerType.none); + SampleDescriptionBox sampleDescriptionBox = new SampleDescriptionBox(); //stbl->stsd->avc1 AVC1SampleEntry aVC1SampleEntry = new AVC1SampleEntry(); aVC1SampleEntry.Width = 0x0220; diff --git a/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs b/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs index fcf2ca6..b88ba25 100644 --- a/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs +++ b/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs @@ -71,7 +71,7 @@ namespace JT1078.FMp4.Test movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List<DataEntryBox>(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1)); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox(); - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List<SampleEntry>(); AVC1SampleEntry avc1 = new AVC1SampleEntry(); avc1.AVCConfigurationBox = new AVCConfigurationBox(); @@ -224,7 +224,7 @@ namespace JT1078.FMp4.Test movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List<DataEntryBox>(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1)); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox(); - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List<SampleEntry>(); AVC1SampleEntry avc1 = new AVC1SampleEntry(); avc1.AVCConfigurationBox = new AVCConfigurationBox(); @@ -373,7 +373,7 @@ namespace JT1078.FMp4.Test movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List<DataEntryBox>(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1)); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox(); - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List<SampleEntry>(); AVC1SampleEntry avc1 = new AVC1SampleEntry(); avc1.AVCConfigurationBox = new AVCConfigurationBox(); @@ -453,12 +453,17 @@ namespace JT1078.FMp4.Test fileStream.Write(moov); foreach (var package in packages) { + var otherStypBuffer = fMp4Encoder.EncoderStypBox(); + fileStream.Write(otherStypBuffer); + var otherSidxBuffer = fMp4Encoder.EncoderSidxBox(package.Timestamp, package.LastIFrameInterval); + fileStream.Write(otherSidxBuffer); var otherNalus = h264Decoder.ParseNALU(package); var flag = package.Label3.DataType == Protocol.Enums.JT1078DataType.视频I帧 ? 1u : 0u; var otherMoofBuffer = fMp4Encoder.EncoderMoofBox(otherNalus, package.Bodies.Length, package.Timestamp, package.LastIFrameInterval, flag); var otherMdatBuffer = fMp4Encoder.EncoderMdatBox(otherNalus, package.Bodies.Length); fileStream.Write(otherMoofBuffer); fileStream.Write(otherMdatBuffer); + } fileStream.Close(); } diff --git a/src/JT1078.FMp4/Boxs/SampleDescriptionBox.cs b/src/JT1078.FMp4/Boxs/SampleDescriptionBox.cs index de595aa..9cd37cc 100644 --- a/src/JT1078.FMp4/Boxs/SampleDescriptionBox.cs +++ b/src/JT1078.FMp4/Boxs/SampleDescriptionBox.cs @@ -16,15 +16,13 @@ namespace JT1078.FMp4 /// <summary> /// stsd /// </summary> - /// <param name="handlerType"></param> /// <param name="version"></param> /// <param name="flags"></param> - public SampleDescriptionBox(HandlerType handlerType,byte version=0, uint flags=0) : base("stsd", version, flags) + public SampleDescriptionBox(byte version=0, uint flags=0) : base("stsd", version, flags) { - HandlerType = handlerType; + } - public HandlerType HandlerType { get; set; } - public uint EntryCount { get; set; } + private uint EntryCount { get; set; } public List<SampleEntry> SampleEntries { get; set; } public void ToBuffer(ref FMp4MessagePackWriter writer) { diff --git a/src/JT1078.FMp4/Boxs/SampleTableBox.cs b/src/JT1078.FMp4/Boxs/SampleTableBox.cs index a130d83..ffb5e46 100644 --- a/src/JT1078.FMp4/Boxs/SampleTableBox.cs +++ b/src/JT1078.FMp4/Boxs/SampleTableBox.cs @@ -26,6 +26,10 @@ namespace JT1078.FMp4 /// </summary> public TimeToSampleBox TimeToSampleBox { get; set; } /// <summary> + /// stss + /// </summary> + public SyncSampleBox SyncSampleBox { get; set; } + /// <summary> /// ctts /// </summary> public CompositionOffsetBox CompositionOffsetBox { get; set; } @@ -44,7 +48,6 @@ namespace JT1078.FMp4 /// </summary> public ChunkOffsetBox ChunkOffsetBox { get; set; } //public ChunkLargeOffsetBox ChunkLargeOffsetBox { get; set; } - //public SyncSampleBox SyncSampleBox { get; set; } //public ShadowSyncSampleBox ShadowSyncSampleBox { get; set; } //public PaddingBitsBox PaddingBitsBox { get; set; } //public DegradationPriorityBox DegradationPriorityBox { get; set; } @@ -58,6 +61,10 @@ namespace JT1078.FMp4 Start(ref writer); SampleDescriptionBox.ToBuffer(ref writer); TimeToSampleBox.ToBuffer(ref writer); + if (SyncSampleBox != null) + { + SyncSampleBox.ToBuffer(ref writer); + } if(CompositionOffsetBox!=null) CompositionOffsetBox.ToBuffer(ref writer); SampleToChunkBox.ToBuffer(ref writer); diff --git a/src/JT1078.FMp4/Boxs/SegmentIndexBox.cs b/src/JT1078.FMp4/Boxs/SegmentIndexBox.cs index e8c708b..04d8825 100644 --- a/src/JT1078.FMp4/Boxs/SegmentIndexBox.cs +++ b/src/JT1078.FMp4/Boxs/SegmentIndexBox.cs @@ -1,58 +1,123 @@ -using System; +using JT1078.FMp4.Interfaces; +using JT1078.FMp4.MessagePack; +using System; using System.Collections.Generic; using System.Text; namespace JT1078.FMp4 { - public class SegmentIndexBox : FullBox + /// <summary> + /// sidx + /// </summary> + public class SegmentIndexBox : FullBox,IFMp4MessagePackFormatter { + /// <summary> + /// sidx + /// </summary> + /// <param name="version"></param> + /// <param name="flags"></param> public SegmentIndexBox(byte version, uint flags=0) : base("sidx", version, flags) { } - - public uint ReferenceID { get; set; } - public string Timescale { get; set; } /// <summary> /// /// </summary> - public ulong EarliestPresentationTimeLarge { get; set; } - public ulong FirstOffsetLarge { get; set; } + public uint ReferenceID { get; set; } = 1; + /// <summary> + /// + /// </summary> + public uint Timescale { get; set; } = 1000; /// <summary> - /// if(version==0) + /// if(version==0) + /// version==0 32 bit + /// version>0 64 bit /// </summary> - public uint EarliestPresentationTime { get; set; } + public ulong EarliestPresentationTime { get; set; } /// <summary> - /// if (version==0) + /// + /// </summary> + public ulong FirstOffset { get; set; } = 0; + private ushort Reserved { get; set; } + //private ushort ReferenceCount { get; set; } + /// <summary> + /// /// </summary> - public uint FirstOffset { get; set; } - public ushort Reserved { get; set; } - public ushort ReferenceCount { get; set; } - public List<SegmentIndex> SegmentIndexs { get; set; } + public void ToBuffer(ref FMp4MessagePackWriter writer) + { + Start(ref writer); + WriterFullBoxToBuffer(ref writer); + writer.WriteUInt32(ReferenceID); + writer.WriteUInt32(Timescale); + if (Version == 0) + { + writer.WriteUInt32((uint)EarliestPresentationTime); + writer.WriteUInt32((uint)FirstOffset); + } + else + { + writer.WriteUInt64(EarliestPresentationTime); + writer.WriteUInt64(FirstOffset); + } + writer.WriteUInt16(Reserved); + if(SegmentIndexs!=null && SegmentIndexs.Count > 0) + { + writer.WriteUInt16((ushort)SegmentIndexs.Count); + foreach(var si in SegmentIndexs) + { + if (si.ReferenceType) + { + writer.WriteUInt32(si.ReferencedSize | 0x80000000); + } + else + { + writer.WriteUInt32(si.ReferencedSize); + } + writer.WriteUInt32(si.SubsegmentDuration); + if (si.StartsWithSAP) + { + writer.WriteUInt32((si.SAPDeltaTime | 0x80000000 | (uint)(si.SAPType << 28 & 0x70000000))); + } + else + { + writer.WriteUInt32((si.SAPDeltaTime | (uint)((si.SAPType <<28) & 0x70000000))); + } + } + } + else + { + writer.WriteUInt16(0); + } + End(ref writer); + } + public class SegmentIndex { /// <summary> /// 4byte 32 - 1 /// </summary> - public bool ReferenceType { get; set; } + public bool ReferenceType { get; set; } = false; /// <summary> /// 4byte 32 - 31 /// </summary> - public uint ReferencedSize { get; set; } + public uint ReferencedSize { get; set; } = 0; + /// <summary> + /// + /// </summary> public uint SubsegmentDuration { get; set; } /// <summary> /// 4byte 32 - 1 /// </summary> - public bool StartsWithSAP { get; set; } + public bool StartsWithSAP { get; set; } = true; /// <summary> /// 4byte 32 - 3 /// </summary> - public byte SAPType { get; set; } + public byte SAPType { get; set; } = 1; /// <summary> /// 4byte 32 - 28 /// </summary> - public uint SAPDeltaTime { get; set; } + public uint SAPDeltaTime { get; set; } = 0; } } } diff --git a/src/JT1078.FMp4/Boxs/SyncSampleBox.cs b/src/JT1078.FMp4/Boxs/SyncSampleBox.cs index ca13df9..0f92c4c 100644 --- a/src/JT1078.FMp4/Boxs/SyncSampleBox.cs +++ b/src/JT1078.FMp4/Boxs/SyncSampleBox.cs @@ -1,17 +1,46 @@ -using System; +using JT1078.FMp4.Interfaces; +using JT1078.FMp4.MessagePack; +using System; using System.Collections.Generic; using System.Text; namespace JT1078.FMp4 { - public class SyncSampleBox : FullBox + /// <summary> + /// stss + /// </summary> + public class SyncSampleBox : FullBox, IFMp4MessagePackFormatter { + /// <summary> + /// stss + /// </summary> + /// <param name="version"></param> + /// <param name="flags"></param> public SyncSampleBox(byte version=0, uint flags=0) : base("stss", version, flags) { } - public uint EntryCount { get; set; } + //private uint EntryCount { get; set; } - public List<uint> SampleNumber { get; set; } + public List<uint> SampleNumbers { get; set; } + + public void ToBuffer(ref FMp4MessagePackWriter writer) + { + Start(ref writer); + WriterFullBoxToBuffer(ref writer); + if(SampleNumbers!=null && SampleNumbers.Count > 0) + { + writer.WriteUInt32((uint)SampleNumbers.Count); + foreach(var item in SampleNumbers) + { + writer.WriteUInt32(item); + } + } + else + { + writer.WriteUInt32(0); + } + End(ref writer); + } } } diff --git a/src/JT1078.FMp4/Boxs/TrackRunBox.cs b/src/JT1078.FMp4/Boxs/TrackRunBox.cs index d572d42..12741bf 100644 --- a/src/JT1078.FMp4/Boxs/TrackRunBox.cs +++ b/src/JT1078.FMp4/Boxs/TrackRunBox.cs @@ -13,13 +13,26 @@ namespace JT1078.FMp4 { /// <summary> /// trun + /// 201 205 1 + /// 201 0010 0000 0001 + /// 205 0010 0000 0101 + /// 1 0000 0000 0001 + /// tr_flags 是用来表示下列 sample 相关的标识符是否应用到每个字段中: + /// 0x000001-0000 0000 0001: data-offset-present,只应用 data-offset + /// 0x000004-0000 0000 0100: 只对第一个 sample 应用对应的 flags。剩余 sample flags 就不管了。 + /// 0x000100-0001 0000 0000: 这个比较重要,表示每个 sample 都有自己的 duration,否则使用默认的 + /// 0x000200-0010 0000 0000: 每个 sample 有自己的 sample_size,否则使用默认的。 + /// 0x000400-0100 0000 0000: 对每个 sample 使用自己的 flags。否则,使用默认的。 + /// 0x000800-1000 0000 0000: 每个 sample 都有自己的 cts 值 /// </summary> /// <param name="version"></param> /// <param name="flags"></param> public TrackRunBox(byte version=0, uint flags= 0x000f01) : base("trun", version, flags) { } - + /// <summary> + /// + /// </summary> public uint SampleCount { get; set; } /// <summary> /// 可选的 diff --git a/src/JT1078.FMp4/FMp4Encoder.cs b/src/JT1078.FMp4/FMp4Encoder.cs index ffe69b1..31274b5 100644 --- a/src/JT1078.FMp4/FMp4Encoder.cs +++ b/src/JT1078.FMp4/FMp4Encoder.cs @@ -18,9 +18,11 @@ namespace JT1078.FMp4 /// stream data /// ftyp /// moov + /// styp 1 /// moof 1 /// mdat 1 /// ... + /// styp n /// moof n /// mdat n /// mfra @@ -37,6 +39,10 @@ namespace JT1078.FMp4 h264Decoder = new H264Decoder(); } + /// <summary> + /// styp + /// </summary> + /// <returns></returns> public byte[] EncoderStypBox() { byte[] buffer = FMp4ArrayPool.Rent(4096); @@ -50,7 +56,7 @@ namespace JT1078.FMp4 stypTypeBox.CompatibleBrands.Add("isom"); stypTypeBox.CompatibleBrands.Add("mp42"); stypTypeBox.CompatibleBrands.Add("msdh"); - stypTypeBox.CompatibleBrands.Add("nsix"); + stypTypeBox.CompatibleBrands.Add("msix"); stypTypeBox.CompatibleBrands.Add("iso5"); stypTypeBox.CompatibleBrands.Add("iso6"); stypTypeBox.ToBuffer(ref writer); @@ -74,23 +80,23 @@ namespace JT1078.FMp4 try { //ftyp - FileTypeBox fileTypeBox = new FileTypeBox(); - fileTypeBox.MajorBrand = "isom"; - fileTypeBox.MinorVersion = "\0\0\u0002\0"; - fileTypeBox.CompatibleBrands.Add("isom"); - fileTypeBox.CompatibleBrands.Add("iso2"); - fileTypeBox.CompatibleBrands.Add("avc1"); - fileTypeBox.CompatibleBrands.Add("mp41"); - fileTypeBox.CompatibleBrands.Add("iso5"); - //FileTypeBox fileTypeBox = new FileTypeBox(); - //fileTypeBox.MajorBrand = "iso5"; + //fileTypeBox.MajorBrand = "isom"; //fileTypeBox.MinorVersion = "\0\0\u0002\0"; - //fileTypeBox.CompatibleBrands.Add("iso5"); - //fileTypeBox.CompatibleBrands.Add("iso6"); + //fileTypeBox.CompatibleBrands.Add("isom"); + //fileTypeBox.CompatibleBrands.Add("iso2"); + //fileTypeBox.CompatibleBrands.Add("avc1"); //fileTypeBox.CompatibleBrands.Add("mp41"); - //fileTypeBox.ToBuffer(ref writer); - + //fileTypeBox.CompatibleBrands.Add("iso5"); + FileTypeBox fileTypeBox = new FileTypeBox(); + fileTypeBox.MajorBrand = "msdh"; + fileTypeBox.MinorVersion = "\0\0\0\0"; + fileTypeBox.CompatibleBrands.Add("isom"); + fileTypeBox.CompatibleBrands.Add("mp42"); + fileTypeBox.CompatibleBrands.Add("msdh"); + fileTypeBox.CompatibleBrands.Add("msix"); + fileTypeBox.CompatibleBrands.Add("iso5"); + fileTypeBox.CompatibleBrands.Add("iso6"); fileTypeBox.ToBuffer(ref writer); var data = writer.FlushAndGetArray(); return data; @@ -101,6 +107,36 @@ namespace JT1078.FMp4 } } + /// <summary> + /// 编码sidx盒子 + /// </summary> + /// <returns></returns> + public byte[] EncoderSidxBox(ulong timestamp, uint frameInterval) + { + byte[] buffer = FMp4ArrayPool.Rent(4096); + FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer); + try + { + SegmentIndexBox segmentIndexBox = new SegmentIndexBox(1); + segmentIndexBox.ReferenceID = 1; + segmentIndexBox.EarliestPresentationTime = timestamp; + segmentIndexBox.SegmentIndexs = new List<SegmentIndexBox.SegmentIndex>() + { + new SegmentIndexBox.SegmentIndex + { + SubsegmentDuration=frameInterval + } + }; + segmentIndexBox.ToBuffer(ref writer); + var data = writer.FlushAndGetArray(); + return data; + } + finally + { + FMp4ArrayPool.Return(buffer); + } + } + /// <summary> /// 编码moov盒子 /// </summary> @@ -151,7 +187,7 @@ namespace JT1078.FMp4 movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List<DataEntryBox>(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1)); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox(); - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List<SampleEntry>(); AVC1SampleEntry avc1 = new AVC1SampleEntry(); avc1.AVCConfigurationBox = new AVCConfigurationBox(); @@ -164,37 +200,11 @@ namespace JT1078.FMp4 avc1.AVCConfigurationBox.PPSs = new List<byte[]>() { ppsNALU.RawData }; avc1.AVCConfigurationBox.SPSs = new List<byte[]>() { spsNALU.RawData }; movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1); - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox = new TimeToSampleBox() { - //TimeToSampleInfos=new List<TimeToSampleBox.TimeToSampleInfo> - //{ - // new TimeToSampleBox.TimeToSampleInfo - // { - // SampleCount=0, - // SampleDelta=0 - // } - //} - }; - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleToChunkBox = new SampleToChunkBox() { - //SampleToChunkInfos=new List<SampleToChunkBox.SampleToChunkInfo>() - //{ - // new SampleToChunkBox.SampleToChunkInfo - // { - - // } - //} - }; - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox() { - //EntrySize = new List<uint>() - //{ - // 0 - //} - }; - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox() { - //ChunkOffset=new List<uint>() - //{ - // 0 - //} - }; + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox = new TimeToSampleBox(); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SyncSampleBox = new SyncSampleBox(); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleToChunkBox = new SampleToChunkBox(); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox(); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox(); movieBox.MovieExtendsBox = new MovieExtendsBox(); movieBox.MovieExtendsBox.TrackExtendsBoxs = new List<TrackExtendsBox>(); TrackExtendsBox trex = new TrackExtendsBox(); @@ -214,7 +224,6 @@ namespace JT1078.FMp4 } } - /// <summary> /// 编码Moof盒子 /// </summary> @@ -237,49 +246,27 @@ namespace JT1078.FMp4 movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)naluLength; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000; movieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox(); - //movieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox = new SampleDependencyTypeBox() - //{ - // SampleDependencyTypes = new List<SampleDependencyTypeBox.SampleDependencyType>() - //}; //trun //0x39 写文件 //0x02 分段 //uint flag = 0x000200 | 0x000800 | 0x000400 | 0x000100; uint flag = 4u; - - //var sdtp = new SampleDependencyTypeBox.SampleDependencyType(); - //if (keyframeFlag==1) - //{ - // sdtp.SampleDependsOn = 2; - // sdtp.SampleIsDependedOn = 1; - //} - //else - //{ - // sdtp.SampleDependsOn = 1; - // sdtp.SampleIsDependedOn = 0; - //} - if (!first) { //sdtp.IsLeading = 1; //flag = 4u; movieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = 0; - movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 0x205); + movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 5); first = true; } else { //flag = 0x000400; - movieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = BaseMediaDecodeTime; - movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 0x205); - BaseMediaDecodeTime += BaseMediaDecodeTime; + movieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = timestamp*1000; + movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 5); } - //movieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes.Add(sdtp); - movieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 33554432; movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List<TrackRunBox.TrackRunInfo>(); - - //movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo()); movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo() { SampleDuration= frameInterval, @@ -287,7 +274,6 @@ namespace JT1078.FMp4 SampleCompositionTimeOffset = frameInterval, SampleFlags = flag }); - movieFragmentBox.ToBuffer(ref writer); var data = writer.FlushAndGetArray(); return data; @@ -381,7 +367,7 @@ namespace JT1078.FMp4 movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List<DataEntryBox>(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1)); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox(); - movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType); + movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List<SampleEntry>(); AVC1SampleEntry avc1 = new AVC1SampleEntry(); avc1.AVCConfigurationBox = new AVCConfigurationBox(); @@ -422,8 +408,6 @@ namespace JT1078.FMp4 bool first = false; - ulong BaseMediaDecodeTime = 2160000; - /// <summary> /// 编码其他视频数据盒子 /// </summary> diff --git a/src/JT1078.FMp4/JT1078.FMp4.xml b/src/JT1078.FMp4/JT1078.FMp4.xml index f26948c..2c0acee 100644 --- a/src/JT1078.FMp4/JT1078.FMp4.xml +++ b/src/JT1078.FMp4/JT1078.FMp4.xml @@ -571,11 +571,10 @@ stsd </summary> </member> - <member name="M:JT1078.FMp4.SampleDescriptionBox.#ctor(JT1078.FMp4.Enums.HandlerType,System.Byte,System.UInt32)"> + <member name="M:JT1078.FMp4.SampleDescriptionBox.#ctor(System.Byte,System.UInt32)"> <summary> stsd </summary> - <param name="handlerType"></param> <param name="version"></param> <param name="flags"></param> </member> @@ -622,6 +621,11 @@ stts </summary> </member> + <member name="P:JT1078.FMp4.SampleTableBox.SyncSampleBox"> + <summary> + stss + </summary> + </member> <member name="P:JT1078.FMp4.SampleTableBox.CompositionOffsetBox"> <summary> ctts @@ -672,19 +676,43 @@ </summary> </member> <!-- Badly formed XML comment ignored for member "P:JT1078.FMp4.SchemeTypeBox.SchemeUri" --> - <member name="P:JT1078.FMp4.SegmentIndexBox.EarliestPresentationTimeLarge"> + <member name="T:JT1078.FMp4.SegmentIndexBox"> + <summary> + sidx + </summary> + </member> + <member name="M:JT1078.FMp4.SegmentIndexBox.#ctor(System.Byte,System.UInt32)"> + <summary> + sidx + </summary> + <param name="version"></param> + <param name="flags"></param> + </member> + <member name="P:JT1078.FMp4.SegmentIndexBox.ReferenceID"> + <summary> + + </summary> + </member> + <member name="P:JT1078.FMp4.SegmentIndexBox.Timescale"> <summary> </summary> </member> <member name="P:JT1078.FMp4.SegmentIndexBox.EarliestPresentationTime"> <summary> - if(version==0) + if(version==0) + version==0 32 bit + version>0 64 bit </summary> </member> <member name="P:JT1078.FMp4.SegmentIndexBox.FirstOffset"> <summary> - if (version==0) + + </summary> + </member> + <member name="P:JT1078.FMp4.SegmentIndexBox.SegmentIndexs"> + <summary> + </summary> </member> <member name="P:JT1078.FMp4.SegmentIndexBox.SegmentIndex.ReferenceType"> @@ -697,6 +725,11 @@ 4byte 32 - 31 </summary> </member> + <member name="P:JT1078.FMp4.SegmentIndexBox.SegmentIndex.SubsegmentDuration"> + <summary> + + </summary> + </member> <member name="P:JT1078.FMp4.SegmentIndexBox.SegmentIndex.StartsWithSAP"> <summary> 4byte 32 - 1 @@ -798,6 +831,18 @@ length:ItemCount </summary> </member> + <member name="T:JT1078.FMp4.SyncSampleBox"> + <summary> + stss + </summary> + </member> + <member name="M:JT1078.FMp4.SyncSampleBox.#ctor(System.Byte,System.UInt32)"> + <summary> + stss + </summary> + <param name="version"></param> + <param name="flags"></param> + </member> <member name="T:JT1078.FMp4.TimeToSampleBox"> <summary> stts @@ -1006,10 +1051,26 @@ <member name="M:JT1078.FMp4.TrackRunBox.#ctor(System.Byte,System.UInt32)"> <summary> trun + 201 205 1 + 201 0010 0000 0001 + 205 0010 0000 0101 + 1 0000 0000 0001 + tr_flags 是用来表示下列 sample 相关的标识符是否应用到每个字段中: + 0x000001-0000 0000 0001: data-offset-present,只应用 data-offset + 0x000004-0000 0000 0100: 只对第一个 sample 应用对应的 flags。剩余 sample flags 就不管了。 + 0x000100-0001 0000 0000: 这个比较重要,表示每个 sample 都有自己的 duration,否则使用默认的 + 0x000200-0010 0000 0000: 每个 sample 有自己的 sample_size,否则使用默认的。 + 0x000400-0100 0000 0000: 对每个 sample 使用自己的 flags。否则,使用默认的。 + 0x000800-1000 0000 0000: 每个 sample 都有自己的 cts 值 </summary> <param name="version"></param> <param name="flags"></param> </member> + <member name="P:JT1078.FMp4.TrackRunBox.SampleCount"> + <summary> + + </summary> + </member> <member name="P:JT1078.FMp4.TrackRunBox.DataOffset"> <summary> 可选的 @@ -1241,9 +1302,11 @@ stream data ftyp moov + styp 1 moof 1 mdat 1 ... + styp n moof n mdat n mfra @@ -1255,12 +1318,24 @@ </summary> </member> + <member name="M:JT1078.FMp4.FMp4Encoder.EncoderStypBox"> + <summary> + styp + </summary> + <returns></returns> + </member> <member name="M:JT1078.FMp4.FMp4Encoder.EncoderFtypBox"> <summary> 编码ftyp盒子 </summary> <returns></returns> </member> + <member name="M:JT1078.FMp4.FMp4Encoder.EncoderSidxBox(System.UInt64,System.UInt32)"> + <summary> + 编码sidx盒子 + </summary> + <returns></returns> + </member> <member name="M:JT1078.FMp4.FMp4Encoder.EncoderMoovBox(System.Collections.Generic.List{JT1078.Protocol.H264.H264NALU},System.Int32)"> <summary> 编码moov盒子