Ядро iOSУтечки видеопамяти

Может ли кто-нибудь помочь мне отследить эти утечки памяти CoreVideo при запуске инструментов в XCode?

Обычно утечка памяти происходит, когда я нажимаю кнопку «Запись видео» на моем пользовательском проигрывателе Motion jpeg. Я не могу точно сказать, какая часть моего кода протекает, поскольку Leaks Instruments не указывает ни на один из моих вызовов. Кстати, я использую iPad для проверки утечек.

Вот сообщения от Leaks Instruments:

  • Ответственная библиотека = CoreVideo
  • Ответственный фрейм: CVPixelBufferBacking :: initWithPixelBufferDescription (..) CVObjectAlloc (...) CVBuffer :: init ()

Вот мой код, который обрабатывает все кадры движения jpeg, передаваемые сервером:

-(void)processServerData:(NSData *)data{    

/*
//render the video in the UIImage control
*/
UIImage *image =[UIImage imageWithData:data];
self.imageCtrl.image = image;

/*
//check if we are recording
*/
if (myRecorder.isRecording) {

    //create initial sample: todo:check if this is still needed
    if (counter==0) {

        self.buffer = [Recorder pixelBufferFromCGImage:image.CGImage size:myRecorder.imageSize];
        CVPixelBufferPoolCreatePixelBuffer (NULL, myRecorder.adaptor.pixelBufferPool, &buffer);

        if(buffer) 
        {
            CVBufferRelease(buffer);
        }
    }

    if (counter < myRecorder.maxFrames)
    {
        if([myRecorder.writerInput isReadyForMoreMediaData])
        {
            CMTime frameTime = CMTimeMake(1, myRecorder.timeScale);
            CMTime lastTime=CMTimeMake(counter, myRecorder.timeScale); 
            CMTime presentTime=CMTimeAdd(lastTime, frameTime);

            self.buffer = [Recorder pixelBufferFromCGImage:image.CGImage size:myRecorder.imageSize];

            [myRecorder.adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];

            if(buffer)
            {
                CVBufferRelease(buffer);
            }

            counter++;

            if (counter==myRecorder.maxFrames)
            {
                [myRecorder finishSession];

                counter=0;
                myRecorder.isRecording = NO;
            }
        }
        else
        {
            NSLog(@"adaptor not ready counter=%d ",counter );
        }
    }
}

}

Вот функция pixelBufferFromCGImage:

+ (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image size:(CGSize) size{
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                         [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                         nil];
CVPixelBufferRef pxbuffer = NULL;

CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, size.width,
                                      size.height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) options, 
                                      &pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
NSParameterAssert(pxdata != NULL);

CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
                                             size.height, 8, 4*size.width, rgbColorSpace, 
                                             kCGImageAlphaNoneSkipFirst);
NSParameterAssert(context);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
                                       CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);

CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

return pxbuffer;

}

Примите любую помощь! Спасибо


person German    schedule 01.04.2011    source источник
comment
Как вы проверяли утечку? Через инструменты? Мое приложение закрывается после использования 400 МБ памяти, и я вижу эту причину в отладчике XCode: Прервано из-за проблемы с памятью   -  person nr5    schedule 05.07.2017


Ответы (2)


Я провел рефакторинг метода processFrame и больше не получаю утечек.

-(void) processFrame:(UIImage *) image {

    if (myRecorder.frameCounter < myRecorder.maxFrames)
    {
        if([myRecorder.writerInput isReadyForMoreMediaData])
        {
            CMTime frameTime = CMTimeMake(1, myRecorder.timeScale);
            CMTime lastTime=CMTimeMake(myRecorder.frameCounter, myRecorder.timeScale); 
            CMTime presentTime=CMTimeAdd(lastTime, frameTime);

            buffer = [Recorder pixelBufferFromCGImage:image.CGImage size:myRecorder.imageSize];

            if(buffer)
            {
                [myRecorder.adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];

                myRecorder.frameCounter++;

                CVBufferRelease(buffer);

                if (myRecorder.frameCounter==myRecorder.maxFrames)
                {
                    [myRecorder finishSession];

                    myRecorder.frameCounter=0;
                    myRecorder.isRecording = NO;
                }
            }
            else
            {
                NSLog(@"Buffer is empty");
            }
        }
        else
        {
            NSLog(@"adaptor not ready frameCounter=%d ",myRecorder.frameCounter );
        }
    }

}
person German    schedule 05.04.2011

Я не вижу ничего слишком очевидного. Я заметил, что вы здесь используете self.buffer и buffer. Если он останется, возможно, вы протекаете там. Если CVPixelBufferPoolCreatePixelBuffer выделяет память во второй строке после того, как self.buffer сохраняется в первой строке, первая может быть утечкой.

    self.buffer = [Recorder pixelBufferFromCGImage:image.CGImage size:myRecorder.imageSize];
    CVPixelBufferPoolCreatePixelBuffer (NULL, myRecorder.adaptor.pixelBufferPool, &buffer);

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

person NWCoder    schedule 01.04.2011
comment
Я попытался удалить себя из self.buffer, но у меня все еще есть утечки памяти. Спасибо - person German; 02.04.2011