通过命名管道发送的视频帧非常慢

时间:2018-03-21 00:28:59

标签: c# .net named-pipes

我有一个应用程序可以处理带有附加图形的视频,并在Windows窗体中显示输出。我不得不将视频处理分离为后台进程/服务,并将视频/帧显示到前端UI。这些图像一旦准备就会通过命名管道发送。

一切正常,但问题是通过命名管道发送视频非常慢。这是相关代码:

后台流程:

if (serverPipe.isConnected()) {
   ImageConverter converter = new ImageConverter();
   erverPipe.WriteBytes((byte[])converter.ConvertTo(_currentImage.ToBitmap(), typeof(byte[])));
   serverPipe.Flush();
}

Foreground UI app:

clientPipe.DataReceived += (sndr, args) =>
{
    form.updatePictureBox(args.Data);
};

命名管道代码来自这篇文章: c# Full Duplex Asynchronous Named Pipes .NET

Github链接:https://github.com/cliftonm/clifton/tree/master/Clifton.Core/Clifton.Core.Pipes

我通过命名管道获得的FPS接近每秒1或2帧。我不确定我是否正在处理命名管道工作方式的限制或我的代码效率低下。

1 个答案:

答案 0 :(得分:0)

我使用您提到的库编写了一个客户端和一个服务器控制台应用程序,在我的机器上,在两个进程之间发送4 MB数据大约需要50-60ms。因此,我认为您不处理命名管道限制。我建议您尝试测量代码的其他部分,并尝试缩小低FPS的原因。

服务器

using Clifton.Core.Pipes;
using System;
using System.Diagnostics;

namespace NamedPipeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServer();
            Console.ReadLine();
        }

        private static void StartServer()
        {
            ServerPipe serverPipe = new ServerPipe("Test", p => p.StartByteReaderAsync());
            var sw = new Stopwatch();

            serverPipe.Connected += (s, ea) => {
                Console.WriteLine("Server connected");
                sw.Start();
            };
            serverPipe.DataReceived += (s, ea) => {
                Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.fff")}\t {sw.ElapsedMilliseconds}\t Data received. Length: {ea.Len}");
                sw.Restart();
            };
        }
    }

<强>客户端

using Clifton.Core.Pipes;
using System;

namespace NamedPipeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            StartClient(iterations: 100);
            Console.ReadLine();
        }

        private static void StartClient(int iterations)
        {
            ClientPipe clientPipe = new ClientPipe(".", "Test", p => p.StartByteReaderAsync());
            clientPipe.Connect();

            byte[] data = CreateRandomData(sizeMb: 4);

            for (int i = 0; i < iterations; i++)
            {
                clientPipe.WriteBytes(data);
                Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.fff")}\t Wrote data {i}");
            }
        }

        private static byte[] CreateRandomData(int sizeMb)
        {
            var data = new byte[1024 * 1024 * sizeMb];
            new Random().NextBytes(data);
            return data;
        }
    }
}