Pārlūkot izejas kodu

添加fmp4盒子mvhd、mdhd、tkhd的组包及对应测试用例

tags/v1.1.0
SmallChi(Koike) pirms 4 gadiem
vecāks
revīzija
715d0eb677
12 mainītis faili ar 327 papildinājumiem un 33 dzēšanām
  1. +39
    -0
      src/JT1078.FMp4.Test/Boxs/MediaHeaderBox_Test.cs
  2. +48
    -0
      src/JT1078.FMp4.Test/Boxs/MovieHeaderBox_Test.cs
  3. +49
    -0
      src/JT1078.FMp4.Test/Boxs/TrackHeaderBox_Test.cs
  4. +2
    -2
      src/JT1078.FMp4/Boxs/FileTypeBox.cs
  5. +32
    -6
      src/JT1078.FMp4/Boxs/MediaHeaderBox.cs
  6. +46
    -5
      src/JT1078.FMp4/Boxs/MovieHeaderBox.cs
  7. +3
    -3
      src/JT1078.FMp4/Boxs/TrackBox.cs
  8. +53
    -8
      src/JT1078.FMp4/Boxs/TrackHeaderBox.cs
  9. +12
    -1
      src/JT1078.FMp4/FullBox.cs
  10. +14
    -3
      src/JT1078.FMp4/JT1078.FMp4.xml
  11. +14
    -1
      src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs
  12. +15
    -4
      src/JT1078.FMp4/Mp4Box.cs

+ 39
- 0
src/JT1078.FMp4.Test/Boxs/MediaHeaderBox_Test.cs Parādīt failu

@@ -0,0 +1,39 @@
using JT1078.FMp4.MessagePack;
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;
using JT1078.Protocol.Extensions;

namespace JT1078.FMp4.Test.Boxs
{
public class MediaHeaderBox_Test
{
/// <summary>
/// 使用doc/video/demo.mp4
/// </summary>
[Fact]
public void Test1()
{
//00 00 00 20--box size 32
//6d 64 68 64--box type mdhd
//00--version
//00 00 00--flags
//d9 3e 0b 8e--creation_time
//d9 3e 0b 8e--modification_time
//00 00 bb 80--timescale
//00 05 28 00--duration
//55 c4--(pad(1) + language(15))
//00 00--pre_defined
MediaHeaderBox movieHeaderBox = new MediaHeaderBox(version:0);
movieHeaderBox.CreationTime = 0xd93e0b8e;
movieHeaderBox.ModificationTime = 0xd93e0b8e;
movieHeaderBox.Timescale = 0x0000bb80;
movieHeaderBox.Duration = 0x00052800;
FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x6c]);
movieHeaderBox.ToBuffer(ref writer);
var hex = writer.FlushAndGetArray().ToHexString();
Assert.Equal("000000206d64686400000000d93e0b8ed93e0b8e0000bb800005280055c40000".ToUpper(), hex);
}
}
}

+ 48
- 0
src/JT1078.FMp4.Test/Boxs/MovieHeaderBox_Test.cs Parādīt failu

@@ -0,0 +1,48 @@
using JT1078.FMp4.MessagePack;
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;
using JT1078.Protocol.Extensions;

