ソースを参照

将1078转fmp4_6

pull/14/head
SmallChi(Koike) 4年前
コミット
ee59551674
8個のファイルの変更367行の追加8行の削除
  1. +284
    -0
      src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs
  2. +6
    -0
      src/JT1078.FMp4/Boxs/MovieFragmentBox.cs
  3. +6
    -0
      src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessBox.cs
  4. +11
    -1
      src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs
  5. +11
    -1
      src/JT1078.FMp4/Boxs/TrackRunBox.cs
  6. +6
    -1
      src/JT1078.FMp4/JT1078.FMp4.xml
  7. +37
    -1
      src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs
  8. +6
    -4
      src/JT1078.FMp4/Mp4Box.cs

+ 284
- 0
src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs ファイルの表示

@@ -4,6 +4,7 @@ using JT1078.FMp4.Samples;
using JT1078.Protocol;
using JT1078.Protocol.Extensions;
using JT1078.Protocol.H264;
using JT1078.Protocol.MessagePack;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
@@ -166,6 +167,269 @@ namespace JT1078.FMp4.Test
fileStream.Close();
}

[Fact]
public void Test2()
{
var jT1078Package = ParseNALUTest();
H264Decoder decoder = new H264Decoder();
var nalus = decoder.ParseNALU(jT1078Package);
var spsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 7);
//SPS
spsNALU.RawData = decoder.DiscardEmulationPreventionBytes(spsNALU.RawData);
var ppsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 8);
ppsNALU.RawData = decoder.DiscardEmulationPreventionBytes(ppsNALU.RawData);
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[65535]);
//ftyp
FileTypeBox fileTypeBox = new FileTypeBox();
fileTypeBox.MajorBrand = "isom";
fileTypeBox.MinorVersion = "\0\0\u0002\0";
fileTypeBox.CompatibleBrands.Add("isom");
fileTypeBox.CompatibleBrands.Add("iso6");
fileTypeBox.CompatibleBrands.Add("iso2");
fileTypeBox.CompatibleBrands.Add("avc1");
fileTypeBox.CompatibleBrands.Add("mp41");
//moov
MovieBox movieBox = new MovieBox();
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(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();
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";
movieBox.TrackBox.MediaBox.MediaInformationBox = new MediaInformationBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.VideoMediaHeaderBox = new VideoMediaHeaderBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox = new DataInformationBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox = new DataReferenceBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List<DataEntryBox>();
movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1));
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType);
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List<SampleEntry>();
AVC1SampleEntry avc1 = new AVC1SampleEntry();
avc1.AVCConfigurationBox = new AVCConfigurationBox();
//h264
avc1.Width = (ushort)movieBox.TrackBox.TrackHeaderBox.Width;
avc1.Height = (ushort)movieBox.TrackBox.TrackHeaderBox.Height;
avc1.AVCConfigurationBox.AVCLevelIndication = 20;
avc1.AVCConfigurationBox.AVCProfileIndication = 77;
avc1.AVCConfigurationBox.PPSs = new List<byte[]>() { ppsNALU.RawData };
avc1.AVCConfigurationBox.SPSs = new List<byte[]>() { spsNALU.RawData };
avc1.AVCConfigurationBox.ProfileCompatibility = 0;
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1);
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox = new TimeToSampleBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleToChunkBox = new SampleToChunkBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox();
movieBox.MovieExtendsBox = new MovieExtendsBox();
movieBox.MovieExtendsBox.TrackExtendsBoxs = new List<TrackExtendsBox>();
TrackExtendsBox trex = new TrackExtendsBox();
trex.TrackID = 1;
trex.DefaultSampleDescriptionIndex = 1;
trex.DefaultSampleDuration = 0;
trex.DefaultSampleSize = 0;
trex.DefaultSampleFlags = 0;
movieBox.MovieExtendsBox.TrackExtendsBoxs.Add(trex);
fileTypeBox.ToBuffer(ref writer);
movieBox.ToBuffer(ref writer);

