Index: pjproject/branches/projects/2.0-dev/pjmedia/build/os-auto.mak.in
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/build/os-auto.mak.in	(revision 3573)
+++ pjproject/branches/projects/2.0-dev/pjmedia/build/os-auto.mak.in	(revision 3577)
@@ -164,6 +164,6 @@
 # Determine whether we should compile the obj-c version of a particular source code
 #
-ifeq ($(AC_PJMEDIA_VIDEO),mac_os)
-# Mac OS specific, use obj-c
+ifeq ($(AC_PJMEDIA_VIDEO),$(filter $(AC_PJMEDIA_VIDEO),mac_os iphone_os))
+# Mac and iPhone OS specific, use obj-c
 export PJMEDIA_VIDEODEV_OBJS += sdl_dev_m.o
 else
Index: pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c
===================================================================
--- pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c	(revision 3573)
+++ pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-videodev/sdl_dev.c	(revision 3577)
@@ -33,4 +33,6 @@
 #   include "SDL_opengl.h"
 #   define OPENGL_DEV_IDX 1
+#else
+#   define OPENGL_DEV_IDX -999
 #endif
 
@@ -55,14 +57,21 @@
 {
 #if PJ_IS_BIG_ENDIAN
-    {PJMEDIA_FORMAT_RGBA,  0, 0xFF000000, 0xFF0000, 0xFF00, 0xFF} ,
-    {PJMEDIA_FORMAT_RGB24, 0, 0xFF0000, 0xFF00, 0xFF, 0} ,
-    {PJMEDIA_FORMAT_BGRA,  0, 0xFF00, 0xFF0000, 0xFF000000, 0xFF} ,
+    {PJMEDIA_FORMAT_RGBA,  SDL_PIXELFORMAT_RGBA8888,
+     0xFF000000, 0xFF0000, 0xFF00, 0xFF} ,
+    {PJMEDIA_FORMAT_RGB24, SDL_PIXELFORMAT_RGB24,
+     0xFF0000, 0xFF00, 0xFF, 0} ,
+    {PJMEDIA_FORMAT_BGRA,  SDL_PIXELFORMAT_BGRA8888,
+     0xFF00, 0xFF0000, 0xFF000000, 0xFF} ,
 #else
-    {PJMEDIA_FORMAT_RGBA,  0, 0xFF, 0xFF00, 0xFF0000, 0xFF000000} ,
-    {PJMEDIA_FORMAT_RGB24, 0, 0xFF, 0xFF00, 0xFF0000, 0} ,
-    {PJMEDIA_FORMAT_BGRA,  0, 0xFF0000, 0xFF00, 0xFF, 0xFF000000} ,
-#endif
-
-    {PJMEDIA_FORMAT_DIB  , 0, 0xFF0000, 0xFF00, 0xFF, 0} ,
+    {PJMEDIA_FORMAT_RGBA,  SDL_PIXELFORMAT_ABGR8888,
+     0xFF, 0xFF00, 0xFF0000, 0xFF000000} ,
+    {PJMEDIA_FORMAT_RGB24, SDL_PIXELFORMAT_BGR24,
+     0xFF, 0xFF00, 0xFF0000, 0} ,
+    {PJMEDIA_FORMAT_BGRA,  SDL_PIXELFORMAT_ARGB8888,
+     0xFF0000, 0xFF00, 0xFF, 0xFF000000} ,
+#endif
+
+    {PJMEDIA_FORMAT_DIB  , SDL_PIXELFORMAT_RGB24,
+     0xFF0000, 0xFF00, 0xFF, 0} ,
 
     {PJMEDIA_FORMAT_YUY2, SDL_YUY2_OVERLAY, 0, 0, 0, 0} ,
@@ -75,4 +84,21 @@
 };
 
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+@interface SDLDelegate: NSObject
+{
+    @public
+    struct sdl_stream	    *strm;
+}
+
+- (void)sdl_init;
+- (void)sdl_quit;
+- (void)detect_new_fmt;
+- (int)sdl_create;
+- (void)sdl_destroy;
+- (int)handle_event;
+- (pj_status_t)put_frame;
+@end
+#endif
+
 /* sdl_ device info */
 struct sdl_dev_info
@@ -90,18 +116,9 @@
     unsigned			 dev_count;
     struct sdl_dev_info	        *dev_info;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+    NSAutoreleasePool		*apool;
+    SDLDelegate			*delegate;
+#endif
 };
-
-#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
-@interface SDLDelegate: NSObject
-{
-    @public
-    struct sdl_stream	    *strm;
-}
-
-- (int)sdl_thread;
-- (int)handle_event;
-- (pj_status_t)put_frame;
-@end
-#endif
 
 /* Video stream. */
@@ -120,5 +137,12 @@
     pj_bool_t			 render_exited;
     pj_status_t			 status;
-
+    pjmedia_format              *new_fmt;
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+    SDL_Window                  *window;            /**< Display window.    */
+    SDL_Renderer                *renderer;          /**< Display renderer.  */
+    SDL_Texture                 *scr_tex;           /**< Screen texture.    */
+    int                          pitch;             /**< Pitch value.       */
+#endif
     SDL_Rect			 rect;              /**< Display rectangle. */
     SDL_Surface			*screen;            /**< Display screen.    */
@@ -126,4 +150,7 @@
     SDL_Overlay			*overlay;           /**< YUV overlay.       */
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+#if SDL_VERSION_ATLEAST(1,3,0)
+    SDL_GLContext               *gl_context;
+#endif
     GLuint			 texture;
     void			*tex_buf;
@@ -231,5 +258,18 @@
     struct sdl_factory *sf = (struct sdl_factory*)f;
     struct sdl_dev_info *ddi;
-    unsigned i;
+    unsigned i, j;
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+    sf->apool = [[NSAutoreleasePool alloc] init];
+    sf->delegate = [[SDLDelegate alloc] init];
+    [sf->delegate performSelectorOnMainThread:@selector(sdl_init) 
+	          withObject:nil waitUntilDone:YES];
+#else
+    /* Initialize the SDL library */
+    if (SDL_Init(SDL_INIT_VIDEO)) {
+        PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL"));
+        return PJMEDIA_EVID_INIT;
+    }
+#endif
 
     sf->dev_count = 1;
@@ -245,21 +285,5 @@
     strncpy(ddi->info.name, "SDL renderer", sizeof(ddi->info.name));
     ddi->info.name[sizeof(ddi->info.name)-1] = '\0';
-    strncpy(ddi->info.driver, "SDL", sizeof(ddi->info.driver));
-    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
-    ddi->info.dir = PJMEDIA_DIR_RENDER;
-    ddi->info.has_callback = PJ_FALSE;
-    ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT |
-		     PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE;
-
     ddi->info.fmt_cnt = PJ_ARRAY_SIZE(sdl_fmts);
-    ddi->info.fmt = (pjmedia_format*)
-		    pj_pool_calloc(sf->pool, ddi->info.fmt_cnt,
-				   sizeof(pjmedia_format));
-    for (i = 0; i < ddi->info.fmt_cnt; i++) {
-        pjmedia_format *fmt = &ddi->info.fmt[i];
-        pjmedia_format_init_video(fmt, sdl_fmts[i].fmt_id,
-				  DEFAULT_WIDTH, DEFAULT_HEIGHT,
-				  DEFAULT_FPS, 1);
-    }
 
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
@@ -268,22 +292,29 @@
     strncpy(ddi->info.name, "SDL openGL renderer", sizeof(ddi->info.name));
     ddi->info.name[sizeof(ddi->info.name)-1] = '\0';
-    strncpy(ddi->info.driver, "SDL", sizeof(ddi->info.driver));
-    ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
-    ddi->info.dir = PJMEDIA_DIR_RENDER;
-    ddi->info.has_callback = PJ_FALSE;
-    ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT;
-    
-    ddi->info.fmt_cnt = PJ_ARRAY_SIZE(sdl_fmts);
     ddi->info.fmt_cnt = 1;
-    ddi->info.fmt = (pjmedia_format*)
-    pj_pool_calloc(sf->pool, ddi->info.fmt_cnt,
-		   sizeof(pjmedia_format));
-    for (i = 0; i < ddi->info.fmt_cnt; i++) {
-        pjmedia_format *fmt = &ddi->info.fmt[i];
-        pjmedia_format_init_video(fmt, sdl_fmts[i].fmt_id,
-				  DEFAULT_WIDTH, DEFAULT_HEIGHT,
-				  DEFAULT_FPS, 1);
-    }    
-#endif
+#endif
+
+    for (i = 0; i < sf->dev_count; i++) {
+        ddi = &sf->dev_info[i];
+        strncpy(ddi->info.driver, "SDL", sizeof(ddi->info.driver));
+        ddi->info.driver[sizeof(ddi->info.driver)-1] = '\0';
+        ddi->info.dir = PJMEDIA_DIR_RENDER;
+        ddi->info.has_callback = PJ_FALSE;
+        ddi->info.caps = PJMEDIA_VID_DEV_CAP_FORMAT |
+                         PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE;
+#if SDL_VERSION_ATLEAST(1,3,0)
+        ddi->info.caps |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
+#endif
+
+        ddi->info.fmt = (pjmedia_format*)
+                        pj_pool_calloc(sf->pool, ddi->info.fmt_cnt,
+                                       sizeof(pjmedia_format));
+        for (j = 0; j < ddi->info.fmt_cnt; j++) {
+            pjmedia_format *fmt = &ddi->info.fmt[j];
+            pjmedia_format_init_video(fmt, sdl_fmts[j].fmt_id,
+                                      DEFAULT_WIDTH, DEFAULT_HEIGHT,
+                                      DEFAULT_FPS, 1);
+        }
+    }
 
     PJ_LOG(4, (THIS_FILE, "SDL initialized"));
