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盒子