@@ -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; | |||
@@ -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(); | |||
} | |||
@@ -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) | |||
{ | |||
@@ -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); | |||
@@ -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; | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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> | |||
/// 可选的 | |||
@@ -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> | |||
@@ -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盒子 | |||