BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.23k stars 4.61k forks source link

Get "initWithCVPixelBuffer failed because the CVPixelBufferRef is not IOSurface backed." in iOS 8 when change CVPixelBufferRef #2299

Open zhihanhe opened 8 years ago

zhihanhe commented 8 years ago

Hi everybody,

I want to send filtered CVPixelBufferRef to Server.GPUImageVideoCamera just filter in local. So I add GPUImageRawDataOutput to send to Server.The sample code in swift is:

let output:GPUImageRawDataOutput = GPUImageRawDataOutput(imageSize: CGSizeMake(288, 352), resultsInBGRAFormat: true);
var videoCamera:GPUImageVideoCamera?;

self.videoCamera = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPreset352x288, cameraPosition: AVCaptureDevicePosition.Front);
videoCamera?.outputImageOrientation = UIInterfaceOrientation.Portrait;
videoCamera?.horizontallyMirrorFrontFacingCamera = true;
videoCamera?.frameRate = 12;
videoCamera?.delegate = self;
output.newFrameAvailableBlock = outputTest;

videoCamera?.addTarget(localCameraPreviewView);
videoCamera?.addTarget(output);
videoCamera?.startCameraCapture();

func outputTest() {
    output.lockFramebufferForReading();

    let width = 288;
    let height = 352;

    let sourceBytes:UnsafeMutablePointer<GLubyte> = output.rawBytesForImage;
    let bytesPerRow = output.bytesPerRowInOutput();

    var pixelBuffer:CVPixelBufferRef?;

//can not fix iOS8's bug
    let empty: CFDictionaryRef = CFDictionaryCreate(kCFAllocatorDefault, nil, nil, 0, nil, nil);

    let attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,1,nil,nil);

    CFDictionarySetValue(attributes, unsafeAddressOf(kCVPixelBufferIOSurfacePropertiesKey), unsafeAddressOf(empty));

    var result:OSStatus = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, sourceBytes, Int(bytesPerRow), nil, nil, attributes, &pixelBuffer);

    var videoInfo:CMVideoFormatDescriptionRef? = nil;
    CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault,pixelBuffer!,&videoInfo);

    var oBuf:CMSampleBufferRef? = nil;
    result = CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault,pixelBuffer!,true,nil,nil,videoInfo!,&sampleTime!,&oBuf);

    output.unlockFramebufferAfterReading();

    send oBuf data to server to show filtered pictures.
}

this code run in iOS9 is very good.But run in iOS8 is a green pictures and output error:

"initWithCVPixelBuffer failed because the CVPixelBufferRef is not IOSurface backed."

I have add "kCVPixelBufferIOSurfacePropertiesKey" but It's still not work in iOS8. Any ideas?

Thanks!

Akhrameev commented 7 years ago

Look: https://developer.apple.com/library/content/qa/qa1781/_index.html (Technical Q&A QA1781). It may help (for example, important note contains text: "You cannot use CVPixelBufferCreateWithBytes() or CVPixelBufferCreateWithPlanarBytes() with kCVPixelBufferIOSurfacePropertiesKey.").

Akhrameev commented 7 years ago

Also, look at: http://stackoverflow.com/questions/31823673/create-cvpixelbuffer-from-yuv-with-iosurface-backed