Ejemplo n.º 1
0
        protected override void InitProtected()
        {
            Codec = new H264Decoder();
            if (Codec == null)
            {
                throw new Exception("codec not found");
            }

            Context = MpegEncContext.avcodec_alloc_context();
            picture = AVFrame.avcodec_alloc_frame();

            // We do not send complete frames
            if ((Codec.capabilities & H264Decoder.CODEC_CAP_TRUNCATED) != 0)
            {
                Context.flags |= MpegEncContext.CODEC_FLAG_TRUNCATED;
            }

            // For some codecs, such as msmpeg4 and mpeg4, width and height
            // MUST be initialized there because this information is not
            // available in the bitstream.

            // Open it
            if (Context.avcodec_open(Codec) < 0)
            {
                throw new Exception("could not open codec");
            }
        }
Ejemplo n.º 2
0
        public void Test4()
        {
            FMp4Encoder fMp4Encoder = new FMp4Encoder();
            H264Decoder h264Decoder = new H264Decoder();
            var         packages    = ParseNALUTests();
            var         filepath    = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_4.mp4");

            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }
            using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
            var ftyp = fMp4Encoder.EncoderFtypBox();

            fileStream.Write(ftyp);
            var package1 = packages[0];
            var nalus1   = h264Decoder.ParseNALU(package1);
            var moov     = fMp4Encoder.EncoderMoovBox(nalus1, package1.Bodies.Length);

            fileStream.Write(moov);
            foreach (var package in packages)
            {
                var otherNalus      = h264Decoder.ParseNALU(package);
                var flag            = package.Label3.DataType == Protocol.Enums.JT1078DataType.视频I帧 ? 1u : 0u;
                var otherMoofBuffer = fMp4Encoder.EncoderMoofBox(otherNalus, package.Bodies.Length, package.Timestamp, package.LastIFrameInterval, flag);
                var otherMdatBuffer = fMp4Encoder.EncoderMdatBox(otherNalus, package.Bodies.Length);
                fileStream.Write(otherMoofBuffer);
                fileStream.Write(otherMdatBuffer);
            }
            fileStream.Close();
        }
Ejemplo n.º 3
0
        public async Task Start_Completes_Async()
        {
            int frameCount = 0;

            Collection <string> imageHashes = new Collection <string>();

            using (var stream = File.OpenRead("video.h264"))
                using (var decoder = new H264Decoder(stream))
                {
                    var frameBuffer = decoder.FrameBuffer;
                    frameBuffer.FrameReceived += (sender, e) =>
                    {
                        Assert.Equal(1334, frameBuffer.Height);
                        Assert.Equal(3000, frameBuffer.Stride);
                        Assert.Equal(750, frameBuffer.Width);
                        Assert.Equal(750, frameBuffer.AlignedWidth);
                        Assert.Equal(1334, frameBuffer.AlignedHeight);

                        frameCount++;
                    };

                    decoder.Start();
                    await Task.WhenAny(
                        decoder.DecodeTask,
                        Task.Delay(TimeSpan.FromSeconds(5))).ConfigureAwait(false);

                    Assert.True(decoder.DecodeTask.IsCompleted, "The decode task did not complete in time");
                }

            Assert.Equal(5, frameCount);
        }
Ejemplo n.º 4
0
        public void 测试第一帧的数据()
        {
            JT1078Package Package         = null;
            var           lines           = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_1.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;
                Package          = JT1078Serializer.Merge(package);
            }
            H264Decoder decoder = new H264Decoder();
            //7 8 6 5 1 1 1 1 1 7 8 6 5 1 1 1 1
            var nalus = decoder.ParseNALU(Package);

            Assert.Equal(4, nalus.Count);

            FlvEncoder encoder  = new FlvEncoder();
            var        contents = encoder.CreateFlvFrame(nalus);
            var        filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_1.flv");

            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }
            FileStream fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);

            fileStream.Write(FlvEncoder.VideoFlvHeaderBuffer);
            fileStream.Write(contents);
            fileStream.Close();
        }
