gpt4 book ai didi

ios - CGBitmapContext和CVPixelBuffer的视频输出失真

转载 作者:行者123 更新时间:2023-12-01 21:46:22 25 4
gpt4 key购买 nike

我一直在尝试调试该代码(现在已经几天了),以从CGImages产生视频。 CGImage实际上是从我在应用程序代码中绘制的CGBitMapContext的创建的。在这里,我已简化为仅画一条对角的黄线并绘制该静态图像的许多帧。但是,这是我在写入路径中发现的失真视频的一个帧(每个帧都是相同的)。
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
}

最佳答案

所以我偶然发现了我的问题here的“答案”。

事实证明,宽度和高度必须是4的倍数。我只想说,我希望这篇文章对将来可怜的人有所帮助,因为错误代码,警告,API成员和文档完全无法帮助我。

关于ios - CGBitmapContext和CVPixelBuffer的视频输出失真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62163449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com