Вызов appendPixelBuffer из AVAssetWriterInputPixelBufferAdaptor Причины EXC_BAD_ACCESS - PullRequest
0 голосов
/ 16 июня 2011

Я генерирую CVPixelBufferRef из слоя OpenGL, как этот

- (CVPixelBufferRef) getGLPixelBuf {
    int s = 1;
    UIScreen * screen = [UIScreen mainScreen];
    if ([screen respondsToSelector:@selector(scale)]){
        s = (int)[screen scale];
    }
    const int w = self.frame.size.width/2;
    const int h = self.frame.size.height/2;
    const NSInteger my_data_length = 4 * w * h * s * s;
    // allocate array and read pixels into it.
    GLubyte * buffer = malloc(my_data_length);

    GLint readType;
    GLint readFormat;
    glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
    glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);

    glReadPixels(0, 0, w * s, h * s, readFormat, readType, buffer);

    // gl renders "upside down" so swap top to bottom into new array.
    GLubyte * buffer2 = malloc(my_data_length);

    for(int y = 0; y < h*s; y++){
        memcpy(buffer2 + (h * s - 1 - y) * 4 * w * s, buffer + (4 * y * w * s), 4 * w * s);
    }

    free(buffer);
    CVPixelBufferRef pixel_buffer = NULL;
    CVPixelBufferCreateWithBytes (NULL, w * 2, h * 2, kCVPixelFormatType_32BGRA, buffer2 , 4 * w * s, NULL, 0, NULL, &pixel_buffer);
    free(buffer2);

    return pixel_buffer;
}

и затем передача этого пиксельного буфера моему AVAssetWriterInputPixelBufferAdaptor внутри вспомогательного класса следующим образом:

- (void)recordFrame {
    if([recorder isRecording]){
        CVPixelBufferRef pixelBuffer = [self getGLPixelBuf];
        CVPixelBufferLockBaseAddress(pixelBuffer, 0);

        [recorder appendPixelBuffer:pixelBuffer withPresentationTime:camera.lastSampleTime];

        CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
        CVPixelBufferRelease(pixelBuffer);
    }
}

однако внутри этого вспомогательного класса следующее

- (BOOL)appendPixelBuffer:(CVPixelBufferRef)pixelBuffer withPresentationTime:(CMTime)presentationTime {
    if (writerInput.readyForMoreMediaData)     
        return [adaptor appendPixelBuffer:pixelBuffer withPresentationTime:presentationTime];  
    return NO;
}

вызывает EXC_BAD_ACCESS, когда я делаю вызов appendPixelBuffer. Я включил NSZombieEnabled, но он не предоставляет мне никакой информации. Рекордер инициализируется до той же высоты и ширины, что и высота подложки и ширина слоя OpenGL. Адаптер настроен для пиксельного формата kCVPixelFormatType_32BGRA, а также для пиксельного буфера.

любая помощь приветствуется! спасибо!

1 Ответ

0 голосов
/ 23 июня 2014

Не блокируйте свой пиксельный буфер, когда вы добавляете его в адаптер, и ваш pixel_buffer, возвращенный методом - (CVPixelBufferRef) getGLPixelBuf;, не сохраняется, чтобы использовать CVPixelBufferRelease(pixelBuffer); в - (void)recordFrame; методе, вам нужно сохранить pixel_buffer перед возвратом из - (CVPixelBufferRef) getGLPixelBuf;

...