- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
对于我当前的项目,我正在读取 iPhone 的主摄像头输出。然后,我通过以下方法将像素缓冲区转换为缓存的 OpenGL 纹理:CVOpenGLESTextureCacheCreateTextureFromImage
。这在处理用于预览的相机帧时效果很好。测试了 iPhone 3GS、4、4S、iPod Touch(第 4 代)和 IOS5、IOS6 的不同组合。
但是,对于具有非常高分辨率的实际最终图像,这仅适用于这些组合:
这不适用于:iPhone 4 + IOS6。
控制台中的确切错误消息:
Failed to create IOSurface image (texture)
2012-10-01 16:24:30.663 GLCameraRipple[676:907] Error at CVOpenGLESTextureCacheCreateTextureFromImage -6683
我已通过更改 Apple 的 GLCameraRipple 项目来隔离此问题。你可以在这里查看我的版本:http://lab.bitshiftcop.com/iosurface.zip
以下是我如何将静止输出添加到当前 session :
- (void)setupAVCapture
{
//-- Create CVOpenGLESTextureCacheRef for optimal CVImageBufferRef to GLES texture conversion.
CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, [EAGLContext currentContext], NULL, &_videoTextureCache);
if (err)
{
NSLog(@"Error at CVOpenGLESTextureCacheCreate %d", err);
return;
}
//-- Setup Capture Session.
_session = [[AVCaptureSession alloc] init];
[_session beginConfiguration];
//-- Set preset session size.
[_session setSessionPreset:_sessionPreset];
//-- Creata a video device and input from that Device. Add the input to the capture session.
AVCaptureDevice * videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if(videoDevice == nil)
assert(0);
//-- Add the device to the session.
NSError *error;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if(error)
assert(0);
[_session addInput:input];
//-- Create the output for the capture session.
AVCaptureVideoDataOutput * dataOutput = [[AVCaptureVideoDataOutput alloc] init];
[dataOutput setAlwaysDiscardsLateVideoFrames:YES]; // Probably want to set this to NO when recording
//-- Set to YUV420.
[dataOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; // Necessary for manual preview
// Set dispatch to be on the main thread so OpenGL can do things with the data
[dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
// Add still output
stillOutput = [[AVCaptureStillImageOutput alloc] init];
[stillOutput setOutputSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
if([_session canAddOutput:stillOutput]) [_session addOutput:stillOutput];
[_session addOutput:dataOutput];
[_session commitConfiguration];
[_session startRunning];
}
下面是我如何捕获静态输出并对其进行处理:
- (void)capturePhoto
{
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in stillOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
[stillOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:
^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
// Process hires image
[self captureOutput:stillOutput didOutputSampleBuffer:imageSampleBuffer fromConnection:videoConnection];
}];
}
下面是纹理的创建方式:
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
CVReturn err;
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
size_t width = CVPixelBufferGetWidth(pixelBuffer);
size_t height = CVPixelBufferGetHeight(pixelBuffer);
if (!_videoTextureCache)
{
NSLog(@"No video texture cache");
return;
}
if (_ripple == nil ||
width != _textureWidth ||
height != _textureHeight)
{
_textureWidth = width;
_textureHeight = height;
_ripple = [[RippleModel alloc] initWithScreenWidth:_screenWidth
screenHeight:_screenHeight
meshFactor:_meshFactor
touchRadius:5
textureWidth:_textureWidth
textureHeight:_textureHeight];
[self setupBuffers];
}
[self cleanUpTextures];
NSLog(@"%zi x %zi", _textureWidth, _textureHeight);
// RGBA texture
glActiveTexture(GL_TEXTURE0);
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
_videoTextureCache,
pixelBuffer,
NULL,
GL_TEXTURE_2D,
GL_RGBA,
_textureWidth,
_textureHeight,
GL_BGRA,
GL_UNSIGNED_BYTE,
0,
&_chromaTexture);
if (err)
{
NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err);
}
glBindTexture(CVOpenGLESTextureGetTarget(_chromaTexture), CVOpenGLESTextureGetName(_chromaTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
对于解决这个问题有什么建议吗?
最佳答案
iPhone 4(以及 iPhone 3GS 和 iPod Touch 第 4 代)使用 PowerVR SGX 535 GPU,maximum OpenGL ES texture size is 2048x2048 .这个值可以通过调用找到
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
第 4 代 iPod Touch。摄像头分辨率为 720x960,iPhone 3GS 为 640x1136,但 iPhone 4 的后置摄像头分辨率为 1936x2592,这对于单个纹理来说太大了。
您始终可以在保持纵横比 (1529x2048) 的同时,以较小的尺寸重写捕获的图像。布拉德·拉尔森 (Brad Larson) 在 his GPUImage framework 上做了这件事,但它非常简单,只需使用 Core Graphics 重绘原始像素缓冲区的数据,然后从重绘数据中制作另一个像素缓冲区。框架的其余部分也是一个很好的资源。
关于ios - CVOpenGLESTextureCacheCreateTextureFromImage 无法创建 IOSurface,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12675655/
如何将一系列 IOSurfaces 绘制到另一个然后将其绘制到屏幕上?我在 MultiGPU 示例项目中尝试过一些来自苹果的源代码,但我设法做的最好的事情就是绘制一个白屏或获得大量的工件并使应用程序崩
这个问题是对: 的扩展链接-1:Creating an image out of the ios surface and saving it Link-2:Taking Screenshots fro
当我尝试编译我的调整时出现此错误。 'IOSurface/IOSurfaceAPI.h' file not found #include 我试过了 this answer ,但我在计算机上找不到 /
要使用快速屏幕截图,我需要执行一些 IOSurfaceRef 操作——使用 CARenderServerRenderDisplay(0, CFSTR("LCD"), iosurfaceref, 0,
如果我使用 IOSurface 框架为我的应用制作视频,苹果会拒绝我的应用吗 最佳答案 是的,如果您链接 IOSurface Apple 将拒绝您的应用程序。 商店中的一些项目正在使用它,但他们可
这是一个由两部分组成的问题。我有以下代码可以抓取当前显示表面并从表面创建视频(一切都在后台发生)。 for(int i=0;i<100;i++){ IOMobileFramebuf
对于我当前的项目,我正在读取 iPhone 的主摄像头输出。然后,我通过以下方法将像素缓冲区转换为缓存的 OpenGL 纹理:CVOpenGLESTextureCacheCreateTextureFr
写入IOSurface时需要使用哪些API,以及需要采取哪些预防措施在 XPC 进程中,该进程也被用作 MTLTexture 的后备存储。在主应用程序中? 在我的 XPC 服务中,我有以下内容: IO
我想使用 mipmapping 渲染 IOSurface 纹理。 我正在从 IOSurface 生成 OpenGL 纹理,如下所示: let error = CGLTexImageIOSurface2
我正在尝试修改 Apple MultiGPUIOSurface 示例(特别是文件 http://developer.apple.com/library/mac/#samplecode/MultiGPU
我正在尝试在 Swift 中创建一个 IOSurface,然后从中创建一个 CIImage。 IOSurfaceRef 看起来不错,但 CIImage 返回 nil: textureImage
我在 iOS 12 及更高版本的应用程序中遇到内存问题。 IOSurface 在 iOS 12.1.1 中同时逐渐增加,在 iOS 11 版本中运行良好。我在下面附上了问题截图, 为什么iOS 12版
我有一个 IOSurface 支持的 CVPixelBuffer,它以 30fps 从外部源更新。我想在 NSView 中呈现图像数据的预览——对我来说最好的方法是什么? 我可以直接在 View 上设
我正在尝试使用 CVPixelBufferCreateWithIOSurface 和从 IOSurfaceGetBaseAddressOfPlane 读取像素来捕获 IOSurface。 但是,在较新
我想从后台服务截屏。私有(private) API 很好,因为我不需要提交到应用商店。我已经尝试过 UIGetScreenImage,它在后台应用程序中不起作用。 我正在使用从 SO 获得的以下代码。
这个错误很奇怪。昨天一切都很好。我安装了Xcode 9 beta,然后我使用Xcode 8在iPhone 6p,iOS 9.3.2上运行我的应用程序(我昨天可以这样做,我可以仍然在模拟器上运行应用程序
当我运行我的项目时,你能帮我解决这个问题吗: Could not load IOSurface for time string. Rendering locally instead 我不知道我的编码是
在使用我的 ipad 应用程序时,我收到了一系列警告(Mar 18 11:18:06 kernel[0] : IOSurface warning: buffer allocation failed.
所以我从网络回调(voip 应用程序)中获取 3 个单独数组中的原始 YUV 数据。根据我的理解,您不能根据 here 使用 CVPixelBufferCreateWithPlanarBytes 创建
我收到 YUV 帧 (kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),当从 CVPixelBufferRef 创建 CIImage 时,我得到: in
我是一名优秀的程序员,十分优秀!