From fae5e4f07feb8a9e93fb96780acaac30e09e3ddf Mon Sep 17 00:00:00 2001
From: "SmallChi(Koike)" <564952747@qq.com>
Date: Wed, 14 Oct 2020 18:16:01 +0800
Subject: [PATCH] =?UTF-8?q?=E7=BB=84=E8=A3=85=E6=B5=8B=E8=AF=95=E7=9B=92?=
=?UTF-8?q?=E5=AD=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/JT1078.FMp4.Test/FMp4Box_Test.cs | 109 ++++++++++++++++
.../JT1078FlvEncoderContext.cs | 2 +-
.../JT808HexExtensions.cs | 2 +-
.../JT1078.Protocol.Benchmark.csproj | 2 -
.../JT1078FlvEncoderContext.cs | 4 +-
.../JT1078SerializerContext.cs | 4 +-
src/JT1078.Protocol/JT1078.Protocol.csproj | 2 +-
src/JT1078.Protocol/JT1078Serializer.cs | 122 ++++++++----------
src/JT1078.sln | 4 +-
9 files changed, 175 insertions(+), 76 deletions(-)
create mode 100644 src/JT1078.FMp4.Test/FMp4Box_Test.cs
diff --git a/src/JT1078.FMp4.Test/FMp4Box_Test.cs b/src/JT1078.FMp4.Test/FMp4Box_Test.cs
new file mode 100644
index 0000000..3c74da6
--- /dev/null
+++ b/src/JT1078.FMp4.Test/FMp4Box_Test.cs
@@ -0,0 +1,109 @@
+using JT1078.FMp4.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Xunit;
+using JT1078.Protocol.Extensions;
+
+namespace JT1078.FMp4.Test
+{
+ public class FMp4Box_Test
+ {
+ ///
+ /// 使用doc/video/fragmented_demo.mp4
+ ///
+ [Fact(DisplayName = "ftyp")]
+ public void ftyp_test()
+ {
+ var MinorVersion = Encoding.ASCII.GetString(new byte[4] { 0,0,2,0});
+ 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("iso6");
+ fileTypeBox.CompatibleBrands.Add("mp41");
+ FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x25]);
+ fileTypeBox.ToBuffer(ref writer);
+ var hex = writer.FlushAndGetArray().ToHexString();
+ Assert.Equal("000000246674797069736f6d0000020069736f6d69736f326176633169736f366d703431".ToUpper(), hex);
+ }
+
+ ///
+ /// 使用doc/video/fragmented_demo.mp4
+ ///
+ [Fact(DisplayName = "moov_mvhd")]
+ public void moov_mvhd_test()
+ {
+ MovieHeaderBox movieHeaderBox = new MovieHeaderBox(0);
+ movieHeaderBox.CreationTime = 0;
+ movieHeaderBox.ModificationTime = 0;
+ movieHeaderBox.Timescale = 1000;
+ movieHeaderBox.Duration = 0;
+ movieHeaderBox.NextTrackID = 2;
+ FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
+ movieHeaderBox.ToBuffer(ref writer);
+ var hex = writer.FlushAndGetArray().ToHexString();
+ Assert.Equal("0000006c6d766864000000000000000000000000000003e8000000000001000001000000000000000000000000010000000000000000000000000000000100000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002".ToUpper(), hex);
+ }
+
+ ///
+ /// 使用doc/video/fragmented_demo.mp4
+ ///
+ [Fact(DisplayName = "trak_tkhd")]
+ public void trak_tkhd_test()
+ {
+ TrackHeaderBox trackHeaderBox = new TrackHeaderBox(0,3);
+ trackHeaderBox.CreationTime = 0;
+ trackHeaderBox.ModificationTime = 0;
+ trackHeaderBox.TrackID = 1;
+ trackHeaderBox.Duration = 0;
+ trackHeaderBox.Width = 544u;
+ trackHeaderBox.Height = 960u;
+ FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
+ trackHeaderBox.ToBuffer(ref writer);
+ var hex = writer.FlushAndGetArray().ToHexString();
+ Assert.Equal("0000005C746B68640000000300000000000000000000000100000000000000000000000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000004000000000000220000003C0".ToUpper(), hex);
+ }
+
+ ///
+ /// 使用doc/video/fragmented_demo.mp4
+ ///
+ [Fact(DisplayName = "trak_mdia")]
+ public void trak_mdia_test()
+ {
+
+
+ }
+
+ ///
+ /// 使用doc/video/fragmented_demo.mp4
+ ///
+ [Fact(DisplayName = "trak_mdia_mdhd")]
+ public void trak_mdia_mdhd_test()
+ {
+
+ MediaHeaderBox mediaHeaderBox = new MediaHeaderBox(0, 0);
+ mediaHeaderBox.CreationTime = 0;
+ mediaHeaderBox.ModificationTime = 0;
+ mediaHeaderBox.Timescale = 0x00124f80;
+ mediaHeaderBox.Duration = 0;
+ mediaHeaderBox.Language = "und";
+ FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
+ mediaHeaderBox.ToBuffer(ref writer);
+ var hex = writer.FlushAndGetArray().ToHexString();
+ //000000206d64686400000000000000000000000000124f800000000055c40000
+ //00000020
+ //6d646864
+ //00000000
+ //00000000
+ //00000000
+ //00124f80
+ //00000000
+ //55c4
+ //0000
+ Assert.Equal("000000206d64686400000000000000000000000000124f800000000055c40000".ToUpper(), hex);
+ }
+ }
+}
diff --git a/src/JT1078.Flv.Benchmark/JT1078FlvEncoderContext.cs b/src/JT1078.Flv.Benchmark/JT1078FlvEncoderContext.cs
index 4d46404..9d7db77 100644
--- a/src/JT1078.Flv.Benchmark/JT1078FlvEncoderContext.cs
+++ b/src/JT1078.Flv.Benchmark/JT1078FlvEncoderContext.cs
@@ -69,7 +69,7 @@ namespace JT1078.Flv.Benchmark
{
public JT1078FlvEncoderConfig()
{
- Add(Job.Default.WithGcServer(false).With(CsProjCoreToolchain.NetCoreApp31).With(Platform.AnyCpu));
+ AddJob(Job.Default.WithGcServer(false).WithToolchain(CsProjCoreToolchain.NetCoreApp31).WithPlatform(Platform.AnyCpu));
}
}
}
diff --git a/src/JT1078.Flv.Benchmark/JT808HexExtensions.cs b/src/JT1078.Flv.Benchmark/JT808HexExtensions.cs
index 8248bd5..622cc6e 100644
--- a/src/JT1078.Flv.Benchmark/JT808HexExtensions.cs
+++ b/src/JT1078.Flv.Benchmark/JT808HexExtensions.cs
@@ -6,7 +6,7 @@ namespace JT808.Protocol.Extensions
///
/// ref:"www.codeproject.com/tips/447938/high-performance-csharp-byte-array-to-hex-string-t"
///
- public static partial class JT808BinaryExtensions
+ internal static partial class JT808BinaryExtensions
{
public static string ToHexString(this byte[] source)
{
diff --git a/src/JT1078.Protocol.Benchmark/JT1078.Protocol.Benchmark.csproj b/src/JT1078.Protocol.Benchmark/JT1078.Protocol.Benchmark.csproj
index d0a50e8..25db222 100644
--- a/src/JT1078.Protocol.Benchmark/JT1078.Protocol.Benchmark.csproj
+++ b/src/JT1078.Protocol.Benchmark/JT1078.Protocol.Benchmark.csproj
@@ -15,9 +15,7 @@
-
-
diff --git a/src/JT1078.Protocol.Benchmark/JT1078FlvEncoderContext.cs b/src/JT1078.Protocol.Benchmark/JT1078FlvEncoderContext.cs
index a7a35f0..acf356f 100644
--- a/src/JT1078.Protocol.Benchmark/JT1078FlvEncoderContext.cs
+++ b/src/JT1078.Protocol.Benchmark/JT1078FlvEncoderContext.cs
@@ -7,7 +7,7 @@ using JT1078.Flv.MessagePack;
using JT1078.Protocol;
using JT1078.Protocol.H264;
using JT1078.Protocol.MessagePack;
-using JT808.Protocol.Extensions;
+using JT1078.Protocol.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
@@ -78,7 +78,7 @@ namespace JT1078.Flv.Benchmark
{
public JT1078FlvEncoderConfig()
{
- Add(Job.Default.WithGcServer(false).With(CsProjCoreToolchain.NetCoreApp31).With(Platform.AnyCpu));
+ AddJob(Job.Default.WithGcServer(false).WithToolchain(CsProjCoreToolchain.NetCoreApp31).WithPlatform(Platform.AnyCpu));
}
}
}
diff --git a/src/JT1078.Protocol.Benchmark/JT1078SerializerContext.cs b/src/JT1078.Protocol.Benchmark/JT1078SerializerContext.cs
index c471fae..22e245f 100644
--- a/src/JT1078.Protocol.Benchmark/JT1078SerializerContext.cs
+++ b/src/JT1078.Protocol.Benchmark/JT1078SerializerContext.cs
@@ -3,10 +3,10 @@ using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Toolchains.CsProj;
-using JT808.Protocol.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
+using JT1078.Protocol.Extensions;
namespace JT1078.Protocol.Benchmark
{
@@ -58,7 +58,7 @@ namespace JT1078.Protocol.Benchmark
{
public JT1078SerializerConfig()
{
- Add(Job.Default.WithGcServer(false).With(CsProjCoreToolchain.NetCoreApp31).With(Platform.AnyCpu));
+ AddJob(Job.Default.WithGcServer(false).WithToolchain(CsProjCoreToolchain.NetCoreApp31).WithPlatform(Platform.AnyCpu));
}
}
}
diff --git a/src/JT1078.Protocol/JT1078.Protocol.csproj b/src/JT1078.Protocol/JT1078.Protocol.csproj
index 1c926b5..d2ab1c4 100644
--- a/src/JT1078.Protocol/JT1078.Protocol.csproj
+++ b/src/JT1078.Protocol/JT1078.Protocol.csproj
@@ -14,7 +14,7 @@
https://github.com/SmallChi/JT1078/blob/master/LICENSE
https://github.com/SmallChi/JT1078/blob/master/LICENSE
false
- 1.0.4-preview1
+ 1.0.4-preview2
false
true
LICENSE
diff --git a/src/JT1078.Protocol/JT1078Serializer.cs b/src/JT1078.Protocol/JT1078Serializer.cs
index f29d875..a5d8e54 100644
--- a/src/JT1078.Protocol/JT1078Serializer.cs
+++ b/src/JT1078.Protocol/JT1078Serializer.cs
@@ -115,80 +115,72 @@ namespace JT1078.Protocol
return jT1078Package;
}
}
- public static byte[] AnalyzeJsonBuffer(ReadOnlySpan bytes, JsonWriterOptions options = default, int minBufferSize = 8096)
+ public static byte[] AnalyzeJsonBuffer(ReadOnlySpan bytes, JsonWriterOptions options = default)
{
- byte[] buffer = JT1078ArrayPool.Rent(minBufferSize);
- try
+ JT1078MessagePackReader jT1078MessagePackReader = new JT1078MessagePackReader(bytes);
+ using (MemoryStream memoryStream = new MemoryStream())
+ using (Utf8JsonWriter writer = new Utf8JsonWriter(memoryStream, options))
{
- JT1078MessagePackReader jT1078MessagePackReader = new JT1078MessagePackReader(bytes);
- using (MemoryStream memoryStream = new MemoryStream())
- using (Utf8JsonWriter writer = new Utf8JsonWriter(memoryStream, options))
- {
- writer.WriteStartObject();
- var header = jT1078MessagePackReader.ReadUInt32();
- writer.WriteString($"[{header}]头部", header.ReadNumber());
- var val1 = jT1078MessagePackReader.ReadByte();
- var label1 = new JT1078Label1(val1);
- var labelSpan = val1.ReadBinary();
- writer.WriteStartObject($"[{labelSpan.ToString()}]object1[{val1.ReadNumber()}]");
- writer.WriteNumber($"({labelSpan.Slice(0,2).ToString()})V[固定为2]", label1.V);
- writer.WriteNumber($"({labelSpan[2]})P[固定为0]", label1.P);
- writer.WriteNumber($"({labelSpan[3]})X[RTP头是否需要扩展位固定为0]", label1.X);
- writer.WriteNumber($"({labelSpan.Slice(4).ToString()})CC[固定为1]", label1.CC);
- writer.WriteEndObject();
+ writer.WriteStartObject();
+ var header = jT1078MessagePackReader.ReadUInt32();
+ writer.WriteNumber($"[{header.ReadNumber()}]头部", header);
+ var val1 = jT1078MessagePackReader.ReadByte();
+ var label1 = new JT1078Label1(val1);
+ var labelSpan = val1.ReadBinary();
+ writer.WriteStartObject($"[{labelSpan.ToString()}]object1[{val1.ReadNumber()}]");
+ writer.WriteNumber($"({labelSpan.Slice(0,2).ToString()})V[固定为2]", label1.V);
+ writer.WriteNumber($"({labelSpan[2]})P[固定为0]", label1.P);
+ writer.WriteNumber($"({labelSpan[3]})X[RTP头是否需要扩展位固定为0]", label1.X);
+ writer.WriteNumber($"({labelSpan.Slice(4).ToString()})CC[固定为1]", label1.CC);
+ writer.WriteEndObject();
- var val2 = jT1078MessagePackReader.ReadByte();
- var label2 = new JT1078Label2(val2);
- var label2Span = val2.ReadBinary();
- writer.WriteStartObject($"[{label2Span.ToString()}]object2[{val2.ReadNumber()}]");
- writer.WriteNumber($"({label2Span.Slice(0, 4).ToString()})M[确定是否是完整数据帧的边界]", label2.M);
- writer.WriteString($"({label2Span.Slice(4).ToString()})PT[负载类型]", label2.PT.ToString());
- writer.WriteEndObject();
+ var val2 = jT1078MessagePackReader.ReadByte();
+ var label2 = new JT1078Label2(val2);
+ var label2Span = val2.ReadBinary();
+ writer.WriteStartObject($"[{label2Span.ToString()}]object2[{val2.ReadNumber()}]");
+ writer.WriteNumber($"({label2Span.Slice(0, 4).ToString()})M[确定是否是完整数据帧的边界]", label2.M);
+ writer.WriteString($"({label2Span.Slice(4).ToString()})PT[负载类型]", label2.PT.ToString());
+ writer.WriteEndObject();
- var sn = jT1078MessagePackReader.ReadUInt16();
- writer.WriteNumber($"{sn.ReadNumber()}[序列号]", sn);
- var sim = jT1078MessagePackReader.ReadBCD(12);
- writer.WriteString($"[终端设备SIM卡号]", sim);
- var logicChannelNumber = jT1078MessagePackReader.ReadByte();
- writer.WriteNumber($"{logicChannelNumber.ReadNumber()}[逻辑通道号]", logicChannelNumber);
+ var sn = jT1078MessagePackReader.ReadUInt16();
+ writer.WriteNumber($"{sn.ReadNumber()}[序列号]", sn);
+ var sim = jT1078MessagePackReader.ReadBCD(12);
+ writer.WriteString($"[终端设备SIM卡号]", sim);
+ var logicChannelNumber = jT1078MessagePackReader.ReadByte();
+ writer.WriteNumber($"{logicChannelNumber.ReadNumber()}[逻辑通道号]", logicChannelNumber);
- var val3 = jT1078MessagePackReader.ReadByte();
- var label3 = new JT1078Label3(val3);
- var label3Span = val3.ReadBinary();
- writer.WriteStartObject($"[{label3Span.ToString()}]object3[{val3.ReadNumber()}]");
- writer.WriteString($"({label3Span.Slice(0, 4).ToString()})[数据类型]", label3.DataType.ToString());
- writer.WriteString($"({label3Span.Slice(4).ToString()})[分包处理标记]", label3.SubpackageType.ToString());
- writer.WriteEndObject();
- if (label3.DataType != JT1078DataType.透传数据)
- {
- var timestamp = jT1078MessagePackReader.ReadUInt64();
- writer.WriteNumber($"{timestamp.ReadNumber()}[标识此RTP数据包当前帧的相对时间,单位毫秒(ms)]", timestamp);
- }
- if (label3.DataType != JT1078DataType.透传数据 &&
- label3.DataType != JT1078DataType.音频帧)
- {
- var lastIFrameInterval = jT1078MessagePackReader.ReadUInt16();
- writer.WriteNumber($"{lastIFrameInterval.ReadNumber()}[该帧与上一个关键帧之间的时间间隔,单位毫秒(ms)]", lastIFrameInterval);
- var lastFrameInterval = jT1078MessagePackReader.ReadUInt16();
- writer.WriteNumber($"{lastFrameInterval.ReadNumber()}[该帧与上一个关键帧之间的时间间隔,单位毫秒(ms)]", lastFrameInterval);
- }
- var dataBodyLength = jT1078MessagePackReader.ReadUInt16();
- writer.WriteNumber($"{dataBodyLength.ReadNumber()}[数据体长度]", dataBodyLength);
- var bodies = jT1078MessagePackReader.ReadRemainArray().ToArray();
- writer.WriteString("[数据体]", string.Join(" ", (bodies).Select(p => p.ToString("X2"))));
- writer.WriteEndObject();
- writer.Flush();
- return memoryStream.ToArray();
+ var val3 = jT1078MessagePackReader.ReadByte();
+ var label3 = new JT1078Label3(val3);
+ var label3Span = val3.ReadBinary();
+ writer.WriteStartObject($"[{label3Span.ToString()}]object3[{val3.ReadNumber()}]");
+ writer.WriteString($"({label3Span.Slice(0, 4).ToString()})[数据类型]", label3.DataType.ToString());
+ writer.WriteString($"({label3Span.Slice(4).ToString()})[分包处理标记]", label3.SubpackageType.ToString());
+ writer.WriteEndObject();
+ if (label3.DataType != JT1078DataType.透传数据)
+ {
+ var timestamp = jT1078MessagePackReader.ReadUInt64();
+ writer.WriteNumber($"{timestamp.ReadNumber()}[标识此RTP数据包当前帧的相对时间,单位毫秒(ms)]", timestamp);
}
- }
- finally
- {
- JT1078ArrayPool.Return(buffer);
+ if (label3.DataType != JT1078DataType.透传数据 &&
+ label3.DataType != JT1078DataType.音频帧)
+ {
+ var lastIFrameInterval = jT1078MessagePackReader.ReadUInt16();
+ writer.WriteNumber($"{lastIFrameInterval.ReadNumber()}[该帧与上一个关键帧之间的时间间隔,单位毫秒(ms)]", lastIFrameInterval);
+ var lastFrameInterval = jT1078MessagePackReader.ReadUInt16();
+ writer.WriteNumber($"{lastFrameInterval.ReadNumber()}[该帧与上一个关键帧之间的时间间隔,单位毫秒(ms)]", lastFrameInterval);
+ }
+ var dataBodyLength = jT1078MessagePackReader.ReadUInt16();
+ writer.WriteNumber($"{dataBodyLength.ReadNumber()}[数据体长度]", dataBodyLength);
+ var bodies = jT1078MessagePackReader.ReadRemainArray().ToArray();
+ writer.WriteString("[数据体]", string.Join(" ", (bodies).Select(p => p.ToString("X2"))));
+ writer.WriteEndObject();
+ writer.Flush();
+ return memoryStream.ToArray();
}
}
- public static string Analyze(ReadOnlySpan bytes,JsonWriterOptions options = default, int minBufferSize = 8096)
+ public static string Analyze(ReadOnlySpan bytes,JsonWriterOptions options = default)
{
- string json = Encoding.UTF8.GetString(AnalyzeJsonBuffer(bytes, options, minBufferSize));
+ string json = Encoding.UTF8.GetString(AnalyzeJsonBuffer(bytes, options));
return json;
}
}
diff --git a/src/JT1078.sln b/src/JT1078.sln
index 5362b6d..696d930 100644
--- a/src/JT1078.sln
+++ b/src/JT1078.sln
@@ -34,9 +34,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Hls", "JT1078.Hls\JT
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Hls.Test", "JT1078.Hls.Test\JT1078.Hls.Test.csproj", "{5564C20B-BFF4-4A2A-BDF2-C7427E93E993}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT1078.FMp4", "JT1078.FMp4\JT1078.FMp4.csproj", "{73F13894-0967-422C-8AC3-5EEF9189AAFC}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.FMp4", "JT1078.FMp4\JT1078.FMp4.csproj", "{73F13894-0967-422C-8AC3-5EEF9189AAFC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT1078.FMp4.Test", "JT1078.FMp4.Test\JT1078.FMp4.Test.csproj", "{56E76D56-4CCC-401F-B25D-9AB41D58A10A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.FMp4.Test", "JT1078.FMp4.Test\JT1078.FMp4.Test.csproj", "{56E76D56-4CCC-401F-B25D-9AB41D58A10A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution