Browse Source

修改fmp4

master
SmallChi(Koike) 3 years ago
parent
commit
c1576f8224
10 changed files with 118 additions and 29 deletions
  1. +1
    -1
      src/JT1078.AV.Benchmark/JT1078AVEncoderContext.cs
  2. +2
    -2
      src/JT1078.FMp4.Test/H264/index.html
  3. +12
    -11
      src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs
  4. +38
    -5
      src/JT1078.FMp4/FMp4Encoder.cs
  5. +1
    -1
      src/JT1078.FMp4/JT1078.FMp4.csproj
  6. +9
    -3
      src/JT1078.FMp4/JT1078.FMp4.xml
  7. +21
    -0
      src/JT1078.Protocol.Test/H264/H264DecoderTest.cs
  8. +3
    -0
      src/JT1078.Protocol.Test/JT1078.Protocol.Test.csproj
  9. +3
    -0
      src/JT1078.SignalR.Test/JT1078.SignalR.Test.csproj
  10. +28
    -6
      src/JT1078.SignalR.Test/Services/ToWebSocketService.cs

+ 1
- 1
src/JT1078.AV.Benchmark/JT1078AVEncoderContext.cs View File

@@ -117,7 +117,7 @@ namespace JT1078.AV.Benchmark
{
for (var i = 0; i < N; i++)
{
var buffer = fmp4Encoder.EncoderOtherVideoBox(FMp4H264NALUs);
var buffer = fmp4Encoder.OtherVideoBox(FMp4H264NALUs);
}
}
}


+ 2
- 2
src/JT1078.FMp4.Test/H264/index.html View File

@@ -173,10 +173,10 @@
ws.on("video", (message) => {
var buff=base64ToArrayBuffer(message);
//console.log(buff);
//putPacket(buff);
putPacket(buff);
//先直接喂进去
//mvhd.duration 谷歌浏览器不会缓存
source_buffer.appendBuffer(buff);
//source_buffer.appendBuffer(buff);
});
ws.start().catch(err => console.error(err));
}


+ 12
- 11
src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs View File

@@ -449,12 +449,12 @@ namespace JT1078.FMp4.Test
}

using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
var ftyp = fMp4Encoder.EncoderFtypBox();
var ftyp = fMp4Encoder.FtypBox();
fileStream.Write(ftyp);

var iNalus = h264Decoder.ParseNALU(packages[0]);
//判断第一帧是否关键帧
var moov = fMp4Encoder.EncoderMoovBox(
var moov = fMp4Encoder.VideoMoovBox(
iNalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS),
iNalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.PPS));
fileStream.Write(moov);
@@ -474,7 +474,7 @@ namespace JT1078.FMp4.Test
{
if (nalus.Count > 0)
{
var otherBuffer = fMp4Encoder.EncoderOtherVideoBox(nalus);
var otherBuffer = fMp4Encoder.OtherVideoBox(nalus);
fileStream.Write(otherBuffer);
nalus.Clear();
}
@@ -498,12 +498,12 @@ namespace JT1078.FMp4.Test
}
using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);

var ftyp = fMp4Encoder.EncoderFtypBox();
var ftyp = fMp4Encoder.FtypBox();
fileStream.Write(ftyp);

var iNalus = h264Decoder.ParseNALU(packages[0]);
//判断第一帧是否关键帧
var moov = fMp4Encoder.EncoderMoovBox(
var moov = fMp4Encoder.VideoMoovBox(
iNalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS),
iNalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.PPS));
fileStream.Write(moov);
@@ -516,7 +516,7 @@ namespace JT1078.FMp4.Test
{
if (nalus.Count > 0)
{
var otherBuffer = fMp4Encoder.EncoderOtherVideoBox(nalus);
var otherBuffer = fMp4Encoder.OtherVideoBox(nalus);
fileStream.Write(otherBuffer);
nalus.Clear();
}
@@ -525,7 +525,7 @@ namespace JT1078.FMp4.Test
}
if (nalus.Count > 0)
{
var otherBuffer = fMp4Encoder.EncoderOtherVideoBox(nalus);
var otherBuffer = fMp4Encoder.OtherVideoBox(nalus);
fileStream.Write(otherBuffer);
nalus.Clear();
}
@@ -545,13 +545,13 @@ namespace JT1078.FMp4.Test
}
using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);

