我正在为一个客户端开发一个现有的(非app-store)应用程序,该应用程序使用IOSurface私有框架在后台进行屏幕捕获.这里有几个线程概述了技术,以及几个开源示例项目.
同样,这是客户端使用的内部应用程序.它不适用于app-store发布,因此它使用私有框架的事实是可以接受的.
这是Github上的一个示例项目,它使用了一种非常相似的技术:
https://github.com/k06a/UIView-FastScreenshot
我只是尝试在最新的iOS 9测试版上运行客户端的应用程序,并且它因无法加载库CoreSurface的错误而崩溃.
我已经看到文档CoreSurface是框架的先前名称IOSurface,但似乎在iOS 8中确实存在一个私有框架CoreSurface以及一个名为的私有框架IOSurface.
还有其他人能够用来IOSurface在iOS 9中从后台进行屏幕截图吗?
我正在为任何可以给我一个方法来为iOS 9做这个工作的人添加赏金(再次,私有框架很好,但它不能在Jailbroken设备上)
我正在尝试使用屏幕上的数据创建 H.264 压缩会话。我创建了一个CGDisplayStreamRef这样的实例:
displayStream = CGDisplayStreamCreateWithDispatchQueue(0, 100, 100, k32BGRAPixelFormat, nil, self.screenCaptureQueue, ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef) {
//Call encoding session here
});
Run Code Online (Sandbox Code Playgroud)
以下是我目前如何设置编码功能:
- (void) encode:(CMSampleBufferRef )sampleBuffer {
CVImageBufferRef imageBuffer = (CVImageBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
CMTime presentationTimeStamp = CMTimeMake(frameID++, 1000);
VTEncodeInfoFlags flags;
OSStatus statusCode = VTCompressionSessionEncodeFrame(EncodingSession,
imageBuffer,
presentationTimeStamp,
kCMTimeInvalid,
NULL, NULL, &flags);
if (statusCode != noErr) {
NSLog(@"H264: VTCompressionSessionEncodeFrame failed with %d", (int)statusCode);
VTCompressionSessionInvalidate(EncodingSession);
CFRelease(EncodingSession);
EncodingSession = NULL;
return;
}
NSLog(@"H264: VTCompressionSessionEncodeFrame Success");
}
Run Code Online (Sandbox Code Playgroud)
我试图了解如何将屏幕上的数据转换为 ,CMSampleBufferRef以便我可以正确调用我的编码功能。到目前为止,我无法确定这是否可行,或者我正在尝试做的事情的正确方法。有没有人有什么建议? …
我的iOS 12及更高版本的应用程序中遇到内存问题。IOSurface在iOS 12.1.1中逐渐同时增加,因为它在iOS 11版本中可以正常工作。我已在下面附上问题截图,
为什么在iOS 12版本中会发生此问题?有人可以帮我解决这个问题吗?我在iOS 11版本中进行了交叉检查,并且工作正常。
这个问题大致与this有关。
我有一个 SceneKit 项目,其中内存管理一直是一个挑战(是的,即使使用 ARC)。
通过以非常具体的方式加载图像,通过weak在闭包中使用变量,以及通过在场景释放之前将SCNMaterials 设置为nil,我已经能够极大地改善内存情况。
这是我加载图像的方式:
DispatchQueue.global(qos: .background).async { [weak material] in
let path = Bundle.main.path(forResource: "myString", ofType: "png")!
let img = UIImage(contentsOfFile: path)
material?.diffuse.contents = img
}
Run Code Online (Sandbox Code Playgroud)
然而,Instruments显示类别的内存VM: IOSurface或多或少地持续增加,但从未被充分回收。根据文档,IOSurface与图像内存有关。
以下是Instruments Allocations显示的内容VM: IOSurface(这里的内存从大约 17MB 到大约 69MB):

对于上图,我多次加载然后卸载 SceneKit 场景。
下面的图表说明了此IOSurface内存与总体内存占用量的关系:

现在,您可能认为我应该使用UIImage(named:)而不是UIImage(contentsOfFile:),因为系统将前者缓存在内存中,而不是后者。但使用前者会导致我的项目中的内存统计数据更差。
我已经看到了这个问题,但它表明问题出在设备摄像头上,而我没有使用它。
问题:您能告诉我IOSurface与 SceneKit 的关系吗?我如何提高其内存使用率?
我正在与CGContextDrawImage/CGDataProviderCopyData函数中的内部缓存(15 mp 图像大约 90 MB)作斗争。
这是分析器中的堆栈跟踪:
在所有情况下,IOSurface都是作为“缓存”创建的,并且在@autoreleasepool排空后不会被清除。
这给应用程序留下了极少的生存机会。
缓存并不取决于图像大小:我试图呈现512x512,以及4500x512和4500x2500(全尺寸)图像块。
在清理它们之前@autoreleasepool,我使用,CFGetRetainCount返回1所有CG对象。
操作数据的代码:
+ (void)render11:(CIImage*)ciImage fromRect:(CGRect)roi toBitmap:(unsigned char*)bitmap {
@autoreleasepool
{
int w = CGRectGetWidth(roi), h = CGRectGetHeight(roi);
CIContext* ciContext = [CIContext contextWithOptions:nil];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef cgContext = CGBitmapContextCreate(bitmap, w, h,
8, w*4, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGImageRef cgImage = [ciContext createCGImage:ciImage
fromRect:roi
format:kCIFormatRGBA8
colorSpace:colorSpace
deferred:YES];
CGContextDrawImage(cgContext, CGRectMake(0, …Run Code Online (Sandbox Code Playgroud) 在写入IOSurface同时用MTLTexture作主应用程序中的后备存储的 XPC 进程时,我需要使用哪些 API,以及需要采取哪些预防措施?
在我的 XPC 服务中,我有以下内容:
IOSurface *surface = ...;
CIRenderDestination *renderDestination = [... initWithIOSurface:surface];
// Send the IOSurface to the client using an NSXPCConnection.
// In the service, periodically write to the IOSurface.
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,我有以下内容:
IOSurface *surface = // ... fetch IOSurface from NSXPConnection.
id<MTLTexture> texture = [device newTextureWithDescriptor:... iosurface:surface];
// The texture is used in a fragment shader (Read-only)
Run Code Online (Sandbox Code Playgroud)
我有一个MTKView正在运行它的正常更新循环。我希望我的 XPC 服务能够定期写入IOSurface使用的 Core Image,然后在应用程序端由 Metal 呈现新内容。
需要什么同步才能确保正确完成?双缓冲或三缓冲策略是一种,但这对我来说并不真正有效,因为我可能没有足够的内存来分配 2 倍或 3 …
当尝试调试某些CoreImage渲染为何会显着增加CPU使用率时,我可以在示例跟踪中看到,当我以某些方式裁剪和合成图像时,CoreImage正在执行memcpys。当我取出作物过滤器时,它消失了。我将其用于实时2D视频管道,所以这不好。
我所有的图像都在GPU上,因此我对其在CPU上复制的内容感到困惑。
任何人都有任何想法可能会做什么?
+ ! 457 -[CIContext render:toCVPixelBuffer:bounds:colorSpace:] (in CoreImage) + 1296 [0x7fff8db01111]
+ ! 457 -[CIContext render:toIOSurface:bounds:colorSpace:] (in CoreImage) + 1907 [0x7fff8db030e5]
+ ! 455 CI::image_render_to_surface(CI::Context*, CI::Image*, CGRect, CGColorSpace*, __IOSurface*, CGPoint, CI::PixelFormat) (in CoreImage) + 1862 [0x7fff8db1d8a9]
+ ! : 451 CI::_image_render(char const*, CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::PixelFormat, unsigned long, CGPoint const&, CI::swizzle_info const&) (in CoreImage) + 869 [0x7fff8db1cdda]
+ ! : | 443 CI::tile_node_graph(CI::Context*, char const*, CI::Node*, CGRect const&, CI::PixelFormat, CI::swizzle_info const&, void (CI::Node*, CGRect) block_pointer) (in CoreImage) …Run Code Online (Sandbox Code Playgroud) iosurface ×7
ios ×3
core-image ×2
macos ×2
memory ×2
metal ×2
caching ×1
ciimage ×1
h.264 ×1
ios9 ×1
memory-leaks ×1
objective-c ×1
scenekit ×1
screenshot ×1
swift ×1
xpc ×1