AVCaptureOutput didOutputSampleBuffer stops getting called

3.1k views Asked by At

I have an issue with the delegate method didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection of AVCaptureOutput.

It stops getting called within a second or two when I'm adding the sampleBuffer to a CFArray. If I remove the CFArray code, the delegate method continues to get called so I have no idea why the CFArray code is causing it to stop. I'd appreciate any help.

@property CFMutableArrayRef sampleBufferArray;

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    NSLog(@"Called");

    if (!self.sampleBufferArray)
    {
        self.sampleBufferArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        CFArrayAppendValue(self.sampleBufferArray, sampleBuffer);
    }
    else
    {
        CFArrayAppendValue(self.sampleBufferArray, sampleBuffer);
    }
}

Console ouput:

// Session start
2015-06-15 13:06:07.264 App[22467:5897858] Called
2015-06-15 13:06:07.286 App[22467:5897858] Called
2015-06-15 13:06:07.289 App[22467:5897858] Called
2015-06-15 13:06:07.315 App[22467:5897895] Called
2015-06-15 13:06:07.366 App[22467:5897895] Called
2015-06-15 13:06:07.384 App[22467:5897895] Called
2015-06-15 13:06:07.411 App[22467:5897895] Called
2015-06-15 13:06:07.449 App[22467:5897858] Called
2015-06-15 13:06:07.480 App[22467:5897858] Called
2015-06-15 13:06:07.513 App[22467:5897895] Called
2015-06-15 13:06:07.546 App[22467:5897895] Called
2015-06-15 13:06:07.579 App[22467:5897895] Called
2015-06-15 13:06:07.614 App[22467:5897895] Called
// No more calls after this point
2

There are 2 answers

6
MDB983 On BEST ANSWER

Your problem is actually referenced in the Docs, Specifically;

If your application is causing samples to be dropped by retaining the provided CMSampleBufferRef objects for too long, but it needs access to the sample data for a long period of time, consider copying the data into a new buffer and then releasing the sample buffer (if it was previously retained) so that the memory it references can be reused.

Essentially, you need to keep the callback operation as simple as possible, and should you need to perform further processing on the frame passed to you in the callback, you need to copy it to a new buffer and perform the processing in the background. Also, Keep in mind that Core Foundation object must explicitly be retained and released.

A further consideration is memory pressure. Frames contain lots of data, retaining too many will cause your app to crash.

1
user11741656 On

I encounter similar issue in Xamarin(C#) iOS development. Use the following code to release the CMSampleBuffer if in Xamarin:

GC.Collect();
GC.WaitForPendingFinalizers();