@@ -300,4 +331,13 @@
     sf->pool = NULL;
     pj_pool_release(pool);
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+    [sf->delegate performSelectorOnMainThread:@selector(sdl_quit) 
+                  withObject:nil waitUntilDone:YES];
+    [sf->delegate release];
+    [sf->apool release];
+#else
+    SDL_Quit();
+#endif
 
     return PJ_SUCCESS;
@@ -378,5 +418,5 @@
 }
 
-static void destroy_sdl(struct sdl_stream *strm)
+static void destroy_sdl(struct sdl_stream *strm, pj_bool_t destroy_win)
 {
     if (strm->surf) {
@@ -393,4 +433,30 @@
 	strm->texture = 0;
     }
+#endif
+#if SDL_VERSION_ATLEAST(1,3,0)
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+    if (strm->gl_context) {
+        SDL_GL_DeleteContext(strm->gl_context);
+        strm->gl_context = NULL;
+    }
+#endif
+    if (strm->scr_tex) {
+        SDL_DestroyTexture(strm->scr_tex);
+        strm->scr_tex = NULL;
+    }
+    if (strm->renderer) {
+        SDL_DestroyRenderer(strm->renderer);
+        strm->renderer = NULL;
+    }
+#ifndef __IPHONEOS__
+    if (destroy_win) {
+        if (strm->window &&
+            !(strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW))
+        {
+            SDL_DestroyWindow(strm->window);
+        }
+        strm->window = NULL;
+    }
+#endif
 #endif
 }
@@ -417,9 +483,56 @@
     strm->rect.h = (Uint16)vfd->size.h;
 
+    destroy_sdl(strm, PJ_FALSE);
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+    if (!strm->window) {
+        Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
+
+        if (strm->param.rend_id == OPENGL_DEV_IDX)
+            flags |= SDL_WINDOW_OPENGL;
+
+        if (strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
+            /* Use the window supplied by the application. */
+            strm->window = SDL_CreateWindowFrom(strm->param.window);
+        } else {
+            /* Create the window where we will draw. */
+            strm->window = SDL_CreateWindow("pjmedia-SDL video",
+                                            SDL_WINDOWPOS_CENTERED,
+                                            SDL_WINDOWPOS_CENTERED,
+                                            strm->rect.w, strm->rect.h,
+                                            flags);
+        }
+        if (!strm->window)
+            return PJMEDIA_EVID_SYSERR;
+    }
+
+    SDL_SetWindowSize(strm->window, strm->rect.w, strm->rect.h);
+
+    /**
+      * We must call SDL_CreateRenderer in order for draw calls to
+      * affect this window.
+      */
+    strm->renderer = SDL_CreateRenderer(strm->window, -1, 0);
+    if (!strm->renderer)
+        return PJMEDIA_EVID_SYSERR;
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+    if (strm->param.rend_id == OPENGL_DEV_IDX) {
+        strm->gl_context = SDL_GL_CreateContext(strm->window);
+        if (!strm->gl_context)
+            return PJMEDIA_EVID_SYSERR;
+        SDL_GL_MakeCurrent(strm->window, strm->gl_context);
+    }
+#endif
+
+    strm->screen = SDL_GetWindowSurface(strm->window);
+
+#else
+
     /* Initialize the display */
     strm->screen = SDL_SetVideoMode(strm->rect.w, strm->rect.h, 0, (
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
                                     strm->param.rend_id == OPENGL_DEV_IDX?
-				    SDL_OPENGL:
+				    SDL_OPENGL | SDL_RESIZABLE:
 #endif
 				    SDL_RESIZABLE | SDL_SWSURFACE));
@@ -429,5 +542,5 @@
     SDL_WM_SetCaption("pjmedia-SDL video", NULL);
 
-    destroy_sdl(strm);
+#endif
 
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
@@ -453,4 +566,7 @@
 	glGenTextures(1, &strm->texture);
 