namespace JT1078.FMp4.Test.Boxs
{
public class MovieHeaderBox_Test
{
/// <summary>
/// 使用doc/video/demo.mp4
/// </summary>
[Fact]
public void Test1()
{
//00 00 00 6c--box size
//6d 76 68 64--box type mvhd
//00--version
//00 00 00--flags
//d9 3e 0b 8e--creation time
//d9 3e 0b 8e--modification time
//00 01 5f 90--time scale
//00 09 c7 e4 --duration
//00 01 00 00--rate
//01 00--volume
//00 00 00 00 00 00 00 00 00 00--保留位 10位
//00 01 00 00 00 00 00 00 00 00 00 00--matrix 视频变换矩阵36 -12
//00 00 00 00 00 01 00 00 00 00 00 00--matrix 视频变换矩阵36 -24
//00 00 00 00 00 00 00 00 40 00 00 00--matrix 视频变换矩阵36 -36
//00 00 00 00 00 00 00 00--pre - defined 24 - 8
//00 00 00 00 00 00 00 00--pre - defined 24 - 16
//00 00 00 00 00 00 00 00--pre - defined 24 - 24
//00 00 00 03--next track id
MovieHeaderBox movieHeaderBox = new MovieHeaderBox(version:0);
movieHeaderBox.CreationTime = 0xd93e0b8e;
movieHeaderBox.ModificationTime = 0xd93e0b8e;
movieHeaderBox.Timescale = 0x00015f90;
movieHeaderBox.Duration = 0x0009c7e4;
movieHeaderBox.NextTrackID = 3;
FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x6c]);
movieHeaderBox.ToBuffer(ref writer);
var hex = writer.FlushAndGetArray().ToHexString();
Assert.Equal("00 00 00 6c 6d 76 68 64 00 00 00 00 d9 3e 0b 8e d9 3e 0b 8e 00 01 5f 90 00 09 c7 e4 00 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03".Replace(" ","").ToUpper(), hex);
}
}
}

+ 49
- 0
src/JT1078.FMp4.Test/Boxs/TrackHeaderBox_Test.cs Parādīt failu

@@ -0,0 +1,49 @@
using JT1078.FMp4.MessagePack;
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;
using JT1078.Protocol.Extensions;

namespace JT1078.FMp4.Test.Boxs
{
public class TrackHeaderBox_Test
{
/// <summary>
/// 使用doc/video/demo.mp4
/// </summary>
[Fact]
public void Test1()
{
//00 00 00 5c--box size 92
//74 6b 68 64--box type tkhd
//00--version
//00 00 01--flags
//d9 3e 0b 8e--creation_time
//d9 3e 0b 8e--modification_time
//00 00 00 01--track_ID
//00 00 00 00--reserved1 保留位1
//00 09 ab 00--duration
//00 00 00 00 00 00 00 00-- reserved2 保留位2
//00 00--layer
//00 00--alternate_group
//01 00--volume
//00 00-- reserved3 保留位3
//00 01 00 00 00 00 00 00 00 00 00 00--matrix 视频变换矩阵36 -12
//00 00 00 00 00 01 00 00 00 00 00 00--matrix 视频变换矩阵36 -24
//00 00 00 00 00 00 00 00 40 00 00 00--matrix 视频变换矩阵36 -36
//00 00 00 00--width
//00 00 00 00--height
TrackHeaderBox trackHeaderBox = new TrackHeaderBox(version:0,flags:1);
trackHeaderBox.CreationTime = 0xd93e0b8e;
trackHeaderBox.ModificationTime = 0xd93e0b8e;
trackHeaderBox.TrackID = 1;
trackHeaderBox.TrackIsAudio = true;
trackHeaderBox.Duration = 0x0009ab00;
FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x6c]);
trackHeaderBox.ToBuffer(ref writer);
var hex = writer.FlushAndGetArray().ToHexString();
Assert.Equal("0000005c746b686400000001d93e0b8ed93e0b8e00000001000000000009ab00000000000000000000000000010000000001000000000000000000000000000000010000000000000000000000000000400000000000000000000000".ToUpper(), hex);
}
}
}

+ 2
- 2
src/JT1078.FMp4/Boxs/FileTypeBox.cs Parādīt failu

@@ -33,7 +33,7 @@ namespace JT1078.FMp4


