From 1c78cba18679e130454d9f82a18752e849fd1b4c Mon Sep 17 00:00:00 2001
From: "SmallChi(Koike)" <564952747@qq.com>
Date: Thu, 18 Mar 2021 18:23:27 +0800
Subject: [PATCH] =?UTF-8?q?=E5=B0=861078=E8=BD=ACfmp4=5F3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/JT1078.FMp4.Test/H264/placeholder.txt | 1 +
src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj | 4 +
src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs | 139 +++++++++++++-----
src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs | 3 +-
src/JT1078.FMp4/Boxs/HandlerBox.cs | 10 +-
src/JT1078.FMp4/Boxs/MediaDataBox.cs | 14 +-
src/JT1078.FMp4/Boxs/MediaHeaderBox.cs | 2 +-
src/JT1078.FMp4/Boxs/MovieBox.cs | 8 +
.../MovieFragmentRandomAccessOffsetBox.cs | 4 +-
src/JT1078.FMp4/Boxs/MovieHeaderBox.cs | 2 +-
.../TrackFragmentBaseMediaDecodeTimeBox.cs | 11 +-
.../Boxs/TrackFragmentHeaderBox.cs | 1 +
.../Boxs/TrackFragmentRandomAccessBox.cs | 6 +
src/JT1078.FMp4/Boxs/TrackHeaderBox.cs | 17 ++-
src/JT1078.FMp4/Boxs/UserDataBox.cs | 18 ++-
src/JT1078.FMp4/FMp4Box.cs | 4 +
src/JT1078.FMp4/JT1078.FMp4.xml | 21 +++
.../MessagePack/FMp4MessagePackWriter.cs | 6 +
18 files changed, 222 insertions(+), 49 deletions(-)
create mode 100644 src/JT1078.FMp4.Test/H264/placeholder.txt
diff --git a/src/JT1078.FMp4.Test/H264/placeholder.txt b/src/JT1078.FMp4.Test/H264/placeholder.txt
new file mode 100644
index 0000000..c3833e4
--- /dev/null
+++ b/src/JT1078.FMp4.Test/H264/placeholder.txt
@@ -0,0 +1 @@
+placeholder
\ No newline at end of file
diff --git a/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj b/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj
index 026873a..4587528 100644
--- a/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj
+++ b/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj
@@ -30,6 +30,7 @@
Always
+
@@ -51,6 +52,9 @@
Always
+
+ Always
+
diff --git a/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs b/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs
index afe89ec..48ed35e 100644
--- a/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs
+++ b/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs
@@ -5,6 +5,7 @@ using JT1078.Protocol;
using JT1078.Protocol.Extensions;
using JT1078.Protocol.H264;
using System;
+using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -38,34 +39,27 @@ namespace JT1078.FMp4.Test
fileTypeBox.CompatibleBrands.Add("mp41");
//moov
MovieBox movieBox = new MovieBox();
- movieBox.MovieHeaderBox = new MovieHeaderBox(1, 0);
- movieBox.MovieHeaderBox.CreationTime = 2;
- movieBox.MovieHeaderBox.ModificationTime = 3;
- //var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
- //var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
- movieBox.MovieHeaderBox.Duration = 1;
+ movieBox.MovieHeaderBox = new MovieHeaderBox(0, 0);
+ movieBox.MovieHeaderBox.CreationTime = 0;
+ movieBox.MovieHeaderBox.ModificationTime = 0;
+ movieBox.MovieHeaderBox.Duration = 0;
movieBox.MovieHeaderBox.Timescale = 1000;
+ movieBox.MovieHeaderBox.NextTrackID = 2;
movieBox.TrackBox = new TrackBox();
- movieBox.TrackBox.TrackHeaderBox = new TrackHeaderBox(1, 7);
- movieBox.TrackBox.TrackHeaderBox.CreationTime = 2;
- movieBox.TrackBox.TrackHeaderBox.ModificationTime = 3;
- movieBox.TrackBox.TrackHeaderBox.TrackID = movieBox.MovieHeaderBox.NextTrackID;
- //duration = track.duration * track.timescale,
- //upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)),
- //lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
+ movieBox.TrackBox.TrackHeaderBox = new TrackHeaderBox(0, 3);
+ movieBox.TrackBox.TrackHeaderBox.CreationTime = 0;
+ movieBox.TrackBox.TrackHeaderBox.ModificationTime = 0;
+ movieBox.TrackBox.TrackHeaderBox.TrackID = 1;
movieBox.TrackBox.TrackHeaderBox.Duration = 0;
movieBox.TrackBox.TrackHeaderBox.TrackIsAudio = false;
movieBox.TrackBox.TrackHeaderBox.Width = 352;
movieBox.TrackBox.TrackHeaderBox.Height = 288;
movieBox.TrackBox.MediaBox = new MediaBox();
movieBox.TrackBox.MediaBox.MediaHeaderBox = new MediaHeaderBox();
- //duration *= timescale;
- //var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
- //var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
- movieBox.TrackBox.MediaBox.MediaHeaderBox.CreationTime = 2;
- movieBox.TrackBox.MediaBox.MediaHeaderBox.ModificationTime = 3;
- movieBox.TrackBox.MediaBox.MediaHeaderBox.Timescale = 1000;
- movieBox.TrackBox.MediaBox.MediaHeaderBox.Duration = 1;
+ movieBox.TrackBox.MediaBox.MediaHeaderBox.CreationTime = 0;
+ movieBox.TrackBox.MediaBox.MediaHeaderBox.ModificationTime = 0;
+ movieBox.TrackBox.MediaBox.MediaHeaderBox.Timescale = 1200000;
+ movieBox.TrackBox.MediaBox.MediaHeaderBox.Duration = 0;
movieBox.TrackBox.MediaBox.HandlerBox = new HandlerBox();
movieBox.TrackBox.MediaBox.HandlerBox.HandlerType = HandlerType.vide;
movieBox.TrackBox.MediaBox.HandlerBox.Name = "VideoHandler";
@@ -85,7 +79,10 @@ namespace JT1078.FMp4.Test
avc1.Height = (ushort)movieBox.TrackBox.TrackHeaderBox.Height;
avc1.AVCConfigurationBox.AVCLevelIndication = 20;
avc1.AVCConfigurationBox.AVCProfileIndication = 77;
- avc1.AVCConfigurationBox.PPSs = new List() { ppsNALU.RawData };
+ //todo:pps解析多一位
+ var a = ppsNALU.RawData.ToList();
+ a.Add(0);
+ avc1.AVCConfigurationBox.PPSs = new List() { a.ToArray() };
avc1.AVCConfigurationBox.SPSs = new List() { spsNALU.RawData };
avc1.AVCConfigurationBox.ProfileCompatibility = 0;
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1);
@@ -96,46 +93,68 @@ namespace JT1078.FMp4.Test
movieBox.MovieExtendsBox = new MovieExtendsBox();
movieBox.MovieExtendsBox.TrackExtendsBoxs = new List();
TrackExtendsBox trex = new TrackExtendsBox();
- trex.TrackID = movieBox.MovieHeaderBox.NextTrackID;
+ trex.TrackID = 1;
trex.DefaultSampleDescriptionIndex = 1;
trex.DefaultSampleDuration = 0;
trex.DefaultSampleSize = 0;
- trex.DefaultSampleFlags = 1;
+ trex.DefaultSampleFlags = 0;
movieBox.MovieExtendsBox.TrackExtendsBoxs.Add(trex);
+ //用户自定义可以不用
+ //movieBox.UserDataBox = new UserDataBox();
+ //movieBox.UserDataBox.Data = "0000005a6d657461000000000000002168646c7200000000000000006d6469726170706c0000000000000000000000002d696c737400000025a9746f6f0000001d6461746100000001000000004c61766635382e34352e313030".ToHexBytes();
//fragment moof n
List moofs = new List();
FragmentBox fragmentBox = new FragmentBox();
fragmentBox.MovieFragmentBox = new MovieFragmentBox();
fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox = new MovieFragmentHeaderBox();
- fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = 0;
+ fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = 1;
fragmentBox.MovieFragmentBox.TrackFragmentBox = new TrackFragmentBox();
- fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox();
- fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = movieBox.MovieHeaderBox.NextTrackID;
- fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox = new SampleDependencyTypeBox();
- fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes = new List();
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x39);
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 1;
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.BaseDataOffset = 0x000000000000028c;
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = 48000;
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)jT1078Package.Bodies.Length;
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000;
+ //fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox = new SampleDependencyTypeBox();
+ //fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes = new List();
//todo:fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox();
//upperWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)),
//lowerWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1));
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = 0;
//trun
- fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox();
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 0x5);
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.DataOffset = 120;
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 33554432;
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List();
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo());
fragmentBox.MediaDataBox = new MediaDataBox();
- var nalUnitTypes = new List() { 7, 8 };
fragmentBox.MediaDataBox.Data = nalus
- .Where(w => !nalUnitTypes.Contains(w.NALUHeader.NalUnitType))
.Select(s => s.RawData)
- .SelectMany(a => a)
- .ToArray();
+ .ToList();
moofs.Add(fragmentBox);
-
-
//mfra
+ MovieFragmentRandomAccessBox movieFragmentRandomAccessBox = new MovieFragmentRandomAccessBox();
+ //mfra->tfra
+ movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox = new TrackFragmentRandomAccessBox(1);
+ movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackID = 0x01;
+ movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos = new List();
+ TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo trackFragmentRandomAccessInfo1 = new TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo();
+ trackFragmentRandomAccessInfo1.Time = 0;
+ trackFragmentRandomAccessInfo1.MoofOffset = 0x000000000000028c;
+ trackFragmentRandomAccessInfo1.TrafNumber = 0x01;
+ trackFragmentRandomAccessInfo1.TrunNumber = 0x01;
+ trackFragmentRandomAccessInfo1.SampleNumber = 0x01;
+ movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos.Add(trackFragmentRandomAccessInfo1);
+ //mfra->mfro
+ movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox = new MovieFragmentRandomAccessOffsetBox(0);
+ movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox.MfraSize = 0x00000043;
FMp4Box fMp4Box = new FMp4Box();
fMp4Box.FileTypeBox = fileTypeBox;
fMp4Box.MovieBox = movieBox;
fMp4Box.FragmentBoxs = moofs;
+ fMp4Box.MovieFragmentRandomAccessBox = movieFragmentRandomAccessBox;
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[65535]);
fMp4Box.ToBuffer(ref writer);
var buffer = writer.FlushAndGetArray();
@@ -147,9 +166,59 @@ namespace JT1078.FMp4.Test
using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
fileStream.Write(buffer);
fileStream.Close();
+ }
+
+ [Fact]
+ public void tkhd_width_height_test()
+ {
+ //01 60 00 00
+ //01 20 00 00
+ var a = BinaryPrimitives.ReadUInt32LittleEndian(new byte[] { 0x01, 0x60, 0, 0 });
+ var b = BinaryPrimitives.ReadUInt32LittleEndian(new byte[] { 0x01, 0x20, 0, 0 });
+
+ //00 00 01 60
+ //00 00 01 20
+ var c = BinaryPrimitives.ReadUInt32BigEndian(new byte[] { 0, 0, 0x01, 0x20 });
+ var d = BinaryPrimitives.ReadUInt32BigEndian(new byte[] { 0, 0, 0x01, 0x60 });
+
+ var e = new byte[4];
+ var f = new byte[4];
+ BinaryPrimitives.WriteUInt32LittleEndian(e, 352);
+ BinaryPrimitives.WriteUInt32LittleEndian(f, 288);
+ //60 01 00 00
+ //20 01 00 00
+ var g = e.ToHexString();
+ var h = f.ToHexString();
+ }
+ [Fact]
+ public void tfdt_test()
+ {
+ var TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox();
+ TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = 0;
+ FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[65535]);
+ TrackFragmentBaseMediaDecodeTimeBox.ToBuffer(ref writer);
+ var buffer = writer.FlushAndGetArray().ToHexString();
}
+ [Fact]
+ public void match_test()
+ {
+ var filepath1 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_1.mp4");
+ var filepath2 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_1_fragmented.mp4");
+ var byte1=File.ReadAllBytes(filepath1);
+ var byte2=File.ReadAllBytes(filepath2);
+ if(byte1.Length== byte2.Length)
+ {
+ for(var i=0;i< byte1.Length; i++)
+ {
+ if (byte1[i] != byte2[i])
+ {
+
+ }
+ }
+ }
+ }
public JT1078Package ParseNALUTest()
{
diff --git a/src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs b/src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs
index 676d4ec..e84b9d3 100644
--- a/src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs
+++ b/src/JT1078.FMp4/Boxs/AVCConfigurationBox.cs
@@ -62,7 +62,8 @@ namespace JT1078.FMp4
writer.WriteByte(AVCProfileIndication);
writer.WriteByte(ProfileCompatibility);
writer.WriteByte(AVCLevelIndication);
- writer.WriteByte((byte)(0xfc | LengthSizeMinusOne));
+ //writer.WriteByte((byte)(0xfc | LengthSizeMinusOne));
+ writer.WriteByte(0xff);
if (SPSs!=null && SPSs.Count > 0)
{
//NumOfSequenceParameterSets
diff --git a/src/JT1078.FMp4/Boxs/HandlerBox.cs b/src/JT1078.FMp4/Boxs/HandlerBox.cs
index a5400e3..c2fed40 100644
--- a/src/JT1078.FMp4/Boxs/HandlerBox.cs
+++ b/src/JT1078.FMp4/Boxs/HandlerBox.cs
@@ -43,7 +43,15 @@ namespace JT1078.FMp4
{
writer.WriteUInt32(r);
}
- writer.WriteUTF8(Name??"\0");
+ if (!string.IsNullOrEmpty(Name))
+ {
+ writer.WriteUTF8(Name);
+ writer.WriteUTF8("\0");
+ }
+ else
+ {
+ writer.WriteUTF8("\0");
+ }
End(ref writer);
}
}
diff --git a/src/JT1078.FMp4/Boxs/MediaDataBox.cs b/src/JT1078.FMp4/Boxs/MediaDataBox.cs
index f826a95..e107f41 100644
--- a/src/JT1078.FMp4/Boxs/MediaDataBox.cs
+++ b/src/JT1078.FMp4/Boxs/MediaDataBox.cs
@@ -23,14 +23,22 @@ namespace JT1078.FMp4
/// Filter out AUD/SPS/PPS NAL units from your stream
/// Write you converted NAL units into the MDAT box
///
- public byte[] Data { get; set; }
+ public List Data { get; set; }
public void ToBuffer(ref FMp4MessagePackWriter writer)
{
Start(ref writer);
- if (Data != null && Data.Length > 0)
+
+ if (Data != null && Data.Count > 0)
{
- writer.WriteArray(Data);
+ foreach(var nalu in Data)
+ {
+ if(nalu!=null && nalu.Length > 0)
+ {
+ writer.WriteInt32(nalu.Length);
+ writer.WriteArray(nalu);
+ }
+ }
}
End(ref writer);
}
diff --git a/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs b/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs
index e0fd9ed..6c523ba 100644
--- a/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs
+++ b/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs
@@ -16,7 +16,7 @@ namespace JT1078.FMp4
///
///
///
- public MediaHeaderBox(byte version=1, uint flags=0) : base("mdhd", version, flags)
+ public MediaHeaderBox(byte version=0, uint flags=0) : base("mdhd", version, flags)
{
}
public ulong CreationTime { get; set; }
diff --git a/src/JT1078.FMp4/Boxs/MovieBox.cs b/src/JT1078.FMp4/Boxs/MovieBox.cs
index d8530d2..231fbb7 100644
--- a/src/JT1078.FMp4/Boxs/MovieBox.cs
+++ b/src/JT1078.FMp4/Boxs/MovieBox.cs
@@ -30,6 +30,10 @@ namespace JT1078.FMp4
/// mvex
///
public MovieExtendsBox MovieExtendsBox { get; set; }
+ ///
+ /// udta
+ ///
+ public UserDataBox UserDataBox { get; set; }
public void ToBuffer(ref FMp4MessagePackWriter writer)
{
@@ -37,6 +41,10 @@ namespace JT1078.FMp4
MovieHeaderBox.ToBuffer(ref writer);
TrackBox.ToBuffer(ref writer);
MovieExtendsBox.ToBuffer(ref writer);
+ if (UserDataBox != null)
+ {
+ UserDataBox.ToBuffer(ref writer);
+ }
End(ref writer);
}
}
diff --git a/src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs b/src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs
index 28da638..105ad7e 100644
--- a/src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs
+++ b/src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs
@@ -19,7 +19,9 @@ namespace JT1078.FMp4
public MovieFragmentRandomAccessOffsetBox(byte version, uint flags=0) : base("mfro", version, flags)
{
}
-
+ ///
+ /// mfra 盒子大小
+ ///
public uint MfraSize { get; set; }
public void ToBuffer(ref FMp4MessagePackWriter writer)
diff --git a/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs b/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs
index 7a73c98..e330ccc 100644
--- a/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs
+++ b/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs
@@ -16,7 +16,7 @@ namespace JT1078.FMp4
///
///
///
- public MovieHeaderBox(byte version=1, uint flags=0) : base("mvhd", version, flags)
+ public MovieHeaderBox(byte version, uint flags=0) : base("mvhd", version, flags)
{
}
public ulong CreationTime { get; set; }
diff --git a/src/JT1078.FMp4/Boxs/TrackFragmentBaseMediaDecodeTimeBox.cs b/src/JT1078.FMp4/Boxs/TrackFragmentBaseMediaDecodeTimeBox.cs
index b5c14b8..5fbc75c 100644
--- a/src/JT1078.FMp4/Boxs/TrackFragmentBaseMediaDecodeTimeBox.cs
+++ b/src/JT1078.FMp4/Boxs/TrackFragmentBaseMediaDecodeTimeBox.cs
@@ -19,13 +19,20 @@ namespace JT1078.FMp4
public TrackFragmentBaseMediaDecodeTimeBox(byte version=1, uint flags=0) : base("tfdt", version, flags)
{
}
- public uint BaseMediaDecodeTime { get; set; }
+ public ulong BaseMediaDecodeTime { get; set; }
public void ToBuffer(ref FMp4MessagePackWriter writer)
{
Start(ref writer);
WriterFullBoxToBuffer(ref writer);
- writer.WriteUInt32(BaseMediaDecodeTime);
+ if (Version == 1)
+ {
+ writer.WriteUInt64(BaseMediaDecodeTime);
+ }
+ else
+ {
+ writer.WriteUInt32((uint)BaseMediaDecodeTime);
+ }
End(ref writer);
}
}
diff --git a/src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs b/src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs
index f293e7e..290d8ed 100644
--- a/src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs
+++ b/src/JT1078.FMp4/Boxs/TrackFragmentHeaderBox.cs
@@ -44,6 +44,7 @@ namespace JT1078.FMp4
public uint DefaultSampleDuration { get; set; }
///
/// TFHD_FLAG_DEFAULT_SIZE
+ /// H.264 NALU SIZE
///
public uint DefaultSampleSize { get; set; }
///
diff --git a/src/JT1078.FMp4/Boxs/TrackFragmentRandomAccessBox.cs b/src/JT1078.FMp4/Boxs/TrackFragmentRandomAccessBox.cs
index 1bf9f1e..50b9151 100644
--- a/src/JT1078.FMp4/Boxs/TrackFragmentRandomAccessBox.cs
+++ b/src/JT1078.FMp4/Boxs/TrackFragmentRandomAccessBox.cs
@@ -37,6 +37,9 @@ namespace JT1078.FMp4
///
public byte LengthSizeOfSampleNum { get; set; }
public uint NumberOfEntry { get; set; }
+ ///
+ /// (moof+mdta)N
+ ///
public List TrackFragmentRandomAccessInfos { get; set; }
public void ToBuffer(ref FMp4MessagePackWriter writer)
@@ -97,6 +100,9 @@ namespace JT1078.FMp4
public class TrackFragmentRandomAccessInfo
{
public ulong Time { get; set; }
+ ///
+ /// 需要定位到当前 moof offset
+ ///
public ulong MoofOffset { get; set; }
public uint TrafNumber { get; set; }
public uint TrunNumber { get; set; }
diff --git a/src/JT1078.FMp4/Boxs/TrackHeaderBox.cs b/src/JT1078.FMp4/Boxs/TrackHeaderBox.cs
index 05e494a..1ef424c 100644
--- a/src/JT1078.FMp4/Boxs/TrackHeaderBox.cs
+++ b/src/JT1078.FMp4/Boxs/TrackHeaderBox.cs
@@ -82,8 +82,21 @@ namespace JT1078.FMp4
{
writer.WriteInt32(m);
}
- writer.WriteUInt32(Width);
- writer.WriteUInt32(Height);
+ //好奇葩的解析方式
+ //实际
+ //01 60 00 00
+ //01 20 00 00
+ //32位大端
+ //00 00 01 60
+ //00 00 01 20
+ //32位小端
+ //60 01 00 00
+ //20 01 00 00
+ //直接用32位去解析是解析不出来的。
+ writer.WriteUInt16((ushort)Width);
+ writer.WriteUInt16(0);
+ writer.WriteUInt16((ushort)Height);
+ writer.WriteUInt16(0);
End(ref writer);
}
}
diff --git a/src/JT1078.FMp4/Boxs/UserDataBox.cs b/src/JT1078.FMp4/Boxs/UserDataBox.cs
index 7abf7f9..2d1f250 100644
--- a/src/JT1078.FMp4/Boxs/UserDataBox.cs
+++ b/src/JT1078.FMp4/Boxs/UserDataBox.cs
@@ -1,13 +1,27 @@
-using System;
+using JT1078.FMp4.Interfaces;
+using JT1078.FMp4.MessagePack;
+using System;
using System.Collections.Generic;
using System.Text;
namespace JT1078.FMp4
{
- public class UserDataBox : Mp4Box
+ public class UserDataBox : Mp4Box, IFMp4MessagePackFormatter
{
public UserDataBox() : base("udta")
{
}
+
+ public byte[] Data { get; set; }
+
+ public void ToBuffer(ref FMp4MessagePackWriter writer)
+ {
+ Start(ref writer);
+ if(Data!=null && Data.Length > 0)
+ {
+ writer.WriteArray(Data);
+ }
+ End(ref writer);
+ }
}
}
diff --git a/src/JT1078.FMp4/FMp4Box.cs b/src/JT1078.FMp4/FMp4Box.cs
index 19b86e7..3957d7a 100644
--- a/src/JT1078.FMp4/FMp4Box.cs
+++ b/src/JT1078.FMp4/FMp4Box.cs
@@ -52,6 +52,10 @@ namespace JT1078.FMp4
item.MediaDataBox.ToBuffer(ref writer);
}
}
+ if (MovieFragmentRandomAccessBox != null)
+ {
+ MovieFragmentRandomAccessBox.ToBuffer(ref writer);
+ }
}
}
}
diff --git a/src/JT1078.FMp4/JT1078.FMp4.xml b/src/JT1078.FMp4/JT1078.FMp4.xml
index a787863..6e97545 100644
--- a/src/JT1078.FMp4/JT1078.FMp4.xml
+++ b/src/JT1078.FMp4/JT1078.FMp4.xml
@@ -386,6 +386,11 @@
mvex
+
+
+ udta
+
+
mvex
@@ -482,6 +487,11 @@
+
+
+ mfra 盒子大小
+
+
mvhd
@@ -892,6 +902,7 @@
TFHD_FLAG_DEFAULT_SIZE
+ H.264 NALU SIZE
@@ -931,6 +942,16 @@
2bit
+
+
+ (moof+mdta)N
+
+
+
+
+ 需要定位到当前 moof offset
+
+
tkhd
diff --git a/src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs b/src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs
index d12cbcc..ddeab4e 100644
--- a/src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs
+++ b/src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs
@@ -49,6 +49,12 @@ namespace JT1078.FMp4.MessagePack
writer.Advance(4);
}
+ public void WriteUInt32Little(uint value)
+ {
+ BinaryPrimitives.WriteUInt32LittleEndian(writer.Free, value);
+ writer.Advance(4);
+ }
+
public void WriteUInt24(uint value)
{
var span = writer.Free;