【问题标题】:iOS Accelerate: Put luma and chroma buffers in a single CVPixelBufferiOS Accelerate:将亮度和色度缓冲区放在单个 CVPixelBuffer 中
【发布时间】:2022-09-27 19:50:14
【问题描述】:

我正在将相机输出 420YpCbCr8BiPlanarFullRange 转换为 ARGB8888 以执行一些图像处理。我需要将结果转换回 420YpCbCr8BiPlanarFullRange 以便使用 webRTC 进行流式传输。我编写了这段代码将其转换回:

func convertTo420Yp8(source: inout vImage_Buffer) -> CVPixelBuffer? {
    let lumaWidth = source.width
    let lumaHeight = source.height
    
    let chromaWidth = source.width
    let chromaHeight = source.height / 2
    
    guard var lumaDestination = try? vImage_Buffer(
        width: Int(lumaWidth),
        height: Int(lumaHeight),
        bitsPerPixel: 8
    ) else {
        return nil
    }
    
    guard var chromaDestination = try? vImage_Buffer(
        width: Int(chromaWidth),
        height: Int(chromaHeight),
        bitsPerPixel: 8
    ) else {
        return nil
    }
    
    defer {
        lumaDestination.free()
        chromaDestination.free()
    }
    
    var error = kvImageNoError
    
    error = vImageConvert_ARGB8888To420Yp8_CbCr8(
        &source,
        &lumaDestination,
        &chromaDestination,
        &infoARGBtoYpCbCr,
        nil,
        vImage_Flags(kvImagePrintDiagnosticsToConsole)
    )
    
    guard error == kvImageNoError else {
        return nil
    }
    
    var pixelFormat = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
    var planeWidths = [Int(lumaWidth), Int(chromaWidth)]
    var planeHeights = [Int(chromaHeight), Int(chromaHeight)]
    var bytesPerRows = [Int(1 * lumaWidth), Int(2 * chromaWidth)]
    var baseAddresses: [UnsafeMutableRawPointer?] = [lumaDestination.data, chromaDestination.data]
    var outputPixelBuffer: CVPixelBuffer?
    
    let status = CVPixelBufferCreateWithPlanarBytes(
        kCFAllocatorDefault,
        Int(lumaWidth),
        Int(lumaHeight),
        pixelFormat,
        nil,
        0,
        2,
        &baseAddresses,
        &planeWidths,
        &planeHeights,
        &bytesPerRows,
        nil,
        nil,
        nil,
        &outputPixelBuffer
    )
    
    if status == noErr {
        print(\"converted to CVPixelBuffer\")
    }
    return outputPixelBuffer
}

vImageConvert_ARGB8888To420Yp8_CbCr8 产生两个缓冲区:色度和亮度。 CVPixelBufferCreateWithPlanarBytes 返回 noErr 状态,但 Chroma 和 Luma 数据不在缓冲区中 - 查询时平面地址为 nil。知道我做错了什么吗?

    标签: ios swift webrtc accelerate


    【解决方案1】:

    您需要锁定CVPixelBuffer 才能访问基址。所以,这有效:

        let cvPixelBuffer = convertTo420Yp8(source: vImageBuffer)!
        
        CVPixelBufferLockBaseAddress(cvPixelBuffer,
                                     CVPixelBufferLockFlags.readOnly)
        
        print(CVPixelBufferGetBaseAddressOfPlane(cvPixelBuffer, 0))
        print(CVPixelBufferGetBaseAddressOfPlane(cvPixelBuffer, 1))
        
        CVPixelBufferUnlockBaseAddress(cvPixelBuffer,
                                       CVPixelBufferLockFlags.readOnly)
    

    我还建议您将bytesPerRow 更改为:

    var bytesPerRows = [lumaDestination.rowBytes, chromaDestination.rowBytes]
    

    有时,vImage 会为缓冲区添加额外的填充以提高性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多