Ejemplo n.º 5
0
        public void Start_IsCompleted()
        {
            using var stream  = File.OpenRead("video.h264");
            using var decoder = new H264Decoder(stream);

            decoder.Start();
            Assert.Throws <InvalidOperationException>(() => decoder.Start());
        }
Ejemplo n.º 6
0
        public void Dispose_Twice()
        {
            using var stream = File.OpenRead("video.h264");

            var decoder = new H264Decoder(stream);

            decoder.Dispose();
            decoder.Dispose();
        }
Ejemplo n.º 7
0
        public void 测试可以播放的Flv2()
        {
            FileStream      fileStream = null;
            H264Decoder     decoder    = new H264Decoder();
            List <H264NALU> h264NALULs = new List <H264NALU>();
            FlvEncoder      encoder    = new FlvEncoder();

            try
            {
                var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_4.flv");
                var lines    = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_4.txt"));
                if (File.Exists(filepath))
                {
                    File.Delete(filepath);
                }

                JT1078Package Package = null;

                foreach (var line in lines)
                {
                    var           data    = line.Split(',');
                    var           bytes   = data[6].ToHexBytes();
                    JT1078Package package = JT1078Serializer.Deserialize(bytes);
                    Package = JT1078Serializer.Merge(package);
                    if (Package != null)
                    {
                        var tmp = decoder.ParseNALU(Package);
                        if (tmp != null && tmp.Count > 0)
                        {
                            h264NALULs = h264NALULs.Concat(tmp).ToList();
                        }
                    }
                }

                fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
                fileStream.Write(FlvEncoder.VideoFlvHeaderBuffer);
                var totalPage = (h264NALULs.Count + 10 - 1) / 10;
                for (var i = 0; i < totalPage; i++)
                {
                    var flv2 = encoder.CreateFlvFrame(h264NALULs.Skip(i * 10).Take(10).ToList());
                    if (flv2.Length != 0)
                    {
                        fileStream.Write(flv2);
                    }
                }
            }
            catch (Exception ex)
            {
                Assert.Throws <Exception>(() => { });
            }
            finally
            {
                fileStream?.Close();
                fileStream?.Dispose();
            }
        }
Ejemplo n.º 8
0
        public void Disposed_ThrowsException()
        {
            var decoder = new H264Decoder(Stream.Null);

            decoder.Dispose();

            Assert.Throws <ObjectDisposedException>(() => decoder.Start());
            Assert.Throws <ObjectDisposedException>(() => decoder.FrameBuffer.CopyFramebuffer(Array.Empty <byte>()));
            Assert.Throws <ObjectDisposedException>(() => decoder.Decode());
        }
Ejemplo n.º 9
0
 public ToWebSocketService(
     H264Decoder h264Decoder,
     WsSession wsSession,
     FMp4Encoder fMp4Encoder,
     ILoggerFactory loggerFactory,
     IHubContext <FMp4Hub> hubContext)
 {
     this.h264Decoder = h264Decoder;
     logger           = loggerFactory.CreateLogger <ToWebSocketService>();
     this.fMp4Encoder = fMp4Encoder;
     _hubContext      = hubContext;
     this.wsSession   = wsSession;
 }
Ejemplo n.º 10
0
        public void ParseNALUTest2()
        {
            JT1078Package Package         = null;
            var           lines           = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_1.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;
                Package          = JT1078Serializer.Merge(package);
            }
            H264Decoder decoder = new H264Decoder();
            var         nalus   = decoder.ParseNALU(Package);

            Assert.Equal(4, nalus.Count);

            //SPS -> 7
            var spsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 7);

            Assert.NotNull(spsNALU);
            spsNALU.RawData = decoder.DiscardEmulationPreventionBytes(spsNALU.RawData);
            //"Z00AFJWoWCWQ"
            var             spsRawDataHex    = JsonConvert.SerializeObject(spsNALU.RawData);
            ExpGolombReader h264GolombReader = new ExpGolombReader(spsNALU.RawData);
            //(77, 20, 0, 352, 288)
            var spsInfo = h264GolombReader.ReadSPS();

            Assert.Equal(77, spsInfo.profileIdc);
            Assert.Equal(20, spsInfo.levelIdc);
            Assert.Equal(0u, spsInfo.profileCompat);
            Assert.Equal(288, spsInfo.height);
            Assert.Equal(352, spsInfo.width);

            //PPS -> 8
            var ppsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 8);

            Assert.NotNull(ppsNALU);

            //IDR -> 5  关键帧
            var idrNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 5);

            Assert.NotNull(idrNALU);

            //SEI -> 6
            var seiNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 6);

            Assert.NotNull(seiNALU);
        }
