swift – CVPixelBufferPool错误(kCVReturnInvalidArgument / -6661)

前端之家收集整理的这篇文章主要介绍了swift – CVPixelBufferPool错误(kCVReturnInvalidArgument / -6661)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经用 Swift( How to use CVPixelBufferPool in conjunction with AVAssetWriterInputPixelBufferAdaptor in iPhone?)实现了以前的建议,
但在使用CVPixelBufferPoolCreatePixelBuffer作为指导时,却遇到了“kCVReturnInvalidArgument”(错误值:-6661).

我基本上试图从图像创建一个电影,但由于缓冲池未成功创建,我无法附加像素缓冲区 – 这是我执行此操作的代码.

任何建议都非常感谢!

  1. import Foundation
  2. import Photos
  3. import OpenGLES
  4. import AVFoundation
  5. import CoreMedia
  6.  
  7. class MovieGenerator {
  8.  
  9. var _videoWriter:AVAssetWriter
  10. var _videoWriterInput: AVAssetWriterInput
  11. var _adapter: AVAssetWriterInputPixelBufferAdaptor
  12. var _buffer = UnsafeMutablePointer<Unmanaged<CVPixelBuffer>?>.alloc(1)
  13.  
  14.  
  15. init(frameSize size: CGSize,outputURL url: NSURL) {
  16.  
  17. // delete file if exists
  18. let sharedManager = NSFileManager.defaultManager() as NSFileManager
  19. if(sharedManager.fileExistsAtPath(url.path!)) {
  20. sharedManager.removeItemAtPath(url.path,error: nil)
  21. }
  22.  
  23. // video writer
  24. _videoWriter = AVAssetWriter(URL: url,fileType: AVFileTypeQuickTimeMovie,error: nil)
  25.  
  26. // writer input
  27. var videoSettings = [AVVideoCodecKey:AVVideoCodecH264,AVVideoWidthKey:size.width,AVVideoHeightKey:size.height]
  28. _videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo,outputSettings: videoSettings)
  29. _videoWriterInput.expectsMediaDataInRealTime = true
  30. _videoWriter.addInput(_videoWriterInput)
  31.  
  32. // pixel buffer adapter
  33. var adapterAttributes = [kCVPixelBufferPixelFormatTypeKey:kCVPixelFormatType_32BGRA,kCVPixelBufferWidthKey: size.width,kCVPixelBufferHeightKey: size.height,kCVPixelFormatOpenGLESCompatibility: kcfBooleanTrue]
  34.  
  35. _adapter = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: _videoWriterInput,sourcePixelBufferAttributes: adapterAttributes)
  36. var poolCreateResult:CVReturn = CVPixelBufferPoolCreatePixelBuffer(nil,_adapter.pixelBufferPool,_buffer)
  37. println("pool creation:\(poolCreateResult)")
  38.  
  39. _videoWriter.startWriting()
  40. _videoWriter.startSessionAtSourceTime(kCMTimeZero)
  41.  
  42. }
  43.  
  44. func addImage(image:UIImage,frameNum:Int,fps:Int)->Bool {
  45.  
  46.  
  47. self.createPixelBufferFromCGImage(image.CGImage,pixelBufferPtr: _buffer)
  48.  
  49. var presentTime:CMTime = CMTimeMake(Int64(frameNum),Int32(fps))
  50. var result:Bool = _adapter.appendPixelBuffer(_buffer.memory?.takeUnretainedValue(),withPresentationTime: presentTime)
  51.  
  52. return result
  53. }
  54.  
  55. func finalizeMovie(timeStamp: CMTime) {
  56. _videoWriterInput.markAsFinished()
  57. _videoWriter.endSessionAtSourceTime(timeStamp)
  58. _videoWriter.finishWritingWithCompletionHandler({println("video writer finished with status: \(self._videoWriter.status)")})
  59. }
  60.  
  61. func createPixelBufferFromCGImage(image: CGImage,pixelBufferPtr: UnsafeMutablePointer<Unmanaged<CVPixelBuffer>?>) {
  62.  
  63. let width:UInt = CGImageGetWidth(image)
  64. let height:UInt = CGImageGetHeight(image)
  65.  
  66. let imageData:CFData = CGDataProviderCopyData(CGImageGetDataProvider(image))
  67. let options:CFDictionary = [kCVPixelBufferCGImageCompatibilityKey:NSNumber.numberWithBool(true),kCVPixelBufferCGBitmapContextCompatibilityKey:NSNumber.numberWithBool(true)]
  68.  
  69. var status:CVReturn = CVPixelBufferCreate(kcfAllocatorDefault,width,height,OSType(kCVPixelFormatType_32BGRA),options,pixelBufferPtr)
  70. assert(status != 0,"CVPixelBufferCreate: \(status)")
  71.  
  72. var lockStatus:CVReturn = CVPixelBufferLockBaseAddress(pixelBufferPtr.memory?.takeUnretainedValue(),0)
  73. println("CVPixelBufferLockBaseAddress: \(lockStatus)")
  74.  
  75. var pxData:UnsafeMutablePointer<(Void)> = CVPixelBufferGetBaseAddress(pixelBufferPtr.memory?.takeUnretainedValue())
  76. let bitmapinfo = CGBitmapInfo.fromRaw(CGImageAlphaInfo.NoneSkipFirst.toRaw())
  77. let rgbColorSpace:CGColorSpace = CGColorSpaceCreateDeviceRGB()
  78.  
  79. var context:CGContextRef = CGBitmapContextCreate(pxData,8,4*CGImageGetWidth(image),rgbColorSpace,bitmapinfo!)
  80.  
  81. CGContextDrawImage(context,CGRectMake(0,CGFloat(width),CGFloat(height)),image)
  82.  
  83. CVPixelBufferUnlockBaseAddress(pixelBufferPtr.memory?.takeUnretainedValue(),0)
  84.  
  85.  
  86. }
  87.  
  88.  
  89.  
  90. }
