4

I have an app that uses AVCaptureSession to process video. I like to write with zero memory leaks, and proper handling of all objects.

That's why this post - How to properly release an AVCaptureSession - was tremendously helpful - Since [session stopRunning] is asynchronous, you can't just stop the session and continue to release the holding object.

So that's solved. This is the code:

// Releases the object - used for late session cleanup
static void capture_cleanup(void* p)
{
    CaptureScreenController* csc = (CaptureScreenController*)p; 
    [csc release];  // releases capture session if dealloc is called
}

// Stops the capture - this stops the capture, and upon stopping completion releases self.
- (void)stopCapture {
    // Retain self, it will be released in capture_cleanup. This is to ensure cleanup is done properly,
    // without the object being released in the middle of it.
    [self retain];

    // Stop the session
    [session stopRunning];

    // Add cleanup code when dispatch queue end 
    dispatch_queue_t queue = dispatch_queue_create("capture_screen", NULL);
    dispatch_set_context(queue, self);
    dispatch_set_finalizer_f(queue, capture_cleanup);
    [dataOutput setSampleBufferDelegate: self queue: queue];
    dispatch_release(queue);
}

Now I come to support app interruptions as a phone call, or pressing the home button. In case application enters background, I'd like to stop capturing, and pop my view controller.

I can't seem to do it at the applicationDidEnterBackground context. dealloc is never called, my object remains alive, and when I reopen the app the frames just start coming in automatically.

I tried using beginBackgroundTaskWithExpirationHandler but to no avail. It didn't change much.

Any suggestions? Thanks!

Community
  • 1
  • 1
Oded Ben Dov
  • 9,936
  • 6
  • 38
  • 53

1 Answers1

0

I don't have an answer to your question. But I also read the thread you mentioned and I'm trying to implement it. I'm surprised you have this code in the stopCapture function:

// Add cleanup code when dispatch queue end 
dispatch_queue_t queue = dispatch_queue_create("capture_screen", NULL);
dispatch_set_context(queue, self);
dispatch_set_finalizer_f(queue, capture_cleanup);
[dataOutput setSampleBufferDelegate: self queue: queue];
dispatch_release(queue);

I thought that code was required as part of the session initialization. Does this work for you?

Does your capture_cleanup function get called? mine isn't getting called and I'm trying to figure out why.

Community
  • 1
  • 1
eddy
  • 693
  • 1
  • 7
  • 17
  • Hi, This code is indeed found in my clean up code. Could be a copy-paste error, but it worked. capture_cleanup did get called. I think I replace the dataOutput queue, and the close it, so clean up is called appropriately. But you can also ask the person who first posted this code :) GL! – Oded Ben Dov Mar 20 '11 at 07:38
  • Same problem in my case, capture_cleanup isn't called. Any idea? – polyclick Dec 13 '11 at 17:19