예제 #1
0
        private static Adapter GetAdapterByContext(CuContext context)
        {
            var contextDevice = context.GetDevice();

            using var factory = new Factory1();

            foreach (var adapter in factory.Adapters)
            {
                var device = CuDevice.GetD3D11Device(adapter.NativePointer);

                if (device.Handle == contextDevice.Handle)
                {
                    return(adapter);
                }

                adapter.Dispose();
            }

            throw new Exception("Unable to locate display adaptor for context.");
        }
예제 #2
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);
        }