2012-12-07 6 views
0

내가 지금 여기의 CGImage에서 CVPixelBufferRef를 만들기 위해 노력하고는 방법 :CGContextDrawImage 충돌

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

    CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image), 
         CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (CFDictionaryRef) options, 
         &pxbuffer); 

    CVPixelBufferLockBaseAddress(pxbuffer, 0); 
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer); 
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image), 
               CGImageGetHeight(image), 8, 4*CGImageGetWidth(image), rgbColorSpace, 
               kCGImageAlphaNoneSkipFirst); 
    CGContextRetain(context); 
    CGContextConcatCTM(context, CGAffineTransformMakeRotation(0)); 
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
               CGImageGetHeight(image)), image); 
    CGColorSpaceRelease(rgbColorSpace); 
    CGContextRelease(context); 
    CVPixelBufferUnlockBaseAddress(pxbuffer, 0); 
    CGContextRelease(context); 
    CGImageRelease(image); 
    return pxbuffer; 
} 

나는 자주이 메소드를 호출, 그것은 비디오 프레임, 초당 25을 생성하는 것입니다. 이 대부분의 시간을 잘 작동하지만 어떤 점에서 그것은 코드의이 라인에 충돌 : I`ve 메모리 사용 및 메모리 누수를 테스트하고 모든 것이 잘 솔기하지만, 호감이 STIL 발생

CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
                CGImageGetHeight(image)), image); 

.

충돌 스택 : 스레드 (6) 추락 :

0 ImageIO       0x39270806 CGImageReadGetBytesAtOffset + 34 
1 ImageIO       0x392707d6 CGImageReadSessionGetBytes + 22 
2 ImageIO       0x39280c3c fill_input_buffer + 148 
3 ImageIO       0x3928003a read_markers + 154 
4 ImageIO       0x3927fd82 consume_markers + 34 
5 ImageIO       0x3927fbd2 _cg_jpeg_consume_input + 66 
6 ImageIO       0x3927fb62 _cg_jpeg_read_header + 38 
7 ImageIO       0x39292782 copyImageBlockSetJPEG + 2346 
8 ImageIO       0x3928953e ImageProviderCopyImageBlockSetCallback + 510 
9 CoreGraphics     0x38e0b9d6 CGImageProviderCopyImageBlockSetWithOptions + 158 
10 CoreGraphics     0x38e0b66a img_blocks_create + 370 
11 CoreGraphics     0x38e07a98 img_data_lock + 1488 
12 CoreGraphics     0x38e06d2a CGSImageDataLock + 126 
+0

[http://stackoverflow.com/questions/10774392/cgcontextdrawimage-crashes] [1] 가 pxdata을 유지하려고 [1] : http://stackoverflow.com/questions 귀하의 조언에 따라/10774392/cgcontextdrawimage-충돌 – zengcity

답변

1

을 충돌 스택에서, 그 자체가 아마 이전 CGImageRetain()에 전화로, 다른 스레드에서 해제 이미지처럼 보인다. 여기서 CGImageRetain()으로 전화한다는 사실은 당신이 그것을 기대한다고 암시합니다. 그러나 그 경우 경쟁 조건을 만들기 때문에 보유가 불충분합니다. 이미지를 유지하려고 시도하기 전에 이미지가 손상되었을 수 있습니다. 따라서 CGImageRetain 중 하나가 불필요하거나 불충분합니다. 어떤 경우에도 그것이 여기에 있어야하지 않으며 (균형을 잡기 위해서도) CGImageRelease.

이것은 다른 스레드에서이 이미지를 사용하는 것이 매우 위험하다는 것을 보여줍니다.이 메서드는 이상하게도이 메서드를 호출하거나 스레드를 지나치게 복잡하게 만들도록 제안합니다. 예를 들어 NSThread을 직접 사용하는 경우 너무 복잡하게 보일 수 있습니다.

이 이미지의 다른 보존 및 배포를 감사하고이 방법을 호출하는 중에 발생할 수 없는지 확인합니다. 그게 무슨 일이 일어나고 있는지 꽤 확신합니다.

사이드 노트 : 필요없는 중복 CGContextRetain/CGContextRelease이 있습니다. CGBitmapContextCreate()에 전화 할 때 보관함이 포함되어 있습니다 (이름에 '작성'이 있음). 즉, 이는 사소한 성능 문제 일뿐입니다. 너는 그들을 적절히 균형 잡았다. 그러나 다른 곳에서의 메모리 관리가 이상 할 수도 있음을 암시하므로 감사해야합니다. 이런

+0

, 나는 이미지의 복사본을 만들려고했습니다 을 - (CVPixelBufferRef) pixelBufferFromCGImage : (CGImageRef) imageInput { CGImageRef 이미지 = CGImageCreateCopy (imageInput); . . 그러나 충돌은 아직 있습니다. 문제가 스레딩 인 경우 해결해야했습니다. –

+0

첫 번째 줄에 복사본을 만들면 경쟁 조건에 대한 내용이 변경되지 않습니다 (메모리와 현 재 보유가 동일 함). 이미지를 유지하지 않은 시점에서이 메서드를 호출하는 것처럼 들립니다. 아마도 당신은'image.CGImage'를 호출 한 다음'image'를 발표했을 것입니다. 어쩌면 다른 곳에서 전달 된 CGImage를 사용한 다음 그것을 유지하지 않고 다른 스레드에서 사용했을 수도 있습니다. 그러나 스레드를 전환하기 전에이를 수정해야합니다. 문제는이 방법 밖에 거의 확실합니다. 이러한 오류는 사람들이 수동으로'NSThread'로 스레드 할 때 가장 일반적입니다. –