HEVC with alpha showing all frames at the same time

169 Views Asked by At

I'm making a video with transparent background using HEVC with alpha, based on a bunch of NSImages, a CVPixelBuffer pool and AVAssetWriter. The NSImages are rendered by an SCNRenderer's [snapshot][1] method.

To turn the NSImages into CVPixelbuffers so I can append them to the pool, I first get a new pixel buffer from the pool, then use this code

        CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
        let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        
        guard let context = CGContext(
            data: pixelData,
            width: Int(image.size.width),
            height: Int(image.size.height),
            bitsPerComponent: 8, 
            bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
            space: colorSpace,
            bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue
        )
        else { return  }
        
        let graphicsContext = NSGraphicsContext(cgContext: context, flipped: false)
        
        NSGraphicsContext.saveGraphicsState()
        NSGraphicsContext.current = graphicsContext
        image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
        NSGraphicsContext.restoreGraphicsState()
        
        CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))

In the exported movie, the colors look good, and the transparency kicks in fine.

But all the frames are added on top of each other, as in the example below.

SIDE NOTE: The weird thing is that if I obtain the pixel buffer with Metal (using the SCNRenderer's render method), but leave everything else as is, it works fine. That's why I'm suspecting that it might be my CGContext that is acting up. Why don't I just use Metal, then? Would love to, but I can't get antialiasing.

enter image description here

0

There are 0 best solutions below