+        if (!strm->texture)
+            return PJMEDIA_EVID_SYSERR;
+
 #if defined(PJ_WIN32) && PJ_WIN32 != 0
 	/**
@@ -466,4 +582,15 @@
     } else
 #endif
+#if SDL_VERSION_ATLEAST(1,3,0)
+    {    
+        strm->scr_tex = SDL_CreateTexture(strm->renderer, sdl_info->sdl_format,
+                                          SDL_TEXTUREACCESS_STREAMING,
+                                          strm->rect.w, strm->rect.h);
+        if (strm->scr_tex == NULL)
+            return PJMEDIA_EVID_SYSERR;
+    
+        strm->pitch = strm->rect.w * SDL_BYTESPERPIXEL(sdl_info->sdl_format);
+    }
+#else
     if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB) {
         strm->surf = SDL_CreateRGBSurface(SDL_SWSURFACE,
@@ -483,11 +610,47 @@
             return PJMEDIA_EVID_SYSERR;
     }
+#endif
 
     return PJ_SUCCESS;
 }
 
+static void detect_fmt_change(struct sdl_stream *strm)
+{
+    if (strm->new_fmt) {
+        /* Stop the stream */
+        sdl_stream_stop((pjmedia_vid_dev_stream *)strm);
+        
+        /* Re-initialize SDL */
+        strm->status = init_sdl(strm, strm->new_fmt);
+        
+        if (strm->status == PJ_SUCCESS) {
+            pjmedia_format_copy(&strm->param.fmt, strm->new_fmt);
+            /* Restart the stream */
+            sdl_stream_start((pjmedia_vid_dev_stream *)strm);
+        }
+        strm->new_fmt = NULL;
+    }
+}
+
 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
 @implementation SDLDelegate
-- (int)sdl_thread
+- (void)sdl_init
+{
+    if (SDL_Init(SDL_INIT_VIDEO)) {
+        PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL"));
+    }
+}
+
+- (void)sdl_quit
+{
+    SDL_Quit();
+}
+
+- (void)detect_new_fmt
+{
+    detect_fmt_change(strm);
+}
+
+- (int)sdl_create
 {
 #else
@@ -496,11 +659,4 @@
     struct sdl_stream *strm = (struct sdl_stream*)data;
 #endif
-
-    /* Initialize the SDL library */
-    if (SDL_Init(SDL_INIT_VIDEO)) {
-        PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL"));
-        strm->status = PJMEDIA_EVID_INIT;
-        goto on_return;
-    }
 
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
@@ -517,6 +673,5 @@
 on_return:
     if (strm->status != PJ_SUCCESS) {
-	destroy_sdl(strm);	
-	SDL_Quit();
+	destroy_sdl(strm, PJ_TRUE);
 	strm->screen = NULL;
     }
@@ -524,4 +679,9 @@
     return strm->status;
 }
+
+- (void)sdl_destroy
+{
+    destroy_sdl(strm, PJ_TRUE);
+}    
 
 - (int)handle_event
@@ -547,4 +707,7 @@
 #endif
 #endif
+
+        detect_fmt_change(strm);
+        
         /**
          * The event polling must be placed in the same thread that
@@ -556,32 +719,4 @@
 
             switch(sevent.type) {
-		case SDL_USEREVENT:
-                {
-                    pjmedia_format *fmt;
-
-                    if (sevent.user.code == PJMEDIA_EVENT_NONE) {
-			strm->is_quitting = PJ_TRUE;
-		        goto on_return;
-		    }
-
-                    pj_assert(sevent.user.code == PJMEDIA_VID_DEV_CAP_FORMAT);
-
-		    fmt = (pjmedia_format *)sevent.user.data1;
-
-		    /* Stop the stream */
-                    sdl_stream_stop((pjmedia_vid_dev_stream *)strm);
-
-		    /* Re-initialize SDL */
-		    strm->status = init_sdl(strm, fmt);
-
-		    if (strm->status == PJ_SUCCESS) {
-			pjmedia_format_copy(&strm->param.fmt, fmt); 
-			/* Restart the stream */
-			sdl_stream_start((pjmedia_vid_dev_stream *)strm);
-		    }
-
-                    break;
-                }
-
                 case SDL_MOUSEBUTTONDOWN:
                     pevent.event_type = PJMEDIA_EVENT_MOUSEBUTTONDOWN;
@@ -670,6 +805,5 @@
 #endif
 on_return:
-    destroy_sdl(strm);
-    SDL_Quit();
+    destroy_sdl(strm, PJ_TRUE);
     strm->screen = NULL;
 