var ftyp = fMp4Encoder.EncoderFtypBox();
var ftyp = fMp4Encoder.FtypBox();
fileStream.Write(ftyp);

var iPackage = packages.FirstOrDefault(f => f.Label3.DataType == JT1078DataType.视频I帧);
var iNalus = h264Decoder.ParseNALU(iPackage);
//判断第一帧是否关键帧
var moov = fMp4Encoder.EncoderMoovBox(
var moov = fMp4Encoder.VideoMoovBox(
iNalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS),
iNalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.PPS));
fileStream.Write(moov);
@@ -564,7 +564,8 @@ namespace JT1078.FMp4.Test
{
if (nalus.Count > 0)
{
var otherBuffer = fMp4Encoder.EncoderOtherVideoBox(nalus);
fileStream.Write(fMp4Encoder.StypBox());
var otherBuffer = fMp4Encoder.OtherVideoBox(nalus);
fileStream.Write(otherBuffer);
nalus.Clear();
}
@@ -573,7 +574,7 @@ namespace JT1078.FMp4.Test
}
if (nalus.Count > 0)
{
var otherBuffer = fMp4Encoder.EncoderOtherVideoBox(nalus);
var otherBuffer = fMp4Encoder.OtherVideoBox(nalus);
fileStream.Write(otherBuffer);
nalus.Clear();
}


+ 38
- 5
src/JT1078.FMp4/FMp4Encoder.cs View File

@@ -32,10 +32,11 @@ namespace JT1078.FMp4
{
Dictionary<string, TrackInfo> TrackInfos;

const uint DefaultSampleDuration = 48000u;
const uint DefaultSampleDuration = 40u;
const uint DefaultSampleFlags = 0x1010000;
const uint FirstSampleFlags = 33554432;
const uint TfhdFlags = 0x2003a;
//const uint TrunFlags = 0x205;
const uint TrunFlags = 0x205;
const uint SampleDescriptionIndex = 1;
const uint TrackID = 1;
@@ -52,7 +53,7 @@ namespace JT1078.FMp4
/// 编码ftyp盒子
/// </summary>
/// <returns></returns>
public byte[] EncoderFtypBox()
public byte[] FtypBox()
{
byte[] buffer = FMp4ArrayPool.Rent(1024);
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer);
@@ -82,7 +83,7 @@ namespace JT1078.FMp4
/// 编码moov盒子
/// </summary>
/// <returns></returns>
public byte[] EncoderMoovBox(in H264NALU sps, in H264NALU pps)
public byte[] VideoMoovBox(in H264NALU sps, in H264NALU pps)
{
byte[] buffer = FMp4ArrayPool.Rent(sps.RawData.Length + pps.RawData.Length + 1024);
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer);
@@ -111,7 +112,8 @@ namespace JT1078.FMp4
movieBox.TrackBox.MediaBox.MediaHeaderBox = new MediaHeaderBox();
movieBox.TrackBox.MediaBox.MediaHeaderBox.CreationTime = 0;
movieBox.TrackBox.MediaBox.MediaHeaderBox.ModificationTime = 0;
movieBox.TrackBox.MediaBox.MediaHeaderBox.Timescale = 1200000;
//movieBox.TrackBox.MediaBox.MediaHeaderBox.Timescale = 1200000;
movieBox.TrackBox.MediaBox.MediaHeaderBox.Timescale = 1000;
movieBox.TrackBox.MediaBox.MediaHeaderBox.Duration = 0;
movieBox.TrackBox.MediaBox.HandlerBox = new HandlerBox();
movieBox.TrackBox.MediaBox.HandlerBox.HandlerType = HandlerType.vide;
@@ -160,11 +162,40 @@ namespace JT1078.FMp4
}
}

