Skip to content

Commit

Permalink
Merge pull request #76 from spoonconsulting/optimise-memory-consumption
Browse files Browse the repository at this point in the history
release unused memory
  • Loading branch information
dinitri authored Jul 5, 2024
2 parents 20fe4ba + 93621d2 commit 2d7e520
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 25 deletions.
1 change: 1 addition & 0 deletions src/ios/CameraRenderController.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
@property (nonatomic) CIContext *ciContext;
@property (nonatomic) CIImage *latestFrame;
@property (nonatomic) EAGLContext *context;
@property (nonatomic) CVPixelBufferRef pixelBuffer;
@property (nonatomic) NSLock *renderLock;
@end
54 changes: 39 additions & 15 deletions src/ios/CameraRenderController.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ - (void)loadView {

- (void)viewDidLoad {
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
if (!self.context)
NSLog(@"Failed to create ES context");

Expand All @@ -33,7 +33,7 @@ - (void)viewDidLoad {

GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
view.drawableDepthFormat = GLKViewDrawableDepthFormatNone;
view.contentMode = UIViewContentModeScaleToFill;

glGenRenderbuffers(1, &_renderBuffer);
Expand All @@ -60,6 +60,11 @@ - (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
[self.view removeFromSuperview];
[EAGLContext setCurrentContext:nil];
self.context = nil;
[self deallocateRenderMemory];
self.ciContext = nil;
}

- (void) appplicationIsActive:(NSNotification *)notification {
Expand All @@ -72,16 +77,21 @@ - (void) appplicationIsActive:(NSNotification *)notification {
}

- (void) applicationEnteredForeground:(NSNotification *)notification {
// dispatch_async(self.sessionManager.sessionQueue, ^{
// NSLog(@"Stopping session");
// [self.sessionManager.session stopRunning];
// });
// dispatch_async(self.sessionManager.sessionQueue, ^{
// NSLog(@"Stopping session");
// [self.sessionManager.session stopRunning];
// });
[self.view removeFromSuperview];
[EAGLContext setCurrentContext:nil];
self.context = nil;
[self deallocateRenderMemory];
self.ciContext = nil;
}

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
if ([self.renderLock tryLock]) {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer];
_pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
CIImage *image = [CIImage imageWithCVPixelBuffer:_pixelBuffer];

__block CGRect frame;
dispatch_sync(dispatch_get_main_queue(), ^{
Expand Down Expand Up @@ -150,17 +160,19 @@ -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMS
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];

if ([EAGLContext currentContext] == self.context) {
[EAGLContext setCurrentContext:nil];
}
[EAGLContext setCurrentContext:nil];
self.context = nil;
[self deallocateRenderMemory];
self.ciContext = nil;
CVBufferRelease(_pixelBuffer);
_pixelBuffer = nil;
}

- (void)dealloc {
if ([EAGLContext currentContext] == self.context) {
[EAGLContext setCurrentContext:nil];
}
[EAGLContext setCurrentContext:nil];
self.context = nil;
[self deallocateRenderMemory];
self.ciContext = nil;
}

- (BOOL)shouldAutorotate {
Expand All @@ -172,10 +184,22 @@ -(void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIVi
__block UIInterfaceOrientation toInterfaceOrientation;
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
toInterfaceOrientation = [self.sessionManager getOrientation];

} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self.sessionManager updateOrientation:[self.sessionManager getCurrentOrientation:toInterfaceOrientation]];
}];
}

-(void) deallocateRenderMemory {
if (_renderBuffer) {
glDeleteRenderbuffers(1, &_renderBuffer);
_renderBuffer = 0;
}
if (_videoTextureCache) {
CVOpenGLESTextureCacheFlush(_videoTextureCache, 0);
CFRelease(_videoTextureCache);
_videoTextureCache = nil;
}
}

@end
1 change: 1 addition & 0 deletions src/ios/CameraSessionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- (void) torchSwitch:(NSInteger)torchState;
- (void) switchCameraTo:(NSString *)cameraMode completion:(void (^)(BOOL success))completion;
- (BOOL) deviceHasUltraWideCamera;
- (void) deallocSession;
- (void) updateOrientation:(AVCaptureVideoOrientation)orientation;
- (AVCaptureVideoOrientation) getCurrentOrientation:(UIInterfaceOrientation)toInterfaceOrientation;
+ (AVCaptureSessionPreset) calculateResolution:(NSInteger)targetSize;
Expand Down
14 changes: 14 additions & 0 deletions src/ios/CameraSessionManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,18 @@ - (UIInterfaceOrientation) getOrientation {
}
}

- (void)deallocSession {
if (self.session.running) {
[self.session stopRunning];
}
self.session = nil;
self.videoDeviceInput = nil;
self.imageOutput = nil;
self.dataOutput = nil;
self.filterLock = nil;
if (self.sessionQueue) {
self.sessionQueue = nil;
}
}

@end
31 changes: 21 additions & 10 deletions src/ios/SimpleCameraPreview.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#import <Cordova/CDV.h>
#import <Cordova/CDVPlugin.h>
#import <Cordova/CDVInvokedUrlCommand.h>
@import CoreLocation;
@import CoreLocation;
@import ImageIO;

#import "SimpleCameraPreview.h"
Expand Down Expand Up @@ -60,6 +60,7 @@ - (void) enable:(CDVInvokedUrlCommand*)command {
[self _setSize:command];
[self.viewController addChildViewController:self.cameraRenderController];
[self.webView.superview insertSubview:self.cameraRenderController.view atIndex:0];
[self.cameraRenderController didMoveToParentViewController:self.viewController];
self.viewController.view.backgroundColor = [UIColor blackColor];

// Setup session
Expand Down Expand Up @@ -112,15 +113,17 @@ - (void) disable:(CDVInvokedUrlCommand*)command {
for(AVCaptureOutput *output in self.sessionManager.session.outputs) {
[self.sessionManager.session removeOutput:output];
}
[self.sessionManager.session stopRunning];
[self.sessionManager deallocSession];
self.sessionManager = nil;
dispatch_async(dispatch_get_main_queue(), ^{
[self.cameraRenderController.view removeFromSuperview];
if(self.viewController.parentViewController != nil) {
[self.cameraRenderController removeFromParentViewController];
}
self.cameraRenderController = nil;
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] callbackId:command.callbackId];
[self.cameraRenderController willMoveToParentViewController:nil];
[self.cameraRenderController.view removeFromSuperview];
if(self.viewController.parentViewController != nil) {
[self.cameraRenderController removeFromParentViewController];
}
self.cameraRenderController = nil;
[self deallocateMemory];
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] callbackId:command.callbackId];
});
}
else {
Expand Down Expand Up @@ -183,8 +186,8 @@ - (void) deviceHasUltraWideCamera:(CDVInvokedUrlCommand *)command{

- (void) deviceHasFlash:(CDVInvokedUrlCommand*)command{
AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera]
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionBack];
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionBack];
NSArray *captureDevices = [captureDeviceDiscoverySession devices];
BOOL hasTorch = NO;

Expand Down Expand Up @@ -346,4 +349,12 @@ - (void)runBlockWithTryCatch:(void (^)(void))block {
}
}

- (void)deallocateMemory {
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureSessionWasInterruptedNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureSessionInterruptionEndedNotification object:nil];
[locationManager stopUpdatingLocation];
locationManager.delegate = nil;
locationManager = nil;
}

@end

0 comments on commit 2d7e520

Please sign in to comment.