Ejemplo n.º 11
0
        public void Test4()
        {
            FMp4Encoder fMp4Encoder = new FMp4Encoder();
            H264Decoder h264Decoder = new H264Decoder();
            var         packages    = ParseNALUTests();
            var         filepath    = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_5.mp4");

            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }

            using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
            var ftyp = fMp4Encoder.EncoderFtypBox();

            fileStream.Write(ftyp);

            var iNalus = h264Decoder.ParseNALU(packages[0]);
            //判断第一帧是否关键帧
            var moov = fMp4Encoder.EncoderMoovBox(
                iNalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS),
                iNalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.PPS));

            fileStream.Write(moov);

            List <H264NALU> nalus = new List <H264NALU>();

            foreach (var package in packages)
            {
                List <H264NALU> h264NALUs = h264Decoder.ParseNALU(package);
                foreach (var nalu in h264NALUs)
                {
                    if (nalu.Slice)
                    {
                        //H264 NALU slice first_mb_in_slice
                        nalus.Add(nalu);
                    }
                    else
                    {
                        if (nalus.Count > 0)
                        {
                            var otherBuffer = fMp4Encoder.EncoderOtherVideoBox(nalus);
                            fileStream.Write(otherBuffer);
                            nalus.Clear();
                        }
                        nalus.Add(nalu);
                    }
                }
            }
            fileStream.Close();
        }
Ejemplo n.º 12
0
        public void ParseNALUTest1()
        {
            H264Decoder   demuxer = new H264Decoder();
            var           hexData = "3031636481e2274b01234567899901100000016cd3ed2fa900500050037f0000000161e022bfb28b470069769838a02eb3b5cc4bccd7b37eb98cd65b2a76ce85a6c82876385a8f646da3d0abb6af58ad1dc7db5dab9719577d9968f7efc9836f4bc8fb7e32f5689b190e9e6e07d2f4448efff9147175f22a4b0f83fd24374b881dddcac5998ab9b03d991eb0045ed98826699a5601cdd6bd1e4b3ca53c175ef36e9f46969018c01b7754304790a17888072647e4c473182f05922770f5aff81e02ea46637b5e90b4382f100a2b55c5f49e0fa0b8203804dcd7714fac1dbd15d0583f8ebdfdf980770d58b38349ad7ec5682f01dae88b2117c6f3b3b58b642354bc23735d9c269028df9774e8182f5d636cec09829886de3ee83406e035bffcce3ed24af0f9a2dee150fab93303f2139c8525eeb89516df169137ef46ed99962343ea7b078bcddd284e44be62936a6c44042d89acb17973eb65e1c21faee6d221627ba834d369f4c023acc122d7d3dd3f55a6c4fb2ba2854498d4041ea00b1252c6d9eb57ac0b10313e8905843054dfbf4c847180aee40980bdfe5cb53133214c77c8e95ebe7601cd0d331f75281d1fadd122985133e74855e13cbb10220bc6e0c946b519b35d933a29e38e175b1398dc0946fc58ec7b686b3aac4bfa9e42bb8e643be04dc55036289c7d378fe37c6c3e1fc06015f8b402a65afac23d78d9fb5e3e0115195c11227ee6f261b67834b51bc665e8a6803af835b5032786e58e7f66049dc767520bae35d527a72458834a846dcd1cccf198d772d3ce0a2db5eb1d8270c483840309e224b2798d9271b30729e0c4f51eb7798d0dd0d8adb3d246e686b42e47f351c482dda833747649e421bbbe04098ca220d4e0e60a3b2854029c95c70394a2991314c50199f2158b68635a622f55ebda0b5e41328843552723fba1d5228963e8562c9105838ec9d341fef19b33a438d903ebcef32cec2ad39fd32aff14c79f07de4ca75e65d20f6ee36e464ee3e5c27871ab594ae3a0b43583c6f4d55ac8b71090fca9a1f4379576e07678983935d6f3a236504c2e4d31f99d62c999f41c11b06c41a6adb07b6e62f50ec5c8dbdb6641c5bc55a695f0f7b4f4d430c1e2f38a77edfc3513f943e1c1d4c0a81ef6c26cc4e7b157d318b49802ea94aa8ab38dadd4986e5330ab49daaec010123c39da63943bfe63bdd1cdd6beec19e1469b989ac10877a24065d7b01ff9cee35632e97243eb7acd79ce9d188b786e44bbe0e922be205c1224a41f387fae0f20d4a203d0ba64a366b8adbe2b80".ToHexBytes();
            JT1078Package package = JT1078Serializer.Deserialize(hexData);
            var           nalus   = demuxer.ParseNALU(package);

            Assert.Single(nalus);
            var nalu = nalus[0];

            Assert.Equal(0, nalu.NALUHeader.ForbiddenZeroBit);
            Assert.Equal(3, nalu.NALUHeader.NalRefIdc);
            Assert.Equal(1, nalu.NALUHeader.NalUnitType);
        }
