Esempio n. 1
0
        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 * 1000;
                //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();
        }