/// <summary>
/// styp
/// </summary>
/// <returns></returns>
public byte[] StypBox()
{
byte[] buffer = FMp4ArrayPool.Rent(1024);
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer);
try
{
SegmentTypeBox stypTypeBox = new SegmentTypeBox();
stypTypeBox.MajorBrand = "isom";
stypTypeBox.MinorVersion = "\0\0\0\0";
stypTypeBox.CompatibleBrands.Add("isom");
stypTypeBox.CompatibleBrands.Add("mp42");
stypTypeBox.CompatibleBrands.Add("msdh");
stypTypeBox.CompatibleBrands.Add("msix");
stypTypeBox.CompatibleBrands.Add("iso5");
stypTypeBox.CompatibleBrands.Add("iso6");
stypTypeBox.ToBuffer(ref writer);
var data = writer.FlushAndGetArray();
return data;
}
finally
{
FMp4ArrayPool.Return(buffer);
}
}

/// <summary>
/// 编码其他视频数据盒子
/// </summary>
/// <returns></returns>
public byte[] EncoderOtherVideoBox(in List<H264NALU> nalus)
public byte[] OtherVideoBox(in List<H264NALU> nalus)
{
byte[] buffer = FMp4ArrayPool.Rent(nalus.Sum(s => s.RawData.Length + s.StartCodePrefix.Length) + 4096);
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer);
@@ -193,12 +224,14 @@ namespace JT1078.FMp4
{
truns.Add(new TrackRunBox.TrackRunInfo()
{
SampleDuration=40,
SampleSize = iSize,
});
iSize = 0;
}
truns.Add(new TrackRunBox.TrackRunInfo()
{
SampleDuration = 40,
SampleSize = (uint)(nalu.RawData.Length + nalu.StartCodePrefix.Length),
});
}


+ 1
- 1
src/JT1078.FMp4/JT1078.FMp4.csproj View File

@@ -14,7 +14,7 @@
<licenseUrl>https://github.com/SmallChi/JT1078/blob/master/LICENSE</licenseUrl>
<license>https://github.com/SmallChi/JT1078/blob/master/LICENSE</license>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.0.0-preview4</Version>
<Version>1.0.0-preview5</Version>
<SignAssembly>false</SignAssembly>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageLicenseFile>LICENSE</PackageLicenseFile>


+ 9
- 3
src/JT1078.FMp4/JT1078.FMp4.xml View File

@@ -1325,19 +1325,25 @@
</summary>
</member>
<member name="M:JT1078.FMp4.FMp4Encoder.EncoderFtypBox">
<member name="M:JT1078.FMp4.FMp4Encoder.FtypBox">
<summary>
编码ftyp盒子
</summary>
<returns></returns>
</member>
<member name="M:JT1078.FMp4.FMp4Encoder.EncoderMoovBox(JT1078.Protocol.H264.H264NALU@,JT1078.Protocol.H264.H264NALU@)">
<member name="M:JT1078.FMp4.FMp4Encoder.VideoMoovBox(JT1078.Protocol.H264.H264NALU@,JT1078.Protocol.H264.H264NALU@)">
<summary>
编码moov盒子
</summary>
<returns></returns>
</member>
<member name="M:JT1078.FMp4.FMp4Encoder.EncoderOtherVideoBox(System.Collections.Generic.List{JT1078.Protocol.H264.H264NALU}@)">
<member name="M:JT1078.FMp4.FMp4Encoder.StypBox">
<summary>
styp
</summary>
<returns></returns>
</member>
<member name="M:JT1078.FMp4.FMp4Encoder.OtherVideoBox(System.Collections.Generic.List{JT1078.Protocol.H264.H264NALU}@)">
<summary>
编码其他视频数据盒子
</summary>


+ 21
- 0
src/JT1078.Protocol.Test/H264/H264DecoderTest.cs View File

@@ -116,5 +116,26 @@ namespace JT1078.Protocol.Test.H264
}
fileStream.Close();
}