public void ToBuffer(ref FMp4MessagePackWriter writer) public void ToBuffer(ref FMp4MessagePackWriter writer)
{ {
ToBuffer(ref writer,out int sizePosition);
Start(ref writer);
writer.WriteASCII(MajorBrand); writer.WriteASCII(MajorBrand);
writer.WriteASCII(MinorVersion); writer.WriteASCII(MinorVersion);
if(CompatibleBrands!=null && CompatibleBrands.Count > 0) if(CompatibleBrands!=null && CompatibleBrands.Count > 0)
@@ -43,7 +43,7 @@ namespace JT1078.FMp4
writer.WriteASCII(item); writer.WriteASCII(item);
} }
} }
writer.WriteUInt32Return((uint)(writer.GetCurrentPosition()- sizePosition), sizePosition);
End(ref writer);
} }
} }
} }

+ 32
- 6
src/JT1078.FMp4/Boxs/MediaHeaderBox.cs Parādīt failu

@@ -1,24 +1,50 @@
using System;
using JT1078.FMp4.Interfaces;
using JT1078.FMp4.MessagePack;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;


namespace JT1078.FMp4 namespace JT1078.FMp4
{ {
public class MediaHeaderBox : FullBox
public class MediaHeaderBox : FullBox, IFMp4MessagePackFormatter
{ {
public MediaHeaderBox(byte version, uint flags=0) : base("mdhd", version, flags) public MediaHeaderBox(byte version, uint flags=0) : base("mdhd", version, flags)
{ {
} }
public uint CreationTime { get; set; }
public uint ModificationTime { get; set; }
public ulong CreationTime { get; set; }
public ulong ModificationTime { get; set; }
public uint Timescale { get; set; } public uint Timescale { get; set; }
public uint Duration { get; set; } = 1;
public ulong Duration { get; set; } = 1;
//public bool Pad { get; set; } //public bool Pad { get; set; }
/// <summary> /// <summary>
/// ISO-639-2/T language code /// ISO-639-2/T language code
/// ref:doc\fmp4\ISO Language Codes.txt
/// und-undetermined /// und-undetermined
/// </summary> /// </summary>
public string Language { get; set; }
public string Language { get; set; } = "und";
public ushort PreDefined { get; set; } public ushort PreDefined { get; set; }

public void ToBuffer(ref FMp4MessagePackWriter writer)
{
Start(ref writer);
WriterToBuffer(ref writer);
if (Version == 1)
{
writer.WriteUInt64(CreationTime);
writer.WriteUInt64(ModificationTime);
writer.WriteUInt32(Timescale);
writer.WriteUInt64(Duration);
}
else
{
writer.WriteUInt32((uint)CreationTime);
writer.WriteUInt32((uint)ModificationTime);
writer.WriteUInt32(Timescale);
writer.WriteUInt32((uint)Duration);
}
writer.WriteIso639(Language);
writer.WriteUInt16(PreDefined);
End(ref writer);
}
} }
} }

+ 46
- 5
src/JT1078.FMp4/Boxs/MovieHeaderBox.cs Parādīt failu

@@ -1,18 +1,20 @@
using System;
using JT1078.FMp4.Interfaces;
using JT1078.FMp4.MessagePack;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;


