0

Metal experts!

I'm struggling with the following error:

failed assertion `GetBytes Validation rowBytes(1600) must be >= (4680)

at

texture.getBytes(pixelBufferBytes, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)

when I try to record the MTLTexture as a video frame using AVFoundation. Therefore I'm converting the MTLTexture into the CVPixelBuffer using the following SO answer (see VideoRecorder.writeFrame).

Here is the place where I pass the texture into the recorder:

extension MetalRenderer: MTKViewDelegate {
  func mtkView(_: MTKView, drawableSizeWillChange _: CGSize) {}

  func draw(in view: MTKView) {
    guard let drawable = view.currentDrawable, let descriptor = view.currentRenderPassDescriptor else {
      return
    }

    let commandBuffer = commandQueue.makeCommandBuffer()!
    let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor)!

    let deltaTime = 1 / Float(view.preferredFramesPerSecond)
    scene?.render(commandEncoder: commandEncoder, deltaTime: deltaTime)

    commandEncoder.endEncoding()
    commandBuffer.present(drawable)
    commandBuffer.commit()

    commandBuffer.addCompletedHandler { commandBuffer in
      let texture = drawable.layer.nextDrawable()?.texture
      recorder.writeFrame(forTexture: texture!)
    }
  }
}

I suppose, something could be wrong with addCompletedHandler or grabbing the texture maybe?

Workarounds

Workaround 1

I tried to disable the Metal API Validation in Run Scheme and got a bunch of the following errors, but not sure how relevant they are:

2023-01-29 23:03:50.009525+0100 [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.commcenter.coretelephony.xpc was invalidated: failed at lookup with error 3 - No such process." UserInfo={NSDebugDescription=The connection to service named com.apple.commcenter.coretelephony.xpc was invalidated: failed at lookup with error 3 - No such process.}

Workaround 2

Also, I tried to set the metalView.framebufferOnly to false, which didn't help to resolve the crash.

I'd appreciate it if someone could answer. Thanks in advance!

aibek
  • 161
  • 8
  • 1
    what are the width height values of MTLTexture and CVPixelBuffer? – udi Jan 30 '23 at 05:50
  • The values are: pixel buffer width: 390 pixel buffer height: 844 texture width: 1170 texture height: 1519 – aibek Jan 30 '23 at 11:43
  • This makes me think that a mismatch between the sizes is causing the error, correct? They need to be equal, I suppose. Is there any way to control texture size? – aibek Jan 30 '23 at 11:45
  • 1
    when creating the buffer use texture.width and texture.height for width and height – udi Jan 30 '23 at 11:56
  • and what about setting the texture's size? for example, if we want to render the video in 780p resolution? – aibek Jan 30 '23 at 11:58
  • btw. using the texture's size for recording did the trick. thank you very much, udi – aibek Jan 30 '23 at 13:20
  • Looks like I could achieve the changed resolution through `MPSImageLanczosScale` – aibek Jan 30 '23 at 20:28

1 Answers1

1

The error message failed assertion `GetBytes Validation rowBytes(1600) must be >= (4680) says that the number of bytes in the row of the CVPixelBuffer obtained from the MTLTexture is not enough to hold the entire row of data in the texture.

So matching the CVPixelBuffer dimensions with the MTLTexture will solve the issue.

udi
  • 3,672
  • 2
  • 12
  • 33