SmallChi(Koike) 4 лет назад
Родитель
Сommit
b5e599b544
5 измененных файлов: 53 добавлений и 29 удалений
  1. +23
    -4
      src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs
  2. +1
    -0
      src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs
  3. +18
    -14
      src/JT1078.FMp4/FMp4Encoder.cs
  4. +3
    -2
      src/JT1078.FMp4/JT1078.FMp4.xml
  5. +8
    -9
      src/JT1078.SignalR.Test/Services/ToWebSocketService.cs

+ 23
- 4
src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs Просмотреть файл

@@ -451,17 +451,36 @@ namespace JT1078.FMp4.Test
var nalus1 = h264Decoder.ParseNALU(package1); var nalus1 = h264Decoder.ParseNALU(package1);
var moov = fMp4Encoder.EncoderMoovBox(nalus1, package1.Bodies.Length); var moov = fMp4Encoder.EncoderMoovBox(nalus1, package1.Bodies.Length);
fileStream.Write(moov); fileStream.Write(moov);
List<NalUnitType> filter = new List<NalUnitType>() {
NalUnitType.SPS,
NalUnitType.PPS,
NalUnitType.AUD};
int i = 0;
foreach (var package in packages) foreach (var package in packages)
{ {
var otherStypBuffer = fMp4Encoder.EncoderStypBox(); var otherStypBuffer = fMp4Encoder.EncoderStypBox();
fileStream.Write(otherStypBuffer); fileStream.Write(otherStypBuffer);
var otherNalus = h264Decoder.ParseNALU(package); 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 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(otherSidxBuffer);
fileStream.Write(otherMoofBuffer); fileStream.Write(otherMoofBuffer);
fileStream.Write(otherMdatBuffer); fileStream.Write(otherMdatBuffer);


+ 1
- 0
src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs Просмотреть файл

@@ -49,6 +49,7 @@ namespace JT1078.FMp4
public uint DefaultSampleSize { get; set; } public uint DefaultSampleSize { get; set; }
/// <summary> /// <summary>
/// TFHD_FLAG_DEFAULT_FLAGS /// TFHD_FLAG_DEFAULT_FLAGS
/// MOV_AUDIO == handler_type ? 0x02000000 : (0x00010000| 0x01000000);
/// </summary> /// </summary>
public uint DefaultSampleFlags { get; set; } public uint DefaultSampleFlags { get; set; }
#endregion #endregion


+ 18
- 14
src/JT1078.FMp4/FMp4Encoder.cs Просмотреть файл

@@ -108,11 +108,13 @@ namespace JT1078.FMp4
} }
} }


uint IframeIntervalCache = 259960;