namespace JT1078.FMp4 namespace JT1078.FMp4
{ {
public class MovieHeaderBox : FullBox
public class MovieHeaderBox : FullBox, IFMp4MessagePackFormatter
{ {
public MovieHeaderBox(byte version, uint flags=0) : base("mvhd", version, flags) public MovieHeaderBox(byte version, uint flags=0) : base("mvhd", version, flags)
{ {
} }
public uint CreationTime { get; set; }
public uint ModificationTime { get; set; }
public ulong CreationTime { get; set; }
public ulong ModificationTime { get; set; }
public uint Timescale { get; set;} public uint Timescale { get; set;}
public uint Duration { get; set; }
public ulong Duration { get; set; }
public int Rate { get; set; } = 0x00010000; public int Rate { get; set; } = 0x00010000;
public short Volume { get; set; } = 0x0100; public short Volume { get; set; } = 0x0100;
public byte[] Reserved1 { get; set; } = new byte[2]; public byte[] Reserved1 { get; set; } = new byte[2];
@@ -20,5 +22,44 @@ namespace JT1078.FMp4
public int[] Matrix { get; set; }=new int [9]{ 0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000 }; public int[] Matrix { get; set; }=new int [9]{ 0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000 };
public byte[] PreDefined { get; set; } = new byte[24]; public byte[] PreDefined { get; set; } = new byte[24];
public uint NextTrackID { get; set; }= uint.MaxValue; public uint NextTrackID { get; set; }= uint.MaxValue;
public void ToBuffer(ref FMp4MessagePackWriter writer)
{
Start(ref writer);
WriterToBuffer(ref writer);
if (Version == 1)
{
writer.WriteUInt64(CreationTime);
writer.WriteUInt64(ModificationTime);
writer.WriteUInt32(Timescale);
writer.WriteUInt64(Duration);
}
else
{
writer.WriteUInt32((uint)CreationTime);
writer.WriteUInt32((uint)ModificationTime);
writer.WriteUInt32(Timescale);
writer.WriteUInt32((uint)Duration);
}
writer.WriteInt32(Rate);
writer.WriteInt16(Volume);
foreach(var r in Reserved1)
{
writer.WriteByte(r);
}
foreach (var r in Reserved2)
{
writer.WriteUInt32(r);
}
foreach(var m in Matrix)
{
writer.WriteInt32(m);
}
foreach (var pd in PreDefined)
{
writer.WriteByte(pd);
}
writer.WriteUInt32(NextTrackID);
End(ref writer);
}
} }
} }

+ 3
- 3
src/JT1078.FMp4/Boxs/TrackBox.cs Parādīt failu

@@ -10,8 +10,8 @@ namespace JT1078.FMp4
{ {
} }
public TrackHeaderBox TrackHeaderBox { get; set; } public TrackHeaderBox TrackHeaderBox { get; set; }
public TrackReferenceBox TrackReferenceBox { get; set; }
public EditBox EditBox { get; set; }
public MediaBox MediaBox { get; set; }
//不是必须的 public TrackReferenceBox TrackReferenceBox { get; set; }
//不是必须的 public EditBox EditBox { get; set; }
public MediaBox MediaBox { get; set; }
} }
} }

+ 53
- 8
src/JT1078.FMp4/Boxs/TrackHeaderBox.cs Parādīt failu

@@ -1,26 +1,71 @@
using System;
using JT1078.FMp4.Interfaces;
using JT1078.FMp4.MessagePack;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;


namespace JT1078.FMp4 namespace JT1078.FMp4
{ {
public class TrackHeaderBox : FullBox
public class TrackHeaderBox : FullBox, IFMp4MessagePackFormatter
{ {
public TrackHeaderBox(byte version, uint flags) : base("tkhd", version, flags) public TrackHeaderBox(byte version, uint flags) : base("tkhd", version, flags)
{ {
} }
public uint CreationTime { get; set; }
public uint ModificationTime { get; set; }
public ulong CreationTime { get; set; }
public ulong ModificationTime { get; set; }
public uint TrackID { get; set; } public uint TrackID { get; set; }
public uint Reserved1 { get; set; } public uint Reserved1 { get; set; }
public uint Duration { get; set; }
public ulong Duration { get; set; }
public uint[] Reserved2 { get; set; } = new uint[2]; public uint[] Reserved2 { get; set; } = new uint[2];
public ushort Layer { get; set; }
public ushort AlternateGroup { get; set; }
public ushort Volume { get; set; }
public short Layer { get; set; }
public short AlternateGroup { get; set; }
public bool TrackIsAudio { get; set; } = false;
public ushort Reserved3 { get; set; } public ushort Reserved3 { get; set; }
public int[] Matrix { get; set; } = new int[9] { 0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000 }; public int[] Matrix { get; set; } = new int[9] { 0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000 };
public uint Width { get; set; } public uint Width { get; set; }
public uint Height { get; set; } public uint Height { get; set; }
public void ToBuffer(ref FMp4MessagePackWriter writer)
{
Start(ref writer);
WriterToBuffer(ref writer);
if (Version == 1)
{
writer.WriteUInt64(CreationTime);
writer.WriteUInt64(ModificationTime);
writer.WriteUInt32(TrackID);
writer.WriteUInt32(Reserved1);
writer.WriteUInt64(Duration);
}
else
{
writer.WriteUInt32((uint)CreationTime);
writer.WriteUInt32((uint)ModificationTime);
writer.WriteUInt32(TrackID);
writer.WriteUInt32(Reserved1);
writer.WriteUInt32((uint)Duration);
}
foreach(var r in Reserved2)
{
writer.WriteUInt32(r);
}
writer.WriteInt16(Layer);
writer.WriteInt16(AlternateGroup);
if (TrackIsAudio)
{
writer.WriteInt16(0x0100);
}
else
{
writer.WriteInt16(0);
}
writer.WriteUInt16(Reserved3);
foreach (var m in Matrix)
{
writer.WriteInt32(m);
}
writer.WriteUInt32(Width);
writer.WriteUInt32(Height);
End(ref writer);
}
} }
} }

