我正在用 C# 编写一个媒体流系统,它需要首先流式传输音频,源是原始 PCM 数据作为字节流,但它需要将其编码为 AAC(不接受其他格式),而不是需要的作为字节流转发,然后再次解码为 RAW PCM 数据。
我只是找不到任何有用的解决方案。
我尝试过 NAudio,但它不支持编码流读取,除非用作MediaFoundationReader(URL_STRING)源,但它只接受文件路径或 URL。在本地创建 TCP HTTP 流服务器不是一个选项,因为从流创建文件也无法读取,并且 PCM->AAC 编码仍然无法以这种方式解决。
我尝试过 SharpDX,但我没有找到任何有用的示例来进行从流到流的转换。
我已经为 NAudio 编写了一个缓冲区作为Stream缓冲 PCM 数据流的接口,因此从技术上讲它可以从字节数组中读取,这可以用作编码器/解码器的输入和/或输出对象。
我也尝试过使用 MFLib 来使用 MediaFoundation 库,但是缺少示例或有用的文档并没有让我的工作变得更轻松,而且实际上对于那些想要在旧版 Windows 操作系统上使用该应用程序的用户来说这并不是最好的选择,因为MF仅适用于Win7+。
是否有任何有用的库可以相对简单地用于这些转换,或者我必须完全弄清楚如何解决这个实际上看起来很简单的问题?
由于 NAudio 和 SharpDX 都是开源的,因此可以接受对类的一些修改。
稍后该系统还需要支持 MP4 视频流,因此能够同时提供 AAC 和 MP4 音频/视频编码/解码的解决方案将是最好的。
我将很感激得到任何提示和/或来源/例子,可以为我的目标提供线索。谢谢。
我知道这个话题有时已经被问到了,并且我已经阅读了几乎所有的主题和评论,但是仍然找不到我的问题的答案。
我正在一个高性能的网络库中工作,该库必须具有TCP服务器和客户端,必须能够接受30000多个连接,并且吞吐量必须尽可能高。
我非常清楚我必须使用async方法,并且已经实现了我发现并测试过的所有解决方案。
在我的基准测试中,仅使用了最少的代码来避免范围内的任何开销,我使用了性能分析来最大程度地减少CPU负载,没有更多的空间可以进行简单的优化,在接收套接字上,总是读取,计数和丢弃缓冲区数据以避免套接字缓冲区完全填满。
这种情况非常简单:一个TCP套接字在本地主机上侦听,另一个TCP套接字连接到侦听套接字(从同一程序,在同一台计算机上),然后一个无限循环开始使用客户端套接字将256kB大小的数据包发送到服务器套接字。
间隔为1000毫秒的计时器将从两个插槽向控制台输出一个字节计数器,以使带宽可见,然后将其重置以进行下一次测量。
我已经意识到数据包大小的最佳点是256kB,套接字的缓冲区大小是64kB,以获得最大的吞吐量。
使用async/await类型方法,我可以达到
~370MB/s (~3.2gbps) on Windows, ~680MB/s (~5.8gbps) on Linux with mono
Run Code Online (Sandbox Code Playgroud)
使用BeginReceive/EndReceive/BeginSend/EndSend类型方法,我可以达到
~580MB/s (~5.0gbps) on Windows, ~9GB/s (~77.3gbps) on Linux with mono
Run Code Online (Sandbox Code Playgroud)
使用SocketAsyncEventArgs/ReceiveAsync/SendAsync类型方法,我可以达到
~1.4GB/s (~12gbps) on Windows, ~1.1GB/s (~9.4gbps) on Linux with mono
Run Code Online (Sandbox Code Playgroud)
问题如下:
async/await方法是最慢的,所以我不会使用它们BeginReceive/EndReceiveBeginAccept/EndAccept在Linux / mono下,方法和方法一起启动了新的异步线程,套接字的每个新实例都非常慢(当ThreadPoolmono中没有更多线程启动新线程,但是创建25个连接实例时大约需要5分钟 …我需要一个线程安全的高性能随机数生成器。我只需要值类型(ulong现在是)中的随机字节,而不是在范围内。我使用了 C# 内置Random类,但它有点慢而且不是线程安全的。
后来我转向实际上工作得很好的 XORShift 函数,但为了实现线程安全,我需要将计算放入 中lock,这会大大降低性能。
我用来生成随机ulong数的内容如下:
public class Rand
{
ulong seed = 0;
object lockObj = new object();
public Rand()
{
unchecked
{
seed = (ulong)DateTime.Now.Ticks;
}
}
public Rand(ulong seed)
{
this.seed = seed;
}
public ulong GetULong()
{
unchecked
{
lock (lockObj)
{
ulong t = 0;
t = seed;
t ^= t >> 12;
t ^= t << 25;
t ^= t >> 27;
seed = …Run Code Online (Sandbox Code Playgroud)