Skip to content

Commit 9efff03

Browse files
author
Bryant Luk
committed
Explicit memory management for CMSampleBufferRef
- Explicitly CFRetain/CFRelease CMSampleBufferRef and CVImageBufferRef to prevent memory issues - CVPixelBufferLockBaseAddress and CVPixelBufferUnlockBaseAddress while image buffer data is retained - See issue #194
1 parent c00c95d commit 9efff03

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

Classes/CardIOIplImage.mm

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
@interface CardIOIplImage ()
1414

1515
@property(nonatomic, assign, readwrite) IplImage *image;
16+
@property(nonatomic, assign, readwrite) CVImageBufferRef imageBuffer;
1617

1718
@end
1819

@@ -26,8 +27,10 @@ + (CardIOIplImage *)imageWithSize:(CvSize)size depth:(int)depth channels:(int)ch
2627
}
2728

2829
+ (CardIOIplImage *)imageFromYCbCrBuffer:(CVImageBufferRef)imageBuffer plane:(size_t)plane {
30+
CVPixelBufferLockBaseAddress(imageBuffer, 0);
2931
char *planeBaseAddress = (char *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, plane);
30-
32+
// CVPixelBufferUnlocked in dealloc of CardIOIplImage to ensure lock of memory
33+
3134
size_t width = CVPixelBufferGetWidthOfPlane(imageBuffer, plane);
3235
size_t height = CVPixelBufferGetHeightOfPlane(imageBuffer, plane);
3336
size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, plane);
@@ -37,16 +40,25 @@ + (CardIOIplImage *)imageFromYCbCrBuffer:(CVImageBufferRef)imageBuffer plane:(si
3740
colocatedImage->imageData = planeBaseAddress;
3841
colocatedImage->widthStep = (int)bytesPerRow;
3942

40-
return [self imageWithIplImage:colocatedImage];
43+
return [[self alloc] initWithIplImage:colocatedImage imageBuffer:imageBuffer];
4144
}
4245

4346
+ (CardIOIplImage *)imageWithIplImage:(IplImage *)anImage {
4447
return [[self alloc] initWithIplImage:anImage];
4548
}
4649

4750
- (id)initWithIplImage:(IplImage *)anImage {
51+
return [self initWithIplImage:anImage imageBuffer:NULL];
52+
}
53+
54+
- (id)initWithIplImage:(IplImage *)anImage imageBuffer:(CVImageBufferRef)imageBuffer {
4855
if((self = [super init])) {
4956
self.image = anImage;
57+
58+
self.imageBuffer = imageBuffer;
59+
if (imageBuffer != NULL) {
60+
CFRetain(imageBuffer);
61+
}
5062
}
5163
return self;
5264
}
@@ -78,6 +90,10 @@ - (NSString *)description {
7890

7991
- (void)dealloc {
8092
cvReleaseImage(&image);
93+
if(_imageBuffer != nil) {
94+
CVPixelBufferUnlockBaseAddress(_imageBuffer, 0);
95+
CFRelease(_imageBuffer);
96+
}
8197
}
8298

8399
- (IplImage *)image {

Classes/CardIOVideoFrame.mm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,18 @@ @implementation CardIOVideoFrame
5252
- (id)initWithSampleBuffer:(CMSampleBufferRef)sampleBuffer interfaceOrientation:(UIInterfaceOrientation)currentOrientation {
5353
if((self = [super init])) {
5454
_buffer = sampleBuffer;
55+
CFRetain(_buffer);
56+
5557
_orientation = currentOrientation; // not using setters/getters, for performance
5658
_dmz = NULL; // use NULL b/c non-object pointer
5759
}
5860
return self;
5961
}
6062

63+
- (void)dealloc {
64+
CFRelease(_buffer);
65+
}
66+
6167
#if USE_CAMERA
6268

6369
- (void)process {

0 commit comments

Comments
 (0)