/// <summary> /// <summary>
/// 编码sidx盒子 /// 编码sidx盒子
/// </summary> /// </summary>
/// <returns></returns> /// <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); byte[] buffer = FMp4ArrayPool.Rent(4096);
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer); FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer);
@@ -120,7 +122,7 @@ namespace JT1078.FMp4
{ {
SegmentIndexBox segmentIndexBox = new SegmentIndexBox(1); SegmentIndexBox segmentIndexBox = new SegmentIndexBox(1);
segmentIndexBox.ReferenceID = 1; segmentIndexBox.ReferenceID = 1;
segmentIndexBox.EarliestPresentationTime = timestamp*1000;
segmentIndexBox.EarliestPresentationTime = timestamp;
segmentIndexBox.SegmentIndexs = new List<SegmentIndexBox.SegmentIndex>() segmentIndexBox.SegmentIndexs = new List<SegmentIndexBox.SegmentIndex>()
{ {
new SegmentIndexBox.SegmentIndex new SegmentIndexBox.SegmentIndex
@@ -203,7 +205,7 @@ namespace JT1078.FMp4
avc1.AVCConfigurationBox.SPSs = new List<byte[]>() { spsNALU.RawData }; avc1.AVCConfigurationBox.SPSs = new List<byte[]>() { spsNALU.RawData };
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1);
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox = new TimeToSampleBox(); 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.SampleToChunkBox = new SampleToChunkBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox();
@@ -230,7 +232,7 @@ namespace JT1078.FMp4
/// 编码Moof盒子 /// 编码Moof盒子
/// </summary> /// </summary>
/// <returns></returns> /// <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); byte[] buffer = FMp4ArrayPool.Rent(naluLength + 4096);
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer); FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer);
@@ -242,8 +244,9 @@ namespace JT1078.FMp4
movieFragmentBox.TrackFragmentBox = new TrackFragmentBox(); movieFragmentBox.TrackFragmentBox = new TrackFragmentBox();
//0x39 写文件 //0x39 写文件
//0x02 分段 //0x02 分段
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x20038);
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x2003a);
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 1; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 1;
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.SampleDescriptionIndex = 1;
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = frameInterval; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = frameInterval;
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)naluLength; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)naluLength;
movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000;
@@ -254,19 +257,21 @@ namespace JT1078.FMp4
//0x02 分段 //0x02 分段
//0x205 //0x205
//uint flag = 0x000200 | 0x000800 | 0x000400 | 0x000100; //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() movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo()
{ {
SampleDuration= frameIntervalCache,
//SampleDuration= frameInterval,
SampleSize = (uint)naluLength, SampleSize = (uint)naluLength,
SampleCompositionTimeOffset = (long)timestamp ,
SampleFlags = movieFragmentBox.TrackFragmentBox.TrackRunBox.Flags
//SampleCompositionTimeOffset = frameInterval,
//SampleFlags = movieFragmentBox.TrackFragmentBox.TrackRunBox.Flags
}); });
movieFragmentBox.ToBuffer(ref writer); movieFragmentBox.ToBuffer(ref writer);
var data = writer.FlushAndGetArray(); var data = writer.FlushAndGetArray();
@@ -399,7 +404,6 @@ namespace JT1078.FMp4
} }


uint sn = 1; uint sn = 1;
uint frameIntervalCache = 0;
bool first = false; bool first = false;


/// <summary> /// <summary>


+ 3
- 2
src/JT1078.FMp4/JT1078.FMp4.xml Просмотреть файл

@@ -983,6 +983,7 @@
<member name="P:JT1078.FMp4.TrackFragmentHeaderBox.DefaultSampleFlags"> <member name="P:JT1078.FMp4.TrackFragmentHeaderBox.DefaultSampleFlags">
<summary> <summary>
TFHD_FLAG_DEFAULT_FLAGS TFHD_FLAG_DEFAULT_FLAGS
MOV_AUDIO == handler_type ? 0x02000000 : (0x00010000| 0x01000000);
</summary> </summary>
</member> </member>
<member name="T:JT1078.FMp4.TrackFragmentRandomAccessBox"> <member name="T:JT1078.FMp4.TrackFragmentRandomAccessBox">
@@ -1335,7 +1336,7 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </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> <summary>
编码sidx盒子 编码sidx盒子
</summary> </summary>
@@ -1347,7 +1348,7 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </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> <summary>
编码Moof盒子 编码Moof盒子
</summary> </summary>


+ 8
- 9
src/JT1078.SignalR.Test/Services/ToWebSocketService.cs Просмотреть файл

@@ -79,20 +79,19 @@ namespace JT1078.SignalR.Test.Services
//q.Enqueue(moov); //q.Enqueue(moov);
first.Add(moov); first.Add(moov);
q.Add(first.SelectMany(s=>s).ToArray()); 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) foreach (var package in packages)
{ {
List<byte[]> other = new List<byte[]>(); List<byte[]> other = new List<byte[]>();
var otherStypBuffer = fMp4Encoder.EncoderStypBox();
other.Add(otherStypBuffer);
var otherNalus = h264Decoder.ParseNALU(package); 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 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); other.Add(otherMdatBuffer);
q.Add(other.SelectMany(s => s).ToArray()); q.Add(other.SelectMany(s => s).ToArray());
} }


Загрузка…
Отмена
Сохранить