CGBitmapContext和CVPixelBuffer的视频输出失真。

问题描述 投票:0回答:1

我一直在尝试调试(几天了)这段代码,从CGImages中产生一个视频。 CGImages实际上是由我在应用代码中画进的CGBitMapContext的创建的。 我在这里简化为简单地画一条黄色的对角线,并画出该静态图像的若干帧。 然而,这里是一帧(每一帧都是一样的)fo扭曲的视频,我发现在写到路径。the distorted image

import Foundation
import CoreGraphics
import CoreMedia
import QuartzCore
import AVFoundation

func exportVideo(
    width: Int = 500,
    height: Int = 500,
    numberOfFrames: Int = 100
) {
    let vidURL = NSURL.fileURL(withPath: "/Users/me/Desktop/testVideo.mp4")

    try? FileManager.default.removeItem(at: vidURL)

    let settings: [String: Any] = [
        AVVideoCodecKey: AVVideoCodecType.h264,
        AVVideoWidthKey: width,
        AVVideoHeightKey: height
    ]

    let assetWriter = try! AVAssetWriter(url: vidURL, fileType: .m4v)
    let writerInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: settings)
    assetWriter.add(writerInput)

    let queue = DispatchQueue.global(qos: .background)

    writerInput.expectsMediaDataInRealTime = false

    let inputAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: writerInput, sourcePixelBufferAttributes: nil)

    assetWriter.startWriting()

    assetWriter.startSession(atSourceTime: CMTime.zero)

    writerInput.requestMediaDataWhenReady(on: queue) {

        for i in 0..<numberOfFrames where writerInput.isReadyForMoreMediaData {

            guard let buffer = newPixelBufferFrom(width: width, height: height) else {
                fatalError()
            }

            inputAdaptor.append(
                buffer,
                withPresentationTime: CMTime(seconds: Double(i), preferredTimescale: CMTimeScale(10))
            )
        }

        writerInput.markAsFinished()

        assetWriter.finishWriting { }
    }
}

private func newPixelBufferFrom(
    width: Int,
    height: Int
) -> CVPixelBuffer? {

    let options:[String: Any] = [
        kCVPixelBufferCGImageCompatibilityKey as String: true,
        kCVPixelBufferCGBitmapContextCompatibilityKey as String: true
    ]

    var pxbuffer: CVPixelBuffer?
    let status = CVPixelBufferCreate(kCFAllocatorDefault,
                                     width,
                                     height,
                                     kCVPixelFormatType_32ARGB,
                                     options as CFDictionary?,
                                     &pxbuffer)

    assert(status == kCVReturnSuccess && pxbuffer != nil, "newPixelBuffer failed")

    CVPixelBufferLockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0))

    let pxdata = CVPixelBufferGetBaseAddress(pxbuffer!)

    let rgbColorSpace = CGColorSpaceCreateDeviceRGB()

    guard let context = CGContext(
        data: pxdata,
        width: width,
        height: height,
        bitsPerComponent: 8,
        bytesPerRow: 4 * width,
        space: rgbColorSpace,
        bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue
        ) else {
            fatalError()
    }

    context.setStrokeColor(UIColor.yellow.cgColor)
    context.setLineWidth(5)
    context.move(to: .init(x: 0, y: 0))
    context.addLine(to: .init(x: width, y: height))
    context.strokePath()

    CVPixelBufferUnlockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0))
    return pxbuffer
}
ios avfoundation cgcontext core-video cvpixelbuffer
1个回答
1
投票

所以我偶然发现了我的问题的 "答案" 此处.

我只想说,我希望这个帖子能帮助到未来的可怜人,因为错误代码、警告、API成员和文档完全不能帮助我。

© www.soinside.com 2019 - 2024. All rights reserved.