Ejemplo n.º 13
0
        public void CopyFrameBuffer_ThrowsOnWrongSize()
        {
            using (var stream = File.OpenRead("video.h264"))
                using (var decoder = new H264Decoder(stream))
                {
                    var frameBuffer = decoder.FrameBuffer;
                    frameBuffer.FrameReceived += (sender, e) =>
                    {
                        byte[] array = new byte[20];
                        Assert.Throws <ArgumentOutOfRangeException>(() => frameBuffer.CopyFramebuffer(array));
                    };

                    decoder.Decode();
                }
        }
Ejemplo n.º 14
0
 public JT1078FMp4NormalMsgHostedService(
     MessageDispatchDataService messageDispatchDataService,
     IMemoryCache memoryCache,
     ILoggerFactory loggerFactory,
     H264Decoder h264Decoder,
     FMp4Encoder fM4Encoder,
     JT1078HttpSessionManager httpSessionManager)
 {
     Logger             = loggerFactory.CreateLogger <JT1078FMp4NormalMsgHostedService>();
     HttpSessionManager = httpSessionManager;
     FM4Encoder         = fM4Encoder;
     H264Decoder        = h264Decoder;
     this.memoryCache   = memoryCache;
     this.messageDispatchDataService = messageDispatchDataService;
     avFrameDict = new ConcurrentDictionary <string, List <H264NALU> >();
 }
Ejemplo n.º 15
0
        public unsafe void DecodeTest()
        {
            int frameCount = 0;

            var imageHashes = new List <string>();

            using (var stream = File.OpenRead("video.h264"))
                using (var decoder = new H264Decoder(stream))
                {
                    var frameBuffer = decoder.FrameBuffer;
                    frameBuffer.FrameReceived += (sender, e) =>
                    {
                        Assert.Equal(1334, frameBuffer.Height);
                        Assert.Equal(3000, frameBuffer.Stride);
                        Assert.Equal(750, frameBuffer.Width);
                        Assert.Equal(750, frameBuffer.AlignedWidth);
                        Assert.Equal(1334, frameBuffer.AlignedHeight);

                        byte[] array = new byte[frameBuffer.FrameBufferSize];
                        frameBuffer.CopyFramebuffer(array);

                        fixed(byte *ptr = array)
                        {
                            // Only reason we do this is to make sure the framebuffer data is relevant
                            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                            {
                                using (var bitmap = new Bitmap(frameBuffer.Width, frameBuffer.Height, frameBuffer.Stride, PixelFormat.Format24bppRgb, (IntPtr)ptr))
                                {
                                    bitmap.Save($"stream-frame.{frameCount}.jpg", ImageFormat.Jpeg);
                                }
                            }
                        }

                        frameCount++;
                    };

                    decoder.Decode();
                }

            Assert.Equal(5, frameCount);
        }