@@ -693,5 +827,9 @@
 	glTexCoord2f(1, 1); glVertex2i(stream->rect.w, stream->rect.h);
 	glEnd();
+#if SDL_VERSION_ATLEAST(1,3,0)
+        SDL_GL_SwapWindow(stream->window);
+#else
 	SDL_GL_SwapBuffers();
+#endif
     }
 }
@@ -736,5 +874,9 @@
 	}
 	SDL_BlitSurface(stream->surf, NULL, stream->screen, NULL);
-	SDL_UpdateRect(stream->screen, 0, 0, 0, 0);
+#if SDL_VERSION_ATLEAST(1,3,0)
+        SDL_UpdateWindowSurface(stream->window);
+#else
+        SDL_UpdateRect(stream->screen, 0, 0, 0, 0);
+#endif
     } else if (stream->overlay) {
 	int i, sz, offset;
@@ -756,4 +898,12 @@
 	SDL_DisplayYUVOverlay(stream->overlay, &stream->rect);
     }
+#if SDL_VERSION_ATLEAST(1,3,0)
+    else if (stream->scr_tex) {
+        SDL_UpdateTexture(stream->scr_tex, NULL, frame->buf, stream->pitch);
+        SDL_RenderClear(stream->renderer);
+        SDL_RenderCopy(stream->renderer, stream->scr_tex, NULL, NULL);
+        SDL_RenderPresent(stream->renderer);
+    }
+#endif
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
     else if (stream->param.rend_id == OPENGL_DEV_IDX) {
@@ -778,5 +928,5 @@
     stream->frame = frame;    
     [stream->delegate performSelectorOnMainThread:@selector(put_frame) 
-			  withObject:nil waitUntilDone:YES];
+	              withObject:nil waitUntilDone:YES];
 
     return PJ_SUCCESS;
@@ -828,10 +978,9 @@
 	strm->status = PJ_SUCCESS;
 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
-	pj_assert(![NSThread isMainThread]);
 	strm->apool = [[NSAutoreleasePool alloc] init];
 	strm->delegate = [[SDLDelegate alloc]init];
 	strm->delegate->strm = strm;