//fragment moof n
List<FragmentBox> moofs = new List<FragmentBox>();
ulong moofOffset = (ulong)writer.GetCurrentPosition();
FragmentBox fragmentBox = new FragmentBox();
fragmentBox.MovieFragmentBox = new MovieFragmentBox();
fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox = new MovieFragmentHeaderBox();
fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = 1;
fragmentBox.MovieFragmentBox.TrackFragmentBox = new TrackFragmentBox();
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x39);
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 1;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.BaseDataOffset = moofOffset;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = 48000;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)jT1078Package.Bodies.Length;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox();
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = 0;
//trun
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 0x5);
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 0;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List<TrackRunBox.TrackRunInfo>();
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo());
fragmentBox.MediaDataBox = new MediaDataBox();
fragmentBox.MediaDataBox.Data = nalus.Select(s => s.RawData).ToList();
moofs.Add(fragmentBox);
foreach(var moof in moofs)
{
moof.ToBuffer(ref writer);
}
//mfra
MovieFragmentRandomAccessBox movieFragmentRandomAccessBox = new MovieFragmentRandomAccessBox();
//mfra->tfra
movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox = new TrackFragmentRandomAccessBox(1);
movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackID = 0x01;
movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos = new List<TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo>();
TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo trackFragmentRandomAccessInfo1 = new TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo();
trackFragmentRandomAccessInfo1.Time = 0;
trackFragmentRandomAccessInfo1.MoofOffset = moofOffset;
trackFragmentRandomAccessInfo1.TrafNumber = 0x01;
trackFragmentRandomAccessInfo1.TrunNumber = 0x01;
trackFragmentRandomAccessInfo1.SampleNumber = 0x01;
movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos.Add(trackFragmentRandomAccessInfo1);
//mfra->mfro
movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox = new MovieFragmentRandomAccessOffsetBox(0);
movieFragmentRandomAccessBox.ToBuffer(ref writer);
var buffer = writer.FlushAndGetArray();

var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_2.mp4");
if (File.Exists(filepath))
{
File.Delete(filepath);
}
using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
fileStream.Write(buffer);
fileStream.Close();
}

[Fact]
public void Test3()
{
H264Decoder decoder = new H264Decoder();
var packages = ParseNALUTests();
//10M
FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[10 * 1024 * 1024]);
var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_3.mp4");
if (File.Exists(filepath))
{
File.Delete(filepath);
}
using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
var jT1078Package = packages.FirstOrDefault();
var nalus = decoder.ParseNALU(jT1078Package);
var spsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 7);
//SPS
spsNALU.RawData = decoder.DiscardEmulationPreventionBytes(spsNALU.RawData);
var ppsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 8);
ppsNALU.RawData = decoder.DiscardEmulationPreventionBytes(ppsNALU.RawData);
ExpGolombReader h264GolombReader = new ExpGolombReader(spsNALU.RawData);
var spsInfo = h264GolombReader.ReadSPS();
//ftyp
FileTypeBox fileTypeBox = new FileTypeBox();
fileTypeBox.MajorBrand = "isom";
fileTypeBox.MinorVersion = "\0\0\u0002\0";
fileTypeBox.CompatibleBrands.Add("isom");
fileTypeBox.CompatibleBrands.Add("iso6");
fileTypeBox.CompatibleBrands.Add("iso2");
fileTypeBox.CompatibleBrands.Add("avc1");
fileTypeBox.CompatibleBrands.Add("mp41");
//moov
MovieBox movieBox = new MovieBox();
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(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 = (uint)spsInfo.width;
movieBox.TrackBox.TrackHeaderBox.Height = (uint)spsInfo.height;
movieBox.TrackBox.MediaBox = new MediaBox();
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.Duration = 0;
movieBox.TrackBox.MediaBox.HandlerBox = new HandlerBox();
movieBox.TrackBox.MediaBox.HandlerBox.HandlerType = HandlerType.vide;
movieBox.TrackBox.MediaBox.HandlerBox.Name = "VideoHandler";
movieBox.TrackBox.MediaBox.MediaInformationBox = new MediaInformationBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.VideoMediaHeaderBox = new VideoMediaHeaderBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox = new DataInformationBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox = new DataReferenceBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List<DataEntryBox>();
movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1));
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType);
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List<SampleEntry>();
AVC1SampleEntry avc1 = new AVC1SampleEntry();
avc1.AVCConfigurationBox = new AVCConfigurationBox();
//h264
avc1.Width = (ushort)movieBox.TrackBox.TrackHeaderBox.Width;
avc1.Height = (ushort)movieBox.TrackBox.TrackHeaderBox.Height;
avc1.AVCConfigurationBox.AVCLevelIndication = spsInfo.levelIdc;
avc1.AVCConfigurationBox.AVCProfileIndication = spsInfo.profileIdc;
avc1.AVCConfigurationBox.ProfileCompatibility = (byte)spsInfo.profileCompat;
avc1.AVCConfigurationBox.PPSs = new List<byte[]>() { ppsNALU.RawData };
avc1.AVCConfigurationBox.SPSs = new List<byte[]>() { spsNALU.RawData };
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1);
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox = new TimeToSampleBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleToChunkBox = new SampleToChunkBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox();
movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox();
movieBox.MovieExtendsBox = new MovieExtendsBox();
movieBox.MovieExtendsBox.TrackExtendsBoxs = new List<TrackExtendsBox>();
TrackExtendsBox trex = new TrackExtendsBox();
trex.TrackID = 1;
trex.DefaultSampleDescriptionIndex = 1;
trex.DefaultSampleDuration = 0;
trex.DefaultSampleSize = 0;
trex.DefaultSampleFlags = 0;
movieBox.MovieExtendsBox.TrackExtendsBoxs.Add(trex);
fileTypeBox.ToBuffer(ref writer);
movieBox.ToBuffer(ref writer);
//fragment moof n
foreach (var package in packages)
{
ulong moofOffset = (ulong)writer.GetCurrentPosition();
var package_nalus = decoder.ParseNALU(package);
FragmentBox fragmentBox = new FragmentBox();
fragmentBox.MovieFragmentBox = new MovieFragmentBox();
fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox = new MovieFragmentHeaderBox();
fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = package.SN;
fragmentBox.MovieFragmentBox.TrackFragmentBox = new TrackFragmentBox();
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x39);
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 1;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.BaseDataOffset = moofOffset;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = 48000;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)package.Bodies.Length;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox();
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = package.Timestamp;
//trun
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 0x5);
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 0;
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List<TrackRunBox.TrackRunInfo>();
fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo());
fragmentBox.MediaDataBox = new MediaDataBox();
fragmentBox.MediaDataBox.Data = package_nalus.Select(s => s.RawData).ToList();
fragmentBox.ToBuffer(ref writer);
}
var buffer = writer.FlushAndGetArray();
fileStream.Write(buffer);
fileStream.Close();
}