Ejemplo n.º 16
0
 /// <summary>
 ///
 /// </summary>
 public FMp4Encoder()
 {
     h264Decoder = new H264Decoder();
 }
Ejemplo n.º 17
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();
        }
Ejemplo n.º 18
0
        public void 测试主次码流切换()
        {
            FileStream      fileStream = null;
            H264Decoder     decoder    = new H264Decoder();
            List <H264NALU> h264NALULs = new List <H264NALU>();
            FlvEncoder      encoder    = new FlvEncoder();

            try
            {
                var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_5.flv");
                var lines    = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_5.txt"));
                if (File.Exists(filepath))
                {
                    File.Delete(filepath);
                }

                JT1078Package Package = null;

                foreach (var line in lines)
                {
                    var           data    = line.Split(',');
                    var           bytes   = data[6].ToHexBytes();
                    JT1078Package package = JT1078Serializer.Deserialize(bytes);
                    Package = JT1078Serializer.Merge(package);
                    if (Package != null)
                    {
                        var tmp = decoder.ParseNALU(Package);
                        if (tmp != null && tmp.Count > 0)
                        {
                            h264NALULs = h264NALULs.Concat(tmp).ToList();
                        }
                    }
                }
                var            tmp1                = h264NALULs.Where(w => w.NALUHeader.NalUnitType == 7).ToList();
                List <SPSInfo> tmpSpss             = new List <SPSInfo>();
                List <ulong>   times               = new List <ulong>();
                List <ushort>  lastIFrameIntervals = new List <ushort>();
                List <ushort>  lastFrameIntervals  = new List <ushort>();
                List <int>     type                = new List <int>();
                foreach (var item in h264NALULs)
                {
                    //type.Add(item.NALUHeader.NalUnitType);
                    times.Add(item.Timestamp);
                    lastFrameIntervals.Add(item.LastFrameInterval);
                    lastIFrameIntervals.Add(item.LastIFrameInterval);
                    if (item.NALUHeader.NalUnitType == 7)
                    {
                        ExpGolombReader expGolombReader = new ExpGolombReader(item.RawData);
                        tmpSpss.Add(expGolombReader.ReadSPS());
                    }
                }
                fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
                var totalPage = (h264NALULs.Count + 10 - 1) / 10;
                for (var i = 0; i < totalPage; i++)
                {
                    var flv2 = encoder.CreateFlvFrame(h264NALULs.Skip(i * 10).Take(10).ToList());
                    if (flv2.Length != 0)
                    {
                        //fileStream.Write(flv2);
                    }
                }
            }
            catch (Exception ex)
            {
                Assert.Throws <Exception>(() => { });
            }
            finally
            {
                fileStream?.Close();
                fileStream?.Dispose();
            }
        }
Ejemplo n.º 19
0
 //public FlvEncoder(int sampleRate = 8000, int channels = 1, int sampleBit = 16, bool adts = false)
 /// <summary>
 ///
 /// </summary>
 public FlvEncoder()
 {
     audioCodecFactory = new AudioCodecFactory();
     h264Decoder       = new H264Decoder();
 }