-	/* On Mac OS X, we need to call SDL functions in the main thread */
-	[strm->delegate performSelectorOnMainThread:@selector(sdl_thread)
+	/* On Darwin OS, we need to call SDL functions in the main thread */
+	[strm->delegate performSelectorOnMainThread:@selector(sdl_create)
 			withObject:nil waitUntilDone:YES];
 	if ((status = strm->status) != PJ_SUCCESS) {
@@ -847,4 +996,7 @@
 
 	while(strm->status == PJ_SUCCESS && !strm->surf && !strm->overlay
+#if SDL_VERSION_ATLEAST(1,3,0)
+              && !strm->scr_tex
+#endif
 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
 	      && !strm->texture
@@ -939,13 +1091,10 @@
 	return PJ_SUCCESS;
     } else if (cap == PJMEDIA_VID_DEV_CAP_FORMAT) {
-	SDL_Event sevent;
-	
-	strm->status = PJ_TRUE;
-	sevent.type = SDL_USEREVENT;
-	sevent.user.code = PJMEDIA_VID_DEV_CAP_FORMAT;
-	sevent.user.data1 = (void *)pval;
-	SDL_PushEvent(&sevent);
-	
-	while (strm->status == PJ_TRUE)
+        strm->new_fmt = (pjmedia_format *)pval;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+        [strm->delegate performSelectorOnMainThread:@selector(detect_new_fmt)
+                        withObject:nil waitUntilDone:YES];
+#endif
+	while (strm->new_fmt)
 	    pj_thread_sleep(10);
 	
@@ -957,9 +1106,10 @@
 	     * to its original format.
 	     */
-	    strm->status = PJ_TRUE;
-	    sevent.user.data1 = &strm->param.fmt;
-	    SDL_PushEvent(&sevent);
-	    
-	    while (strm->status == PJ_TRUE)
+            strm->new_fmt = &strm->param.fmt;
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+            [strm->delegate performSelectorOnMainThread:@selector(detect_new_fmt)
+                            withObject:nil waitUntilDone:YES];
+#endif
+	    while (strm->new_fmt)
 		pj_thread_sleep(10);
 	    
@@ -1004,5 +1154,8 @@
     /* Wait for renderer put_frame() to finish */
     stream->is_running = PJ_FALSE;
-    for (i=0; !stream->render_exited && i<100; ++i)
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+    if (![NSThread isMainThread])
+#endif
+    for (i=0; !stream->render_exited && i<50; ++i)
 	pj_thread_sleep(10);
 
@@ -1015,5 +1168,4 @@
 {
     struct sdl_stream *stream = (struct sdl_stream*)strm;
-    SDL_Event sevent;
 
     PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
@@ -1022,7 +1174,5 @@
 
     if (!stream->is_quitting) {
-	sevent.type = SDL_USEREVENT;
-	sevent.user.code = PJMEDIA_EVENT_NONE;
-	SDL_PushEvent(&sevent);
+        stream->is_quitting = PJ_TRUE;
 	if (stream->sdl_thread)
 	    pj_thread_join(stream->sdl_thread);
@@ -1030,8 +1180,14 @@
 
 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
-    if (stream->delegate)
+    if (stream->delegate) {
+        [stream->delegate performSelectorOnMainThread:@selector(sdl_destroy)
+                          withObject:nil waitUntilDone:YES];
 	[stream->delegate release];
-    if (stream->apool)
+        stream->delegate = NULL;
+    }
+    if (stream->apool) {
 	[stream->apool release];
+        stream->apool = NULL;
+    }
 #endif
     pj_pool_release(stream->pool);
Index: pjproject/branches/projects/2.0-dev/pjsip-apps/src/ipjsua/config.cfg
===================================================================
--- pjproject/branches/projects/2.0-dev/pjsip-apps/src/ipjsua/config.cfg	(revision 3573)
+++ pjproject/branches/projects/2.0-dev/pjsip-apps/src/ipjsua/config.cfg	(revision 3577)
@@ -1,1 +1,3 @@
+--auto-answer=200
+--video
 --clock-rate=8000
Index: pjproject/branches/projects/2.0-dev/pjsip-apps/src/ipjsua/ipjsua.xcodeproj/project.pbxproj
===================================================================
--- pjproject/branches/projects/2.0-dev/pjsip-apps/src/ipjsua/ipjsua.xcodeproj/project.pbxproj	(revision 3573)
+++ pjproject/branches/projects/2.0-dev/pjsip-apps/src/ipjsua/ipjsua.xcodeproj/project.pbxproj	(revision 3577)
@@ -19,4 +19,20 @@
 		3A0D7ECD123DD46C009D5030 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3A0D7ECC123DD46C009D5030 /* MainWindow-iPad.xib */; };
 		3A0D7F20123F2254009D5030 /* SecondView-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3A0D7F1F123F2254009D5030 /* SecondView-iPad.xib */; };
+		3AE06674138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06673138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a */; };
+		3AE06681138E6F88008EE71A /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06680138E6F88008EE71A /* AVFoundation.framework */; };
+		3AE06683138E6FBB008EE71A /* libSDL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06682138E6FBB008EE71A /* libSDL.a */; };
+		3AE06693138E7056008EE71A /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06692138E7056008EE71A /* OpenGLES.framework */; };
+		3AE06695138E70B9008EE71A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06694138E70B9008EE71A /* libz.dylib */; };
+		3AE06699138E70F0008EE71A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06696138E70F0008EE71A /* CoreGraphics.framework */; };
+		3AE0669A138E70F0008EE71A /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06697138E70F0008EE71A /* CoreMedia.framework */; };
+		3AE0669B138E70F0008EE71A /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE06698138E70F0008EE71A /* CoreVideo.framework */; };
+		3AE0669D138E710C008EE71A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE0669C138E710C008EE71A /* QuartzCore.framework */; };
+		3AE066A5138E72A4008EE71A /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE0669E138E72A4008EE71A /* libavcodec.a */; };
+		3AE066A6138E72A4008EE71A /* libavcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE0669F138E72A4008EE71A /* libavcore.a */; };
+		3AE066A7138E72A4008EE71A /* libavdevice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A0138E72A4008EE71A /* libavdevice.a */; };
+		3AE066A8138E72A4008EE71A /* libavfilter.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A1138E72A4008EE71A /* libavfilter.a */; };
+		3AE066A9138E72A4008EE71A /* libavformat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A2138E72A4008EE71A /* libavformat.a */; };
+		3AE066AA138E72A4008EE71A /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A3138E72A4008EE71A /* libavutil.a */; };
+		3AE066AB138E72A4008EE71A /* libswscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE066A4138E72A4008EE71A /* libswscale.a */; };
 		3AE9099D11587BB900FAEAA5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE9099C11587BB900FAEAA5 /* AudioToolbox.framework */; };
 		3AE90A2D1158B52500FAEAA5 /* pjsua_app.c in Sources */ = {isa = PBXBuildFile; fileRef = 3AE90A2C1158B52500FAEAA5 /* pjsua_app.c */; };
