Create a copy of CMSampleBuffer in Swift 2.0
Asked Answered
F

2

5

This has been asked before, but something must have changed in Swift since it was asked. I am trying to store CMSampleBuffer objects returned from an AVCaptureSession to be processed later. After some experimentation I discovered that AVCaptureSession must be reusing its CMSampleBuffer references. When I try to keep more than 15 the session hangs. So I thought I would make copies of the sample buffers. But I can't seem to get it to work. Here is what I have written:

var allocator: Unmanaged<CFAllocator>! = CFAllocatorGetDefault()
var bufferCopy: UnsafeMutablePointer<CMSampleBuffer?>
let err = CMSampleBufferCreateCopy(allocator.takeRetainedValue(), sampleBuffer, bufferCopy)
if err == noErr {
    bufferArray.append(bufferCopy.memory!)
} else {
    NSLog("Failed to copy buffer. Error: \(err)")
}

This won't compile because it says that Variable 'bufferCopy' used before being initialized. I've looked at many examples and they'll either compile and not work or they won't compile.

Anyone see what I'm doing wrong here?

Flesher answered 17/2, 2016 at 21:11 Comment(0)
N
2

Literally you're attempting to use the variable bufferCopy before it is initialized.

You've declared a type for it, but haven't allocated the memory it's pointing to.

You should instead create CMSampleBuffers using the following call https://developer.apple.com/library/tvos/documentation/CoreMedia/Reference/CMSampleBuffer/index.html#//apple_ref/c/func/CMSampleBufferCreate

You should be able to copy the buffer into this then (as long as the format of the buffer matches the one you're copying from).

Newlywed answered 17/2, 2016 at 22:51 Comment(5)
Thanks for the response Tim, this seems like it may be a good solution for a deep clone. But I'm not that familiar with the way the memory is used at this level. Do you know where I might find a decent example of how to create a deep clone of a CMSampleBuffer for both video and audio? Apple apparently holds a cache of 15 CMSampleBuffers that it recycles when running the AVCaptureSession. I will evidently need to deep clone to store my own.Flesher
I finally figured out how to use this to create a deep clone. All the copy methods reused the data in the heap which kept would lock the AVCaptureSession. So I had to pull the data out into a NSMutableData object and then created a new sample buffer. ThanksFlesher
@Flesher could you add your code for deep cloning. I have the same issue and am already searching for half a day.Prolific
@Rob, your exact procedure has been asked about in a follow-up question: stackoverflow.com/questions/38335365 Perhaps you'd like to post an answer there?Gong
@Rob, Can you share please your solutionIschium
S
8

You can simply pass a CMSampleBuffer? variable (which, as an optional, is implicitly initialized with nil) as inout argument with &:

var bufferCopy : CMSampleBuffer?
let err = CMSampleBufferCreateCopy(kCFAllocatorDefault, buffer, &bufferCopy)
if err == noErr {
    // ...
}
Scale answered 18/2, 2016 at 7:51 Comment(1)
Thank you. This answered the problem I had above for getting the code to compile. And when I test ran the code it turns out that it must be a shallow clone. The data that the new CMSampleBuffer held was in the same location as the previous. So when I ran the AVCaptureSession it sent 15 sample and locked again because I was holding the reference to the underlying data location. Any idea how I can create a deep clone so I can duplicate the data into a new location in memory? Thanks!Flesher
N
2

Literally you're attempting to use the variable bufferCopy before it is initialized.

You've declared a type for it, but haven't allocated the memory it's pointing to.

You should instead create CMSampleBuffers using the following call https://developer.apple.com/library/tvos/documentation/CoreMedia/Reference/CMSampleBuffer/index.html#//apple_ref/c/func/CMSampleBufferCreate

You should be able to copy the buffer into this then (as long as the format of the buffer matches the one you're copying from).

Newlywed answered 17/2, 2016 at 22:51 Comment(5)
Thanks for the response Tim, this seems like it may be a good solution for a deep clone. But I'm not that familiar with the way the memory is used at this level. Do you know where I might find a decent example of how to create a deep clone of a CMSampleBuffer for both video and audio? Apple apparently holds a cache of 15 CMSampleBuffers that it recycles when running the AVCaptureSession. I will evidently need to deep clone to store my own.Flesher
I finally figured out how to use this to create a deep clone. All the copy methods reused the data in the heap which kept would lock the AVCaptureSession. So I had to pull the data out into a NSMutableData object and then created a new sample buffer. ThanksFlesher
@Flesher could you add your code for deep cloning. I have the same issue and am already searching for half a day.Prolific
@Rob, your exact procedure has been asked about in a follow-up question: stackoverflow.com/questions/38335365 Perhaps you'd like to post an answer there?Gong
@Rob, Can you share please your solutionIschium

© 2022 - 2024 — McMap. All rights reserved.