流媒体播放音乐时CPU贪婪循环
本文关键字:贪婪 循环 CPU 媒体播放 音乐 | 更新日期: 2023-09-27 18:27:21
为了提供一些上下文,我正在开发一个开源的替代桌面Spotify客户端,其核心是可访问性。你还会在这里看到一些NAudio。
播放一开始,我就注意到CPU使用非常频繁。即使在暂停时,CPU也很高。
我运行了Visual Studio的内置探查器,试图了解可能发生的任何资源占用。正如我所怀疑的,问题出在我的播放管理器的流媒体循环中。
探查器标记为最丰富样本之一的代码如下:
const int secondsToBuffer = 3;
private void GetStreaming(object state)
{
this.fullyDownloaded = false;
// secondsToBuffer is an integer to represent how many seconds we should buffer up at once to prevent choppy playback on slow connections
try
{
do
{
if (bufferedWaveProvider == null)
{
this.bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(44100, 2));
this.bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(20); // allow us to get well ahead of ourselves
Logger.WriteDebug("Creating buffered wave provider");
this.gatekeeper.MinimumSampleSize = bufferedWaveProvider.WaveFormat.AverageBytesPerSecond * secondsToBuffer;
}
// this bit in particular seems to be the hot point
if (bufferedWaveProvider != null && bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes < bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4)
{
Logger.WriteDebug("Buffer getting full, taking a break");
Thread.Sleep(500);
}
// do we have at least double the buffered sample's size in free space, just in case
else if (bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes > bufferedWaveProvider.WaveFormat.AverageBytesPerSecond * (secondsToBuffer * 2))
{
var sample = gatekeeper.Read();
if (sample != null)
{
bufferedWaveProvider.AddSamples(sample, 0, sample.Length);
}
}
} while (playbackState != StreamingPlaybackState.Stopped);
Logger.WriteDebug("Playback stopped");
}
finally
{
// no post-processing work here, right?
}
}
NAudio样本是我用这种方法处理流媒体的灵感来源。要查找完整文件的源代码,您可以在此处查看:http://blindspot.codeplex.com/SourceControl/latest#Blindspot.Playback/PlaybackManager.cs
我是一个分析的新手,也不是流媒体的年度专家(两者可能都很明显)。
有什么办法可以减少这个循环的资源密集度吗。在缓冲区已满的if块中增加睡眠量会有帮助吗?还是我找错树了。看起来会的,但我本以为半秒钟就足够了。
感谢您的帮助。
基本上,您已经创建了一个无限循环,直到缓冲区满为止。你用标记的部分
// this bit in particular seems to be the hot point
可能是因为if语句中的计算只是一次又一次地重复;它们中的任何一个能移出循环吗?
我会在while语句之前加一个Thread.Sleep(50)来防止颠簸,看看这是否有什么不同(我怀疑会的)。