vlc/vlc-3.0 | branch: master | Thomas Guillem <tho...@gllm.fr> | Tue Mar 6 13:14:29 2018 +0100| [f5380c99a43a6f1327c4179e950629c24a8655fe] | committer: Thomas Guillem
vout: ios: don't wait for the MainThead from the Close callback (cherry picked from commit e3a38e5a9c185f68bef8749f2eb093b4fee98b1d) Signed-off-by: Thomas Guillem <tho...@gllm.fr> > http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=f5380c99a43a6f1327c4179e950629c24a8655fe --- modules/video_output/ios.m | 131 +++++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 51 deletions(-) diff --git a/modules/video_output/ios.m b/modules/video_output/ios.m index 5da6c2382a..03cd0257d4 100644 --- a/modules/video_output/ios.m +++ b/modules/video_output/ios.m @@ -97,6 +97,9 @@ vlc_module_end () BOOL _appActive; BOOL _placeInvalidated; + UIView *_viewContainer; + UITapGestureRecognizer *_tapRecognizer; + /* Written from MT, read locked from vout */ vout_display_place_t _place; CGSize _viewSize; @@ -111,6 +114,7 @@ vlc_module_end () @property GLuint shaderProgram; - (id)initWithFrameAndVd:(CGRect)frame withVd:(vout_display_t*)vd; +- (void)cleanAndRelease; - (void)createBuffers; - (void)destroyBuffers; - (BOOL)makeCurrent:(EAGLContext **)previousEaglContext; @@ -120,14 +124,11 @@ vlc_module_end () - (void)updateVoutCfg:(const vout_display_cfg_t *)cfg withVGL:(vout_display_opengl_t *)vgl; - (void)getPlaceLocked:(vout_display_place_t *)place; - (void)reshape; -- (void)propagateDimensionsToVoutCore; @end struct vout_display_sys_t { VLCOpenGLES2VideoView *glESView; - UIView *viewContainer; - UITapGestureRecognizer *tapRecognizer; vlc_gl_t *gl; @@ -176,13 +177,8 @@ static int Open(vlc_object_t *this) waitUntilDone:YES]; if (!sys->glESView) { msg_Err(vd, "Creating OpenGL ES 2 view failed"); - goto bailout; - } - - [sys->glESView performSelectorOnMainThread:@selector(fetchViewContainer) withObject:nil waitUntilDone:YES]; - if (!sys->viewContainer) { - msg_Err(vd, "Fetching view container failed"); - goto bailout; + var_Destroy(vd->obj.parent, "ios-eaglcontext"); + return VLC_EGENERIC; } const vlc_fourcc_t *subpicture_chromas; @@ -253,17 +249,7 @@ static void Close (vlc_object_t *this) vout_display_sys_t *sys = vd->sys; @autoreleasepool { - if (sys->tapRecognizer) { - [sys->tapRecognizer.view performSelectorOnMainThread:@selector(removeGestureRecognizer:) withObject:sys->tapRecognizer waitUntilDone:YES]; - [sys->tapRecognizer release]; - } - var_Destroy (vd, "drawable-nsobject"); - @synchronized(sys->viewContainer) { - [sys->glESView performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:NO]; - [sys->viewContainer performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO]; - } - sys->viewContainer = nil; if (sys->gl != NULL) { struct gl_sys *glsys = sys->gl->sys; @@ -278,7 +264,7 @@ static void Close (vlc_object_t *this) vlc_object_release(sys->gl); } - [sys->glESView release]; + [sys->glESView cleanAndRelease]; } var_Destroy(vd->obj.parent, "ios-eaglcontext"); } @@ -453,67 +439,94 @@ static void GLESSwap(vlc_gl_t *gl) [self releaseCurrent:previousEaglContext]; [self createBuffers]; - [self reshape]; + + if (![self fetchViewContainer]) + { + vlc_mutex_destroy(&_mutex); + [_eaglContext release]; + return nil; + } return self; } -- (void)fetchViewContainer +- (BOOL)fetchViewContainer { @try { /* get the object we will draw into */ UIView *viewContainer = var_CreateGetAddress (_voutDisplay, "drawable-nsobject"); if (unlikely(viewContainer == nil)) { msg_Err(_voutDisplay, "provided view container is nil"); - return; + return NO; } if (unlikely(![viewContainer respondsToSelector:@selector(isKindOfClass:)])) { msg_Err(_voutDisplay, "void pointer not an ObjC object"); - return; + return NO; } [viewContainer retain]; - @synchronized(viewContainer) { - if (![viewContainer isKindOfClass:[UIView class]]) { - msg_Err(_voutDisplay, "passed ObjC object not of class UIView"); - return; - } - - vout_display_sys_t *sys = _voutDisplay->sys; + if (![viewContainer isKindOfClass:[UIView class]]) { + msg_Err(_voutDisplay, "passed ObjC object not of class UIView"); + return NO; + } - /* This will be released in Close(), on - * main thread, after we are done using it. */ - sys->viewContainer = viewContainer; + /* This will be released in Close(), on + * main thread, after we are done using it. */ + _viewContainer = viewContainer; - self.frame = viewContainer.bounds; - [self reshape]; + self.frame = viewContainer.bounds; + [self reshape]; - [sys->viewContainer addSubview:self]; + [_viewContainer addSubview:self]; - /* add tap gesture recognizer for DVD menus and stuff */ - sys->tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self - action:@selector(tapRecognized:)]; - if (sys->viewContainer.window) { - if (sys->viewContainer.window.rootViewController) { - if (sys->viewContainer.window.rootViewController.view) - [sys->viewContainer.superview addGestureRecognizer:sys->tapRecognizer]; - } - } - sys->tapRecognizer.cancelsTouchesInView = NO; - } + /* add tap gesture recognizer for DVD menus and stuff */ + _tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(tapRecognized:)]; + if (_viewContainer.window + && _viewContainer.window.rootViewController + && _viewContainer.window.rootViewController.view) + [_viewContainer.superview addGestureRecognizer:_tapRecognizer]; + _tapRecognizer.cancelsTouchesInView = NO; + return YES; } @catch (NSException *exception) { msg_Err(_voutDisplay, "Handling the view container failed due to an Obj-C exception (%s, %s", [exception.name UTF8String], [exception.reason UTF8String]); vout_display_sys_t *sys = _voutDisplay->sys; - sys->viewContainer = nil; + if (_tapRecognizer) + [_tapRecognizer release]; + return NO; } } -- (void)dealloc +- (void)cleanAndRelease { + if (![NSThread isMainThread]) + { + vlc_mutex_lock(&_mutex); + _voutDisplay = nil; + vlc_mutex_unlock(&_mutex); + + [self performSelectorOnMainThread:@selector(cleanAndRelease) + withObject:nil + waitUntilDone:NO]; + return; + } + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [_tapRecognizer.view removeGestureRecognizer:_tapRecognizer]; + [_tapRecognizer release]; + + [self removeFromSuperview]; + [_viewContainer release]; + [_eaglContext release]; + [self release]; +} + +- (void)dealloc +{ vlc_mutex_destroy(&_mutex); [super dealloc]; } @@ -651,6 +664,7 @@ static void GLESSwap(vlc_gl_t *gl) - (void)getPlaceLocked:(vout_display_place_t *)place { + assert(_voutDisplay); vout_display_cfg_t cfg = _cfg; cfg.display.width = _viewSize.width * _scaleFactor; @@ -670,6 +684,11 @@ static void GLESSwap(vlc_gl_t *gl) } vlc_mutex_lock(&_mutex); + if (!_voutDisplay) + { + vlc_mutex_unlock(&_mutex); + return; + } _viewSize = [self bounds].size; _scaleFactor = self.contentScaleFactor; @@ -681,6 +700,7 @@ static void GLESSwap(vlc_gl_t *gl) _placeInvalidated = YES; _place = place; } + vout_display_SendEventDisplaySize(_voutDisplay, _viewSize.width * _scaleFactor, _viewSize.height * _scaleFactor); @@ -689,6 +709,13 @@ static void GLESSwap(vlc_gl_t *gl) - (void)tapRecognized:(UITapGestureRecognizer *)tapRecognizer { + vlc_mutex_lock(&_mutex); + if (!_voutDisplay) + { + vlc_mutex_unlock(&_mutex); + return; + } + UIGestureRecognizerState state = [tapRecognizer state]; CGPoint touchPoint = [tapRecognizer locationInView:self]; CGFloat scaleFactor = self.contentScaleFactor; @@ -698,6 +725,8 @@ static void GLESSwap(vlc_gl_t *gl) vout_display_SendEventMousePressed(_voutDisplay, MOUSE_BUTTON_LEFT); vout_display_SendEventMouseReleased(_voutDisplay, MOUSE_BUTTON_LEFT); + + vlc_mutex_unlock(&_mutex); } - (void)updateVoutCfg:(const vout_display_cfg_t *)cfg withVGL:(vout_display_opengl_t *)vgl _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits