2012-10-01 16 views
17

बनाने में विफल रहता है मेरे वर्तमान प्रोजेक्ट के लिए मैं आईफोन का मुख्य कैमरा आउटपुट पढ़ रहा हूं। मैं फिर पिक्सेलबफर को कैश किए गए ओपनजीएल बनावट में विधि के माध्यम से परिवर्तित कर रहा हूं: CVOpenGLESTextureCacheCreateTextureFromImage। पूर्वावलोकन के लिए उपयोग किए जाने वाले कैमरे के फ्रेम को संसाधित करते समय यह बहुत अच्छा काम करता है। आईफोन 3 जीएस, 4, 4 एस, आईपॉड टच (चौथा जीन) और आईओएस 5, आईओएस 6 के साथ विभिन्न संयोजनों पर परीक्षण किया गया। आईओएस 5.1.1 CVOpenGLESTextureCacheCreateTextureFromImage IOSurface

  • iPhone 4 + आईओएस 5.1.1
    • iPhone 3GS +:

      लेकिन, वास्तविक अंतिम छवि, एक बहुत ही उच्च संकल्प है जो के लिए, यह केवल इन संयोजनों पर काम करता है

    • iPhone 4S + आईओएस 6.0
    • आइपॉड टच (4 जनरल) + आईओएस 5,0

    और इस के लिए काम नहीं करता है: iPhone 4 + IOS6।

    कंसोल में सटीक त्रुटि संदेश:

    Failed to create IOSurface image (texture) 
    2012-10-01 16:24:30.663 GLCameraRipple[676:907] Error at CVOpenGLESTextureCacheCreateTextureFromImage -6683 
    

    मैं एप्पल से GLCameraRipple परियोजना को बदलने के द्वारा इस समस्या को अलग-थलग पड़ गए हैं। आप यहाँ पर मेरे संस्करण की जाँच कर सकते हैं: http://lab.bitshiftcop.com/iosurface.zip

    यहाँ कैसे मैं वर्तमान सत्र के लिए stilloutput जोड़ते हैं:

    - (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); 
    } 
    

    कोई भी इस समस्या के समाधान के लिए सुझाव?

    +0

    मैं अब कई उपकरणों पर परीक्षण कर रहा हूं और अब तक यह अभी भी अद्वितीय कॉम्बो है: आईफोन 4 + आईओएस 6.0। यहां तक ​​कि आइपॉड टच (चौथा जीन) कैमरा फ्रेम को जीएलएस बनावट में परिवर्तित कर सकता है। – polyclick

    उत्तर

    1

    हम अभी भी एक छवि बनावट को एक CVOpenGLESTextureCacheRef पर नहीं डाल सकते हैं। कोर वीडियो आपको वीडियो फ्रेम सीधे ओपनजीएल बनावट में मैप करने देता है। एक वीडियो बफर का उपयोग करना जहां कोर वीडियो बनावट बनाता है और उन्हें पहले से ही वीडियो मेमोरी में देता है।

    OpenGLES बनावट इस लिंक आप Link

    2

    मदद मिल सकती है iPhone 4 बनाने के लिए (और साथ ही iPhone 3GS और आइपॉड टच 4 पीढ़ी।) एक PowerVR SGX 535 GPU है, जिसके लिए maximum OpenGL ES texture size is 2048x2048 उपयोग करता है। यह मान

    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); 
    

    आईपॉड टच 4 वें जीन को कॉल करके पाया जा सकता है। 720x960 का कैमरा रिज़ॉल्यूशन और आईफोन 3 जीएस, 640x1136 है, लेकिन आईफोन 4 का पिछला चेहरा वाला कैमरा रेज़ोल्यूशन 1 9 36x2592 है, जो एक बनावट पर फिट होने के लिए बहुत बड़ा है।

    पहलू अनुपात (1529x2048) को संरक्षित करते समय आप हमेशा छोटे आकार पर कैप्चर की गई छवि को फिर से लिख सकते हैं। ब्रैड लार्सन his GPUImage framework पर यह ओवर करता है, लेकिन यह कोर सीधा ग्राफिक्स का उपयोग करके मूल पिक्सेल बफर के डेटा को फिर से खींचा जा रहा है और फिर एक और पिक्सेल बफर को फिर से खींचे गए डेटा से बाहर कर रहा है। बाकी ढांचा भी एक महान संसाधन है।