Changeset 3676 for pjproject


Ignore:
Timestamp:
Jul 22, 2011 8:28:53 AM (13 years ago)
Author:
ming
Message:

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
Location:
pjproject/trunk/pjmedia
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia-videodev/videodev.h

    r3675 r3676  
    7878    union 
    7979    { 
    80         void        *ptr;       /**< Pointer value      */ 
    81         int          fd;        /**< Descriptor value   */ 
    82     } hwnd; 
     80        struct { 
     81            void    *hwnd;      /**< HWND       */ 
     82        } win; 
     83        struct { 
     84            void    *window;    /**< Window     */ 
     85            void    *display;   /**< Display    */ 
     86        } x11; 
     87        struct { 
     88            void    *window;    /**< Window     */ 
     89        } cocoa; 
     90        struct { 
     91            void    *window;    /**< Window     */ 
     92        } ios; 
     93        void        *window; 
     94    } info; 
    8395 
    8496} pjmedia_vid_dev_hwnd; 
  • pjproject/trunk/pjmedia/src/pjmedia-videodev/sdl_dev.c

    r3675 r3676  
    2323#include <pj/os.h> 
    2424 
    25  
    2625#if defined(PJMEDIA_VIDEO_DEV_HAS_SDL) && PJMEDIA_VIDEO_DEV_HAS_SDL != 0 
    2726 
    28  
    2927#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
     28#   include "TargetConditionals.h" 
    3029#   include <Foundation/Foundation.h> 
    31 #endif 
     30#endif /* PJ_DARWINOS */ 
    3231 
    3332#include <SDL.h> 
     33#include <SDL_syswm.h> 
    3434#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    3535#   include "SDL_opengl.h" 
    3636#   define OPENGL_DEV_IDX 1 
    37 #else 
     37#else /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    3838#   define OPENGL_DEV_IDX -999 
    39 #endif 
     39#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    4040 
    4141#define THIS_FILE               "sdl_dev.c" 
     
    5353#   define SDL_PIXELFORMAT_ARGB8888 0 
    5454#   define SDL_PIXELFORMAT_RGB24    0 
    55 #endif 
     55#endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */ 
    5656 
    5757typedef struct sdl_fmt_info 
     
    7474    {PJMEDIA_FORMAT_BGRA,  (Uint32)SDL_PIXELFORMAT_BGRA8888, 
    7575     0xFF00, 0xFF0000, 0xFF000000, 0xFF} , 
    76 #else 
     76#else /* PJ_IS_BIG_ENDIAN */ 
    7777    {PJMEDIA_FORMAT_RGBA,  (Uint32)SDL_PIXELFORMAT_ABGR8888, 
    7878     0xFF, 0xFF00, 0xFF0000, 0xFF000000} , 
     
    8181    {PJMEDIA_FORMAT_BGRA,  (Uint32)SDL_PIXELFORMAT_ARGB8888, 
    8282     0xFF0000, 0xFF00, 0xFF, 0xFF000000} , 
    83 #endif 
     83#endif /* PJ_IS_BIG_ENDIAN */ 
    8484 
    8585    {PJMEDIA_FORMAT_DIB , (Uint32)SDL_PIXELFORMAT_RGB24, 
     
    104104- (void)sdl_init; 
    105105- (void)sdl_quit; 
    106 - (void)detect_new_fmt; 
    107 - (int)sdl_create; 
     106- (void)detect_fmt_change; 
     107- (void)sdl_create; 
    108108- (void)sdl_destroy; 
    109 - (int)handle_event; 
    110 - (pj_status_t)put_frame; 
     109- (void)handle_event; 
     110- (void)put_frame; 
    111111@end 
    112 #endif 
     112#endif /* PJ_DARWINOS */ 
    113113 
    114114/* sdl_ device info */ 
     
    130130    NSAutoreleasePool           *apool; 
    131131    SDLDelegate                 *delegate; 
    132 #endif 
     132#endif /* PJ_DARWINOS */ 
    133133}; 
    134134 
     
    157157    SDL_Texture                 *scr_tex;           /**< Screen texture.    */ 
    158158    int                          pitch;             /**< Pitch value.       */ 
    159 #endif 
     159#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    160160    SDL_Rect                     rect;              /**< Frame rectangle.   */ 
    161161    SDL_Rect                     dstrect;           /**< Display rectangle. */ 
     
    164164    SDL_Overlay                 *overlay;           /**< YUV overlay.       */ 
    165165#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    166 #if SDL_VERSION_ATLEAST(1,3,0) 
     166#   if SDL_VERSION_ATLEAST(1,3,0) 
    167167    SDL_GLContext               *gl_context; 
    168 #endif 
     168#   endif /* SDL_VERSION_ATLEAST(1,3,0) */  
    169169    GLuint                       texture; 
     170#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    170171    void                        *tex_buf; 
    171172    pj_size_t                    tex_buf_size; 
    172 #endif 
     173 
    173174#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    174175    NSAutoreleasePool           *apool; 
    175176    SDLDelegate                 *delegate; 
    176177    const pjmedia_frame         *frame; 
    177 #endif 
     178#endif /* PJ_DARWINOS */ 
    178179 
    179180    /* For frame conversion */ 
     
    219220static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm); 
    220221 
    221 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    222 static void draw_gl(struct sdl_stream *stream, void *tex_buf); 
    223 #endif 
    224  
    225222/* Operations */ 
    226223static pjmedia_vid_dev_factory_op factory_op = 
     
    275272    struct sdl_dev_info *ddi; 
    276273    unsigned i, j; 
    277  
    278 #if SDL_VERSION_ATLEAST(1,3,0) 
    279 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
     274    SDL_version version; 
     275    SDL_VERSION(&version); 
     276 
     277#if SDL_VERSION_ATLEAST(1,3,0) 
     278#   if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    280279    sf->apool = [[NSAutoreleasePool alloc] init]; 
    281280    sf->delegate = [[SDLDelegate alloc] init]; 
    282281    [sf->delegate performSelectorOnMainThread:@selector(sdl_init)  
    283282                  withObject:nil waitUntilDone:YES]; 
    284 #else 
     283#   else /* PJ_DARWINOS */ 
    285284    /* Initialize the SDL library */ 
    286285    if (SDL_Init(SDL_INIT_VIDEO)) 
    287286        return PJMEDIA_EVID_INIT; 
    288 #endif 
    289 #endif 
     287#   endif /* PJ_DARWINOS */ 
     288#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    290289 
    291290    sf->dev_count = 1; 
    292291#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    293292    sf->dev_count++; 
    294 #endif 
     293#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    295294    sf->dev_info = (struct sdl_dev_info*) 
    296295                   pj_pool_calloc(sf->pool, sf->dev_count, 
     
    309308    ddi->info.name[sizeof(ddi->info.name)-1] = '\0'; 
    310309    ddi->info.fmt_cnt = 1; 
    311 #endif 
     310#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    312311 
    313312    for (i = 0; i < sf->dev_count; i++) { 
     
    321320#if SDL_VERSION_ATLEAST(1,3,0) 
    322321        ddi->info.caps |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW; 
    323 #endif 
     322#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    324323 
    325324        for (j = 0; j < ddi->info.fmt_cnt; j++) { 
     
    331330    } 
    332331 
    333     PJ_LOG(4, (THIS_FILE, "SDL initialized")); 
     332    PJ_LOG(4, (THIS_FILE, "SDL %d.%d initialized", 
     333                          version.major, version.minor)); 
    334334 
    335335    return PJ_SUCCESS; 
     
    346346 
    347347#if SDL_VERSION_ATLEAST(1,3,0) 
    348 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
     348#   if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    349349    [sf->delegate performSelectorOnMainThread:@selector(sdl_quit)  
    350350                  withObject:nil waitUntilDone:YES]; 
    351351    [sf->delegate release]; 
    352352    [sf->apool release]; 
    353 #else 
     353#   else /* PJ_DARWINOS */ 
    354354    SDL_Quit(); 
    355 #endif 
    356 #endif 
     355#   endif /* PJ_DARWINOS */ 
     356#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    357357 
    358358    return PJ_SUCCESS; 
     
    426426} 
    427427 
    428 static void destroy_sdl(struct sdl_stream *strm, pj_bool_t destroy_win) 
     428static void sdl_destroy(struct sdl_stream *strm, pj_bool_t destroy_win) 
    429429{ 
    430430    PJ_UNUSED_ARG(destroy_win); 
     
    443443        strm->texture = 0; 
    444444    } 
    445 #endif 
    446 #if SDL_VERSION_ATLEAST(1,3,0) 
    447 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
     445#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
     446#if SDL_VERSION_ATLEAST(1,3,0) 
     447#   if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    448448    if (strm->gl_context) { 
    449449        SDL_GL_DeleteContext(strm->gl_context); 
    450450        strm->gl_context = NULL; 
    451451    } 
    452 #endif 
     452#   endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    453453    if (strm->scr_tex) { 
    454454        SDL_DestroyTexture(strm->scr_tex); 
     
    459459        strm->renderer = NULL; 
    460460    } 
    461 #ifndef __IPHONEOS__ 
     461#   if !defined(TARGET_OS_IPHONE) || TARGET_OS_IPHONE == 0 
    462462    if (destroy_win) { 
    463463        if (strm->window && 
     
    468468        strm->window = NULL; 
    469469    } 
    470 #endif 
    471 #endif 
    472 } 
    473  
    474 static pj_status_t init_sdl(struct sdl_stream *strm, pjmedia_format *fmt) 
     470#   endif /* TARGET_OS_IPHONE */ 
     471#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
     472} 
     473 
     474static pj_status_t sdl_create_view(struct sdl_stream *strm, 
     475                                   pjmedia_format *fmt) 
    475476{ 
    476477    sdl_fmt_info *sdl_info = get_sdl_format_info(fmt->id); 
     
    500501    strm->dstrect.h = (Uint16)strm->param.disp_size.h; 
    501502 
    502     destroy_sdl(strm, PJ_FALSE); 
     503    sdl_destroy(strm, PJ_FALSE); 
    503504 
    504505#if SDL_VERSION_ATLEAST(1,3,0) 
     
    511512        if (strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) { 
    512513            /* Use the window supplied by the application. */ 
    513             strm->window = SDL_CreateWindowFrom(strm->param.window.hwnd.ptr); 
     514            strm->window = SDL_CreateWindowFrom(strm->param.window.info.window); 
    514515        } else { 
    515516            /* Create the window where we will draw. */ 
     
    536537        return PJMEDIA_EVID_SYSERR; 
    537538 
    538 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
     539#   if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    539540    if (strm->param.rend_id == OPENGL_DEV_IDX) { 
    540541        strm->gl_context = SDL_GL_CreateContext(strm->window); 
     
    543544        SDL_GL_MakeCurrent(strm->window, strm->gl_context); 
    544545    } 
    545 #endif 
     546#   endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    546547 
    547548    strm->screen = SDL_GetWindowSurface(strm->window); 
    548549 
    549 #else 
     550#else /* SDL_VERSION_ATLEAST(1,3,0) */ 
    550551    /* Initialize the display */ 
    551552    strm->screen = SDL_SetVideoMode(strm->param.disp_size.w,  
    552553                                    strm->param.disp_size.h, 0, ( 
    553 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
     554#   if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    554555                                    strm->param.rend_id == OPENGL_DEV_IDX? 
    555556                                    SDL_OPENGL | SDL_RESIZABLE: 
    556 #endif 
     557#   endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    557558                                    SDL_RESIZABLE | SDL_SWSURFACE)); 
    558559    if (strm->screen == NULL) 
     
    561562    SDL_WM_SetCaption("pjmedia-SDL video", NULL); 
    562563 
    563 #endif 
     564#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    564565 
    565566#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
     
    588589            return PJMEDIA_EVID_SYSERR; 
    589590 
    590 #if defined(PJ_WIN32) && PJ_WIN32 != 0 
     591#   if !defined(PJ_DARWINOS) || PJ_DARWINOS == 0 
    591592        /** 
    592          * On Win32 platform, the OpenGL drawing must be in the same 
     593         * OpenGL drawing must be in the same 
    593594         * thread that calls SDL_SetVideoMode(), hence we need a buffer 
    594595         * for the frame from sdl_stream_put_frame() 
     
    598599            strm->tex_buf = pj_pool_alloc(strm->pool, strm->vafp.framebytes); 
    599600        } 
    600 #endif 
     601#   endif /* PJ_DARWINOS */ 
    601602    } else 
    602 #endif 
     603#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    603604#if SDL_VERSION_ATLEAST(1,3,0) 
    604605    {     
     
    610611     
    611612        strm->pitch = strm->rect.w * SDL_BYTESPERPIXEL(sdl_info->sdl_format); 
    612     } 
    613 #else 
     613 
     614#   if !defined(PJ_DARWINOS) || PJ_DARWINOS == 0 
     615        if (strm->vafp.framebytes > strm->tex_buf_size) { 
     616            strm->tex_buf_size = strm->vafp.framebytes; 
     617            strm->tex_buf = pj_pool_alloc(strm->pool, strm->vafp.framebytes); 
     618        } 
     619#   endif /* !PJ_DARWINOS */ 
     620    } 
     621#else /* SDL_VERSION_ATLEAST(1,3,0) */ 
    614622    if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB) { 
    615623        strm->surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 
     
    629637            return PJMEDIA_EVID_SYSERR; 
    630638    } 
    631 #endif 
     639#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    632640 
    633641    return PJ_SUCCESS; 
     642} 
     643 
     644static pj_status_t sdl_create(struct sdl_stream *strm) 
     645{ 
     646#if !(SDL_VERSION_ATLEAST(1,3,0)) 
     647    if (SDL_Init(SDL_INIT_VIDEO)) { 
     648        strm->status = PJMEDIA_EVID_INIT; 
     649        goto on_return; 
     650    } 
     651#endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */ 
     652 
     653#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
     654    if (strm->param.rend_id == OPENGL_DEV_IDX) { 
     655        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); 
     656    } 
     657#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
     658 
     659    strm->status = sdl_create_view(strm, &strm->param.fmt); 
     660    if (strm->status != PJ_SUCCESS) 
     661        goto on_return; 
     662 
     663on_return: 
     664    if (strm->status != PJ_SUCCESS) { 
     665        sdl_destroy(strm, PJ_TRUE); 
     666#if !(SDL_VERSION_ATLEAST(1,3,0)) 
     667        SDL_Quit(); 
     668#endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */ 
     669        strm->screen = NULL; 
     670    } 
     671     
     672    return strm->status; 
    634673} 
    635674 
     
    645684 
    646685        /* Re-initialize SDL */ 
    647         strm->status = init_sdl(strm, (strm->new_fmt? strm->new_fmt : 
    648                                 &strm->param.fmt)); 
    649          
     686        strm->status = sdl_create_view(strm, (strm->new_fmt? strm->new_fmt : 
     687                                       &strm->param.fmt)); 
     688 
    650689        if (strm->status == PJ_SUCCESS) { 
    651690            if (strm->new_fmt) 
     
    657696        strm->new_disp_size = NULL; 
    658697    } 
    659 } 
    660  
    661 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    662 @implementation SDLDelegate 
    663 - (void)sdl_init 
    664 { 
    665     if (SDL_Init(SDL_INIT_VIDEO)) { 
    666         PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL")); 
    667     } 
    668 } 
    669  
    670 - (void)sdl_quit 
    671 { 
    672     SDL_Quit(); 
    673 } 
    674  
    675 - (void)detect_new_fmt 
    676 { 
    677     detect_fmt_change(strm); 
    678 } 
    679  
    680 - (int)sdl_create 
    681 { 
    682 #else 
    683 static int sdlthread(void * data) 
    684 { 
    685     struct sdl_stream *strm = (struct sdl_stream*)data; 
    686     pj_bool_t notify_wnd_closed_event = PJ_FALSE; 
    687     pj_status_t saved_stream_status; 
    688 #endif 
    689  
    690 #if !(SDL_VERSION_ATLEAST(1,3,0)) 
    691     if (SDL_Init(SDL_INIT_VIDEO)) { 
    692         strm->status = PJMEDIA_EVID_INIT; 
    693         goto on_return; 
    694     } 
    695 #endif 
    696  
    697 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    698     if (strm->param.rend_id == OPENGL_DEV_IDX) { 
    699         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); 
    700     } 
    701 #endif 
    702  
    703     strm->status = init_sdl(strm, &strm->param.fmt); 
    704     if (strm->status != PJ_SUCCESS) 
    705         goto on_return; 
    706  
    707 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    708 on_return: 
    709     if (strm->status != PJ_SUCCESS) { 
    710         destroy_sdl(strm, PJ_TRUE); 
    711 #if !(SDL_VERSION_ATLEAST(1,3,0)) 
    712         SDL_Quit(); 
    713 #endif 
    714         strm->screen = NULL; 
    715     } 
    716      
    717     return strm->status; 
    718 } 
    719  
    720 - (void)sdl_destroy 
    721 { 
    722     destroy_sdl(strm, PJ_TRUE); 
    723 }     
    724  
    725 - (int)handle_event 
    726 { 
    727     const pjmedia_video_format_info *vfi; 
    728     pjmedia_video_format_detail *vfd; 
    729     pj_bool_t notify_wnd_closed_event = PJ_FALSE; 
    730     pj_status_t saved_stream_status; 
    731      
    732     vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(), 
    733                                         strm->param.fmt.id); 
    734     vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE); 
    735 #else 
    736     while(!strm->is_quitting)  
    737 #endif 
    738     { 
    739         SDL_Event sevent; 
    740         pjmedia_event pevent; 
    741  
    742 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    743 #if defined(PJ_WIN32) && PJ_WIN32 != 0   
    744         if (strm->param.rend_id == OPENGL_DEV_IDX) { 
    745             draw_gl(strm, strm->tex_buf); 
    746         } 
    747 #endif 
    748 #endif 
    749  
    750         detect_fmt_change(strm); 
    751          
    752         /** 
    753          * The event polling must be placed in the same thread that 
    754          * call SDL_SetVideoMode(). Please consult the official doc of 
    755          * SDL_PumpEvents(). 
    756          */ 
    757         while (SDL_PollEvent(&sevent)) { 
    758             pjmedia_event_init(&pevent, PJMEDIA_EVENT_NONE, &strm->last_ts, 
    759                                &strm->base.epub); 
    760  
    761             switch(sevent.type) { 
    762                 case SDL_MOUSEBUTTONDOWN: 
    763                     pevent.type = PJMEDIA_EVENT_MOUSE_BTN_DOWN; 
    764                     break; 
    765 #if SDL_VERSION_ATLEAST(1,3,0) 
    766                 case SDL_WINDOWEVENT: 
    767                     switch (sevent.window.event) { 
    768                         case SDL_WINDOWEVENT_RESIZED: 
    769                             pevent.type = PJMEDIA_EVENT_WND_RESIZED; 
    770                             pevent.data.wnd_resized.new_size.w = 
    771                                 sevent.window.data1; 
    772                             pevent.data.wnd_resized.new_size.h = 
    773                                 sevent.window.data2; 
    774                             break; 
    775                     } 
    776                     break; 
    777 #else 
    778                 case SDL_VIDEORESIZE: 
    779                     pevent.type = PJMEDIA_EVENT_WND_RESIZED; 
    780                     pevent.data.wnd_resized.new_size.w = sevent.resize.w; 
    781                     pevent.data.wnd_resized.new_size.h = sevent.resize.h; 
    782                     break; 
    783                 case SDL_QUIT: 
    784                     pevent.type = PJMEDIA_EVENT_WND_CLOSING; 
    785                     break; 
    786 #endif 
    787             } 
    788  
    789             if (pevent.type != PJMEDIA_EVENT_NONE) { 
    790                 pj_status_t status; 
    791  
    792                 status = pjmedia_event_publish(&strm->base.epub, &pevent); 
    793  
    794                 switch (pevent.type) { 
    795                 case PJMEDIA_EVENT_WND_RESIZED: 
    796                     strm->new_disp_size = &pevent.data.wnd_resized.new_size; 
    797                     detect_fmt_change(strm); 
    798                     break; 
    799  
    800                 case PJMEDIA_EVENT_WND_CLOSING: 
    801                     if (pevent.data.wnd_closing.cancel) { 
    802                         /* Cancel the closing operation */ 
    803                         break; 
    804                     } 
    805  
    806                     /* Proceed to cleanup SDL. App must still call 
    807                      * pjmedia_dev_stream_destroy() when getting WND_CLOSED 
    808                      * event 
    809                      */ 
    810                     strm->is_quitting = PJ_TRUE; 
    811                     notify_wnd_closed_event = PJ_TRUE; 
    812                     sdl_stream_stop(&strm->base); 
    813                     goto on_return; 
    814  
    815                 default: 
    816                     /* Just to prevent gcc warning about unused enums */ 
    817                     break; 
    818                 } 
    819             } 
    820         } 
    821     } 
    822  
    823 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    824     return 0; 
    825 #endif 
    826 on_return: 
    827     destroy_sdl(strm, PJ_TRUE); 
    828 #if !(SDL_VERSION_ATLEAST(1,3,0)) 
    829     SDL_Quit(); 
    830 #endif 
    831     strm->screen = NULL; 
    832     saved_stream_status = strm->status; 
    833  
    834     if (notify_wnd_closed_event) { 
    835         pjmedia_event pevent; 
    836  
    837         pjmedia_event_init(&pevent, PJMEDIA_EVENT_WND_CLOSED, &strm->last_ts, 
    838                            &strm->base.epub); 
    839         pjmedia_event_publish(&strm->base.epub, &pevent); 
    840     } 
    841  
    842     /* 
    843      * Note: don't access the stream after this point, it  might have 
    844      * been destroyed 
    845      */ 
    846  
    847     return saved_stream_status; 
    848698} 
    849699 
     
    865715        glVertex2i(stream->param.disp_size.w, stream->param.disp_size.h); 
    866716        glEnd(); 
    867 #if SDL_VERSION_ATLEAST(1,3,0) 
     717#   if SDL_VERSION_ATLEAST(1,3,0) 
    868718        SDL_GL_SwapWindow(stream->window); 
    869 #else 
     719#   else /* SDL_VERSION_ATLEAST(1,3,0) */ 
    870720        SDL_GL_SwapBuffers(); 
    871 #endif 
    872     } 
    873 } 
    874 #endif 
     721#   endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
     722    } 
     723} 
     724#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
     725 
     726static void draw_texture(struct sdl_stream *stream, void *tex_buf) 
     727{ 
     728#if SDL_VERSION_ATLEAST(1,3,0) 
     729    SDL_UpdateTexture(stream->scr_tex, NULL, tex_buf, stream->pitch); 
     730    SDL_RenderClear(stream->renderer); 
     731    SDL_RenderCopy(stream->renderer, stream->scr_tex, NULL, NULL); 
     732    SDL_RenderPresent(stream->renderer); 
     733#else /* SDL_VERSION_ATLEAST(1,3,0) */ 
     734    PJ_UNUSED_ARG(stream); 
     735    PJ_UNUSED_ARG(tex_buf); 
     736#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
     737} 
     738 
     739static void handle_event(struct sdl_stream *strm) 
     740{ 
     741    const pjmedia_video_format_info *vfi; 
     742    pjmedia_video_format_detail *vfd; 
     743    pj_bool_t notify_wnd_closed_event = PJ_FALSE; 
     744    SDL_Event sevent; 
     745    pjmedia_event pevent; 
     746     
     747    vfi = pjmedia_get_video_format_info(pjmedia_video_format_mgr_instance(), 
     748                                        strm->param.fmt.id); 
     749    vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE); 
     750 
     751    if (strm->tex_buf) { 
     752#if SDL_VERSION_ATLEAST(1,3,0) 
     753        if (strm->scr_tex) { 
     754            draw_texture(strm, strm->tex_buf); 
     755        } 
     756#else /* SDL_VERSION_ATLEAST(1,3,0) */ 
     757        if (0) { } 
     758#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
     759#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
     760        else if (strm->param.rend_id == OPENGL_DEV_IDX) { 
     761            draw_gl(strm, strm->tex_buf); 
     762        } 
     763#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
     764    } 
     765 
     766    detect_fmt_change(strm); 
     767 
     768    /** 
     769     * The event polling must be placed in the same thread that 
     770     * call SDL_SetVideoMode(). Please consult the official doc of 
     771     * SDL_PumpEvents(). 
     772     */ 
     773    while (SDL_PollEvent(&sevent)) { 
     774        pjmedia_event_init(&pevent, PJMEDIA_EVENT_NONE, &strm->last_ts, 
     775                           &strm->base.epub); 
     776 
     777        switch(sevent.type) { 
     778            case SDL_MOUSEBUTTONDOWN: 
     779                pevent.type = PJMEDIA_EVENT_MOUSE_BTN_DOWN; 
     780                break; 
     781#if SDL_VERSION_ATLEAST(1,3,0) 
     782            case SDL_WINDOWEVENT: 
     783                switch (sevent.window.event) { 
     784                    case SDL_WINDOWEVENT_RESIZED: 
     785                        pevent.type = PJMEDIA_EVENT_WND_RESIZED; 
     786                        pevent.data.wnd_resized.new_size.w = 
     787                            sevent.window.data1; 
     788                        pevent.data.wnd_resized.new_size.h = 
     789                            sevent.window.data2; 
     790                        break; 
     791                } 
     792                break; 
     793#else /* SDL_VERSION_ATLEAST(1,3,0) */ 
     794            case SDL_VIDEORESIZE: 
     795                pevent.type = PJMEDIA_EVENT_WND_RESIZED; 
     796                pevent.data.wnd_resized.new_size.w = sevent.resize.w; 
     797                pevent.data.wnd_resized.new_size.h = sevent.resize.h; 
     798                break; 
     799            case SDL_QUIT: 
     800                pevent.type = PJMEDIA_EVENT_WND_CLOSING; 
     801                break; 
     802#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
     803        } 
     804 
     805        if (pevent.type != PJMEDIA_EVENT_NONE) { 
     806            pj_status_t status; 
     807 
     808            status = pjmedia_event_publish(&strm->base.epub, &pevent); 
     809 
     810            switch (pevent.type) { 
     811            case PJMEDIA_EVENT_WND_RESIZED: 
     812                strm->new_disp_size = &pevent.data.wnd_resized.new_size; 
     813                detect_fmt_change(strm); 
     814                break; 
     815 
     816            case PJMEDIA_EVENT_WND_CLOSING: 
     817                if (pevent.data.wnd_closing.cancel) { 
     818                    /* Cancel the closing operation */ 
     819                    break; 
     820                } 
     821 
     822                /* Proceed to cleanup SDL. App must still call 
     823                 * pjmedia_dev_stream_destroy() when getting WND_CLOSED 
     824                 * event 
     825                 */ 
     826                strm->is_quitting = PJ_TRUE; 
     827                notify_wnd_closed_event = PJ_TRUE; 
     828                sdl_stream_stop(&strm->base); 
     829                goto on_return; 
     830 
     831            default: 
     832                /* Just to prevent gcc warning about unused enums */ 
     833                break; 
     834            } 
     835        } 
     836    } 
     837 
     838    return; 
     839 
     840on_return: 
     841    sdl_destroy(strm, PJ_TRUE); 
     842#if !(SDL_VERSION_ATLEAST(1,3,0)) 
     843    SDL_Quit(); 
     844#endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */ 
     845    strm->screen = NULL; 
     846 
     847    if (notify_wnd_closed_event) { 
     848        pjmedia_event pevent; 
     849 
     850        pjmedia_event_init(&pevent, PJMEDIA_EVENT_WND_CLOSED, &strm->last_ts, 
     851                           &strm->base.epub); 
     852        pjmedia_event_publish(&strm->base.epub, &pevent); 
     853    } 
     854 
     855    /* 
     856     * Note: don't access the stream after this point, it  might have 
     857     * been destroyed 
     858     */ 
     859} 
     860 
     861static int sdl_thread(void * data) 
     862{ 
     863    struct sdl_stream *strm = (struct sdl_stream*)data; 
    875864 
    876865#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    877 - (pj_status_t)put_frame 
    878 { 
    879     const pjmedia_frame *frame = strm->frame; 
    880 #else     
    881 /* API: Put frame from stream */ 
    882 static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm, 
    883                                         const pjmedia_frame *frame) 
    884 { 
    885 #endif 
    886     struct sdl_stream *stream = (struct sdl_stream*)strm; 
     866    while(!strm->is_quitting) { 
     867        [strm->delegate performSelectorOnMainThread:@selector(handle_event) 
     868                        withObject:nil waitUntilDone:YES]; 
     869    } 
     870    [strm->delegate performSelectorOnMainThread:@selector(sdl_destroy) 
     871                    withObject:nil waitUntilDone:YES]; 
     872#   if !(SDL_VERSION_ATLEAST(1,3,0)) 
     873    [strm->delegate performSelectorOnMainThread:@selector(sdl_quit) 
     874                    withObject:nil waitUntilDone:YES]; 
     875#   endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */ 
     876#else /* PJ_DARWINOS */ 
     877    sdl_create(strm); 
     878    while(!strm->is_quitting) { 
     879        handle_event(strm); 
     880    } 
     881    sdl_destroy(strm, PJ_TRUE); 
     882#   if !(SDL_VERSION_ATLEAST(1,3,0)) 
     883    SDL_Quit(); 
     884#   endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */ 
     885#endif /* PJ_DARWINOS */ 
     886    strm->screen = NULL; 
     887 
     888    return 0; 
     889} 
     890 
     891static pj_status_t put_frame(struct sdl_stream *stream, 
     892                             const pjmedia_frame *frame) 
     893{ 
    887894    pj_status_t status = PJ_SUCCESS; 
    888895 
     
    916923#if SDL_VERSION_ATLEAST(1,3,0) 
    917924        SDL_UpdateWindowSurface(stream->window); 
    918 #else 
     925#else /* SDL_VERSION_ATLEAST(1,3,0) */ 
    919926        SDL_UpdateRect(stream->screen, 0, 0, 0, 0); 
    920 #endif 
     927#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    921928    } else if (stream->overlay) { 
    922929        int i, sz, offset; 
     
    940947#if SDL_VERSION_ATLEAST(1,3,0) 
    941948    else if (stream->scr_tex) { 
    942         SDL_UpdateTexture(stream->scr_tex, NULL, frame->buf, stream->pitch); 
    943         SDL_RenderClear(stream->renderer); 
    944         SDL_RenderCopy(stream->renderer, stream->scr_tex, NULL, NULL); 
    945         SDL_RenderPresent(stream->renderer); 
    946     } 
    947 #endif 
     949        if (stream->tex_buf) 
     950            pj_memcpy(stream->tex_buf, frame->buf, stream->vafp.framebytes); 
     951        else 
     952            draw_texture(stream, frame->buf); 
     953    } 
     954#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    948955#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    949956    else if (stream->param.rend_id == OPENGL_DEV_IDX) { 
    950 #if defined(PJ_WIN32) && PJ_WIN32 != 0 
    951         pj_memcpy(stream->tex_buf, frame->buf, stream->vafp.framebytes); 
    952 #else 
    953         draw_gl(stream, frame->buf); 
    954 #endif 
    955     } 
    956 #endif 
     957        if (stream->tex_buf) 
     958            pj_memcpy(stream->tex_buf, frame->buf, stream->vafp.framebytes); 
     959        else 
     960            draw_gl(stream, frame->buf); 
     961    } 
     962#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    957963 
    958964on_return: 
     965    stream->status = status; 
    959966    return status; 
    960967} 
    961 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    962 @end 
    963  
     968 
     969/* API: Put frame from stream */ 
    964970static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm, 
    965971                                        const pjmedia_frame *frame) 
    966972{ 
    967973    struct sdl_stream *stream = (struct sdl_stream*)strm; 
     974 
     975#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    968976    stream->frame = frame;     
    969977    [stream->delegate performSelectorOnMainThread:@selector(put_frame)  
    970978                      withObject:nil waitUntilDone:YES]; 
    971979 
    972     return PJ_SUCCESS; 
    973 } 
    974      
    975 static int sdlthread(void * data) 
    976 { 
    977     struct sdl_stream *strm = (struct sdl_stream*)data; 
    978      
    979     while(!strm->is_quitting) { 
    980         [strm->delegate performSelectorOnMainThread:@selector(handle_event) 
    981                         withObject:nil waitUntilDone:YES]; 
    982     } 
    983      
    984     return 0; 
    985 } 
    986      
    987 #endif 
     980    return stream->status; 
     981#else /* PJ_DARWINOS */ 
     982    return put_frame(stream, frame); 
     983#endif /* PJ_DARWINOS */ 
     984} 
    988985 
    989986/* API: create stream */ 
     
    10261023            goto on_error; 
    10271024        } 
    1028 #endif 
    1029         status = pj_thread_create(pool, "sdl_thread", sdlthread, 
     1025#endif /* PJ_DARWINOS */ 
     1026        status = pj_thread_create(pool, "sdl_thread", sdl_thread, 
    10301027                                  strm, 0, 0, &strm->sdl_thread); 
    10311028 
     
    10371034#if SDL_VERSION_ATLEAST(1,3,0) 
    10381035              && !strm->scr_tex 
    1039 #endif 
     1036#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    10401037#if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    10411038              && !strm->texture 
    1042 #endif 
     1039#endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
    10431040              ) 
    10441041        { 
     
    11211118    if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) 
    11221119    { 
    1123         *((void **)pval) = strm->window; 
    1124         return PJ_SUCCESS; 
     1120        SDL_SysWMinfo info; 
     1121        SDL_VERSION(&info.version); 
     1122 
     1123        if (SDL_GetWindowWMInfo(strm->window, &info)) { 
     1124            pjmedia_vid_dev_hwnd *wnd = (pjmedia_vid_dev_hwnd *)pval; 
     1125            if (info.subsystem == SDL_SYSWM_WINDOWS) { 
     1126#if defined(SDL_VIDEO_DRIVER_WINDOWS) 
     1127                wnd->type = PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS; 
     1128                wnd->info.win.hwnd = (void *)info.info.win.window; 
     1129#endif 
     1130            } else if (info.subsystem == SDL_SYSWM_X11) { 
     1131#if defined(SDL_VIDEO_DRIVER_X11) 
     1132                wnd->info.x11.window = (void *)info.info.x11.window; 
     1133                wnd->info.x11.display = (void *)info.info.x11.display; 
     1134#endif 
     1135            } else if (info.subsystem == SDL_SYSWM_COCOA) { 
     1136#if defined(SDL_VIDEO_DRIVER_COCOA) 
     1137                wnd->info.cocoa.window = (void *)info.info.cocoa.window; 
     1138#endif 
     1139            } else if (info.subsystem == SDL_SYSWM_UIKIT) { 
     1140#if defined(SDL_VIDEO_DRIVER_UIKIT) 
     1141                wnd->info.ios.window = (void *)info.info.uikit.window; 
     1142#endif 
     1143            } 
     1144            return PJ_SUCCESS; 
     1145        } else 
     1146            return PJMEDIA_EVID_INVCAP; 
    11251147    } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) { 
    11261148        SDL_GetWindowPosition(strm->window, &((pjmedia_coord *)pval)->x, 
     
    11361158        return PJ_SUCCESS; 
    11371159    } 
    1138 #endif 
     1160#else /* SDL_VERSION_ATLEAST(1,3,0) */ 
     1161    PJ_UNUSED_ARG(cap); 
     1162#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    11391163 
    11401164    return PJMEDIA_EVID_INVCAP; 
     
    11641188        return PJ_SUCCESS; 
    11651189    } else 
    1166 #endif 
     1190#endif /* SDL_VERSION_ATLEAST(1,3,0) */ 
    11671191    if (cap == PJMEDIA_VID_DEV_CAP_FORMAT) { 
    11681192        strm->new_fmt = (pjmedia_format *)pval; 
    11691193#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    1170         [strm->delegate performSelectorOnMainThread:@selector(detect_new_fmt) 
     1194        [strm->delegate performSelectorOnMainThread: 
     1195                        @selector(detect_fmt_change) 
    11711196                        withObject:nil waitUntilDone:YES]; 
    1172 #endif 
     1197#endif /* PJ_DARWINOS */ 
    11731198        while (strm->new_fmt) 
    11741199            pj_thread_sleep(10); 
     
    11841209#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    11851210            [strm->delegate performSelectorOnMainThread: 
    1186                             @selector(detect_new_fmt) 
     1211                            @selector(detect_fmt_change) 
    11871212                            withObject:nil waitUntilDone:YES]; 
    1188 #endif 
     1213#endif /* PJ_DARWINOS */ 
    11891214            while (strm->new_fmt) 
    11901215                pj_thread_sleep(10); 
     
    12061231#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    12071232        [strm->delegate performSelectorOnMainThread: 
    1208                         @selector(detect_new_fmt) 
     1233                        @selector(detect_fmt_change) 
    12091234                        withObject:nil waitUntilDone:YES]; 
    1210 #endif 
     1235#endif /* PJ_DARWINOS */ 
    12111236        while (strm->new_disp_size) 
    12121237            pj_thread_sleep(10); 
     
    12431268#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    12441269    if (![NSThread isMainThread]) 
    1245 #endif 
     1270#endif /* PJ_DARWINOS */ 
    12461271    for (i=0; !stream->render_exited && i<50; ++i) 
    12471272        pj_thread_sleep(10); 
     
    12681293#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
    12691294    if (stream->delegate) { 
    1270         [stream->delegate performSelectorOnMainThread:@selector(sdl_destroy) 
    1271                           withObject:nil waitUntilDone:YES]; 
    12721295        [stream->delegate release]; 
    12731296        stream->delegate = NULL; 
     
    12771300        stream->apool = NULL; 
    12781301    } 
    1279 #endif 
     1302#endif /* PJ_DARWINOS */ 
    12801303    pj_pool_release(stream->pool); 
    12811304     
     
    12831306    return PJ_SUCCESS; 
    12841307} 
     1308 
     1309#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
     1310@implementation SDLDelegate 
     1311- (void)sdl_init 
     1312{ 
     1313    if (SDL_Init(SDL_INIT_VIDEO)) { 
     1314        PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL")); 
     1315    } 
     1316} 
     1317 
     1318- (void)sdl_quit 
     1319{ 
     1320    SDL_Quit(); 
     1321} 
     1322 
     1323- (void)detect_fmt_change 
     1324{ 
     1325    detect_fmt_change(strm); 
     1326} 
     1327 
     1328- (void)sdl_create 
     1329{ 
     1330    sdl_create(strm); 
     1331} 
     1332 
     1333- (void)sdl_destroy 
     1334{ 
     1335    sdl_destroy(strm, PJ_TRUE); 
     1336} 
     1337 
     1338- (void)handle_event 
     1339{ 
     1340    handle_event(strm); 
     1341} 
     1342 
     1343- (void)put_frame 
     1344{ 
     1345    put_frame(strm, strm->frame); 
     1346} 
     1347 
     1348@end 
     1349#endif /* PJ_DARWINOS */ 
    12851350 
    12861351#ifdef _MSC_VER 
     
    12881353#   if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 
    12891354#       pragma comment(lib, "OpenGL32.lib") 
    1290 #   endif 
    1291 #endif 
     1355#   endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 
     1356#endif /* _MSC_VER */ 
    12921357 
    12931358 
Note: See TracChangeset for help on using the changeset viewer.