Пример #1
0
        public void ReadNextPacket()
        {
            Span <byte> stream = new byte[] {
                0, 0, 1, 0xfe, 0xff,
                0, 0, 0, 0, 1, 0xc4, 0xc5, 0xc5, 0xc5
            };

            {
                var packet = NalPacket.ReadNextPacket(ref stream);

                Assert.IsTrue(packet.Complete);
                CollectionAssert.AreEqual(
                    new byte[] { 0, 0, 1, 0xfe, 0xff },
                    packet.Packet.ToArray());
            }

            {
                var packet = NalPacket.ReadNextPacket(ref stream);

                Assert.IsFalse(packet.Complete);
                CollectionAssert.AreEqual(
                    new byte[] { 0, 0, 0, 0, 1, 0xc4, 0xc5, 0xc5, 0xc5 },
                    packet.Packet.ToArray());
            }
        }
Пример #2
0
        public void ReadMultipleSegmentedWrites()
        {
            var stream = new MemoryStream(new byte[] {
                0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x34, 0xAC, 0x2B,
                0x40, 0x1E, 0x00, 0x21, 0xF6, 0x02, 0x20, 0x00, 0x00, 0x7D,
                0x00, 0x00, 0x20, 0x3A, 0x10, 0x80, 0x00, 0x00, 0x00, 0x01,
                0x68, 0xEE, 0x3C, 0xB0, 0x00, 0x00, 0x00, 0x01, 0x05, 0xB8
            });

            var buffer = new byte[10];

            {
                var nread       = stream.Read(buffer, 0, buffer.Length);
                var inputBuffer = new Span <byte>(buffer, 0, nread);
                var packet      = NalPacket.ReadNextPacket(ref inputBuffer);
                Assert.AreEqual(10, packet.Packet.Length);
                Assert.AreEqual(0, packet.PacketPrefix.Length);
                Assert.AreEqual(false, packet.Complete);
            }

            {
                var nread       = stream.Read(buffer, 0, buffer.Length);
                var inputBuffer = new Span <byte>(buffer, 0, nread);
                var packet      = NalPacket.ReadNextPacket(ref inputBuffer);
                Assert.AreEqual(10, packet.Packet.Length);
                Assert.AreEqual(0, packet.PacketPrefix.Length);
                Assert.AreEqual(false, packet.Complete);
            }

            {
                var nread       = stream.Read(buffer, 0, buffer.Length);
                var inputBuffer = new Span <byte>(buffer, 0, nread);
                var packet      = NalPacket.ReadNextPacket(ref inputBuffer);
                Assert.AreEqual(6, packet.Packet.Length);
                Assert.AreEqual(0, packet.PacketPrefix.Length);
                Assert.AreEqual(true, packet.Complete);

                var packet2 = NalPacket.ReadNextPacket(ref inputBuffer);
                Assert.AreEqual(4, packet2.Packet.Length);
                Assert.AreEqual(0, packet2.PacketPrefix.Length);
                Assert.AreEqual(false, packet2.Complete);
            }

            {
                var nread       = stream.Read(buffer, 0, buffer.Length);
                var inputBuffer = new Span <byte>(buffer, 0, nread);
                var packet      = NalPacket.ReadNextPacket(ref inputBuffer);
                Assert.AreEqual(6, packet.Packet.Length);
                Assert.AreEqual(0, packet.PacketPrefix.Length);
                Assert.AreEqual(true, packet.Complete);
            }
        }
Пример #3
0
        public void GetNalPacketType()
        {
            Span <byte> stream = new byte[] {
                0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x34, 0xAC, 0x2B,
                0x40, 0x1E, 0x00, 0x21, 0xF6, 0x02, 0x20, 0x00, 0x00, 0x7D,
                0x00, 0x00, 0x20, 0x3A, 0x10, 0x80
            };

            var packet = NalPacket.ReadNextPacket(ref stream);

            Assert.AreEqual(
                NalPacketType.SequenceParameterSet,
                packet.PacketType);
        }