[Fact]
public void tkhd_width_height_test()
{
@@ -233,5 +497,25 @@ namespace JT1078.FMp4.Test
}
return Package;
}

public List<JT1078Package> ParseNALUTests()
{
List<JT1078Package> packages = new List<JT1078Package>();
var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_3.txt"));
int mergeBodyLength = 0;
foreach (var line in lines)
{
var data = line.Split(',');
var bytes = data[6].ToHexBytes();
JT1078Package package = JT1078Serializer.Deserialize(bytes);
mergeBodyLength += package.DataBodyLength;
var packageMerge = JT1078Serializer.Merge(package);
if (packageMerge != null)
{
packages.Add(packageMerge);
}
}
return packages;
}
}
}

+ 6
- 0
src/JT1078.FMp4/Boxs/MovieFragmentBox.cs ファイルの表示

@@ -38,6 +38,12 @@ namespace JT1078.FMp4
TrackFragmentBox.ToBuffer(ref writer);
}
End(ref writer);
var trunOffsetPosition = writer.GetTrunOffsetPosition();
if (trunOffsetPosition > 0)
{
writer.WriteInt32Return(writer.GetCurrentPosition() - SizePosition + 8, trunOffsetPosition);
writer.ClearTrunOffsetPosition();
}
}
}
}

+ 6
- 0
src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessBox.cs ファイルの表示

@@ -38,6 +38,12 @@ namespace JT1078.FMp4
MovieFragmentRandomAccessOffsetBox.ToBuffer(ref writer);
}
End(ref writer);
var mfraSizePosition = writer.GetMfraSizePositionn();
if (mfraSizePosition > 0)
{
writer.WriteInt32Return(writer.GetCurrentPosition() - SizePosition, mfraSizePosition);
writer.ClearMfraSizePosition();
}
}
}
}

+ 11
- 1
src/JT1078.FMp4/Boxs/MovieFragmentRandomAccessOffsetBox.cs ファイルの表示

@@ -28,7 +28,17 @@ namespace JT1078.FMp4
{
Start(ref writer);
WriterFullBoxToBuffer(ref writer);
writer.WriteUInt32(MfraSize);
if (MfraSize > 0)
{
//人工
writer.WriteUInt32(MfraSize);
}
else
{
//程序自动计算
writer.CreateMfraSizePosition();
writer.Skip(4, out _);
}
End(ref writer);
}
}


