quark
quark

Reputation: 1735

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)

Upvotes: 3

Views: 3005

Answers (2)

Sulthan
Sulthan

Reputation: 130102

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).

Upvotes: 2

amattn
amattn

Reputation: 10065

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"

Upvotes: 6

Related Questions