2013-02-18 66 views
2

我的C#代码中有30FPS的视频帧,我想在本地主机上广播它,以便所有其他应用程序都可以使用它。我虽然是因为它是一个视频,并且没有任何问题,如果任何数据包丢失,并且不需要连接/从客户端接受,UDP是一个不错的选择。通过套接字传输视频的帧

但这里有很多问题。

  • 如果我使用UDP单播的速度是不够的,大约25FPS(CPU使用率是25% 是在我的4核CPU的一个线程是指100%,这是不理想,但 至少它发送足够的一套数据)。但单播不能向所有客户端发送数据 。
  • 如果我用广播速度很低。大约10FPS具有相同的CPU使用率。

我该怎么办?数据在同一台计算机中,因此不需要从局域网等进行远程访问。我只是希望在同一台机器的不同应用程序之间每秒钟传输大约30MBytes的数据。 (640x480是固定大小的图像×30fps×3byte每像素约为27000KByte每秒)

  1. UDP Multicast是否有更好的性能?
  2. 即使我接受每个客户端 并单独发送给他们,TCP是否可以给我更好的性能?
  3. 有没有比Socket更好的方法?记忆共享什么的?!
  4. 为什么UDP广播很慢?!只有约10MBy每 秒?!
  5. 是否有一种快速压缩具有高性能帧的方法(至 每秒编码30fps并在其他部分解码)?客户端应用程序在 C++中,所以这必须是跨平台的方式。

我只想知道其他开发人员的经验和想法,所以请写下您的想法。 感谢您的帮助。

编辑:有关数据

更多信息:数据是位图格式RGB24,他们是从设备分流到我的30FPS的应用程序。我想将这些数据广播给其他应用程序,并且他们需要再次以RGB24格式显示此图像。没有标题或任何东西,只有固定大小的位图数据。所有操作必须在飞行中执行。无论使用有损压缩算法还是任何事物。

+0

是有一些原因的许多现有的视频流的协议之一是不合适的,以及为什么使用许多视频流媒体解决方案的一个都不行?这是一个已经通过多种不同方式解决的问题。当然,其中一种方法应该能够满足您的需求,而不需要您重新发明轮子。 – Pete 2013-02-18 17:38:08

+0

@Pete,你知道任何基于UDP的跨平台(.Net,C++)视频流媒体库吗?!不幸的是我找不到一个。因为在没有库的情况下实现这些协议之一并不容易,因此发明整个解决方案并不容易 – 2013-02-18 17:47:03

+0

查看FFMPEG – Pete 2013-02-18 17:50:34

回答

2

我在一个工业环境中试验多播,这是一个很好的选择通过一个不稳定的可靠网络

本地主机共享存储器可能是一个很好的选择,因为你可以建立帧的圆形队列,并从一个到下一个只用一个单一的互斥来保护一个指针分配翻转(writter侧)。只需一名作者,几名读者,就不会出现问题。

在Windows上使用C++ C#共享内存称为文件映射,但您可以使用系统分页文件(RAM和/或磁盘)。

看到这些详细信息的链接

共享内存空间没有保护,也没有私人但它的名字。

通常,作者进程创建它,读者通过它的名字打开它。防病毒软件以与其他所有方式相同的方式查看这种I/O,但不阻止通信。

这里是开始与文件映射的例子:

char shmName[MAX_PATH+1]; 
sprintf(shmName, "shmVideo_%s", name); 
shmName[MAX_PATH] = '\0'; 
_hMap = 
    CreateFileMapping(
     INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, shmName); 
if(_hMap == 0) { 
    throw OSException(__FILE__, __LINE__); 
} 
_owner = (GetLastError() != ERROR_ALREADY_EXISTS); 
_mutex = Mutex::getMutex(name); 
Synchronize sync(*_mutex); 
_data = (char *)MapViewOfFile(_hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
if(_data == 0) { 
    throw OSException(__FILE__, __LINE__); 
} 
+0

这似乎是一个很好的答案。谢谢,但我有一些关于内存映射文件的问题。首先,我如何从非托管端(C++客户端)访问其他托管进程内存文件?其次,用户权限,防病毒和其他安全软件/限制怎么样? – 2013-02-20 21:06:58

+0

好的谢谢。让我看看,我会接受你的答案。目前我不能给予赏金,因为它需要更多的7个小时:) – 2013-02-20 22:12:50

+0

目前使用内存映射文件,它有非常好的性能。幸运的是,从托管和非托管端访问它没有问题。只有一些人需要注意的是多进程写入,它们需要很少的精确度。谢谢。 – 2013-02-21 16:29:45

0

使用live555 http://www.live555.com/与您最喜爱的压缩器 - ffmpeg组合使用。

+0

那么我怎样才能使用它来发送位图数据?!这是一个现场凸轮,所以我不能将它们保存到磁盘,然后使用FFMPEG将它们转换为视频,然后使用Live555发送它们!我需要某种实时解决方案,它能够将30位图从内存编码到视频(再次在内存中,位图流是流式传输,因此它们在应用程序启动时不可用),然后使用其他解决方案(或相同的库或I可以写这个发送部分)发送给其他应用程序。他们还必须能够将数据解码到内存中的RGB数据帧。 – 2013-02-19 19:29:52