+ 12
- 1
src/JT1078.FMp4/FullBox.cs Parādīt failu

@@ -1,4 +1,6 @@
using System;
using JT1078.FMp4.Interfaces;
using JT1078.FMp4.MessagePack;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;


@@ -19,5 +21,14 @@ namespace JT1078.FMp4
/// bit(24) /// bit(24)
/// </summary> /// </summary>
public uint Flags { get; set; } public uint Flags { get; set; }
/// <summary>
///
/// </summary>
/// <param name="writer"></param>
protected void WriterToBuffer(ref FMp4MessagePackWriter writer)
{
writer.WriteByte(Version);
writer.WriteUInt24(Flags);
}
} }
} }

+ 14
- 3
src/JT1078.FMp4/JT1078.FMp4.xml Parādīt failu

@@ -168,6 +168,7 @@
<member name="P:JT1078.FMp4.MediaHeaderBox.Language"> <member name="P:JT1078.FMp4.MediaHeaderBox.Language">
<summary> <summary>
ISO-639-2/T language code ISO-639-2/T language code
ref:doc\fmp4\ISO Language Codes.txt
und-undetermined und-undetermined
</summary> </summary>
</member> </member>
@@ -358,6 +359,12 @@
bit(24) bit(24)
</summary> </summary>
</member> </member>
<member name="M:JT1078.FMp4.FullBox.WriterToBuffer(JT1078.FMp4.MessagePack.FMp4MessagePackWriter@)">
<summary>
</summary>
<param name="writer"></param>
</member>
<member name="M:JT1078.FMp4.MessagePack.FMp4MessagePackReader.ReadIso639"> <member name="M:JT1078.FMp4.MessagePack.FMp4MessagePackReader.ReadIso639">
<summary> <summary>
@@ -368,7 +375,6 @@
<member name="M:JT1078.FMp4.MessagePack.FMp4MessagePackWriter.WriteIso639(System.String)"> <member name="M:JT1078.FMp4.MessagePack.FMp4MessagePackWriter.WriteIso639(System.String)">
<summary> <summary>
ref ref
<see cref="!:https://github.com/sannies/JT1078.FMp4/blob/master/isoparser/src/main/java/org/JT1078.FMp4/tools/IsoTypeWriter.java"/>
</summary> </summary>
<param name="language"></param> <param name="language"></param>
</member> </member>
@@ -382,12 +388,17 @@
盒子类型 盒子类型
</summary> </summary>
</member> </member>
<member name="M:JT1078.FMp4.Mp4Box.ToBuffer(JT1078.FMp4.MessagePack.FMp4MessagePackWriter@,System.Int32@)">
<member name="M:JT1078.FMp4.Mp4Box.Start(JT1078.FMp4.MessagePack.FMp4MessagePackWriter@)">
<summary>
</summary>
<param name="writer"></param>
</member>
<member name="M:JT1078.FMp4.Mp4Box.End(JT1078.FMp4.MessagePack.FMp4MessagePackWriter@)">
<summary> <summary>
</summary> </summary>
<param name="writer"></param> <param name="writer"></param>
<param name="sizePosition"></param>
</member> </member>
<!-- Badly formed XML comment ignored for member "P:JT1078.FMp4.Samples.AudioSampleEntry.Samplerate" --> <!-- Badly formed XML comment ignored for member "P:JT1078.FMp4.Samples.AudioSampleEntry.Samplerate" -->
</members> </members>


