diff --git a/doc/ffmpeginfo.txt b/doc/ffmpeginfo.txt
index 0058b3b..f11e1e7 100644
--- a/doc/ffmpeginfo.txt
+++ b/doc/ffmpeginfo.txt
@@ -2,9 +2,10 @@ ffmpeg -i demo.mp4 -c copy -f flv -vcodec h264 -acodec aac demo_flv.flv
./ffmpeg -i JT1078_3.h264 -r 25 -c copy -f flv "D:\JT1078_3.flv"
-ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -t 60 -c copy -f h264 -vcodec h264 jt1078.264
+ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -t 60 -c copy -f h264 -vcodec h264 ipc.264
ffmpeg -i demo.264 -vcodec copy -f mp4 -movflags frag_keyframe+empty_moov fragmented_demo.mp4
+ffmpeg -i ipc.264 -vcodec copy -f mp4 -movflags frag_keyframe+empty_moov ipc_fragmented_demo.mp4
chrome://media-internals/
\ No newline at end of file
diff --git a/doc/video/ipc.264 b/doc/video/ipc.264
new file mode 100644
index 0000000..3052a10
Binary files /dev/null and b/doc/video/ipc.264 differ
diff --git a/doc/video/ipc_fragmented_demo.mp4 b/doc/video/ipc_fragmented_demo.mp4
new file mode 100644
index 0000000..eeab519
Binary files /dev/null and b/doc/video/ipc_fragmented_demo.mp4 differ
diff --git a/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj b/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj
index 1937a79..026873a 100644
--- a/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj
+++ b/src/JT1078.FMp4.Test/JT1078.FMp4.Test.csproj
@@ -22,6 +22,7 @@
+
Always
@@ -30,6 +31,7 @@
Always
+
Always
@@ -38,5 +40,17 @@
Always
-
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
diff --git a/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs b/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs
new file mode 100644
index 0000000..f66523b
--- /dev/null
+++ b/src/JT1078.FMp4.Test/JT1078ToFMp4Box_Test.cs
@@ -0,0 +1,119 @@
+using JT1078.FMp4.Enums;
+using JT1078.FMp4.Samples;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace JT1078.FMp4.Test
+{
+ public class JT1078ToFMp4Box_Test
+ {
+ [Fact]
+ public void Test1()
+ {
+ //ftyp
+ FileTypeBox fileTypeBox = new FileTypeBox();
+ fileTypeBox.MajorBrand = "isom";
+ fileTypeBox.MinorVersion = "\0\0\0\u0001";
+ fileTypeBox.CompatibleBrands.Add("isom");
+ fileTypeBox.CompatibleBrands.Add("avc1");
+ //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=
+ //movieBox.MovieHeaderBox.Timescale=
+ 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.Duration=
+ //movieBox.TrackBox.TrackHeaderBox.Timescale=
+ movieBox.TrackBox.TrackHeaderBox.TrackIsAudio = false;
+ //movieBox.TrackBox.TrackHeaderBox.Width=
+ //movieBox.TrackBox.TrackHeaderBox.Height=
+ 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=
+ //movieBox.TrackBox.MediaBox.MediaHeaderBox.Duration=
+ 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();
+ 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();
+ AVC1SampleEntry avc1 = new AVC1SampleEntry();
+ avc1.AVCConfigurationBox = new AVCConfigurationBox();
+ //h264
+ //avc1.Width=
+ //avc1.Height=
+ //avc1.AVCConfigurationBox.AVCLevelIndication
+ //avc1.AVCConfigurationBox.AVCProfileIndication
+ //avc1.AVCConfigurationBox.PPSs
+ //avc1.AVCConfigurationBox.SPSs
+ //avc1.AVCConfigurationBox.ProfileCompatibility
+ 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 trex = new TrackExtendsBox();
+ trex.TrackID = movieBox.MovieHeaderBox.NextTrackID;
+ trex.DefaultSampleDescriptionIndex = 1;
+ trex.DefaultSampleDuration = 0;
+ trex.DefaultSampleSize = 0;
+ trex.DefaultSampleFlags = 1;
+ movieBox.MovieExtendsBox.TrackExtendsBoxs.Add(trex);
+ //fragment moof n
+ List moofs = new List();
+ FragmentBox fragmentBox = new FragmentBox();
+ fragmentBox.MovieFragmentBox = new MovieFragmentBox();
+ fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox = new MovieFragmentHeaderBox();
+ //fragmentBox.MovieFragmentBox.MovieFragmentHeaderBox.SequenceNumber=SN
+ 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();
+ //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
+ //trun
+ fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox();
+
+ moofs.Add(fragmentBox);
+
+
+
+
+ //mfra
+
+
+ }
+ }
+}
diff --git a/src/JT1078.FMp4/Boxs/FragmentBox.cs b/src/JT1078.FMp4/Boxs/FragmentBox.cs
index 9f7b6c4..c2edf2a 100644
--- a/src/JT1078.FMp4/Boxs/FragmentBox.cs
+++ b/src/JT1078.FMp4/Boxs/FragmentBox.cs
@@ -6,6 +6,9 @@ using System.Text;
namespace JT1078.FMp4
{
+ ///
+ ///
+ ///
public class FragmentBox:IFMp4MessagePackFormatter
{
///
@@ -16,7 +19,10 @@ namespace JT1078.FMp4
/// mdat
///
public MediaDataBox MediaDataBox { get; set; }
-
+ ///
+ ///
+ ///
+ ///
public void ToBuffer(ref FMp4MessagePackWriter writer)
{
if (MovieFragmentBox != null)
diff --git a/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs b/src/JT1078.FMp4/Boxs/MediaHeaderBox.cs
index db67b8f..e0fd9ed 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, uint flags=0) : base("mdhd", version, flags)
+ public MediaHeaderBox(byte version=1, uint flags=0) : base("mdhd", version, flags)
{
}
public ulong CreationTime { get; set; }
diff --git a/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs b/src/JT1078.FMp4/Boxs/MovieHeaderBox.cs
index e330ccc..7a73c98 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, uint flags=0) : base("mvhd", version, flags)
+ public MovieHeaderBox(byte version=1, uint flags=0) : base("mvhd", version, flags)
{
}
public ulong CreationTime { get; set; }
diff --git a/src/JT1078.FMp4/Boxs/SampleTableBox.cs b/src/JT1078.FMp4/Boxs/SampleTableBox.cs
index d46a2ab..a130d83 100644
--- a/src/JT1078.FMp4/Boxs/SampleTableBox.cs
+++ b/src/JT1078.FMp4/Boxs/SampleTableBox.cs
@@ -30,13 +30,14 @@ namespace JT1078.FMp4
///
public CompositionOffsetBox CompositionOffsetBox { get; set; }
///
- /// stsc
- ///
- public SampleToChunkBox SampleToChunkBox { get; set; }
- ///
/// stsz
///
public SampleSizeBox SampleSizeBox { get; set; }
+ ///
+ /// stsc
+ ///
+ public SampleToChunkBox SampleToChunkBox { get; set; }
+
//public CompactSampleSizeBox CompactSampleSizeBox { get; set; }
///
/// stco
diff --git a/src/JT1078.FMp4/FMp4Box.cs b/src/JT1078.FMp4/FMp4Box.cs
index b910171..19b86e7 100644
--- a/src/JT1078.FMp4/FMp4Box.cs
+++ b/src/JT1078.FMp4/FMp4Box.cs
@@ -8,6 +8,15 @@ namespace JT1078.FMp4
{
///
/// fmp4
+ /// stream data
+ /// ftyp
+ /// moov
+ /// moof 1
+ /// mdat 1
+ /// ...
+ /// moof n
+ /// mdat n
+ /// mfra
///
public class FMp4Box:IFMp4MessagePackFormatter
{
@@ -27,7 +36,10 @@ namespace JT1078.FMp4
/// mfra
///
public MovieFragmentRandomAccessBox MovieFragmentRandomAccessBox { get; set; }
-
+ ///
+ ///
+ ///
+ ///
public void ToBuffer(ref FMp4MessagePackWriter writer)
{
FileTypeBox.ToBuffer(ref writer);
diff --git a/src/JT1078.FMp4/JT1078.FMp4.xml b/src/JT1078.FMp4/JT1078.FMp4.xml
index b53b130..47b5e3f 100644
--- a/src/JT1078.FMp4/JT1078.FMp4.xml
+++ b/src/JT1078.FMp4/JT1078.FMp4.xml
@@ -175,6 +175,11 @@
4位*n
+
+
+
+
+
moof
@@ -185,6 +190,12 @@
mdat
+
+
+
+
+
+
填充值
@@ -1045,6 +1056,15 @@
fmp4
+ stream data
+ ftyp
+ moov
+ moof 1
+ mdat 1
+ ...
+ moof n
+ mdat n
+ mfra
@@ -1067,6 +1087,12 @@
mfra
+
+
+
+
+
+
日期限制于2000年
@@ -1186,6 +1212,11 @@
+
+
+
+
+
盒子大小
diff --git a/src/JT1078.FMp4/Mp4Box.cs b/src/JT1078.FMp4/Mp4Box.cs
index 2bedc2d..f85faff 100644
--- a/src/JT1078.FMp4/Mp4Box.cs
+++ b/src/JT1078.FMp4/Mp4Box.cs
@@ -6,6 +6,9 @@ using System.Text;
namespace JT1078.FMp4
{
+ ///
+ ///
+ ///
public abstract class Mp4Box
{
//public const string UUID = "uuid";
diff --git a/src/JT1078.FMp4/Samples/VisualSampleEntry.cs b/src/JT1078.FMp4/Samples/VisualSampleEntry.cs
index 0ef485f..ba8b9e1 100644
--- a/src/JT1078.FMp4/Samples/VisualSampleEntry.cs
+++ b/src/JT1078.FMp4/Samples/VisualSampleEntry.cs
@@ -10,7 +10,7 @@ namespace JT1078.FMp4.Samples
///
public abstract class VisualSampleEntry : SampleEntry
{
- const string COMPRESSORNAME = "jt1078&SmallChi(koike)&TK";
+ const string COMPRESSORNAME = "jt1078&SmallChi(Koike)&TK";
///
/// VisualSampleEntry
///