如何加快缩放图像的绘制速度?调整窗口大小期间音频播放卡住

发布于 2024-08-26 13:06:04 字数 1136 浏览 2 评论 0原文

我正在为 OSX 编写一个音频播放器。一种视图是显示波形的自定义视图。波形存储为带有 NSBitmapImageRepNSImage 类型的实例变量。该视图还显示进度指示器(粗红线)。因此,它每 30 毫秒更新/重绘一次。

由于重新计算图像需要相当长的时间,因此每次调整窗口大小并在新图像准备好后更新显示的图像后,我都会在后台线程中执行此操作。同时,原始图像会进行缩放以适合视图,如下所示:

// The drawing rectangle is slightly smaller than the view, defined by
//   the two margins.
NSRect drawingRect;
drawingRect.origin = NSMakePoint(sideEdgeMarginWidth, topEdgeMarginHeight);
drawingRect.size = NSMakeSize([self bounds].size.width-2*sideEdgeMarginWidth,
                              [self bounds].size.height-2*topEdgeMarginHeight);
[waveform drawInRect:drawingRect
            fromRect:NSZeroRect
           operation:NSCompositeSourceOver
            fraction:1];

视图构成了窗口的最大部分。在实时调整大小期间,音频开始窒息。在我的 Macbook Pro 上选择“大”显卡可以让情况有所好转,但也不会差很多。实时调整大小期间,CPU 利用率约为 20-40%。
Instruments 表明问题在于图像的重新缩放/重绘。一旦我停止调整窗口大小,CPU 利用率就会下降,音频也会停止出现故障。

我已经尝试禁用图像插值以加快绘图速度,如下所示:

[[NSGraphicsContext currentContext] 
    setImageInterpolation:NSImageInterpolationNone];

这有帮助,但在实时调整大小时音频仍然会卡住。

您知道如何改进吗?
最主要的是防止音频哽咽。

I am writing an audio player for OSX. One view is a custom view that displays a waveform. The waveform is stored as a instance variable of type NSImage with an NSBitmapImageRep. The view also displays a progress indicator (a thick red line). Therefore, it is updated/redrawn every 30 milliseconds.

Since it takes a rather long time to recalculate the image, I do that in a background thread after every window resize and update the displayed image once the new image is ready. In the meantime, the original image is scaled to fit the view like this:

// The drawing rectangle is slightly smaller than the view, defined by
//   the two margins.
NSRect drawingRect;
drawingRect.origin = NSMakePoint(sideEdgeMarginWidth, topEdgeMarginHeight);
drawingRect.size = NSMakeSize([self bounds].size.width-2*sideEdgeMarginWidth,
                              [self bounds].size.height-2*topEdgeMarginHeight);
[waveform drawInRect:drawingRect
            fromRect:NSZeroRect
           operation:NSCompositeSourceOver
            fraction:1];

The view makes up the biggest part of the window. During live resize, audio starts choking. Selecting the "big" graphic card on my Macbook Pro makes it less bad, but not by much. CPU utilization is somewhere around 20-40% during live resizes.
Instruments suggests that rescaling/redrawing of the image is the problem. Once I stop resizing the window, CPU utilization goes down and audio stops glitching.

I already tried to disable image interpolation to speed up the drawing like this:

[[NSGraphicsContext currentContext] 
    setImageInterpolation:NSImageInterpolationNone];

That helps, but audio still chokes during live resizes.

Do you have an idea how to improve this?
The main thing is to prevent the audio from choking.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我鬧 2024-09-02 13:06:04

图形重画不应影响音频播放。我有一个音频应用程序,可以在调整窗口大小时进行实时重绘,还有一个后台线程来渲染波形,并且播放音频没有问题。 ioProc 读取音频数据的音频线程是一个实时线程,并且比大多数其他线程具有更高的优先级。

如果您的图形线程有锁或调用了音频线程中阻塞(包括内存分配或释放)某些内容的内容,则可能会导致音频卡顿。多线程问题比较复杂,需要处理数据结构的线程安全、锁、优先级反转、阻塞等很多问题。

The graphics redraw should not affect audio playback. I have an audio app that does live redraw when resizing the window, as well as a background thread to render the waveform, and it has no problem playing back audio. The audio thread that the ioProc which reads the audio data is a real-time thread, and has a higher priority than most other threads.

If your graphics thread has a lock or calls something that blocks (including memory allocations or freeing) something in the audio thread, that could cause the audio to stutter. Multi-threading issues are complex, with issues such as thread-safety of data structures, locks, priority inversion, blocking, and many other things to deal with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文