Video Capture OpenGL error after capture starts




I’ve implemented the method for capturing video described in

In the process I’ve ported this approach to Swift.

I’m testing with Swift 3.1 and on a device running iOS 10.3 and Kudan AR 1.5.1


Everything works up until after the completion of the setupFBO() and setupAssetWriter() calls. I have checked these calls in detail in the debugger and everything looks fine.

After this I get a succession of errors

OpenGL error 0x506: (null).

And further calls to glCheckFramebufferStatus return error 36055 which is apparently FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT

While my code is in Swift, I don’t think this is material to the problem I’m experiencing.

I have added additional calls to


in order to check on the FBO. I get the correct GL_FRAMEBUFFER_COMPLETE response at the end of setupFBO()

Other things I’ve checked and found OK :

  • viewport sizes attached to my ARRenderTarget
  • correct size of my ARRenderTarget comparing it to the FBO obtained from ARRenderer.getInstance() and the default ARRenderTarget

My video file is rendered and written correctly but all the frames are (as expected from this error) black.

Key parts of code in my ARRenderTarget

enum CaptureState {
    case ready
    case writing
    case complete
    case failedAssetWriterInit

// The following is inside my ARRenderTarget implementation
 func setupAssetWriter() {
        guard let url = setupFileSystem()  else { print ("output setup failure"); return }

do {
    try self.assetWriter = AVAssetWriter(url: url, fileType: AVFileTypeQuickTimeMovie)
catch {
    print("failed to setup asset writer")
    self.videoCaptureState = .failedAssetWriterInit

let writerDict:[String : Any] = [ AVVideoCodecKey: AVVideoCodecH264,  AVVideoWidthKey: self.width,  AVVideoHeightKey: self.height]
let assetWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: writerDict)

let sourcePixelBufferDict:[String:Any] = [ kCVPixelBufferPixelFormatTypeKey as String : kCVPixelFormatType_32BGRA  ,  kCVPixelBufferWidthKey as String : self.width, kCVPixelBufferHeightKey as String  : self.height]
assetWriterPixelBufferInput = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: assetWriterInput, sourcePixelBufferAttributes: sourcePixelBufferDict)

guard let writer = self.assetWriter else { return }

if writer.canAdd(assetWriterInput)   {
else {
    print("error setting up the asset writer for videos")
    self.videoCaptureState = .failedAssetWriterInit

writer.startSession(atSourceTime: kCMTimeZero)

startDate = Date()

if( writer.status == .failed) {
    print("failed to start asset writer for videos")
    self.videoCaptureState = .failedAssetWriterInit

self.videoCaptureState = .writing


func setupFBO() {

//Create renderer context for creating new OpenGL objects
guard let renderer = ARRenderer.getInstance()  else { print("can't get renderer"); return }

//Create and bind the FBO
glGenFramebuffers(1, &fbo)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER),  fbo)
print("FBO BOUND = \(fbo)")

//Create the texture cache
var cvTextureCacheRef:CVOpenGLESTextureCache?

var err =  CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, nil, EAGLContext.current(),  nil,  &cvTextureCacheRef)
if err != kCVReturnSuccess {
    assert(false, "Error at CVOpenGLESTextureCacheCreate \(err)")

//Create the texture we will render into
guard let writerPixelBufferInput = assetWriterPixelBufferInput else { print("no assetWriterPixelBufferInput" ); return }
guard let pixelBufferPool = writerPixelBufferInput.pixelBufferPool else { print("no pixelBufferPool" ); return }
err = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pixelBufferPool, &self.pixeBuffer)
if err != kCVReturnSuccess {
    print ("error msg createing Pixelbuffer pool \(err)")

var renderTexture:CVOpenGLESTexture?
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
if err != kCVReturnSuccess {
    print ("error CVOpenGLESTextureCacheCreateTextureFromImage \(err)")

//bind our render texture to framebuffer
glBindTexture(CVOpenGLESTextureGetTarget(renderTexture!), CVOpenGLESTextureGetName(renderTexture!))
glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S),   GLfloat(GL_CLAMP_TO_EDGE)  )
glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T),   GLfloat(GL_CLAMP_TO_EDGE)  )

glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0),   GLenum(GL_TEXTURE_2D),  CVOpenGLESTextureGetName(renderTexture!), 0)

var depthRenderBuffer:GLuint = 0
glGenRenderbuffers(1, &depthRenderBuffer)
print("depth render buffer =\(depthRenderBuffer)")

glBindRenderbuffer(GLenum(GL_RENDERBUFFER), depthRenderBuffer)
glRenderbufferStorage(GLenum(GL_RENDERBUFFER), GLenum(GL_DEPTH24_STENCIL8_OES),  GLsizei(self.width), GLsizei(self.height))
glFramebufferRenderbuffer(GLenum(GL_RENDERBUFFER), GLenum(GL_DEPTH_ATTACHMENT),  GLenum(GL_RENDERBUFFER),   depthRenderBuffer)

let fbostatus  = glCheckFramebufferStatus(GLenum(GL_FRAMEBUFFER))
if fbostatus == GLenum(GL_FRAMEBUFFER_COMPLETE) {
    print("FBO status COMPLETE  = \(fbostatus)")
else {
    print("FBO status 'ERROR' = \(fbostatus)")

override func bindBuffer() {
   glBindFramebuffer(GLenum(GL_FRAMEBUFFER),  fbo)

Calling method from hosting view controller, appears to complete correctly

 func startVideoCapture() {
        guard let captureTarget = ARCRenderTarget(width: Float(self.cameraView.frame.size.width), height: Float(self.cameraView.frame.size.height))  else { print("failed to start render target"); return }
        videoCaptureTarget = captureTarget
        guard let renderer = ARRenderer.getInstance()  else { print("can't get renderer"); return }
        print("targets = \(renderer)")

I have tried running with either or both viewPorts removed to make sure its not an incorrectly specified viewPort that is causing the issue, but the same thing happens in all cases.


Hi paulfreeman,

I have also faced this error and not found the solution to fix yet.

Have you fixed this OpenGL error?

Best Regards,