|
|
@@ -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; |
|
|
|
} |
|
|
|
} |
|
|
|
} |