+ 14
- 1
src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs Parādīt failu

@@ -28,6 +28,11 @@ namespace JT1078.FMp4.MessagePack
BinaryPrimitives.WriteUInt16BigEndian(writer.Free, value); BinaryPrimitives.WriteUInt16BigEndian(writer.Free, value);
writer.Advance(2); writer.Advance(2);
} }
public void WriteInt16(short value)
{
BinaryPrimitives.WriteInt16BigEndian(writer.Free, value);
writer.Advance(2);
}
public void WriteInt32(int value) public void WriteInt32(int value)
{ {
BinaryPrimitives.WriteInt32BigEndian(writer.Free, value); BinaryPrimitives.WriteInt32BigEndian(writer.Free, value);
@@ -44,6 +49,15 @@ namespace JT1078.FMp4.MessagePack
writer.Advance(4); writer.Advance(4);
} }


public void WriteUInt24(uint value)
{
var span = writer.Free;
span[0] = (byte)(value >> 16);
span[1] = (byte)(value >> 8);
span[2] = (byte)value;
writer.Advance(3);
}

public void WriteASCII(string value) public void WriteASCII(string value)
{ {
var data = Encoding.ASCII.GetBytes(value); var data = Encoding.ASCII.GetBytes(value);
@@ -88,7 +102,6 @@ namespace JT1078.FMp4.MessagePack


/// <summary> /// <summary>
/// ref /// ref
/// <see cref="https://github.com/sannies/JT1078.FMp4/blob/master/isoparser/src/main/java/org/JT1078.FMp4/tools/IsoTypeWriter.java"/>
/// </summary> /// </summary>
/// <param name="language"></param> /// <param name="language"></param>
public void WriteIso639(string language) public void WriteIso639(string language)


+ 15
- 4
src/JT1078.FMp4/Mp4Box.cs Parādīt failu

@@ -1,4 +1,5 @@
using JT1078.FMp4.MessagePack;
using JT1078.FMp4.Interfaces;
using JT1078.FMp4.MessagePack;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@@ -9,7 +10,7 @@ namespace JT1078.FMp4
{ {
//public const string UUID = "uuid"; //public const string UUID = "uuid";


public const int FixedSizeLength = 4;
const int FixedSizeLength = 4;


public Mp4Box(string boxType) public Mp4Box(string boxType)
{ {
@@ -49,15 +50,25 @@ namespace JT1078.FMp4
///// </summary> ///// </summary>
//public string UserType { get; set; } //public string UserType { get; set; }


private int sizePosition;

/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="writer"></param> /// <param name="writer"></param>
/// <param name="sizePosition"></param>
public void ToBuffer(ref FMp4MessagePackWriter writer, out int sizePosition)
public void Start(ref FMp4MessagePackWriter writer)
{ {
writer.Skip(FixedSizeLength, out sizePosition); writer.Skip(FixedSizeLength, out sizePosition);
writer.WriteASCII(BoxType); writer.WriteASCII(BoxType);
} }
/// <summary>
///
/// </summary>
/// <param name="writer"></param>
public void End(ref FMp4MessagePackWriter writer)
{
writer.WriteUInt32Return((uint)(writer.GetCurrentPosition() - sizePosition), sizePosition);
}
} }
} }

Notiek ielāde…
Atcelt
Saglabāt