Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CFRelease on CMSampleBufferRef - Why do I need to call this?

CMSampleBufferRef sampleBuffer = [assetOutput copyNextSampleBuffer];
CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer(sampleBuffer);
CMBlockBufferAppendBufferReference(_sem == 0 ? _buffer0 : _buffer1, buffer, 0, 0, 0);
//if(sampleBuffer)
//    CFRelease(sampleBuffer);

Why does this cause a memory leak at the first line (at least that's where Leaks suggests)? I have my assetOutput.shouldAlwaysCopySampleOutput = NO. Here's my understanding of the situation:

CMSampleBufferRef sampleBuffer = [assetOutput copyNextSampleBuffer];

This line will create a reference to the sample buffer from the assetOutput.

CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer(sampleBuffer);

This line will get the CMBlockBuffer from the CMSampleBuffer but will not allocate a new buffer, and the Get method in this case means it is a temporary (autoreleased) buffer

CMBlockBufferAppendBufferReference(_sem == 0 ? _buffer0 : _buffer1, buffer, 0, 0, 0);

This line will append the reference of the CMBlockBuffer created above, to the selected global-scope buffer. It will not copy any memory blocks.

So in none of these three lines do I allocate any memory nor do I copy any memory, it's all references. I don't understand where the leak is coming from. I tried adding the commented out lines and it still seems to leak (although fewer times)

like image 538
quark Avatar asked Feb 03 '26 09:02

quark


2 Answers

alwaysCopiesSampleData is not about memory management. It is only about whether you are scribbling on the original sample buffer or a clone of the original. It is somewhat unfortunately named.

copyNextSampleBuffer follows the create rule and as such, should be released when you are done with it. It creates a reference with a retain count of at least 1.

The Create Rule:

https://developer.apple.com/library/ios/DOCUMENTATION/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029

Apple's doc links tend to change, but if the above link dies, just google "The Create Rule"

like image 72
amattn Avatar answered Feb 04 '26 21:02

amattn


Core Foundation data structures follows the same ownership rules as Foundation objects.

The rules are pretty simple - whatewer you create (or get the ownership by some other way), you have to destroy. If some other method wants to work with the same structure/object, it has to ask for the ownership and thus preventing the destruction.

Taking ownership = "create" / "retain"
Releasing ownership ("destruction") = "release"

In your sample code, you have created a structure using copyNextSampleBuffer. That means, you have to also destroy it using CFRelease.

(Note that with ARC you don't actually see the retain and release calls but with Core Foundation, you have to use them explicitely).

like image 27
Sulthan Avatar answered Feb 04 '26 23:02

Sulthan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!