[Fact]
public void ParseNALUTest5()
{
string file = "jt1078_6";
var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", $"{file}.txt"));
List<H264NALU> nALUs = new List<H264NALU>();
H264Decoder decoder = new H264Decoder();
foreach (var line in lines)
{
var bytes = line.ToHexBytes();
JT1078Package package = JT1078Serializer.Deserialize(bytes);
var packageMerge = JT1078Serializer.Merge(package);
if (packageMerge != null)
{
var nalus = decoder.ParseNALU(packageMerge);
nALUs = nALUs.Concat(nalus).ToList();
}
}
var a = nALUs.Count(c => !c.Slice);
}
}
}

+ 3
- 0
src/JT1078.Protocol.Test/JT1078.Protocol.Test.csproj View File

@@ -32,5 +32,8 @@
<None Include="..\..\doc\video\jt1078_5.txt" Link="H264\jt1078_5.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\doc\video\jt1078_6.txt" Link="H264\jt1078_6.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

+ 3
- 0
src/JT1078.SignalR.Test/JT1078.SignalR.Test.csproj View File

@@ -23,5 +23,8 @@
<None Include="..\..\doc\video\jt1078_5.txt" Link="H264\jt1078_5.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\doc\video\jt1078_6.txt" Link="H264\jt1078_6.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

+ 28
- 6
src/JT1078.SignalR.Test/Services/ToWebSocketService.cs View File

@@ -53,15 +53,19 @@ namespace JT1078.SignalR.Test.Services
{
List<JT1078Package> packages = new List<JT1078Package>();
//var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_3.txt"));
var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_5.txt"));
//var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_5.txt"));
var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_6.txt"));
int mergeBodyLength = 0;
foreach (var line in lines)
{
var data = line.Split(',');
//var data = line.Split(',');
//jt1078_5
var bytes = data[1].ToHexBytes();
//var bytes = data[1].ToHexBytes();
//jt1078_3
//var bytes = data[6].ToHexBytes();
//jt1078_6
var bytes = line.ToHexBytes();

JT1078Package package = JT1078Serializer.Deserialize(bytes);
mergeBodyLength += package.DataBodyLength;
var packageMerge = JT1078Serializer.Merge(package);
@@ -74,12 +78,12 @@ namespace JT1078.SignalR.Test.Services
//var styp = fMp4Encoder.EncoderStypBox();
//first.Add(styp);
//q.Enqueue(styp);
var ftyp = fMp4Encoder.EncoderFtypBox();
var ftyp = fMp4Encoder.FtypBox();
//q.Enqueue(ftyp);
first.Add(ftyp);
var package1 = packages[0];
var nalus1 = h264Decoder.ParseNALU(package1);
var moov = fMp4Encoder.EncoderMoovBox(
var moov = fMp4Encoder.VideoMoovBox(
nalus1.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS),
nalus1.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.PPS));
//q.Enqueue(moov);
@@ -90,6 +94,23 @@ namespace JT1078.SignalR.Test.Services
foreach (var package in packages)
{
List<H264NALU> h264NALUs = h264Decoder.ParseNALU(package);
//if(package.Label3.DataType== Protocol.Enums.JT1078DataType.视频I帧)
//{
// if (nalus.Count > 0)
// {
// var otherBuffer = fMp4Encoder.OtherVideoBox(nalus);
// q.Add(fMp4Encoder.StypBox().Concat(otherBuffer).ToArray());
// nalus.Clear();
// }
// else
// {
// nalus = nalus.Concat(h264NALUs).ToList();
// }
//}
//else
//{
// nalus = nalus.Concat(h264NALUs).ToList();
//}
foreach (var nalu in h264NALUs)
{
if (nalu.Slice)
@@ -101,7 +122,8 @@ namespace JT1078.SignalR.Test.Services
{
if (nalus.Count > 0)
{
var otherBuffer = fMp4Encoder.EncoderOtherVideoBox(nalus);
q.Add(fMp4Encoder.StypBox());
var otherBuffer = fMp4Encoder.OtherVideoBox(nalus);
q.Add(otherBuffer);
nalus.Clear();
}


Loading…
Cancel
Save