Rob
Rob

Reputation: 4239

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
}

Upvotes: 3

Views: 1684

Answers (1)

nevyn
nevyn

Reputation: 7122

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.

Upvotes: 2

Related Questions