summaryrefslogtreecommitdiff
path: root/pjmedia/src
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2011-07-22 08:28:53 +0000
committerLiong Sauw Ming <ming@teluu.com>2011-07-22 08:28:53 +0000
commitc336074922672ac6d31e1d0337f3dac7c6b4563d (patch)
treea4f7056068f490a31f1813bcfcea7cf7c252695c /pjmedia/src
parent14b2271cecf6fe8820d293cc55a6c8750182416c (diff)
Re #1334: Refactor SDL device
* Separate Obj-C implementation for Mac OS X so that the code will be more organized and readable. * Add get native window capability via OUTPUT_WINDOW cap git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3676 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src')
-rw-r--r--pjmedia/src/pjmedia-videodev/sdl_dev.c629
1 files changed, 347 insertions, 282 deletions
diff --git a/pjmedia/src/pjmedia-videodev/sdl_dev.c b/pjmedia/src/pjmedia-videodev/sdl_dev.c
index a39aa02e..b06b28e1 100644
--- a/pjmedia/src/pjmedia-videodev/sdl_dev.c
+++ b/pjmedia/src/pjmedia-videodev/sdl_dev.c
@@ -22,21 +22,21 @@
#include <pj/log.h>
#include <pj/os.h>
-
#if defined(PJMEDIA_VIDEO_DEV_HAS_SDL) && PJMEDIA_VIDEO_DEV_HAS_SDL != 0
-
#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+# include "TargetConditionals.h"
# include <Foundation/Foundation.h>
-#endif
+#endif /* PJ_DARWINOS */
#include <SDL.h>
+#include <SDL_syswm.h>
#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
# include "SDL_opengl.h"
# define OPENGL_DEV_IDX 1
-#else
+#else /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
# define OPENGL_DEV_IDX -999
-#endif
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
#define THIS_FILE "sdl_dev.c"
#define DEFAULT_CLOCK_RATE 90000
@@ -52,7 +52,7 @@
# define SDL_PIXELFORMAT_BGR24 0
# define SDL_PIXELFORMAT_ARGB8888 0
# define SDL_PIXELFORMAT_RGB24 0
-#endif
+#endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */
typedef struct sdl_fmt_info
{
@@ -73,14 +73,14 @@ static sdl_fmt_info sdl_fmts[] =
0xFF0000, 0xFF00, 0xFF, 0} ,
{PJMEDIA_FORMAT_BGRA, (Uint32)SDL_PIXELFORMAT_BGRA8888,
0xFF00, 0xFF0000, 0xFF000000, 0xFF} ,
-#else
+#else /* PJ_IS_BIG_ENDIAN */
{PJMEDIA_FORMAT_RGBA, (Uint32)SDL_PIXELFORMAT_ABGR8888,
0xFF, 0xFF00, 0xFF0000, 0xFF000000} ,
{PJMEDIA_FORMAT_RGB24, (Uint32)SDL_PIXELFORMAT_BGR24,
0xFF, 0xFF00, 0xFF0000, 0} ,
{PJMEDIA_FORMAT_BGRA, (Uint32)SDL_PIXELFORMAT_ARGB8888,
0xFF0000, 0xFF00, 0xFF, 0xFF000000} ,
-#endif
+#endif /* PJ_IS_BIG_ENDIAN */
{PJMEDIA_FORMAT_DIB , (Uint32)SDL_PIXELFORMAT_RGB24,
0xFF0000, 0xFF00, 0xFF, 0} ,
@@ -103,13 +103,13 @@ static sdl_fmt_info sdl_fmts[] =
- (void)sdl_init;
- (void)sdl_quit;
-- (void)detect_new_fmt;
-- (int)sdl_create;
+- (void)detect_fmt_change;
+- (void)sdl_create;
- (void)sdl_destroy;
-- (int)handle_event;
-- (pj_status_t)put_frame;
+- (void)handle_event;
+- (void)put_frame;
@end
-#endif
+#endif /* PJ_DARWINOS */
/* sdl_ device info */
struct sdl_dev_info
@@ -129,7 +129,7 @@ struct sdl_factory
#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
NSAutoreleasePool *apool;
SDLDelegate *delegate;
-#endif
+#endif /* PJ_DARWINOS */
};
/* Video stream. */
@@ -156,25 +156,26 @@ struct sdl_stream
SDL_Renderer *renderer; /**< Display renderer. */
SDL_Texture *scr_tex; /**< Screen texture. */
int pitch; /**< Pitch value. */
-#endif
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
SDL_Rect rect; /**< Frame rectangle. */
SDL_Rect dstrect; /**< Display rectangle. */
SDL_Surface *screen; /**< Display screen. */
SDL_Surface *surf; /**< RGB surface. */
SDL_Overlay *overlay; /**< YUV overlay. */
#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
-#if SDL_VERSION_ATLEAST(1,3,0)
+# if SDL_VERSION_ATLEAST(1,3,0)
SDL_GLContext *gl_context;
-#endif
+# endif /* SDL_VERSION_ATLEAST(1,3,0) */
GLuint texture;
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
void *tex_buf;
pj_size_t tex_buf_size;
-#endif
+
#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
NSAutoreleasePool *apool;
SDLDelegate *delegate;
const pjmedia_frame *frame;
-#endif
+#endif /* PJ_DARWINOS */
/* For frame conversion */
pjmedia_converter *conv;
@@ -218,10 +219,6 @@ static pj_status_t sdl_stream_start(pjmedia_vid_dev_stream *strm);
static pj_status_t sdl_stream_stop(pjmedia_vid_dev_stream *strm);
static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm);
-#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
-static void draw_gl(struct sdl_stream *stream, void *tex_buf);
-#endif
-
/* Operations */
static pjmedia_vid_dev_factory_op factory_op =
{
@@ -274,24 +271,26 @@ static pj_status_t sdl_factory_init(pjmedia_vid_dev_factory *f)
struct sdl_factory *sf = (struct sdl_factory*)f;
struct sdl_dev_info *ddi;
unsigned i, j;
+ SDL_version version;
+ SDL_VERSION(&version);
#if SDL_VERSION_ATLEAST(1,3,0)
-#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+# 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
+# else /* PJ_DARWINOS */
/* Initialize the SDL library */
if (SDL_Init(SDL_INIT_VIDEO))
return PJMEDIA_EVID_INIT;
-#endif
-#endif
+# endif /* PJ_DARWINOS */
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
sf->dev_count = 1;
#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
sf->dev_count++;
-#endif
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
sf->dev_info = (struct sdl_dev_info*)
pj_pool_calloc(sf->pool, sf->dev_count,
sizeof(struct sdl_dev_info));
@@ -308,7 +307,7 @@ static pj_status_t sdl_factory_init(pjmedia_vid_dev_factory *f)
strncpy(ddi->info.name, "SDL openGL renderer", sizeof(ddi->info.name));
ddi->info.name[sizeof(ddi->info.name)-1] = '\0';
ddi->info.fmt_cnt = 1;
-#endif
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
for (i = 0; i < sf->dev_count; i++) {
ddi = &sf->dev_info[i];
@@ -320,7 +319,7 @@ static pj_status_t sdl_factory_init(pjmedia_vid_dev_factory *f)
PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE;
#if SDL_VERSION_ATLEAST(1,3,0)
ddi->info.caps |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW;
-#endif
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
for (j = 0; j < ddi->info.fmt_cnt; j++) {
pjmedia_format *fmt = &ddi->info.fmt[j];
@@ -330,7 +329,8 @@ static pj_status_t sdl_factory_init(pjmedia_vid_dev_factory *f)
}
}
- PJ_LOG(4, (THIS_FILE, "SDL initialized"));
+ PJ_LOG(4, (THIS_FILE, "SDL %d.%d initialized",
+ version.major, version.minor));
return PJ_SUCCESS;
}
@@ -345,15 +345,15 @@ static pj_status_t sdl_factory_destroy(pjmedia_vid_dev_factory *f)
pj_pool_release(pool);
#if SDL_VERSION_ATLEAST(1,3,0)
-#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+# if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
[sf->delegate performSelectorOnMainThread:@selector(sdl_quit)
withObject:nil waitUntilDone:YES];
[sf->delegate release];
[sf->apool release];
-#else
+# else /* PJ_DARWINOS */
SDL_Quit();
-#endif
-#endif
+# endif /* PJ_DARWINOS */
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
return PJ_SUCCESS;
}
@@ -425,7 +425,7 @@ static sdl_fmt_info* get_sdl_format_info(pjmedia_format_id id)
return NULL;
}
-static void destroy_sdl(struct sdl_stream *strm, pj_bool_t destroy_win)
+static void sdl_destroy(struct sdl_stream *strm, pj_bool_t destroy_win)
{
PJ_UNUSED_ARG(destroy_win);
@@ -442,14 +442,14 @@ static void destroy_sdl(struct sdl_stream *strm, pj_bool_t destroy_win)
glDeleteTextures(1, &strm->texture);
strm->texture = 0;
}
-#endif
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
#if SDL_VERSION_ATLEAST(1,3,0)
-#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+# if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
if (strm->gl_context) {
SDL_GL_DeleteContext(strm->gl_context);
strm->gl_context = NULL;
}
-#endif
+# endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
if (strm->scr_tex) {
SDL_DestroyTexture(strm->scr_tex);
strm->scr_tex = NULL;
@@ -458,7 +458,7 @@ static void destroy_sdl(struct sdl_stream *strm, pj_bool_t destroy_win)
SDL_DestroyRenderer(strm->renderer);
strm->renderer = NULL;
}
-#ifndef __IPHONEOS__
+# if !defined(TARGET_OS_IPHONE) || TARGET_OS_IPHONE == 0
if (destroy_win) {
if (strm->window &&
!(strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW))
@@ -467,11 +467,12 @@ static void destroy_sdl(struct sdl_stream *strm, pj_bool_t destroy_win)
}
strm->window = NULL;
}
-#endif
-#endif
+# endif /* TARGET_OS_IPHONE */
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
}
-static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
+static pj_status_t sdl_create_view(struct sdl_stream *strm,
+ pjmedia_format *fmt)
{
sdl_fmt_info *sdl_info = get_sdl_format_info(fmt->id);
const pjmedia_video_format_info *vfi;
@@ -499,7 +500,7 @@ static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
strm->dstrect.w = (Uint16)strm->param.disp_size.w;
strm->dstrect.h = (Uint16)strm->param.disp_size.h;
- destroy_sdl(strm, PJ_FALSE);
+ sdl_destroy(strm, PJ_FALSE);
#if SDL_VERSION_ATLEAST(1,3,0)
if (!strm->window) {
@@ -510,7 +511,7 @@ static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
if (strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
/* Use the window supplied by the application. */
- strm->window = SDL_CreateWindowFrom(strm->param.window.hwnd.ptr);
+ strm->window = SDL_CreateWindowFrom(strm->param.window.info.window);
} else {
/* Create the window where we will draw. */
strm->window = SDL_CreateWindow("pjmedia-SDL video",
@@ -535,32 +536,32 @@ static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
if (!strm->renderer)
return PJMEDIA_EVID_SYSERR;
-#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+# 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
+# endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
strm->screen = SDL_GetWindowSurface(strm->window);
-#else
+#else /* SDL_VERSION_ATLEAST(1,3,0) */
/* Initialize the display */
strm->screen = SDL_SetVideoMode(strm->param.disp_size.w,
strm->param.disp_size.h, 0, (
-#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+# if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
strm->param.rend_id == OPENGL_DEV_IDX?
SDL_OPENGL | SDL_RESIZABLE:
-#endif
+# endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
SDL_RESIZABLE | SDL_SWSURFACE));
if (strm->screen == NULL)
return PJMEDIA_EVID_SYSERR;
SDL_WM_SetCaption("pjmedia-SDL video", NULL);
-#endif
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
if (strm->param.rend_id == OPENGL_DEV_IDX) {
@@ -587,9 +588,9 @@ static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
if (!strm->texture)
return PJMEDIA_EVID_SYSERR;
-#if defined(PJ_WIN32) && PJ_WIN32 != 0
+# if !defined(PJ_DARWINOS) || PJ_DARWINOS == 0
/**
- * On Win32 platform, the OpenGL drawing must be in the same
+ * OpenGL drawing must be in the same
* thread that calls SDL_SetVideoMode(), hence we need a buffer
* for the frame from sdl_stream_put_frame()
*/
@@ -597,9 +598,9 @@ static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
strm->tex_buf_size = strm->vafp.framebytes;
strm->tex_buf = pj_pool_alloc(strm->pool, strm->vafp.framebytes);
}
-#endif
+# endif /* PJ_DARWINOS */
} else
-#endif
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
#if SDL_VERSION_ATLEAST(1,3,0)
{
strm->scr_tex = SDL_CreateTexture(strm->renderer, sdl_info->sdl_format,
@@ -609,8 +610,15 @@ static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
return PJMEDIA_EVID_SYSERR;
strm->pitch = strm->rect.w * SDL_BYTESPERPIXEL(sdl_info->sdl_format);
+
+# if !defined(PJ_DARWINOS) || PJ_DARWINOS == 0
+ if (strm->vafp.framebytes > strm->tex_buf_size) {
+ strm->tex_buf_size = strm->vafp.framebytes;
+ strm->tex_buf = pj_pool_alloc(strm->pool, strm->vafp.framebytes);
+ }
+# endif /* !PJ_DARWINOS */
}
-#else
+#else /* SDL_VERSION_ATLEAST(1,3,0) */
if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB) {
strm->surf = SDL_CreateRGBSurface(SDL_SWSURFACE,
strm->rect.w, strm->rect.h,
@@ -628,11 +636,42 @@ static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt)
if (strm->overlay == NULL)
return PJMEDIA_EVID_SYSERR;
}
-#endif
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
return PJ_SUCCESS;
}
+static pj_status_t sdl_create(struct sdl_stream *strm)
+{
+#if !(SDL_VERSION_ATLEAST(1,3,0))
+ if (SDL_Init(SDL_INIT_VIDEO)) {
+ strm->status = PJMEDIA_EVID_INIT;
+ goto on_return;
+ }
+#endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */
+
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+ if (strm->param.rend_id == OPENGL_DEV_IDX) {
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
+ }
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
+
+ strm->status = sdl_create_view(strm, &strm->param.fmt);
+ if (strm->status != PJ_SUCCESS)
+ goto on_return;
+
+on_return:
+ if (strm->status != PJ_SUCCESS) {
+ sdl_destroy(strm, PJ_TRUE);
+#if !(SDL_VERSION_ATLEAST(1,3,0))
+ SDL_Quit();
+#endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */
+ strm->screen = NULL;
+ }
+
+ return strm->status;
+}
+
static void detect_fmt_change(struct sdl_stream *strm)
{
if (strm->new_fmt || strm->new_disp_size) {
@@ -644,9 +683,9 @@ static void detect_fmt_change(struct sdl_stream *strm)
sizeof(strm->param.disp_size));
/* Re-initialize SDL */
- strm->status = init_sdl(strm, (strm->new_fmt? strm->new_fmt :
- &strm->param.fmt));
-
+ strm->status = sdl_create_view(strm, (strm->new_fmt? strm->new_fmt :
+ &strm->param.fmt));
+
if (strm->status == PJ_SUCCESS) {
if (strm->new_fmt)
pjmedia_format_copy(&strm->param.fmt, strm->new_fmt);
@@ -658,178 +697,152 @@ static void detect_fmt_change(struct sdl_stream *strm)
}
}
-#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
-@implementation SDLDelegate
-- (void)sdl_init
+#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
+static void draw_gl(struct sdl_stream *stream, void *tex_buf)
{
- if (SDL_Init(SDL_INIT_VIDEO)) {
- PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL"));
+ if (stream->texture) {
+ glBindTexture(GL_TEXTURE_2D, stream->texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ stream->rect.w, stream->rect.h, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, tex_buf);
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2f(0, 0); glVertex2i(0, 0);
+ glTexCoord2f(1, 0); glVertex2i(stream->param.disp_size.w, 0);
+ glTexCoord2f(0, 1); glVertex2i(0, stream->param.disp_size.h);
+ glTexCoord2f(1, 1);
+ glVertex2i(stream->param.disp_size.w, stream->param.disp_size.h);
+ glEnd();
+# if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_GL_SwapWindow(stream->window);
+# else /* SDL_VERSION_ATLEAST(1,3,0) */
+ SDL_GL_SwapBuffers();
+# endif /* SDL_VERSION_ATLEAST(1,3,0) */
}
}
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
-- (void)sdl_quit
-{
- SDL_Quit();
-}
-
-- (void)detect_new_fmt
-{
- detect_fmt_change(strm);
-}
-
-- (int)sdl_create
-{
-#else
-static int sdlthread(void * data)
+static void draw_texture(struct sdl_stream *stream, void *tex_buf)
{
- struct sdl_stream *strm = (struct sdl_stream*)data;
- pj_bool_t notify_wnd_closed_event = PJ_FALSE;
- pj_status_t saved_stream_status;
-#endif
-
-#if !(SDL_VERSION_ATLEAST(1,3,0))
- if (SDL_Init(SDL_INIT_VIDEO)) {
- strm->status = PJMEDIA_EVID_INIT;
- goto on_return;
- }
-#endif
-
-#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
- if (strm->param.rend_id == OPENGL_DEV_IDX) {
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
- }
-#endif
-
- strm->status = init_sdl(strm, &strm->param.fmt);
- if (strm->status != PJ_SUCCESS)
- goto on_return;
-
-#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
-on_return:
- if (strm->status != PJ_SUCCESS) {
- destroy_sdl(strm, PJ_TRUE);
-#if !(SDL_VERSION_ATLEAST(1,3,0))
- SDL_Quit();
-#endif
- strm->screen = NULL;
- }
-
- return strm->status;
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_UpdateTexture(stream->scr_tex, NULL, tex_buf, stream->pitch);
+ SDL_RenderClear(stream->renderer);
+ SDL_RenderCopy(stream->renderer, stream->scr_tex, NULL, NULL);
+ SDL_RenderPresent(stream->renderer);
+#else /* SDL_VERSION_ATLEAST(1,3,0) */
+ PJ_UNUSED_ARG(stream);
+ PJ_UNUSED_ARG(tex_buf);
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
}
-- (void)sdl_destroy
-{
- destroy_sdl(strm, PJ_TRUE);
-}
-
-- (int)handle_event
+static void handle_event(struct sdl_stream *strm)
{
const pjmedia_video_format_info *vfi;
pjmedia_video_format_detail *vfd;
pj_bool_t notify_wnd_closed_event = PJ_FALSE;
- pj_status_t saved_stream_status;
+ SDL_Event sevent;
+ pjmedia_event pevent;
vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(),
strm->param.fmt.id);
vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
-#else
- while(!strm->is_quitting)
-#endif
- {
- SDL_Event sevent;
- pjmedia_event pevent;
+ if (strm->tex_buf) {
+#if SDL_VERSION_ATLEAST(1,3,0)
+ if (strm->scr_tex) {
+ draw_texture(strm, strm->tex_buf);
+ }
+#else /* SDL_VERSION_ATLEAST(1,3,0) */
+ if (0) { }
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
-#if defined(PJ_WIN32) && PJ_WIN32 != 0
- if (strm->param.rend_id == OPENGL_DEV_IDX) {
+ else if (strm->param.rend_id == OPENGL_DEV_IDX) {
draw_gl(strm, strm->tex_buf);
}
-#endif
-#endif
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
+ }
+
+ detect_fmt_change(strm);
- detect_fmt_change(strm);
-
- /**
- * The event polling must be placed in the same thread that
- * call SDL_SetVideoMode(). Please consult the official doc of
- * SDL_PumpEvents().
- */
- while (SDL_PollEvent(&sevent)) {
- pjmedia_event_init(&pevent, PJMEDIA_EVENT_NONE, &strm->last_ts,
- &strm->base.epub);
-
- switch(sevent.type) {
- case SDL_MOUSEBUTTONDOWN:
- pevent.type = PJMEDIA_EVENT_MOUSE_BTN_DOWN;
- break;
+ /**
+ * The event polling must be placed in the same thread that
+ * call SDL_SetVideoMode(). Please consult the official doc of
+ * SDL_PumpEvents().
+ */
+ while (SDL_PollEvent(&sevent)) {
+ pjmedia_event_init(&pevent, PJMEDIA_EVENT_NONE, &strm->last_ts,
+ &strm->base.epub);
+
+ switch(sevent.type) {
+ case SDL_MOUSEBUTTONDOWN:
+ pevent.type = PJMEDIA_EVENT_MOUSE_BTN_DOWN;
+ break;
#if SDL_VERSION_ATLEAST(1,3,0)
- case SDL_WINDOWEVENT:
- switch (sevent.window.event) {
- case SDL_WINDOWEVENT_RESIZED:
- pevent.type = PJMEDIA_EVENT_WND_RESIZED;
- pevent.data.wnd_resized.new_size.w =
- sevent.window.data1;
- pevent.data.wnd_resized.new_size.h =
- sevent.window.data2;
- break;
- }
- break;
-#else
- case SDL_VIDEORESIZE:
- pevent.type = PJMEDIA_EVENT_WND_RESIZED;
- pevent.data.wnd_resized.new_size.w = sevent.resize.w;
- pevent.data.wnd_resized.new_size.h = sevent.resize.h;
- break;
- case SDL_QUIT:
- pevent.type = PJMEDIA_EVENT_WND_CLOSING;
- break;
-#endif
- }
+ case SDL_WINDOWEVENT:
+ switch (sevent.window.event) {
+ case SDL_WINDOWEVENT_RESIZED:
+ pevent.type = PJMEDIA_EVENT_WND_RESIZED;
+ pevent.data.wnd_resized.new_size.w =
+ sevent.window.data1;
+ pevent.data.wnd_resized.new_size.h =
+ sevent.window.data2;
+ break;
+ }
+ break;
+#else /* SDL_VERSION_ATLEAST(1,3,0) */
+ case SDL_VIDEORESIZE:
+ pevent.type = PJMEDIA_EVENT_WND_RESIZED;
+ pevent.data.wnd_resized.new_size.w = sevent.resize.w;
+ pevent.data.wnd_resized.new_size.h = sevent.resize.h;
+ break;
+ case SDL_QUIT:
+ pevent.type = PJMEDIA_EVENT_WND_CLOSING;
+ break;
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
+ }
- if (pevent.type != PJMEDIA_EVENT_NONE) {
- pj_status_t status;
+ if (pevent.type != PJMEDIA_EVENT_NONE) {
+ pj_status_t status;
- status = pjmedia_event_publish(&strm->base.epub, &pevent);
+ status = pjmedia_event_publish(&strm->base.epub, &pevent);
- switch (pevent.type) {
- case PJMEDIA_EVENT_WND_RESIZED:
- strm->new_disp_size = &pevent.data.wnd_resized.new_size;
- detect_fmt_change(strm);
- break;
+ switch (pevent.type) {
+ case PJMEDIA_EVENT_WND_RESIZED:
+ strm->new_disp_size = &pevent.data.wnd_resized.new_size;
+ detect_fmt_change(strm);
+ break;
- case PJMEDIA_EVENT_WND_CLOSING:
- if (pevent.data.wnd_closing.cancel) {
- /* Cancel the closing operation */
- break;
- }
-
- /* Proceed to cleanup SDL. App must still call
- * pjmedia_dev_stream_destroy() when getting WND_CLOSED
- * event
- */
- strm->is_quitting = PJ_TRUE;
- notify_wnd_closed_event = PJ_TRUE;
- sdl_stream_stop(&strm->base);
- goto on_return;
-
- default:
- /* Just to prevent gcc warning about unused enums */
+ case PJMEDIA_EVENT_WND_CLOSING:
+ if (pevent.data.wnd_closing.cancel) {
+ /* Cancel the closing operation */
break;
}
- }
+
+ /* Proceed to cleanup SDL. App must still call
+ * pjmedia_dev_stream_destroy() when getting WND_CLOSED
+ * event
+ */
+ strm->is_quitting = PJ_TRUE;
+ notify_wnd_closed_event = PJ_TRUE;
+ sdl_stream_stop(&strm->base);
+ goto on_return;
+
+ default:
+ /* Just to prevent gcc warning about unused enums */
+ break;
+ }
}
}
-#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
- return 0;
-#endif
+ return;
+
on_return:
- destroy_sdl(strm, PJ_TRUE);
+ sdl_destroy(strm, PJ_TRUE);
#if !(SDL_VERSION_ATLEAST(1,3,0))
SDL_Quit();
-#endif
+#endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */
strm->screen = NULL;
- saved_stream_status = strm->status;
if (notify_wnd_closed_event) {
pjmedia_event pevent;
@@ -843,47 +856,41 @@ on_return:
* Note: don't access the stream after this point, it might have
* been destroyed
*/
-
- return saved_stream_status;
}
-#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
-static void draw_gl(struct sdl_stream *stream, void *tex_buf)
+static int sdl_thread(void * data)
{
- if (stream->texture) {
- glBindTexture(GL_TEXTURE_2D, stream->texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- stream->rect.w, stream->rect.h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, tex_buf);
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2f(0, 0); glVertex2i(0, 0);
- glTexCoord2f(1, 0); glVertex2i(stream->param.disp_size.w, 0);
- glTexCoord2f(0, 1); glVertex2i(0, stream->param.disp_size.h);
- glTexCoord2f(1, 1);
- glVertex2i(stream->param.disp_size.w, stream->param.disp_size.h);
- glEnd();
-#if SDL_VERSION_ATLEAST(1,3,0)
- SDL_GL_SwapWindow(stream->window);
-#else
- SDL_GL_SwapBuffers();
-#endif
+ struct sdl_stream *strm = (struct sdl_stream*)data;
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ while(!strm->is_quitting) {
+ [strm->delegate performSelectorOnMainThread:@selector(handle_event)
+ withObject:nil waitUntilDone:YES];
}
+ [strm->delegate performSelectorOnMainThread:@selector(sdl_destroy)
+ withObject:nil waitUntilDone:YES];
+# if !(SDL_VERSION_ATLEAST(1,3,0))
+ [strm->delegate performSelectorOnMainThread:@selector(sdl_quit)
+ withObject:nil waitUntilDone:YES];
+# endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */
+#else /* PJ_DARWINOS */
+ sdl_create(strm);
+ while(!strm->is_quitting) {
+ handle_event(strm);
+ }
+ sdl_destroy(strm, PJ_TRUE);
+# if !(SDL_VERSION_ATLEAST(1,3,0))
+ SDL_Quit();
+# endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */
+#endif /* PJ_DARWINOS */
+ strm->screen = NULL;
+
+ return 0;
}
-#endif
-#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
-- (pj_status_t)put_frame
+static pj_status_t put_frame(struct sdl_stream *stream,
+ const pjmedia_frame *frame)
{
- const pjmedia_frame *frame = strm->frame;
-#else
-/* API: Put frame from stream */
-static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm,
- const pjmedia_frame *frame)
-{
-#endif
- struct sdl_stream *stream = (struct sdl_stream*)strm;
pj_status_t status = PJ_SUCCESS;
stream->last_ts.u64 = frame->timestamp.u64;
@@ -915,9 +922,9 @@ static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm,
SDL_BlitSurface(stream->surf, NULL, stream->screen, &stream->dstrect);
#if SDL_VERSION_ATLEAST(1,3,0)
SDL_UpdateWindowSurface(stream->window);
-#else
+#else /* SDL_VERSION_ATLEAST(1,3,0) */
SDL_UpdateRect(stream->screen, 0, 0, 0, 0);
-#endif
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
} else if (stream->overlay) {
int i, sz, offset;
@@ -939,52 +946,42 @@ static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm,
}
#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);
+ if (stream->tex_buf)
+ pj_memcpy(stream->tex_buf, frame->buf, stream->vafp.framebytes);
+ else
+ draw_texture(stream, frame->buf);
}
-#endif
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
else if (stream->param.rend_id == OPENGL_DEV_IDX) {
-#if defined(PJ_WIN32) && PJ_WIN32 != 0
- pj_memcpy(stream->tex_buf, frame->buf, stream->vafp.framebytes);
-#else
- draw_gl(stream, frame->buf);
-#endif
+ if (stream->tex_buf)
+ pj_memcpy(stream->tex_buf, frame->buf, stream->vafp.framebytes);
+ else
+ draw_gl(stream, frame->buf);
}
-#endif
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
on_return:
+ stream->status = status;
return status;
}
-#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
-@end
+/* API: Put frame from stream */
static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm,
const pjmedia_frame *frame)
{
struct sdl_stream *stream = (struct sdl_stream*)strm;
+
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
stream->frame = frame;
[stream->delegate performSelectorOnMainThread:@selector(put_frame)
withObject:nil waitUntilDone:YES];
- return PJ_SUCCESS;
-}
-
-static int sdlthread(void * data)
-{
- struct sdl_stream *strm = (struct sdl_stream*)data;
-
- while(!strm->is_quitting) {
- [strm->delegate performSelectorOnMainThread:@selector(handle_event)
- withObject:nil waitUntilDone:YES];
- }
-
- return 0;
+ return stream->status;
+#else /* PJ_DARWINOS */
+ return put_frame(stream, frame);
+#endif /* PJ_DARWINOS */
}
-
-#endif
/* API: create stream */
static pj_status_t sdl_factory_create_stream(
@@ -1025,8 +1022,8 @@ static pj_status_t sdl_factory_create_stream(
if ((status = strm->status) != PJ_SUCCESS) {
goto on_error;
}
-#endif
- status = pj_thread_create(pool, "sdl_thread", sdlthread,
+#endif /* PJ_DARWINOS */
+ status = pj_thread_create(pool, "sdl_thread", sdl_thread,
strm, 0, 0, &strm->sdl_thread);
if (status != PJ_SUCCESS) {
@@ -1036,10 +1033,10 @@ static pj_status_t sdl_factory_create_stream(
while(strm->status == PJ_SUCCESS && !strm->surf && !strm->overlay
#if SDL_VERSION_ATLEAST(1,3,0)
&& !strm->scr_tex
-#endif
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
&& !strm->texture
-#endif
+#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
)
{
pj_thread_sleep(10);
@@ -1120,8 +1117,33 @@ static pj_status_t sdl_stream_get_cap(pjmedia_vid_dev_stream *s,
#if SDL_VERSION_ATLEAST(1,3,0)
if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW)
{
- *((void **)pval) = strm->window;
- return PJ_SUCCESS;
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+
+ if (SDL_GetWindowWMInfo(strm->window, &info)) {
+ pjmedia_vid_dev_hwnd *wnd = (pjmedia_vid_dev_hwnd *)pval;
+ if (info.subsystem == SDL_SYSWM_WINDOWS) {
+#if defined(SDL_VIDEO_DRIVER_WINDOWS)
+ wnd->type = PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS;
+ wnd->info.win.hwnd = (void *)info.info.win.window;
+#endif
+ } else if (info.subsystem == SDL_SYSWM_X11) {
+#if defined(SDL_VIDEO_DRIVER_X11)
+ wnd->info.x11.window = (void *)info.info.x11.window;
+ wnd->info.x11.display = (void *)info.info.x11.display;
+#endif
+ } else if (info.subsystem == SDL_SYSWM_COCOA) {
+#if defined(SDL_VIDEO_DRIVER_COCOA)
+ wnd->info.cocoa.window = (void *)info.info.cocoa.window;
+#endif
+ } else if (info.subsystem == SDL_SYSWM_UIKIT) {
+#if defined(SDL_VIDEO_DRIVER_UIKIT)
+ wnd->info.ios.window = (void *)info.info.uikit.window;
+#endif
+ }
+ return PJ_SUCCESS;
+ } else
+ return PJMEDIA_EVID_INVCAP;
} else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) {
SDL_GetWindowPosition(strm->window, &((pjmedia_coord *)pval)->x,
&((pjmedia_coord *)pval)->y);
@@ -1135,7 +1157,9 @@ static pj_status_t sdl_stream_get_cap(pjmedia_vid_dev_stream *s,
*((pj_bool_t *)pval) = (flag | SDL_WINDOW_HIDDEN)? PJ_TRUE: PJ_FALSE;
return PJ_SUCCESS;
}
-#endif
+#else /* SDL_VERSION_ATLEAST(1,3,0) */
+ PJ_UNUSED_ARG(cap);
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
return PJMEDIA_EVID_INVCAP;
}
@@ -1163,13 +1187,14 @@ static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *s,
SDL_ShowWindow(strm->window);
return PJ_SUCCESS;
} else
-#endif
+#endif /* SDL_VERSION_ATLEAST(1,3,0) */
if (cap == PJMEDIA_VID_DEV_CAP_FORMAT) {
strm->new_fmt = (pjmedia_format *)pval;
#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
- [strm->delegate performSelectorOnMainThread:@selector(detect_new_fmt)
+ [strm->delegate performSelectorOnMainThread:
+ @selector(detect_fmt_change)
withObject:nil waitUntilDone:YES];
-#endif
+#endif /* PJ_DARWINOS */
while (strm->new_fmt)
pj_thread_sleep(10);
@@ -1183,9 +1208,9 @@ static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *s,
strm->new_fmt = &strm->param.fmt;
#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
[strm->delegate performSelectorOnMainThread:
- @selector(detect_new_fmt)
+ @selector(detect_fmt_change)
withObject:nil waitUntilDone:YES];
-#endif
+#endif /* PJ_DARWINOS */
while (strm->new_fmt)
pj_thread_sleep(10);
@@ -1205,9 +1230,9 @@ static pj_status_t sdl_stream_set_cap(pjmedia_vid_dev_stream *s,
strm->new_disp_size = (pjmedia_rect_size *)pval;
#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
[strm->delegate performSelectorOnMainThread:
- @selector(detect_new_fmt)
+ @selector(detect_fmt_change)
withObject:nil waitUntilDone:YES];
-#endif
+#endif /* PJ_DARWINOS */
while (strm->new_disp_size)
pj_thread_sleep(10);
@@ -1242,7 +1267,7 @@ static pj_status_t sdl_stream_stop(pjmedia_vid_dev_stream *strm)
stream->is_running = PJ_FALSE;
#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
if (![NSThread isMainThread])
-#endif
+#endif /* PJ_DARWINOS */
for (i=0; !stream->render_exited && i<50; ++i)
pj_thread_sleep(10);
@@ -1267,8 +1292,6 @@ static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm)
#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
if (stream->delegate) {
- [stream->delegate performSelectorOnMainThread:@selector(sdl_destroy)
- withObject:nil waitUntilDone:YES];
[stream->delegate release];
stream->delegate = NULL;
}
@@ -1276,19 +1299,61 @@ static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm)
[stream->apool release];
stream->apool = NULL;
}
-#endif
+#endif /* PJ_DARWINOS */
pj_pool_release(stream->pool);
return PJ_SUCCESS;
}
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+@implementation SDLDelegate
+- (void)sdl_init
+{
+ if (SDL_Init(SDL_INIT_VIDEO)) {
+ PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL"));
+ }
+}
+
+- (void)sdl_quit
+{
+ SDL_Quit();
+}
+
+- (void)detect_fmt_change
+{
+ detect_fmt_change(strm);
+}
+
+- (void)sdl_create
+{
+ sdl_create(strm);
+}
+
+- (void)sdl_destroy
+{
+ sdl_destroy(strm, PJ_TRUE);
+}
+
+- (void)handle_event
+{
+ handle_event(strm);
+}
+
+- (void)put_frame
+{
+ put_frame(strm, strm->frame);
+}
+
+@end
+#endif /* PJ_DARWINOS */
+
#ifdef _MSC_VER
# pragma comment( lib, "sdl.lib")
# if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL
# pragma comment(lib, "OpenGL32.lib")
-# endif
-#endif
+# endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */
+#endif /* _MSC_VER */
#endif /* PJMEDIA_VIDEO_DEV_HAS_SDL */