@@ -60,4 +76,20 @@
 		3A0D7ECC123DD46C009D5030 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "Resources-iPad/MainWindow-iPad.xib"; sourceTree = "<group>"; };
 		3A0D7F1F123F2254009D5030 /* SecondView-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "SecondView-iPad.xib"; path = "Resources-iPad/SecondView-iPad.xib"; sourceTree = "<group>"; };
+		3AE06673138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libpjmedia-videodev-arm-apple-darwin9.a"; path = "../../../pjmedia/lib/libpjmedia-videodev-arm-apple-darwin9.a"; sourceTree = "<group>"; };
+		3AE06680138E6F88008EE71A /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+		3AE06682138E6FBB008EE71A /* libSDL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL.a; path = "../../../../../Library/Developer/Xcode/DerivedData/SDLiPhoneOS-fyjdxvchuwlpnghehmebkvasdrke/Build/Products/Debug-iphoneos/libSDL.a"; sourceTree = "<group>"; };
+		3AE06692138E7056008EE71A /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+		3AE06694138E70B9008EE71A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+		3AE06696138E70F0008EE71A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+		3AE06697138E70F0008EE71A /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
+		3AE06698138E70F0008EE71A /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
+		3AE0669C138E710C008EE71A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+		3AE0669E138E72A4008EE71A /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = "../../../../video/ffmpeg-iphone/lib/libavcodec.a"; sourceTree = "<group>"; };
+		3AE0669F138E72A4008EE71A /* libavcore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcore.a; path = "../../../../video/ffmpeg-iphone/lib/libavcore.a"; sourceTree = "<group>"; };
+		3AE066A0138E72A4008EE71A /* libavdevice.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavdevice.a; path = "../../../../video/ffmpeg-iphone/lib/libavdevice.a"; sourceTree = "<group>"; };
+		3AE066A1138E72A4008EE71A /* libavfilter.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavfilter.a; path = "../../../../video/ffmpeg-iphone/lib/libavfilter.a"; sourceTree = "<group>"; };
+		3AE066A2138E72A4008EE71A /* libavformat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavformat.a; path = "../../../../video/ffmpeg-iphone/lib/libavformat.a"; sourceTree = "<group>"; };
+		3AE066A3138E72A4008EE71A /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = "../../../../video/ffmpeg-iphone/lib/libavutil.a"; sourceTree = "<group>"; };
+		3AE066A4138E72A4008EE71A /* libswscale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswscale.a; path = "../../../../video/ffmpeg-iphone/lib/libswscale.a"; sourceTree = "<group>"; };
 		3AE9099C11587BB900FAEAA5 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
 		3AE90A2C1158B52500FAEAA5 /* pjsua_app.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pjsua_app.c; path = ../pjsua/pjsua_app.c; sourceTree = SOURCE_ROOT; };
@@ -117,4 +149,20 @@
 				3AE90EBC115F7BCE00FAEAA5 /* libsrtp-arm-apple-darwin9.a in Frameworks */,
 				3A0D789F121E324E009D5030 /* CFNetwork.framework in Frameworks */,
+				3AE06674138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a in Frameworks */,
+				3AE06681138E6F88008EE71A /* AVFoundation.framework in Frameworks */,
+				3AE06683138E6FBB008EE71A /* libSDL.a in Frameworks */,
+				3AE06693138E7056008EE71A /* OpenGLES.framework in Frameworks */,
+				3AE06695138E70B9008EE71A /* libz.dylib in Frameworks */,
+				3AE06699138E70F0008EE71A /* CoreGraphics.framework in Frameworks */,
+				3AE0669A138E70F0008EE71A /* CoreMedia.framework in Frameworks */,
+				3AE0669B138E70F0008EE71A /* CoreVideo.framework in Frameworks */,
+				3AE0669D138E710C008EE71A /* QuartzCore.framework in Frameworks */,
+				3AE066A5138E72A4008EE71A /* libavcodec.a in Frameworks */,
+				3AE066A6138E72A4008EE71A /* libavcore.a in Frameworks */,
+				3AE066A7138E72A4008EE71A /* libavdevice.a in Frameworks */,
+				3AE066A8138E72A4008EE71A /* libavfilter.a in Frameworks */,
+				3AE066A9138E72A4008EE71A /* libavformat.a in Frameworks */,
+				3AE066AA138E72A4008EE71A /* libavutil.a in Frameworks */,
+				3AE066AB138E72A4008EE71A /* libswscale.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -185,4 +233,11 @@
 			isa = PBXGroup;
 			children = (
+				3AE06694138E70B9008EE71A /* libz.dylib */,
+				3AE0669C138E710C008EE71A /* QuartzCore.framework */,
+				3AE06696138E70F0008EE71A /* CoreGraphics.framework */,
+				3AE06697138E70F0008EE71A /* CoreMedia.framework */,
+				3AE06698138E70F0008EE71A /* CoreVideo.framework */,
+				3AE06692138E7056008EE71A /* OpenGLES.framework */,
+				3AE06680138E6F88008EE71A /* AVFoundation.framework */,
 				1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
 				1D30AB110D05D00D00671497 /* Foundation.framework */,
