2013-09-27 58 views
4

我現在正在編寫一個程序來捕獲屏幕並轉換爲視頻。如果視頻少於10秒,我可以成功保存視頻。但是,如果不止於此,我收到了內存警告和應用程序崩潰。我寫了如下代碼。我錯在哪裏發佈數據?我想知道該怎麼做。捕獲屏幕並保存到視頻時收到內存警告ios

-(void)captureAndSaveImage 
{ 

if(!stopCapturing){ 

if (assetWriterInput.readyForMoreMediaData) 
{ 
    keepTrackOfBackGroundMood++; 
    NSLog(@"keepTrackOfBackGroundMood is %d",keepTrackOfBackGroundMood); 

    CVReturn cvErr = kCVReturnSuccess; 

    CGSize imageSize = screenCaptureAndDraw.bounds.size; 


    CGFloat imageScale = 0; //if zero, it reduce processing time 

    if (NULL != UIGraphicsBeginImageContextWithOptions) 
    { 
     UIGraphicsBeginImageContextWithOptions(imageSize, NO, imageScale); 
    } 
    else 
    { 
     UIGraphicsBeginImageContext(imageSize); 
    } 

    [self.hiddenView.layer renderInContext:UIGraphicsGetCurrentContext()]; 

    [self.screenCaptureAndDraw.layer renderInContext:UIGraphicsGetCurrentContext()]; 


    UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 



    image = (CGImageRef) [img CGImage]; 

    CVPixelBufferRef pixelBuffer = NULL; 
    CFDataRef imageData= CGDataProviderCopyData(CGImageGetDataProvider(image)); 
    cvErr = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, 
             FRAME_WIDTH2, 
             FRAME_HEIGHT2, 
             kCVPixelFormatType_32BGRA, 
             (void*)CFDataGetBytePtr(imageData), 
             CGImageGetBytesPerRow(image), 
             NULL, 
             NULL, 
             NULL, 
             &pixelBuffer); 


    //CFRelease(imageData); 
    //CGImageRelease(image); //I can't write this code because I am not creating it and when I check online, it say it is not my responsibility to release. If I write, the application crash immediately 


    // calculate the time 
    CFAbsoluteTime thisFrameWallClockTime = CFAbsoluteTimeGetCurrent(); 
    CFTimeInterval elapsedTime = thisFrameWallClockTime - firstFrameWallClockTime; 


    // write the sample 

    BOOL appended = [assetWriterPixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:presentationTime]; 

    if (appended) { 
     NSLog (@"appended sample at time %lf and keepTrackofappended is %d", CMTimeGetSeconds(presentationTime),keepTrackofappended); 
     keepTrackofappended++; 
    } else { 
     NSLog (@"failed to append"); 
     [self stopRecording]; 
     //self.startStopButton.selected = NO; 
     screenRecord=false; 
    } 



} 

}//stop capturing 
// }); 


} 
+0

你必須在某個地方有泄漏(至少,我會取消註釋'CFRelease(imageData)'並且不要忘記'CVPixelBufferRelease')。我剛剛測試了一次1200幀捕捉,並且在我的iPhone 5上很好。當我在樂器中進行測試時,分配是平坦的,所以除非你有一些泄漏,否則你應該沒問題。 – Rob

回答

2

我同意你不想做CGImageRelease(image)。該對象是通過調用UIImage對象的方法CGImage創建的。因此,所有權並未轉移,ARC仍在爲您的對象執行內存管理,因此不需要釋放對象。

但我想你想恢復你的CFRelease(imageData)。這是由CGDataProviderCopyData創建的對象,因此您擁有它並且必須清理。

我也認爲你必須在appendPixelBuffer之後發佈CVPixelBufferCreateWithBytes創建的pixelBuffer。您可以使用CVPixelBufferRelease函數。

核心基金會內存規則是,如果函數名稱中有CopyCreate,則您擁有該對象並負責釋放它。請參閱針對Core Foundation的「內存管理編程指南」中的Create Rule

我還以爲這個靜態分析(轉變 + 命令 + 或從Xcode的「產品」菜單中的「分析」)將已經確定了這個問題,因爲它已經得到了在要好得多尋找核心基金會的內存問題(儘管不完美)。或者,如果您通過樂器中的Leaks工具運行應用程序(它也會同時向您顯示分配工具),則可以查看您的內存使用情況。雖然視頻捕捉需要大量的實時字節,但根據我的經驗,它仍然非常平實。如果它在增長,你會在某處發生泄漏。

+0

哦,謝謝Rob。你真的幫助我。我認爲它現在解決內存泄漏問題。我會再次用靜態分析儀檢查。 –

+0

@Rob解決了嗎? –

+0

@ user1111是的,'CFRelease(imageData)'和'CVPixelBufferRelease(pixelBuffer)'(但不是'CGImageRelease(image)')應該可以彌補泄漏。 – Rob