+ 11
- 1
src/JT1078.FMp4/Boxs/TrackRunBox.cs ファイルの表示

@@ -52,7 +52,17 @@ namespace JT1078.FMp4
}
if((Flags & FMp4Constants.TRUN_FLAG_DATA_OFFSET_PRESENT) > 0)
{
writer.WriteInt32(DataOffset);
if (DataOffset > 0)
{
//人工
writer.WriteInt32(DataOffset);
}
else
{
//程序自动计算
writer.CreateTrunOffsetPosition();
writer.Skip(4, out _);
}
}
if ((Flags & FMp4Constants.TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT) > 0)
{


+ 6
- 1
src/JT1078.FMp4/JT1078.FMp4.xml ファイルの表示

@@ -986,7 +986,7 @@
<summary>
可选的
用来表示和该moof配套的mdat中实际数据内容距moof开头有多少byte
相当于就是 moof.byteLength + mdat.headerSize
相当于就是 moof.byteLength + mdat.headerSize(8)
</summary>
</member>
<member name="P:JT1078.FMp4.TrackRunBox.FirstSampleFlags">
@@ -1250,6 +1250,11 @@
盒子类型
</summary>
</member>
<member name="F:JT1078.FMp4.Mp4Box.SizePosition">
<summary>
</summary>
</member>
<member name="M:JT1078.FMp4.Mp4Box.Start(JT1078.FMp4.MessagePack.FMp4MessagePackWriter@)">
<summary>


+ 37
- 1
src/JT1078.FMp4/MessagePack/FMp4MessagePackWriter.cs ファイルの表示

@@ -9,9 +9,16 @@ namespace JT1078.FMp4.MessagePack
public ref struct FMp4MessagePackWriter
{
private FMp4BufferWriter writer;

private int TrunDataOffsetPosition;

private int MfraSizePosition;

public FMp4MessagePackWriter(Span<byte> buffer)
{
this.writer = new FMp4BufferWriter(buffer);
TrunDataOffsetPosition = 0;
MfraSizePosition = 0;
}
public byte[] FlushAndGetArray()
{
@@ -90,7 +97,6 @@ namespace JT1078.FMp4.MessagePack
tmp.CopyTo(writer.Free);
writer.Advance(count);
}

public void WriteUInt16Return(ushort value, int position)
{
BinaryPrimitives.WriteUInt16BigEndian(writer.Written.Slice(position, 2), value);
@@ -113,6 +119,36 @@ namespace JT1078.FMp4.MessagePack
return writer.WrittenCount;
}

public void CreateTrunOffsetPosition()
{
TrunDataOffsetPosition = writer.WrittenCount;
}

public int GetTrunOffsetPosition()
{
return TrunDataOffsetPosition;
}

public void ClearTrunOffsetPosition()
{
TrunDataOffsetPosition = 0;
}

public void CreateMfraSizePosition()
{
MfraSizePosition = writer.WrittenCount;
}

public int GetMfraSizePositionn()
{
return MfraSizePosition;
}

public void ClearMfraSizePosition()
{
MfraSizePosition = 0;
}

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


+ 6
- 4
src/JT1078.FMp4/Mp4Box.cs ファイルの表示

@@ -52,8 +52,10 @@ namespace JT1078.FMp4
///// int(8)[16]
///// </summary>
//public string UserType { get; set; }

private int sizePosition;
/// <summary>
///
/// </summary>
public int SizePosition;

/// <summary>
///
@@ -61,7 +63,7 @@ namespace JT1078.FMp4
/// <param name="writer"></param>
public void Start(ref FMp4MessagePackWriter writer)
{
writer.Skip(FixedSizeLength, out sizePosition);
writer.Skip(FixedSizeLength, out SizePosition);
writer.WriteASCII(BoxType);
}
@@ -71,7 +73,7 @@ namespace JT1078.FMp4
/// <param name="writer"></param>
public void End(ref FMp4MessagePackWriter writer)
{
writer.WriteUInt32Return((uint)(writer.GetCurrentPosition() - sizePosition), sizePosition);
writer.WriteUInt32Return((uint)(writer.GetCurrentPosition() - SizePosition), SizePosition);
}
}
}

読み込み中…
キャンセル
保存