@@ -451,17 +451,36 @@ namespace JT1078.FMp4.Test | |||
var nalus1 = h264Decoder.ParseNALU(package1); | |||
var moov = fMp4Encoder.EncoderMoovBox(nalus1, package1.Bodies.Length); | |||
fileStream.Write(moov); | |||
List<NalUnitType> filter = new List<NalUnitType>() { | |||
NalUnitType.SPS, | |||
NalUnitType.PPS, | |||
NalUnitType.AUD}; | |||
int i = 0; | |||
foreach (var package in packages) | |||
{ | |||
var otherStypBuffer = fMp4Encoder.EncoderStypBox(); | |||
fileStream.Write(otherStypBuffer); | |||
var otherNalus = h264Decoder.ParseNALU(package); | |||
var flag = package.Label3.DataType == Protocol.Enums.JT1078DataType.视频I帧 ? 1u : 0u; | |||
//var filterOtherNalus = otherNalus.Where(w => !filter.Contains(w.NALUHeader.NalUnitType)).ToList(); | |||
//if (filterOtherNalus.Count <= 0) | |||
//{ | |||
// continue; | |||
//} | |||
//int length = filterOtherNalus.Sum(s => s.RawData.Length); | |||
foreach(var nalu in otherNalus) | |||
{ | |||
//H264 NALU slice first_mb_in_slice | |||
if ((nalu.RawData[1] & 0x80) == 0x80) | |||
{ | |||
var otherMoofBuffer = fMp4Encoder.EncoderMoofBox(otherNalus, package.Bodies.Length, package.Timestamp, package.LastIFrameInterval, flag); | |||
} | |||
} | |||
var flag = package.Label3.DataType == Protocol.Enums.JT1078DataType.视频I帧 ? 1u : 0u; | |||
var otherMoofBuffer = fMp4Encoder.EncoderMoofBox(otherNalus, package.Bodies.Length, package.Timestamp, package.LastFrameInterval, package.LastIFrameInterval, flag); | |||
var otherMdatBuffer = fMp4Encoder.EncoderMdatBox(otherNalus, package.Bodies.Length); | |||
var otherSidxBuffer = fMp4Encoder.EncoderSidxBox(otherMoofBuffer.Length + otherMdatBuffer.Length, package.Timestamp, package.LastIFrameInterval); | |||
//var otherMoofBuffer = fMp4Encoder.EncoderMoofBox(filterOtherNalus, length, package.Timestamp, package.LastFrameInterval, package.LastIFrameInterval, flag); | |||
//var otherMdatBuffer = fMp4Encoder.EncoderMdatBox(filterOtherNalus, length); | |||
var otherSidxBuffer = fMp4Encoder.EncoderSidxBox(otherMoofBuffer.Length + otherMdatBuffer.Length, package.Timestamp, package.LastIFrameInterval, package.LastFrameInterval); | |||
fileStream.Write(otherSidxBuffer); | |||
fileStream.Write(otherMoofBuffer); | |||
fileStream.Write(otherMdatBuffer); | |||
@@ -49,6 +49,7 @@ namespace JT1078.FMp4 | |||
public uint DefaultSampleSize { get; set; } | |||
/// <summary> | |||
/// TFHD_FLAG_DEFAULT_FLAGS | |||
/// MOV_AUDIO == handler_type ? 0x02000000 : (0x00010000| 0x01000000); | |||
/// </summary> | |||
public uint DefaultSampleFlags { get; set; } | |||
#endregion | |||
@@ -108,11 +108,13 @@ namespace JT1078.FMp4 | |||
} | |||
} | |||
uint IframeIntervalCache = 259960; | |||
/// <summary> | |||
/// 编码sidx盒子 | |||
/// </summary> | |||
/// <returns></returns> | |||
public byte[] EncoderSidxBox(int moofAndMdatLength, ulong timestamp, uint frameInterval) | |||
public byte[] EncoderSidxBox(int moofAndMdatLength, ulong timestamp, uint IframeInterval, uint frameInterval) | |||
{ | |||
byte[] buffer = FMp4ArrayPool.Rent(4096); | |||
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer); | |||
@@ -120,7 +122,7 @@ namespace JT1078.FMp4 | |||
{ | |||
SegmentIndexBox segmentIndexBox = new SegmentIndexBox(1); | |||
segmentIndexBox.ReferenceID = 1; | |||
segmentIndexBox.EarliestPresentationTime = timestamp*1000; | |||
segmentIndexBox.EarliestPresentationTime = timestamp; | |||
segmentIndexBox.SegmentIndexs = new List<SegmentIndexBox.SegmentIndex>() | |||
{ | |||
new SegmentIndexBox.SegmentIndex | |||
@@ -203,7 +205,7 @@ namespace JT1078.FMp4 | |||
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(); | |||
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SyncSampleBox = new SyncSampleBox(); | |||
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(); | |||
@@ -230,7 +232,7 @@ namespace JT1078.FMp4 | |||
/// 编码Moof盒子 | |||
/// </summary> | |||
/// <returns></returns> | |||
public byte[] EncoderMoofBox(List<H264NALU> nalus, int naluLength,ulong timestamp,uint frameInterval, uint keyframeFlag,int moofOffset=0) | |||
public byte[] EncoderMoofBox(List<H264NALU> nalus, int naluLength, ulong timestamp, uint frameInterval, uint IframeInterval, uint keyframeFlag) | |||
{ | |||
byte[] buffer = FMp4ArrayPool.Rent(naluLength + 4096); | |||
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer); | |||
@@ -242,8 +244,9 @@ namespace JT1078.FMp4 | |||
movieFragmentBox.TrackFragmentBox = new TrackFragmentBox(); | |||
//0x39 写文件 | |||
//0x02 分段 | |||
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x20038); | |||
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x2003a); | |||
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 1; | |||
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.SampleDescriptionIndex = 1; | |||
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = frameInterval; | |||
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)naluLength; | |||
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000; | |||
@@ -254,19 +257,21 @@ namespace JT1078.FMp4 | |||
//0x02 分段 | |||
//0x205 | |||
//uint flag = 0x000200 | 0x000800 | 0x000400 | 0x000100; | |||
movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(); | |||
movieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 33554432; | |||
movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List<TrackRunBox.TrackRunInfo>(); | |||
if (frameIntervalCache == 0) | |||
uint flag = 0x0001; | |||
if (keyframeFlag == 1) | |||
{ | |||
frameIntervalCache += frameInterval; | |||
flag |= 0x0004; | |||
} | |||
//flag |= 0x000200; | |||
movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: flag); | |||
movieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 33554432; | |||
movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List<TrackRunBox.TrackRunInfo>(); | |||
movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo() | |||
{ | |||
SampleDuration= frameIntervalCache, | |||
//SampleDuration= frameInterval, | |||
SampleSize = (uint)naluLength, | |||
SampleCompositionTimeOffset = (long)timestamp , | |||
SampleFlags = movieFragmentBox.TrackFragmentBox.TrackRunBox.Flags | |||
//SampleCompositionTimeOffset = frameInterval, | |||
//SampleFlags = movieFragmentBox.TrackFragmentBox.TrackRunBox.Flags | |||
}); | |||
movieFragmentBox.ToBuffer(ref writer); | |||
var data = writer.FlushAndGetArray(); | |||
@@ -399,7 +404,6 @@ namespace JT1078.FMp4 | |||
} | |||
uint sn = 1; | |||
uint frameIntervalCache = 0; | |||
bool first = false; | |||
/// <summary> | |||
@@ -983,6 +983,7 @@ | |||
<member name="P:JT1078.FMp4.TrackFragmentHeaderBox.DefaultSampleFlags"> | |||
<summary> | |||
TFHD_FLAG_DEFAULT_FLAGS | |||
MOV_AUDIO == handler_type ? 0x02000000 : (0x00010000| 0x01000000); | |||
</summary> | |||
</member> | |||
<member name="T:JT1078.FMp4.TrackFragmentRandomAccessBox"> | |||
@@ -1335,7 +1336,7 @@ | |||
</summary> | |||
<returns></returns> | |||
</member> | |||
<member name="M:JT1078.FMp4.FMp4Encoder.EncoderSidxBox(System.Int32,System.UInt64,System.UInt32)"> | |||
<member name="M:JT1078.FMp4.FMp4Encoder.EncoderSidxBox(System.Int32,System.UInt64,System.UInt32,System.UInt32)"> | |||
<summary> | |||
编码sidx盒子 | |||
</summary> | |||
@@ -1347,7 +1348,7 @@ | |||
</summary> | |||
<returns></returns> | |||
</member> | |||
<member name="M:JT1078.FMp4.FMp4Encoder.EncoderMoofBox(System.Collections.Generic.List{JT1078.Protocol.H264.H264NALU},System.Int32,System.UInt64,System.UInt32,System.UInt32,System.Int32)"> | |||
<member name="M:JT1078.FMp4.FMp4Encoder.EncoderMoofBox(System.Collections.Generic.List{JT1078.Protocol.H264.H264NALU},System.Int32,System.UInt64,System.UInt32,System.UInt32,System.UInt32)"> | |||
<summary> | |||
编码Moof盒子 | |||
</summary> | |||
@@ -79,20 +79,19 @@ namespace JT1078.SignalR.Test.Services | |||
//q.Enqueue(moov); | |||
first.Add(moov); | |||
q.Add(first.SelectMany(s=>s).ToArray()); | |||
List<NalUnitType> filter = new List<NalUnitType>() { NalUnitType.SEI,NalUnitType.SPS,NalUnitType.PPS}; | |||
List<NalUnitType> filter = new List<NalUnitType>() { NalUnitType.SEI,NalUnitType.SPS,NalUnitType.PPS,NalUnitType.AUD}; | |||
foreach (var package in packages) | |||
{ | |||
List<byte[]> other = new List<byte[]>(); | |||
var otherStypBuffer = fMp4Encoder.EncoderStypBox(); | |||
other.Add(otherStypBuffer); | |||
var otherNalus = h264Decoder.ParseNALU(package); | |||
var filterNalus = otherNalus.Where(w => !filter.Contains(w.NALUHeader.NalUnitType)).ToList(); | |||
var flag = package.Label3.DataType == Protocol.Enums.JT1078DataType.视频I帧 ? 1u : 0u; | |||
var len = filterNalus.Sum(s => s.RawData.Length); | |||
var len1 = otherNalus.Sum(s => s.RawData.Length); | |||
var moofBuffer = fMp4Encoder.EncoderMoofBox(filterNalus, len, package.Timestamp, package.LastIFrameInterval, flag); | |||
//q.Enqueue(moofBuffer); | |||
other.Add(moofBuffer); | |||
var otherMdatBuffer = fMp4Encoder.EncoderMdatBox(filterNalus, len); | |||
//q.Enqueue(otherMdatBuffer); | |||
var otherMoofBuffer = fMp4Encoder.EncoderMoofBox(otherNalus, package.Bodies.Length, package.Timestamp, package.LastFrameInterval, package.LastIFrameInterval, flag); | |||
var otherMdatBuffer = fMp4Encoder.EncoderMdatBox(otherNalus, package.Bodies.Length); | |||
var otherSidxBuffer = fMp4Encoder.EncoderSidxBox(otherMoofBuffer.Length + otherMdatBuffer.Length, package.Timestamp, package.LastIFrameInterval, package.LastFrameInterval); | |||
other.Add(otherSidxBuffer); | |||
other.Add(otherMoofBuffer); | |||
other.Add(otherMdatBuffer); | |||
q.Add(other.SelectMany(s => s).ToArray()); | |||
} | |||