2011-04-01 88 views
4

在XCode中运行Instruments时,有人能帮助我追踪这些CoreVideo内存泄漏吗?iOS CoreVideo内存泄漏

基本上,当我按下自定义运动JPEG播放器上的“录制视频”按钮时,会发生内存泄漏。由于Leaks Instruments没有指向我的任何呼叫,因此我无法确切知道我的代码的哪个部分在泄漏。顺便说一句,我正在使用iPad设备来测试泄漏。

继承人从泄漏仪器消息:

  • 负责图书馆= corevideo的
  • 负责任的框架: CVPixelBufferBacking :: initWithPixelBufferDescription(..) CVObjectAlloc(...) CVBuffer :: init()

这是我的代码,它处理每个运动jpeg帧s服务器treamed:

-(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; 

}

Aprpeciate任何帮助!谢谢

+0

你是怎么检查泄漏的?通过仪器?我的应用在使用400MB内存后退出,我在XCode调试器中看到这个原因:由于内存问题终止 – Nil 2017-07-05 15:28:42

回答

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); 
     } 
    } 

} 
0

我没有看到任何太明显。我注意到你在这里使用self.buffer和buffer。如果它被保留,你可能会在那里泄漏。如果CVPixelBufferPoolCreatePixelBuffer在self.buffer保留在第一行后在第二行中分配内存,则第一行可能会泄漏。

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

希望有帮助。

+0

我尝试从self.buffer中删除“self”,但仍有内存泄漏。谢谢 – German 2011-04-01 22:16:30