Index: pjproject/trunk/pjmedia/src/pjmedia-videodev/android_opengl.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-videodev/android_opengl.c	(revision 4977)
+++ pjproject/trunk/pjmedia/src/pjmedia-videodev/android_opengl.c	(revision 4978)
@@ -36,4 +36,8 @@
 
 #define MAX_JOBS 1
+/* Define the number of errors before the stream stops trying to do rendering.
+ * To disable this feature, put 0.
+ */
+#define STOP_IF_ERROR_RENDERING 5
 
 extern JavaVM *pj_jni_jvm;
@@ -87,4 +91,5 @@
     job_queue              *jq;
     pj_bool_t               is_running;
+    pj_int32_t		    err_rend;
     const pjmedia_frame    *frame;
     
@@ -132,6 +137,4 @@
 };
 
-ANativeWindow *def_native_win = NULL;
-
 static void get_jvm(JNIEnv **jni_env)
 {
@@ -139,16 +142,9 @@
 }
 
-void android_opengl_set_surface(jobject surface)
+void* android_opengl_get_surface(jobject surface)
 {
     JNIEnv *env = 0;
-
-    PJ_LOG(4, (THIS_FILE, "Setting default OpenGL surface"));
-
-    if (!surface) {
-        def_native_win = NULL;
-    } else {
-        get_jvm(&env);
-        if (env) def_native_win = ANativeWindow_fromSurface(env, surface);
-    }
+    get_jvm(&env);
+    return ((env && surface)? ANativeWindow_fromSurface(env, surface): NULL);
 }
 
@@ -245,9 +241,24 @@
 {
     struct andgl_stream *stream = (struct andgl_stream *)data;
-
+    
+    if (!stream->window || stream->err_rend == 0)
+    	return PJ_SUCCESS;
+    
     pjmedia_vid_dev_opengl_draw(stream->gl_buf, stream->vid_size.w,
                                 stream->vid_size.h, stream->frame->buf);
         
-    return eglSwapBuffers(stream->display, stream->surface);
+    if (!eglSwapBuffers(stream->display, stream->surface)) {
+        if (eglGetError() == EGL_BAD_SURFACE && stream->err_rend > 0) {
+            stream->err_rend--;
+            if (stream->err_rend == 0) {
+                PJ_LOG(3, (THIS_FILE, "Stopping OpenGL rendering due to "
+			              "consecutive errors. If app is in bg,"
+			              "it's advisable to stop the stream."));
+            }
+        }
+        return eglGetError();
+    }
+    
+    return PJ_SUCCESS;
 }
 
@@ -256,11 +267,23 @@
     struct andgl_stream *stream = (struct andgl_stream *)data;
 
-    pjmedia_vid_dev_opengl_destroy_buffers(stream->gl_buf);
-
-    eglMakeCurrent(stream->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                   EGL_NO_CONTEXT);
-    eglDestroyContext(stream->display, stream->context);
-    eglDestroySurface(stream->display, stream->surface);
-    eglTerminate(stream->display);
+    if (stream->gl_buf) {
+        pjmedia_vid_dev_opengl_destroy_buffers(stream->gl_buf);
+        stream->gl_buf = NULL;
+    }
+
+    if (stream->display != EGL_NO_DISPLAY) {
+        eglMakeCurrent(stream->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                       EGL_NO_CONTEXT);
+        if (stream->context != EGL_NO_CONTEXT)
+            eglDestroyContext(stream->display, stream->context);
+        if (stream->surface != EGL_NO_SURFACE)
+            eglDestroySurface(stream->display, stream->surface);
+        eglTerminate(stream->display);
+    }
+    
+    if (stream->window) {
+        ANativeWindow_release(stream->window);
+        stream->window = NULL;
+    }
     
     stream->display = EGL_NO_DISPLAY;
@@ -288,4 +311,5 @@
     pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
     strm->user_data = user_data;
+    strm->display = EGL_NO_DISPLAY;
     
     vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
@@ -297,17 +321,4 @@
     }
 
-    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
-        andgl_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
-                             param->window.info.android.window);
-    } else {
-        strm->window = def_native_win;
-    }
-    
-    if (!strm->window) {
-        PJ_LOG(3, (THIS_FILE, "Unable to find output window nor surface"));
-        status = PJ_EINVAL;
-        goto on_error;
-    }
-    
     /* Set video format */
     status = andgl_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_FORMAT,
@@ -320,7 +331,15 @@
         goto on_error;
 
-    job_queue_post_job(strm->jq, init_opengl, strm, 0, &status);
-    if (status != PJ_SUCCESS)
+    if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
+        status = andgl_stream_set_cap(&strm->base,
+                	  	      PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
+                             	      &param->window);
+    }
+    
+    if (status != PJ_SUCCESS) {
+        PJ_LOG(3, (THIS_FILE, "Failed to initialize OpenGL with the specified"
+			      " output window"));
         goto on_error;
+    }
 
     /* Apply the remaining settings */
@@ -417,7 +436,29 @@
 	return PJ_SUCCESS;
     } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
-        strm->window = (ANativeWindow *)pval;
-        strm->param.window.info.android.window = (void *)pval;
-        return PJ_SUCCESS;
+        pj_bool_t is_running = strm->is_running;
+        pj_status_t status = PJ_SUCCESS;
+        pjmedia_vid_dev_hwnd *wnd = (pjmedia_vid_dev_hwnd *)pval;
+        ANativeWindow *native_wnd = (ANativeWindow *)wnd->info.android.window;
+
+        if (strm->window == native_wnd)
+            return PJ_SUCCESS;
+        
+        /* Stop the stream and re-init OpenGL */
+    	andgl_stream_stop(s);
+        job_queue_post_job(strm->jq, deinit_opengl, strm, 0, NULL);
+
+        strm->window = strm->param.window.info.android.window = native_wnd;
+        if (strm->window) {
+            job_queue_post_job(strm->jq, init_opengl, strm, 0, &status);
+        }
+
+        PJ_LOG(3, (THIS_FILE, "Re-initializing OpenGL with window %p: %s",
+        		      strm->window,
+                              (status == PJ_SUCCESS? "success": "failed")));
+        
+        if (is_running)
+	    andgl_stream_start(s);
+
+        return status;
     } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE) {
         pj_memcpy(&strm->param.disp_size, pval, sizeof(strm->param.disp_size));
@@ -438,4 +479,6 @@
     struct andgl_stream *stream = (struct andgl_stream*)strm;
     
+    stream->err_rend = STOP_IF_ERROR_RENDERING;
+    if (!stream->err_rend) stream->err_rend = 0xFFFF;
     stream->is_running = PJ_TRUE;
     PJ_LOG(4, (THIS_FILE, "Starting Android opengl stream"));
@@ -451,5 +494,5 @@
     pj_status_t status;
 
-    if (!stream->is_running)
+    if (!stream->is_running || !stream->window)
 	return PJ_EINVALIDOP;
     
Index: pjproject/trunk/pjmedia/src/pjmedia-videodev/opengl_dev.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-videodev/opengl_dev.c	(revision 4977)
+++ pjproject/trunk/pjmedia/src/pjmedia-videodev/opengl_dev.c	(revision 4978)
@@ -30,5 +30,7 @@
 #       include <GLES2/gl2.h>
 #       include <GLES2/gl2ext.h>
-#	define GL_BGRA GL_RGBA
+#	undef GL_RGBA
+#	define GL_RGBA GL_BGRA_EXT
+#	define GL_BGRA GL_BGRA_EXT
 #   else
 #       include <OpenGLES/ES2/gl.h>