令人沮丧的是,我无法准确回答你的问题,但我正在研究基本相同的代码.并且,我的情况恰好比你得到的错误更进一步;它一直到试图将图像添加到电影中然后因为从未从appendPixelBuffer()获得成功结果而失败 – 我不知道如何找出原因.我发布这篇文章是为了帮助你进一步发展.

(我的代码改编自AVFoundation + AssetWriter: Generate Movie With Images and Audio,我用你的帖子来帮助浏览指针互操作的somanigans …)

  1. func writeAnimationToMovie(path: String,size: CGSize,animation: Animation) -> Bool {
  2. var error: NSError?
  3. let writer = AVAssetWriter(URL: NSURL(fileURLWithPath: path),error: &error)
  4.  
  5. let videoSettings = [AVVideoCodecKey: AVVideoCodecH264,AVVideoWidthKey: size.width,AVVideoHeightKey: size.height]
  6.  
  7. let input = AVAssetWriterInput(mediaType: AVMediaTypeVideo,outputSettings: videoSettings)
  8. let pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: input,sourcePixelBufferAttributes: nil)
  9. input.expectsMediaDataInRealTime = true
  10. writer.addInput(input)
  11.  
  12. writer.startWriting()
  13. writer.startSessionAtSourceTime(kCMTimeZero)
  14.  
  15. var buffer: CVPixelBufferRef
  16.  
  17. var frameCount = 0
  18. for frame in animation.frames {
  19. let rect = CGRectMake(0,size.width,size.height)
  20. let rectPtr = UnsafeMutablePointer<CGRect>.alloc(1)
  21. rectPtr.memory = rect
  22. buffer = pixelBufferFromCGImage(frame.image.CGImageForProposedRect(rectPtr,context: nil,hints: nil).takeUnretainedValue(),size)
  23. var appendOk = false
  24. var j = 0
  25. while (!appendOk && j < 30) {
  26. if pixelBufferAdaptor.assetWriterInput.readyForMoreMediaData {
  27. let frameTime = CMTimeMake(Int64(frameCount),10)
  28. appendOk = pixelBufferAdaptor.appendPixelBuffer(buffer,withPresentationTime: frameTime)
  29. // appendOk will always be false
  30. NSThread.sleepForTimeInterval(0.05)
  31. } else {
  32. NSThread.sleepForTimeInterval(0.1)
  33. }
  34. j++
  35. }
  36. if (!appendOk) {
  37. println("Doh,frame \(frame) at offset \(frameCount) Failed to append")
  38. }
  39. }
  40.  
  41. input.markAsFinished()
  42. writer.finishWritingWithCompletionHandler({
  43. if writer.status == AVAssetWriterStatus.Failed {
  44. println("oh noes,an error: \(writer.error.description)")
  45. } else {
  46. println("hrmmm,there should be a movie?")
  47. }
  48. })
  49.  
  50. return true;
  51. }

其中pixelBufferFromCGImage的定义如下:

  1. func pixelBufferFromCGImage(image: CGImageRef,size: CGSize) -> CVPixelBufferRef {
  2. let options = [
  3. kCVPixelBufferCGImageCompatibilityKey: true,kCVPixelBufferCGBitmapContextCompatibilityKey: true]
  4. var pixBufferPointer = UnsafeMutablePointer<Unmanaged<CVPixelBuffer>?>.alloc(1)
  5.  
  6. let status = CVPixelBufferCreate(
  7. nil,UInt(size.width),UInt(size.height),OSType(kCVPixelFormatType_32ARGB),pixBufferPointer)
  8.  
  9. CVPixelBufferLockBaseAddress(pixBufferPointer.memory?.takeUnretainedValue(),0)
  10.  
  11. let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
  12. let bitmapinfo = CGBitmapInfo.fromRaw(CGImageAlphaInfo.NoneSkipFirst.toRaw())
  13.  
  14. var pixBufferData:UnsafeMutablePointer<(Void)> = CVPixelBufferGetBaseAddress(pixBufferPointer.memory?.takeUnretainedValue())
  15.  
  16. let context = CGBitmapContextCreate(
  17. pixBufferData,UInt(4 * size.width),bitmapinfo!)
  18.  
  19. CGContextConcatCTM(context,CGAffineTransformMakeRotation(0))
  20. CGContextDrawImage(
  21. context,CGFloat(CGImageGetWidth(image)),CGFloat(CGImageGetHeight(image))),image)
  22.  
  23. CVPixelBufferUnlockBaseAddress(pixBufferPointer.memory?.takeUnretainedValue(),0)
  24. return pixBufferPointer.memory!.takeUnretainedValue()
  25. }

猜你在找的Swift相关文章