【问题标题】:CIContext drawImage causes EXC_BAD_ACCESS - iOS 6CIContext drawImage 导致 EXC_BAD_ACCESS - iOS 6
【发布时间】:2013-05-31 02:13:58
【问题描述】:

我正在尝试将一个简单的核心图像过滤器应用于实时摄像机输入。我认为我的代码没问题,但是在 captureOutput 方法中使用方法 drawImage:inRect:fromRect 会导致 EXC_BAD_ACCESS[__NSCFNumber drawImage:inRect:fromRect:]: unrecognized 选择器,这让我认为当我尝试在其上调用 drawImage 时我的上下文已被释放。这对我来说没有意义,因为我的 CIContext 是班级成员。

问题似乎不是来自 OpenGL,因为我尝试使用简单的上下文(不是从 EAGLContext 创建的)并且我遇到了同样的问题。

我正在使用 ios 6 的 iphone 5 上对其进行测试,因为相机无法在模拟器上工作。

你能帮我吗?非常感谢您的宝贵时间

我有我的 .h 文件:

<!-- language: c# -->

    //  CameraController.h

    #import <UIKit/UIKit.h>
    #import <OpenGLES/EAGL.h>
    #import <AVFoundation/AVFoundation.h>
    #import <GLKit/GLKit.h>
    #import <CoreMedia/CoreMedia.h>
    #import <CoreVideo/CoreVideo.h>
    #import <QuartzCore/QuartzCore.h>
    #import <CoreImage/CoreImage.h>
    #import <ImageIO/ImageIO.h>

    @interface CameraController : GLKViewController <AVCaptureVideoDataOutputSampleBufferDelegate>{

        AVCaptureSession *avCaptureSession;
        CIContext *coreImageContext;
        CIContext *ciTestContext;
        GLuint _renderBuffer;
        EAGLContext *glContext;
    }

    @end

还有我的 .m 文件

<!-- language: c# -->

    //  CameraController.m

    #import "CameraController.h"

    @interface CameraController ()

    @end

    @implementation CameraController

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {

        }
        return self;
    }

    - (void)viewDidLoad
    {
        [super viewDidLoad];

        // Initialize Open GL ES2 Context
        glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        if (!glContext) {
            NSLog(@"Failed to create ES context");
        }
        [EAGLContext setCurrentContext:nil];

        // Gets the GL View and sets the depth format to 24 bits, and the context of the view to be the Open GL context created above
        GLKView *view = (GLKView *)self.view;
        view.context = glContext;
        view.drawableDepthFormat = GLKViewDrawableDepthFormat24;

        // Creates CI Context from  EAGLContext
        NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
        [options setObject: [NSNull null] forKey: kCIContextWorkingColorSpace];
        coreImageContext = [CIContext contextWithEAGLContext:glContext options:options];

        glGenRenderbuffers(1, &_renderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffer);

        // Initialize Video Capture Device
        NSError *error;
        AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];

        // Initialize Video Output object and set output settings
        AVCaptureVideoDataOutput *dataOutput = [[AVCaptureVideoDataOutput alloc] init];

        [dataOutput setAlwaysDiscardsLateVideoFrames:YES];
        [dataOutput setVideoSettings:[NSDictionary  dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
                                                                  forKey:(id)kCVPixelBufferPixelFormatTypeKey]];


        // Delegates the SampleBuffer to the current object which implements the AVCaptureVideoDataOutputSampleBufferDelegate interface via the captureOutput method
        [dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

        // Initialize the capture session, add input, output, start urnning
        avCaptureSession = [[AVCaptureSession alloc] init];
        [avCaptureSession beginConfiguration];
        [avCaptureSession setSessionPreset:AVCaptureSessionPreset1280x720];
        [avCaptureSession addInput:input];
        [avCaptureSession addOutput:dataOutput];
        [avCaptureSession commitConfiguration];
        [avCaptureSession startRunning];


    }

    -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {

        // Creates a CIImage from the sample buffer of the camera frame
        CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
        CIImage *inputImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];

        // Creates the relevant filter
        CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"];
        [filter setValue:inputImage forKey:kCIInputImageKey];
        [filter setValue:[NSNumber numberWithFloat:0.8f] forKey:@"InputIntensity"];

        // Creates a reference to the output of the filter
        CIImage *result = [filter valueForKey:kCIOutputImageKey];

        // Draw to the context
        [coreImageContext drawImage:result inRect:[result extent] fromRect:[result extent]]; // 5

        [glContext presentRenderbuffer:GL_RENDERBUFFER];
    }

    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }


    @end

【问题讨论】:

    标签: ios ios6 opengl-es-2.0 avfoundation core-image


    【解决方案1】:

    在你的 viewDidLoad 方法中,你有:

    coreImageContext = [CIContext contextWithEAGLContext:glContext options:options];
    

    如果要在 captureOutput 方法中使用 coreImageContext 需要保留。

    【讨论】:

    • 好的,谢谢你现在它正在工作,是不是因为 captureOutput 是协议的实现?
    • 不,这是因为从 contextWithEAGLContext 返回的 CIContext 对象是一个自动释放的对象。当它到达 captureOutput 方法时,它已经被释放了。
    • 您能否提供有关您如何保留该对象的详细信息。我正在尝试实现与您类似的东西,并且遇到对象被解除分配的相同问题。我尝试通过使变量成为强原子属性来保留对象[在启用 ARC 的目标 C 中],但应用程序仍然抛出相同的 BAD_ACCESS 异常 [在僵尸中发送的消息:发送到已释放实例的消息]
    • 如果我看到一些代码真的会有所帮助。也许你可以问一个单独的问题?
    • 此方法在 setTime 方法期间被调用,该方法调用每个时间帧。 - (void)updateImage { if (!_transitionFilter) { _transitionFilter = [CIFilter filterWithName:@"CIPerspectiveTransform"]; [_transitionFilter setDefaults]; } } _transitionFilter ,对象被释放了一些时间。我们观察到的是,如果我们保留对象 _transitionFilter = [CIFilter filterWithName:@"CIPerspectiveTransform"];在 @synchrozed 块的旁边,它正在工作。但我们不知道原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    • 2018-07-26
    • 1970-01-01
    • 2012-07-27
    • 2016-11-19
    • 2012-10-02
    • 2011-04-14
    相关资源
    最近更新 更多