Index: /pjproject/trunk/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m	(revision 5046)
+++ /pjproject/trunk/pjmedia/src/pjmedia-videodev/ios_opengl_dev.m	(revision 5047)
@@ -32,4 +32,10 @@
 #define THIS_FILE		"ios_opengl_dev.c"
 
+/* If this is enabled, iOS OpenGL will not return error during creation when
+ * in the background. Instead, it will perform the initialization later
+ * during rendering.
+ */ 
+#define ALLOW_DELAYED_INITIALIZATION 	0
+
 typedef struct iosgl_fmt_info
 {
@@ -61,4 +67,5 @@
     void		   *user_data;          /**< Application data  */
     
+    pj_bool_t		    is_running;
     pj_status_t             status;
     pj_timestamp            frame_ts;
@@ -67,7 +74,7 @@
     const pjmedia_frame    *frame;
     
-    gl_buffers                  *gl_buf;
-    GLView                      *gl_view;
-    EAGLContext                 *ogl_context;
+    gl_buffers             *gl_buf;
+    GLView                 *gl_view;
+    EAGLContext            *ogl_context;
 };
 
@@ -129,5 +136,5 @@
 }
 
-- (void) init_buffers
+- (void) init_gl
 {
     /* Initialize OpenGL ES 2 */
@@ -140,4 +147,11 @@
      nil];
     
+    /* EAGLContext initialization will crash if we are in background mode */
+    if ([UIApplication sharedApplication].applicationState ==
+        UIApplicationStateBackground) {
+        stream->status = PJMEDIA_EVID_INIT;
+        return;
+    }
+    
     stream->ogl_context = [[EAGLContext alloc] initWithAPI:
                            kEAGLRenderingAPIOpenGLES2];
@@ -145,4 +159,5 @@
         ![EAGLContext setCurrentContext:stream->ogl_context])
     {
+        NSLog(@"Failed in initializing EAGLContext");
         stream->status = PJMEDIA_EVID_SYSERR;
         return;
@@ -160,4 +175,22 @@
 }
 
+- (void)deinit_gl
+{
+    if ([EAGLContext currentContext] == stream->ogl_context)
+        [EAGLContext setCurrentContext:nil];
+    
+    if (stream->ogl_context) {
+        [stream->ogl_context release];
+        stream->ogl_context = NULL;
+    }
+    
+    if (stream->gl_buf) {
+        pjmedia_vid_dev_opengl_destroy_buffers(stream->gl_buf);
+        stream->gl_buf = NULL;
+    }
+    
+    [self removeFromSuperview];
+}
+
 - (void)render
 {
@@ -165,6 +198,20 @@
     if ([UIApplication sharedApplication].applicationState ==
         UIApplicationStateBackground)
+    {
         return;
-    
+    }
+
+#if ALLOW_DELAYED_INITIALIZATION
+    if (stream->status != PJ_SUCCESS) {
+        if (stream->status == PJMEDIA_EVID_INIT) {
+            [self init_gl];
+            NSLog(@"Initializing OpenGL now %s", stream->status == PJ_SUCCESS?
+            	  "success": "failed");
+        }
+        
+        return;
+    }
+#endif
+
     if (![EAGLContext setCurrentContext:stream->ogl_context]) {
         /* Failed to set context */
@@ -174,4 +221,11 @@
     pjmedia_vid_dev_opengl_draw(stream->gl_buf, stream->vid_size.w, stream->vid_size.h,
                                 stream->frame->buf);
+}
+
+- (void)finish_render
+{
+    /* Do nothing. This function is serialized in the main thread, so when
+     * it is called, we can be sure that render() has completed.
+     */
 }
 
@@ -219,9 +273,18 @@
     /* Perform OpenGL buffer initializations in the main thread. */
     strm->status = PJ_SUCCESS;
-    [strm->gl_view performSelectorOnMainThread:@selector(init_buffers)
+    [strm->gl_view performSelectorOnMainThread:@selector(init_gl)
                                     withObject:nil waitUntilDone:YES];
-    if ((status = strm->status) != PJ_SUCCESS) {
-        PJ_LOG(3, (THIS_FILE, "Unable to create and init OpenGL buffers"));
-        goto on_error;
+    if ((status = strm->status) != PJ_SUCCESS)
+    {
+        if (status == PJMEDIA_EVID_INIT) {
+            PJ_LOG(3, (THIS_FILE, "Failed to initialize iOS OpenGL because "
+            			  "we are in background"));
+#if !ALLOW_DELAYED_INITIALIZATION
+            goto on_error;
+#endif
+	} else {
+            PJ_LOG(3, (THIS_FILE, "Unable to create and init OpenGL buffers"));
+            goto on_error;
+        }
     }
     
@@ -377,7 +440,6 @@
     struct iosgl_stream *stream = (struct iosgl_stream*)strm;
     
-    PJ_UNUSED_ARG(stream);
-    
     PJ_LOG(4, (THIS_FILE, "Starting ios opengl stream"));
+    stream->is_running = PJ_TRUE;
     
     return PJ_SUCCESS;
@@ -389,4 +451,7 @@
 {
     struct iosgl_stream *stream = (struct iosgl_stream*)strm;
+    
+    if (!stream->is_running)
+	return PJ_EINVALIDOP;
     
     stream->frame = frame;
@@ -394,6 +459,4 @@
     [stream->gl_view performSelectorOnMainThread:@selector(render)
                            withObject:nil waitUntilDone:YES];
-    //    dispatch_async(dispatch_get_main_queue(),
-    //                   ^{[stream->gl_view render];});
     
     [stream->ogl_context presentRenderbuffer:GL_RENDERBUFFER];
@@ -407,7 +470,10 @@
     struct iosgl_stream *stream = (struct iosgl_stream*)strm;
     
-    PJ_UNUSED_ARG(stream);
-    
     PJ_LOG(4, (THIS_FILE, "Stopping ios opengl stream"));
+    stream->is_running = PJ_FALSE;
+
+    /* Wait until the rendering finishes */
+    [stream->gl_view performSelectorOnMainThread:@selector(finish_render)
+                     withObject:nil waitUntilDone:YES];
 
     return PJ_SUCCESS;
@@ -422,26 +488,15 @@
     PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
     
-    iosgl_stream_stop(strm);
-    
-    if ([EAGLContext currentContext] == stream->ogl_context)
-        [EAGLContext setCurrentContext:nil];
-    
-    if (stream->ogl_context) {
-        [stream->ogl_context release];
-        stream->ogl_context = NULL;
-    }
+    if (stream->is_running)
+        iosgl_stream_stop(strm);
     
     if (stream->gl_view) {
-        UIView *view = stream->gl_view;
-        dispatch_async(dispatch_get_main_queue(),
-                      ^{
-                          [view removeFromSuperview];
-                          [view release];
-                       });
+        [stream->gl_view performSelectorOnMainThread:@selector(deinit_gl)
+              		 withObject:nil waitUntilDone:YES];
+
+        [stream->gl_view release];
         stream->gl_view = NULL;
     }
     
-    pjmedia_vid_dev_opengl_destroy_buffers(stream->gl_buf);
-    
     pj_pool_release(stream->pool);
     
