2013-08-26 2 views
0

Я захвата кадров из камеры с помощью кода:IOS - CMSampleBufferRef не освобождаясь от captureOutput: didOutputSampleBuffer: fromConnection

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     :(AVCaptureConnection *)connection 
{ 
    // Create a UIImage from the sample buffer data 
    UIImage *image = [self imageFromSampleBuffer:sampleBuffer]; 

    if(delegate && [delegate respondsToSelector:@selector(captureManagerCapturedFrame:withFrameImage:withFrameBuffer:)]) { 
     [delegate captureManagerCapturedFrame:self withFrameImage:image withFrameBuffer:sampleBuffer]; 
    } 

} 

Я делаю это потому, что в методе делегата captureManagerCapturedFrame:withFrameImage:withFrameBuffer: у меня есть флаг, который указывает приложение использовать либо возвращенный uiimage ИЛИ возвращенный sampleBuffer.

метод делегата:

- (void) captureManagerCapturedFrame:(AVCamCaptureManager *)captureManager 
         withFrameImage:(UIImage *)image 
        withFrameBuffer:(CMSampleBufferRef)frameBuffer { 

    if(_screen1) { 
     NSLog(@"Only display camera image\n"); 
    } 
    else if(_screen2) { 
     //Enable IR 
     NSLog(@"Display AND Process camera image\n"); 
     [self imageReconigitionProcessFrame:frameBuffer]; 
    } 
} 

где imageReconigitionProcessFrame: является:

-(void)imageReconigitionProcessFrame:(CMSampleBufferRef)frameBuffer { 

    //CFRetain(frameBuffer); 
    MSImage *qry = [[MSImage alloc] initWithBuffer:frameBuffer orientation:AVCaptureVideoOrientationPortrait]; //MEMORY LEAK HERE??? 
    qry = nil; 
    //CFRelease(frameBuffer); 
} 

Этот код работает эффективно. Но вот моя проблема. Когда этот код запущен и профилирован в инструментах, я вижу быстрое увеличение используемого overall bytes, но профилировщик распределения не растет. Также не вижу никаких «утечек», используя инструмент утечек. Но, очевидно, происходит быстрое увеличение памяти каждый раз, когда вызывается imageReconigitionProcessFrame:, и приложение падает через несколько секунд. Когда я устанавливаю frameBuffer в nil, нет увеличения объема памяти (или, конечно, у меня также нет буфера кадров для обработки).

Я пробовал передать право собственности на frameBuffer с использованием CFRetain и CFRelease (прокомментирован в вышеуказанном коде), но они также ничего не делают.

Кто-нибудь есть идеи, где я мог бы утечка памяти внутри этой функции ??? Метод [[MSImage alloc] initWithBuffer: представляет собой SDK третьей стороны (Moodstocks, который является удивительным SDK распознавания образов), и он отлично работает в своих демонстрационных версиях, поэтому я не думаю, что проблема внутри этой функции.

ответ

0

Прежде всего, спасибо за упоминание Moodstocks (я работаю на них): мы рады, что вы нашли наш SDK полезным!

Чтобы ответить на ваш вопрос, я думаю, что ваш код действительно содержит утечку: в конце метода imageReconigitionProcessFrame вы должны позвонить [qry release]. Правило в Obj-C довольно просто: всякий раз, когда вы вручную вызываете alloc на объект, его также следует отпустить вручную!

Это BTW, что делается в Moodstocks SDK обертке: если вы посмотрите на метод [MSScannerSession session: didOutputSampleBuffer:], вы увидите, что мы вручную освободить MSImage объект после того, как он был обработан.

Что касается того, почему профайлер не находит эту утечку, я полагаю, что это связано с тем, что утечки анализируются каждые 10 секунд по умолчанию: в этом случае утечка памяти настолько тяжелая (1280x720 кадров, при 15 + FPS, если вы находитесь на iPhone 5, в течение 10 секунд: пропустили не менее 130 МБ), что код должен потерпеть крах до достижения первых 10 секунд.

Надеюсь, это поможет!

+0

Мой проект включен ARC, поэтому добавление оператора '[qry release]' не идет. Я попытался добавить '[[MSImage alloc] initWithBuffer:' непосредственно в метод 'captureOutput: didOutputSampleBuffer: fromConnection' (вместо того, чтобы передавать буфер обратно через класс делегата, и та же проблема сохраняется. – Brett

+0

ОК, я не знакомый с ARC, к сожалению ... Обычно я разработчик Android здесь: D.Тем не менее, я бы попытался проверить, что метод '[MSImage dealloc]' вызывается: если это так, то объект, ответственный за утечку, не является 'qry', а что-то еще ... – mbrenon

+0

' [MSImage dealloc] 'на самом деле является называется. Это еще одна причина, по которой я думаю, что это связано с буфером кадров, а не с созданием MSImage. – Brett