@@ -206,4 +261,12 @@
 			isa = PBXGroup;
 			children = (
+				3AE0669E138E72A4008EE71A /* libavcodec.a */,
+				3AE0669F138E72A4008EE71A /* libavcore.a */,
+				3AE066A0138E72A4008EE71A /* libavdevice.a */,
+				3AE066A1138E72A4008EE71A /* libavfilter.a */,
+				3AE066A2138E72A4008EE71A /* libavformat.a */,
+				3AE066A3138E72A4008EE71A /* libavutil.a */,
+				3AE066A4138E72A4008EE71A /* libswscale.a */,
+				3AE06682138E6FBB008EE71A /* libSDL.a */,
 				3AE90EB1115F7BCE00FAEAA5 /* libg7221codec-arm-apple-darwin9.a */,
 				3AE90EB2115F7BCE00FAEAA5 /* libilbccodec-arm-apple-darwin9.a */,
@@ -218,4 +281,5 @@
 				3AE90A711158C6B400FAEAA5 /* libpjmedia-audiodev-arm-apple-darwin9.a */,
 				3AE90A731158C6B400FAEAA5 /* libpjmedia-codec-arm-apple-darwin9.a */,
+				3AE06673138E6C25008EE71A /* libpjmedia-videodev-arm-apple-darwin9.a */,
 				3AE90A751158C6B400FAEAA5 /* libpjnath-arm-apple-darwin9.a */,
 				3AE90A771158C6B400FAEAA5 /* libpjsip-arm-apple-darwin9.a */,
@@ -258,5 +322,9 @@
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ipjsua" */;
 			compatibilityVersion = "Xcode 3.1";
+			developmentRegion = English;
 			hasScannedForEncodings = 1;
+			knownRegions = (
+				en,
+			);
 			mainGroup = 29B97314FDCFA39411CA2CEA /* ipjsua */;
 			projectDirPath = "";
@@ -320,7 +388,11 @@
 					"\"$(SRCROOT)/../../../pjnath/lib\"",
 					"\"$(SRCROOT)/../../../pjsip/lib\"",
+					"\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/AVFoundation.framework\"",
+					"\"$(SRCROOT)/../../../../../Library/Developer/Xcode/DerivedData/SDLiPhoneOS-fyjdxvchuwlpnghehmebkvasdrke/Build/Products/Debug-iphoneos\"",
+					"\"$(SRCROOT)/../../../../video/ffmpeg-iphone/lib\"",
 				);
+				ONLY_ACTIVE_ARCH = YES;
 				PRODUCT_NAME = ipjsua;
-				SDKROOT = iphoneos3.2;
+				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
 			};
@@ -345,7 +417,11 @@
 					"\"$(SRCROOT)/../../../pjnath/lib\"",
 					"\"$(SRCROOT)/../../../pjsip/lib\"",
+					"\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/AVFoundation.framework\"",
+					"\"$(SRCROOT)/../../../../../Library/Developer/Xcode/DerivedData/SDLiPhoneOS-fyjdxvchuwlpnghehmebkvasdrke/Build/Products/Debug-iphoneos\"",
+					"\"$(SRCROOT)/../../../../video/ffmpeg-iphone/lib\"",
 				);
+				ONLY_ACTIVE_ARCH = YES;
 				PRODUCT_NAME = ipjsua;
-				SDKROOT = iphoneos3.2;
+				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
 			};
@@ -376,7 +452,8 @@
 					../../../third_party/lib,
 				);
+				ONLY_ACTIVE_ARCH = NO;
 				OTHER_CFLAGS = "";
 				PREBINDING = NO;
-				SDKROOT = iphoneos3.2;
+				SDKROOT = iphoneos;
 			};
 			name = Debug;
@@ -406,7 +483,8 @@
 					../../../third_party/lib,
 				);
+				ONLY_ACTIVE_ARCH = NO;
 				OTHER_CFLAGS = "";
 				PREBINDING = NO;
-				SDKROOT = iphoneos3.2;
+				SDKROOT = iphoneos;
 			};
 			name = Release;