Ejemplo n.º 20
0
        private void Init()
        {
            avpkt.av_init_packet();

            // Set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams)
            Arrays.Fill(inbuf, INBUF_SIZE, MpegEncContext.FF_INPUT_BUFFER_PADDING_SIZE + INBUF_SIZE, (sbyte)0);

            // Find the mpeg1 video decoder
            codec = new H264Decoder();
            if (codec == null)
            {
                throw (new Exception("codec not found"));
            }

            c       = MpegEncContext.avcodec_alloc_context();
            picture = AVFrame.avcodec_alloc_frame();

            // We do not send complete frames
            if ((codec.capabilities & H264Decoder.CODEC_CAP_TRUNCATED) != 0)
            {
                c.flags |= MpegEncContext.CODEC_FLAG_TRUNCATED;
            }

            // For some codecs, such as msmpeg4 and mpeg4, width and height
            // MUST be initialized there because this information is not
            // available in the bitstream.

            // Open it
            if (c.avcodec_open(codec) < 0)
            {
                throw (new Exception("could not open codec"));
            }

            // The codec gives us the frame size, in samples

            frame = 0;

            // avpkt must contain exactly 1 NAL Unit in order for decoder to decode correctly.
            // thus we must read until we get next NAL header before sending it to decoder.
            // Find 1st NAL
            cacheRead[0] = fin.ReadByte();
            cacheRead[1] = fin.ReadByte();
            cacheRead[2] = fin.ReadByte();

            while (!(cacheRead[0] == 0x00 && cacheRead[1] == 0x00 && cacheRead[2] == 0x01))
            {
                cacheRead[0] = cacheRead[1];
                cacheRead[1] = cacheRead[2];
                cacheRead[2] = fin.ReadByte();
                if (cacheRead[2] == -1)
                {
                    throw(new EndOfStreamException());
                }
            }             // while

            // 4 first bytes always indicate NAL header
            inbuf_int[0] = inbuf_int[1] = inbuf_int[2] = 0x00;
            inbuf_int[3] = 0x01;

            hasMoreNAL = true;
        }
Ejemplo n.º 21
0
        public void Test1()
        {
            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);
            //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;
            //MSE codecs avc1.4D0014
            //4D 00 14
            //AVCProfileIndication profile_compability AVCLevelIndication
            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);
            //用户自定义可以不用
            //movieBox.UserDataBox = new UserDataBox();
            //movieBox.UserDataBox.Data = "0000005a6d657461000000000000002168646c7200000000000000006d6469726170706c0000000000000000000000002d696c737400000025a9746f6f0000001d6461746100000001000000004c61766635382e34352e313030".ToHexBytes();
            //fragment moof n
            List <FragmentBox> moofs       = new List <FragmentBox>();
            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;
            //todo:BaseDataOffset
            fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.BaseDataOffset        = 0x000000000000028b;
            fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = 48000;
            fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize     = (uint)jT1078Package.Bodies.Length;
            fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags    = 0x1010000;
            //fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox = new SampleDependencyTypeBox();
            //fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes = new List<SampleDependencyTypeBox.SampleDependencyType>();
            //todo:fragmentBox.MovieFragmentBox.TrackFragmentBox.SampleDependencyTypeBox.SampleDependencyTypes
            fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox();
            //todo:BaseMediaDecodeTime
            fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = 0;
            //trun
            fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox                  = new TrackRunBox(flags: 0x5);
            fragmentBox.MovieFragmentBox.TrackFragmentBox.TrackRunBox.DataOffset       = 120;
            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);
            //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;
            //todo:MoofOffset
            trackFragmentRandomAccessInfo1.MoofOffset   = 0x000000000000028b;
            trackFragmentRandomAccessInfo1.TrafNumber   = 0x01;
            trackFragmentRandomAccessInfo1.TrunNumber   = 0x01;
            trackFragmentRandomAccessInfo1.SampleNumber = 0x01;
            movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos.Add(trackFragmentRandomAccessInfo1);
            //mfra->mfro
            movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox = new MovieFragmentRandomAccessOffsetBox(0);
            //todo:MfraSize
            movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox.MfraSize = 0x00000043;
            FMp4Box fMp4Box = new FMp4Box();

            fMp4Box.FileTypeBox  = fileTypeBox;
            fMp4Box.MovieBox     = movieBox;
            fMp4Box.FragmentBoxs = moofs;
            fMp4Box.MovieFragmentRandomAccessBox = movieFragmentRandomAccessBox;
            FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[65535]);

            fMp4Box.ToBuffer(ref writer);
            var buffer   = writer.FlushAndGetArray();
            var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_1.mp4");

            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }
            using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
            fileStream.Write(buffer);
            fileStream.Close();
        }