Пример #4
0
        public void IndexOfSignature()
        {
            {
                Span <byte> index0 = new byte[] { 0, 0, 1 };
                Assert.AreEqual(0, NalPacket.IndexOfSignature(index0, out var size));
                Assert.AreEqual(size, 3);
            }

            {
                Span <byte> index1 = new byte[] { 0, 0, 0, 1 };
                Assert.AreEqual(0, NalPacket.IndexOfSignature(index1, out var size));
                Assert.AreEqual(size, 4);
            }

            {
                Span <byte> indexNever = new byte[] { 0, 0, 0, 0 };
                Assert.AreEqual(-1, NalPacket.IndexOfSignature(indexNever, out var size));
            }
        }
Пример #5
0
        private int Run()
        {
            _displayThread.Start();

            LibCuda.Initialize();

            var descriptions = CuDevice.GetDescriptions().ToArray();

            if (descriptions.Length == 0)
            {
                Console.Error.WriteLine("No CUDA devices found.");
                return(-1);
            }

            foreach (var description in descriptions)
            {
                PrintInformation($"Device {description.Handle}", new Dictionary <string, object> {
                    ["Memory"]               = description.TotalMemory,
                    ["Name"]                 = description.Name,
                    ["PciBusId"]             = description.GetPciBusId(),
                    ["MaxThreadsPerBlock"]   = description.GetAttribute(CuDeviceAttribute.MaxThreadsPerBlock),
                    ["SharedMemoryPerBlock"] = description.GetAttribute(CuDeviceAttribute.SharedMemoryPerBlock)
                });
            }

            var device = descriptions[0].Device;

            _context     = device.CreateContext(CuContextFlags.SchedBlockingSync);
            _contextLock = _context.CreateLock();

            _window = new DisplayWindow(_context, "Decoded video", 800, 600);

            var parserParams = new CuVideoParserParams
            {
                CodecType            = CuVideoCodec.H264,
                MaxNumDecodeSurfaces = 1,
                MaxDisplayDelay      = 0,
                ErrorThreshold       = 100,
                UserData             = IntPtr.Zero,
                DisplayPicture       = VideoDisplayCallback,
                DecodePicture        = DecodePictureCallback,
                SequenceCallback     = SequenceCallback
            };

            using var parser = CuVideoParser.Create(ref parserParams);
            using var fs     = File.OpenRead(_args.InputPath);
            const int bufferSize     = 10 * 1024 * 1024;
            var       inputBufferPtr = Marshal.AllocHGlobal(bufferSize);
            var       count          = 0;

            var backbuffer       = new byte[50 * 1024 * 1024];
            var backbufferStream = new MemoryStream(backbuffer);

            void SendBackbuffer()
            {
                if (backbufferStream.Position == 0)
                {
                    return;
                }

                var span = new Span <byte>(
                    backbuffer, 0,
                    (int)backbufferStream.Position);

                parser.ParseVideoData(span);

                Array.Fill <byte>(backbuffer, 0);
                backbufferStream = new MemoryStream(backbuffer);
            }

            var watch = Stopwatch.StartNew();

            while (true)
            {
                var inputBuffer = new Span <byte>(
                    (void *)inputBufferPtr, bufferSize);

                var nread = fs.Read(inputBuffer);
                if (nread == 0)
                {
                    break;
                }

                var inputStream = inputBuffer.Slice(0, nread);

                while (true)
                {
                    var packet = NalPacket.ReadNextPacket(ref inputStream);

                    if (packet.PacketPrefix.Length > 0)
                    {
                        backbufferStream.Write(packet.PacketPrefix);
                        SendBackbuffer();
                    }

                    if (packet.Packet.Length == 0)
                    {
                        break;
                    }

                    if (packet.Complete)
                    {
                        parser.ParseVideoData(packet.Packet);
                    }
                    else
                    {
                        backbufferStream.Write(packet.Packet);
                    }

                    ++count;

                    if (inputStream.Length == 0)
                    {
                        break;
                    }
                }
            }

            parser.SendEndOfStream();

            _renderingCompleted.Wait();
            watch.Stop();

            Marshal.FreeHGlobal(inputBufferPtr);
            Console.WriteLine($"Sent {count} packets.");
            Console.WriteLine($"Rendered {_displayedFrames} in {watch.Elapsed}. ~{Math.Round(_displayedFrames / watch.Elapsed.TotalSeconds, 2)} FPS.");

            return(0);
        }