首页 > 解决方案 > 修改 CVPixelBuffer

问题描述

我正在使用下面的方法将绘图添加到像素缓冲区,然后将其附加到AVAssetWriterInputPixelBufferAdaptor.

它适用于我的 Mac mini(macOS 12 beta 7),但drawingHandler在我的 MacBook(macOS 11.5.2)上没有任何效果。

这段代码有什么问题吗?

#if os(macOS)
import AppKit
#else
import UIKit
#endif

import CoreMedia

extension CMSampleBuffer {
    
    func pixelBuffer(drawingHandler: ((CGRect) -> Void)? = nil) -> CVPixelBuffer? {
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(self) else {
            return nil
        }
        guard let drawingHandler = drawingHandler else {
            return pixelBuffer
        }
        guard CVPixelBufferLockBaseAddress(pixelBuffer, .readOnly) == kCVReturnSuccess else {
            return pixelBuffer
        }
        
        let data = CVPixelBufferGetBaseAddress(pixelBuffer)
        let width = CVPixelBufferGetWidth(pixelBuffer)
        let height = CVPixelBufferGetHeight(pixelBuffer)
        let bitsPerComponent = 8
        let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let imageByteOrderInfo = CGImageByteOrderInfo.order32Little
        let imageAlphaInfo = CGImageAlphaInfo.premultipliedFirst
        
        if let ctx = CGContext(data: data,
                               width: width,
                               height: height,
                               bitsPerComponent: bitsPerComponent,
                               bytesPerRow: bytesPerRow,
                               space: colorSpace,
                               bitmapInfo: imageByteOrderInfo.rawValue | imageAlphaInfo.rawValue)
        {
            // Push
            #if os(macOS)
            let graphCtx = NSGraphicsContext(cgContext: ctx, flipped: false)
            NSGraphicsContext.saveGraphicsState()
            NSGraphicsContext.current = graphCtx
            #else
            UIGraphicsPushContext(ctx)
            #endif
            
            let rect = CGRect(x: 0, y: 0, width: width, height: height)
            drawingHandler(rect)
            
            // Pop
            #if os(macOS)
            NSGraphicsContext.restoreGraphicsState()
            #else
            UIGraphicsPopContext()
            #endif
        }
        
        CVPixelBufferUnlockBaseAddress(pixelBuffer, .readOnly)
        
        return pixelBuffer
    }
    
}

标签: swiftmacoscvpixelbuffercmsamplebuffer

解决方案


更改锁定标志。

let lockFlags = CVPixelBufferLockFlags(rawValue: 0)

guard CVPixelBufferLockBaseAddress(pixelBuffer, lockFlags) == kCVReturnSuccess else {
    return pixelBuffer
}

// ...

CVPixelBufferUnlockBaseAddress(pixelBuffer, lockFlags)

推荐阅读