【问题标题】:Call to appendPixelBuffer of AVAssetWriterInputPixelBufferAdaptor Causes EXC_BAD_ACCESS调用 AVAssetWriterInputPixelBufferAdaptor 的 appendPixelBuffer 导致 EXC_BAD_ACCESS
【发布时间】:2011-06-15 21:29:22
【问题描述】:

我正在从这样的 OpenGL 层生成 CVPixelBufferRef

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

当我调用 appendPixelBuffer 时会导致 EXC_BAD_ACCESS。我已启用 NSZombieEnabled 但它没有为我提供任何信息。记录器被初始化为与 OpenGL 层的背景高度和宽度相同的高度和宽度。适配器配置为 kCVPixelFormatType_32BGRA 像素格式以及像素缓冲区。

感谢任何帮助!谢谢!

【问题讨论】:

  • 你有没有用调试器检查并找到它出错的那一行?
  • 你发送的参数在被调用的方法中是同一个对象吗?
  • 我现在可以使用它了。看起来好像我的像素缓冲区脱离了上下文。我将上面的两种方法合二为一,我不再收到 EXC_BAD_ACCESS。
  • 我遇到了类似的问题(opengl 似乎落在了上下文中......即调用 glReadPixels 后缓冲区中的所有字节都是 0。)但是,如果我尝试附加主渲染循环中的像素缓冲区然后我调用 appendPixelBuffer 我收到此错误:-[NSCFNumber appendPixelBuffer:withPresentationTime:]: unrecognized selector sent to instance 0x64d0860 我确定我在某处犯了一个简单的错误,但我没有遇到任何简单的工作示例代码都会将一系列 openGL 纹理(或渲染缓冲区)写入视频文件。
  • 问题是你使用的是free(buffer2);在使用使用 buffer2 的像素缓冲区之前。

标签: ios iphone opengl-es avassetwriter


【解决方案1】:

当您将像素缓冲区附加到适配器时不要锁定像素缓冲区,并且方法- (CVPixelBufferRef) getGLPixelBuf;返回的pixel_buffer没有保留,要在- (void)recordFrame;方法中使用CVPixelBufferRelease(pixelBuffer);,您需要在从- (CVPixelBufferRef) getGLPixelBuf;返回之前保留pixel_buffer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-11
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 2016-11-19
    • 2012-10-02
    • 2011-04-14
    相关资源
    最近更新 更多