Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CVPixelBufferCreateWithPlanarBytes returns -6661 (kCVReturnInvalidArgument)

I am trying to make a deep copy of a CVPixelBuffer. I receive the error kCVReturnInvalidArgument or value -661. I have verified the type of each argument and the length of the arrays and I cannot find what I've coded wrongly. I hope someone will spot it.

Here is the code:

func clonePixelBuffer(pixelBuffer: CVPixelBuffer) -> CVPixelBuffer? {
    CVPixelBufferLockBaseAddress(pixelBuffer, 0)
    let height = CVPixelBufferGetHeight(pixelBuffer)
    let width = CVPixelBufferGetWidth(pixelBuffer)
    let numberOfPlanes = CVPixelBufferGetPlaneCount(pixelBuffer)
    var planeBaseAddresses = [UnsafeMutablePointer<Void>]()
    var planeWidths = [Int]()
    var planeHeights = [Int]()
    var planeBytesPerRows = [Int]()
    for i in 0..<numberOfPlanes {
        planeBaseAddresses.append(CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0))
        planeWidths.append(CVPixelBufferGetWidthOfPlane(pixelBuffer, i))
        planeHeights.append(CVPixelBufferGetHeightOfPlane(pixelBuffer, i))
        planeBytesPerRows.append(CVPixelBufferGetHeightOfPlane(pixelBuffer, i))
    }
    let newPixelBuffer = UnsafeMutablePointer<CVPixelBuffer?>()
    let status = CVPixelBufferCreateWithPlanarBytes(nil, width, height, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, nil, 0, numberOfPlanes, &planeBaseAddresses, &planeWidths, &planeHeights, &planeBytesPerRows, nil, nil, nil, newPixelBuffer)
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
    if status == noErr { <------ status = -6661
        return newPixelBuffer.memory
    }
    return nil
}
like image 531
Rob Avatar asked Jun 02 '26 10:06

Rob


1 Answers

Not sure if this is it, but there's a copypaste error on the bytesPerRows line -- it says

planeBytesPerRows.append(CVPixelBufferGetHeightOfPlane(pixelBuffer, i))

but should be

planeBytesPerRows.append(CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, i))

You might as well forward FormatType too instead of hard-coding it.

As far as I've understood CVPixelBufferRef, this won't actually copy the pixel buffer's data, only reference the data in one PixelBuffer to that of the other PixelBuffer. You would need to malloc your own region of memory for the planes, reference the data in that range, and then provide a Free callback function to free() that memory once the CVPixelBufferRef is destroyed.

like image 200
nevyn Avatar answered Jun 05 '26 00:06

nevyn