Changeset 3676 for pjproject/trunk/pjmedia/src/pjmedia-videodev/sdl_dev.c
- Timestamp:
- Jul 22, 2011 8:28:53 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia-videodev/sdl_dev.c
r3675 r3676 23 23 #include <pj/os.h> 24 24 25 26 25 #if defined(PJMEDIA_VIDEO_DEV_HAS_SDL) && PJMEDIA_VIDEO_DEV_HAS_SDL != 0 27 26 28 29 27 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 28 # include "TargetConditionals.h" 30 29 # include <Foundation/Foundation.h> 31 #endif 30 #endif /* PJ_DARWINOS */ 32 31 33 32 #include <SDL.h> 33 #include <SDL_syswm.h> 34 34 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 35 35 # include "SDL_opengl.h" 36 36 # define OPENGL_DEV_IDX 1 37 #else 37 #else /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 38 38 # define OPENGL_DEV_IDX -999 39 #endif 39 #endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 40 40 41 41 #define THIS_FILE "sdl_dev.c" … … 53 53 # define SDL_PIXELFORMAT_ARGB8888 0 54 54 # define SDL_PIXELFORMAT_RGB24 0 55 #endif 55 #endif /* !(SDL_VERSION_ATLEAST(1,3,0)) */ 56 56 57 57 typedef struct sdl_fmt_info … … 74 74 {PJMEDIA_FORMAT_BGRA, (Uint32)SDL_PIXELFORMAT_BGRA8888, 75 75 0xFF00, 0xFF0000, 0xFF000000, 0xFF} , 76 #else 76 #else /* PJ_IS_BIG_ENDIAN */ 77 77 {PJMEDIA_FORMAT_RGBA, (Uint32)SDL_PIXELFORMAT_ABGR8888, 78 78 0xFF, 0xFF00, 0xFF0000, 0xFF000000} , … … 81 81 {PJMEDIA_FORMAT_BGRA, (Uint32)SDL_PIXELFORMAT_ARGB8888, 82 82 0xFF0000, 0xFF00, 0xFF, 0xFF000000} , 83 #endif 83 #endif /* PJ_IS_BIG_ENDIAN */ 84 84 85 85 {PJMEDIA_FORMAT_DIB , (Uint32)SDL_PIXELFORMAT_RGB24, … … 104 104 - (void)sdl_init; 105 105 - (void)sdl_quit; 106 - (void)detect_ new_fmt;107 - ( int)sdl_create;106 - (void)detect_fmt_change; 107 - (void)sdl_create; 108 108 - (void)sdl_destroy; 109 - ( int)handle_event;110 - ( pj_status_t)put_frame;109 - (void)handle_event; 110 - (void)put_frame; 111 111 @end 112 #endif 112 #endif /* PJ_DARWINOS */ 113 113 114 114 /* sdl_ device info */ … … 130 130 NSAutoreleasePool *apool; 131 131 SDLDelegate *delegate; 132 #endif 132 #endif /* PJ_DARWINOS */ 133 133 }; 134 134 … … 157 157 SDL_Texture *scr_tex; /**< Screen texture. */ 158 158 int pitch; /**< Pitch value. */ 159 #endif 159 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 160 160 SDL_Rect rect; /**< Frame rectangle. */ 161 161 SDL_Rect dstrect; /**< Display rectangle. */ … … 164 164 SDL_Overlay *overlay; /**< YUV overlay. */ 165 165 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 166 # if SDL_VERSION_ATLEAST(1,3,0)166 # if SDL_VERSION_ATLEAST(1,3,0) 167 167 SDL_GLContext *gl_context; 168 # endif168 # endif /* SDL_VERSION_ATLEAST(1,3,0) */ 169 169 GLuint texture; 170 #endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 170 171 void *tex_buf; 171 172 pj_size_t tex_buf_size; 172 #endif 173 173 174 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 174 175 NSAutoreleasePool *apool; 175 176 SDLDelegate *delegate; 176 177 const pjmedia_frame *frame; 177 #endif 178 #endif /* PJ_DARWINOS */ 178 179 179 180 /* For frame conversion */ … … 219 220 static pj_status_t sdl_stream_destroy(pjmedia_vid_dev_stream *strm); 220 221 221 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL222 static void draw_gl(struct sdl_stream *stream, void *tex_buf);223 #endif224 225 222 /* Operations */ 226 223 static pjmedia_vid_dev_factory_op factory_op = … … 275 272 struct sdl_dev_info *ddi; 276 273 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 280 279 sf->apool = [[NSAutoreleasePool alloc] init]; 281 280 sf->delegate = [[SDLDelegate alloc] init]; 282 281 [sf->delegate performSelectorOnMainThread:@selector(sdl_init) 283 282 withObject:nil waitUntilDone:YES]; 284 # else283 # else /* PJ_DARWINOS */ 285 284 /* Initialize the SDL library */ 286 285 if (SDL_Init(SDL_INIT_VIDEO)) 287 286 return PJMEDIA_EVID_INIT; 288 # endif289 #endif 287 # endif /* PJ_DARWINOS */ 288 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 290 289 291 290 sf->dev_count = 1; 292 291 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 293 292 sf->dev_count++; 294 #endif 293 #endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 295 294 sf->dev_info = (struct sdl_dev_info*) 296 295 pj_pool_calloc(sf->pool, sf->dev_count, … … 309 308 ddi->info.name[sizeof(ddi->info.name)-1] = '\0'; 310 309 ddi->info.fmt_cnt = 1; 311 #endif 310 #endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 312 311 313 312 for (i = 0; i < sf->dev_count; i++) { … … 321 320 #if SDL_VERSION_ATLEAST(1,3,0) 322 321 ddi->info.caps |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW; 323 #endif 322 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 324 323 325 324 for (j = 0; j < ddi->info.fmt_cnt; j++) { … … 331 330 } 332 331 333 PJ_LOG(4, (THIS_FILE, "SDL initialized")); 332 PJ_LOG(4, (THIS_FILE, "SDL %d.%d initialized", 333 version.major, version.minor)); 334 334 335 335 return PJ_SUCCESS; … … 346 346 347 347 #if SDL_VERSION_ATLEAST(1,3,0) 348 # if defined(PJ_DARWINOS) && PJ_DARWINOS!=0348 # if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 349 349 [sf->delegate performSelectorOnMainThread:@selector(sdl_quit) 350 350 withObject:nil waitUntilDone:YES]; 351 351 [sf->delegate release]; 352 352 [sf->apool release]; 353 # else353 # else /* PJ_DARWINOS */ 354 354 SDL_Quit(); 355 # endif356 #endif 355 # endif /* PJ_DARWINOS */ 356 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 357 357 358 358 return PJ_SUCCESS; … … 426 426 } 427 427 428 static void destroy_sdl(struct sdl_stream *strm, pj_bool_t destroy_win)428 static void sdl_destroy(struct sdl_stream *strm, pj_bool_t destroy_win) 429 429 { 430 430 PJ_UNUSED_ARG(destroy_win); … … 443 443 strm->texture = 0; 444 444 } 445 #endif 446 #if SDL_VERSION_ATLEAST(1,3,0) 447 # if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL445 #endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 446 #if SDL_VERSION_ATLEAST(1,3,0) 447 # if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 448 448 if (strm->gl_context) { 449 449 SDL_GL_DeleteContext(strm->gl_context); 450 450 strm->gl_context = NULL; 451 451 } 452 # endif452 # endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 453 453 if (strm->scr_tex) { 454 454 SDL_DestroyTexture(strm->scr_tex); … … 459 459 strm->renderer = NULL; 460 460 } 461 # ifndef __IPHONEOS__461 # if !defined(TARGET_OS_IPHONE) || TARGET_OS_IPHONE == 0 462 462 if (destroy_win) { 463 463 if (strm->window && … … 468 468 strm->window = NULL; 469 469 } 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 474 static pj_status_t sdl_create_view(struct sdl_stream *strm, 475 pjmedia_format *fmt) 475 476 { 476 477 sdl_fmt_info *sdl_info = get_sdl_format_info(fmt->id); … … 500 501 strm->dstrect.h = (Uint16)strm->param.disp_size.h; 501 502 502 destroy_sdl(strm, PJ_FALSE);503 sdl_destroy(strm, PJ_FALSE); 503 504 504 505 #if SDL_VERSION_ATLEAST(1,3,0) … … 511 512 if (strm->param.flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) { 512 513 /* 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); 514 515 } else { 515 516 /* Create the window where we will draw. */ … … 536 537 return PJMEDIA_EVID_SYSERR; 537 538 538 # if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL539 # if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 539 540 if (strm->param.rend_id == OPENGL_DEV_IDX) { 540 541 strm->gl_context = SDL_GL_CreateContext(strm->window); … … 543 544 SDL_GL_MakeCurrent(strm->window, strm->gl_context); 544 545 } 545 # endif546 # endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 546 547 547 548 strm->screen = SDL_GetWindowSurface(strm->window); 548 549 549 #else 550 #else /* SDL_VERSION_ATLEAST(1,3,0) */ 550 551 /* Initialize the display */ 551 552 strm->screen = SDL_SetVideoMode(strm->param.disp_size.w, 552 553 strm->param.disp_size.h, 0, ( 553 # if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL554 # if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 554 555 strm->param.rend_id == OPENGL_DEV_IDX? 555 556 SDL_OPENGL | SDL_RESIZABLE: 556 # endif557 # endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 557 558 SDL_RESIZABLE | SDL_SWSURFACE)); 558 559 if (strm->screen == NULL) … … 561 562 SDL_WM_SetCaption("pjmedia-SDL video", NULL); 562 563 563 #endif 564 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 564 565 565 566 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL … … 588 589 return PJMEDIA_EVID_SYSERR; 589 590 590 # if defined(PJ_WIN32) && PJ_WIN32 != 0591 # if !defined(PJ_DARWINOS) || PJ_DARWINOS == 0 591 592 /** 592 * O n Win32 platform, the OpenGL drawing must be in the same593 * OpenGL drawing must be in the same 593 594 * thread that calls SDL_SetVideoMode(), hence we need a buffer 594 595 * for the frame from sdl_stream_put_frame() … … 598 599 strm->tex_buf = pj_pool_alloc(strm->pool, strm->vafp.framebytes); 599 600 } 600 # endif601 # endif /* PJ_DARWINOS */ 601 602 } else 602 #endif 603 #endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 603 604 #if SDL_VERSION_ATLEAST(1,3,0) 604 605 { … … 610 611 611 612 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) */ 614 622 if (vfi->color_model == PJMEDIA_COLOR_MODEL_RGB) { 615 623 strm->surf = SDL_CreateRGBSurface(SDL_SWSURFACE, … … 629 637 return PJMEDIA_EVID_SYSERR; 630 638 } 631 #endif 639 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 632 640 633 641 return PJ_SUCCESS; 642 } 643 644 static 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 663 on_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; 634 673 } 635 674 … … 645 684 646 685 /* Re-initialize SDL */ 647 strm->status = init_sdl(strm, (strm->new_fmt? strm->new_fmt :648 649 686 strm->status = sdl_create_view(strm, (strm->new_fmt? strm->new_fmt : 687 &strm->param.fmt)); 688 650 689 if (strm->status == PJ_SUCCESS) { 651 690 if (strm->new_fmt) … … 657 696 strm->new_disp_size = NULL; 658 697 } 659 }660 661 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0662 @implementation SDLDelegate663 - (void)sdl_init664 {665 if (SDL_Init(SDL_INIT_VIDEO)) {666 PJ_LOG(4, (THIS_FILE, "Cannot initialize SDL"));667 }668 }669 670 - (void)sdl_quit671 {672 SDL_Quit();673 }674 675 - (void)detect_new_fmt676 {677 detect_fmt_change(strm);678 }679 680 - (int)sdl_create681 {682 #else683 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 #endif689 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 #endif696 697 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL698 if (strm->param.rend_id == OPENGL_DEV_IDX) {699 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);700 }701 #endif702 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!=0708 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 #endif714 strm->screen = NULL;715 }716 717 return strm->status;718 }719 720 - (void)sdl_destroy721 {722 destroy_sdl(strm, PJ_TRUE);723 }724 725 - (int)handle_event726 {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 #else736 while(!strm->is_quitting)737 #endif738 {739 SDL_Event sevent;740 pjmedia_event pevent;741 742 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL743 #if defined(PJ_WIN32) && PJ_WIN32 != 0744 if (strm->param.rend_id == OPENGL_DEV_IDX) {745 draw_gl(strm, strm->tex_buf);746 }747 #endif748 #endif749 750 detect_fmt_change(strm);751 752 /**753 * The event polling must be placed in the same thread that754 * call SDL_SetVideoMode(). Please consult the official doc of755 * 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 #else778 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 #endif787 }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 call807 * pjmedia_dev_stream_destroy() when getting WND_CLOSED808 * event809 */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!=0824 return 0;825 #endif826 on_return:827 destroy_sdl(strm, PJ_TRUE);828 #if !(SDL_VERSION_ATLEAST(1,3,0))829 SDL_Quit();830 #endif831 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 have844 * been destroyed845 */846 847 return saved_stream_status;848 698 } 849 699 … … 865 715 glVertex2i(stream->param.disp_size.w, stream->param.disp_size.h); 866 716 glEnd(); 867 # if SDL_VERSION_ATLEAST(1,3,0)717 # if SDL_VERSION_ATLEAST(1,3,0) 868 718 SDL_GL_SwapWindow(stream->window); 869 # else719 # else /* SDL_VERSION_ATLEAST(1,3,0) */ 870 720 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 726 static 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 739 static 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 840 on_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 861 static int sdl_thread(void * data) 862 { 863 struct sdl_stream *strm = (struct sdl_stream*)data; 875 864 876 865 #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 891 static pj_status_t put_frame(struct sdl_stream *stream, 892 const pjmedia_frame *frame) 893 { 887 894 pj_status_t status = PJ_SUCCESS; 888 895 … … 916 923 #if SDL_VERSION_ATLEAST(1,3,0) 917 924 SDL_UpdateWindowSurface(stream->window); 918 #else 925 #else /* SDL_VERSION_ATLEAST(1,3,0) */ 919 926 SDL_UpdateRect(stream->screen, 0, 0, 0, 0); 920 #endif 927 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 921 928 } else if (stream->overlay) { 922 929 int i, sz, offset; … … 940 947 #if SDL_VERSION_ATLEAST(1,3,0) 941 948 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) */ 948 955 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 949 956 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 */ 957 963 958 964 on_return: 965 stream->status = status; 959 966 return status; 960 967 } 961 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 962 @end 963 968 969 /* API: Put frame from stream */ 964 970 static pj_status_t sdl_stream_put_frame(pjmedia_vid_dev_stream *strm, 965 971 const pjmedia_frame *frame) 966 972 { 967 973 struct sdl_stream *stream = (struct sdl_stream*)strm; 974 975 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 968 976 stream->frame = frame; 969 977 [stream->delegate performSelectorOnMainThread:@selector(put_frame) 970 978 withObject:nil waitUntilDone:YES]; 971 979 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 } 988 985 989 986 /* API: create stream */ … … 1026 1023 goto on_error; 1027 1024 } 1028 #endif 1029 status = pj_thread_create(pool, "sdl_thread", sdl thread,1025 #endif /* PJ_DARWINOS */ 1026 status = pj_thread_create(pool, "sdl_thread", sdl_thread, 1030 1027 strm, 0, 0, &strm->sdl_thread); 1031 1028 … … 1037 1034 #if SDL_VERSION_ATLEAST(1,3,0) 1038 1035 && !strm->scr_tex 1039 #endif 1036 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 1040 1037 #if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 1041 1038 && !strm->texture 1042 #endif 1039 #endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 1043 1040 ) 1044 1041 { … … 1121 1118 if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) 1122 1119 { 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; 1125 1147 } else if (cap == PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) { 1126 1148 SDL_GetWindowPosition(strm->window, &((pjmedia_coord *)pval)->x, … … 1136 1158 return PJ_SUCCESS; 1137 1159 } 1138 #endif 1160 #else /* SDL_VERSION_ATLEAST(1,3,0) */ 1161 PJ_UNUSED_ARG(cap); 1162 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 1139 1163 1140 1164 return PJMEDIA_EVID_INVCAP; … … 1164 1188 return PJ_SUCCESS; 1165 1189 } else 1166 #endif 1190 #endif /* SDL_VERSION_ATLEAST(1,3,0) */ 1167 1191 if (cap == PJMEDIA_VID_DEV_CAP_FORMAT) { 1168 1192 strm->new_fmt = (pjmedia_format *)pval; 1169 1193 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 1170 [strm->delegate performSelectorOnMainThread:@selector(detect_new_fmt) 1194 [strm->delegate performSelectorOnMainThread: 1195 @selector(detect_fmt_change) 1171 1196 withObject:nil waitUntilDone:YES]; 1172 #endif 1197 #endif /* PJ_DARWINOS */ 1173 1198 while (strm->new_fmt) 1174 1199 pj_thread_sleep(10); … … 1184 1209 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 1185 1210 [strm->delegate performSelectorOnMainThread: 1186 @selector(detect_ new_fmt)1211 @selector(detect_fmt_change) 1187 1212 withObject:nil waitUntilDone:YES]; 1188 #endif 1213 #endif /* PJ_DARWINOS */ 1189 1214 while (strm->new_fmt) 1190 1215 pj_thread_sleep(10); … … 1206 1231 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 1207 1232 [strm->delegate performSelectorOnMainThread: 1208 @selector(detect_ new_fmt)1233 @selector(detect_fmt_change) 1209 1234 withObject:nil waitUntilDone:YES]; 1210 #endif 1235 #endif /* PJ_DARWINOS */ 1211 1236 while (strm->new_disp_size) 1212 1237 pj_thread_sleep(10); … … 1243 1268 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 1244 1269 if (![NSThread isMainThread]) 1245 #endif 1270 #endif /* PJ_DARWINOS */ 1246 1271 for (i=0; !stream->render_exited && i<50; ++i) 1247 1272 pj_thread_sleep(10); … … 1268 1293 #if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 1269 1294 if (stream->delegate) { 1270 [stream->delegate performSelectorOnMainThread:@selector(sdl_destroy)1271 withObject:nil waitUntilDone:YES];1272 1295 [stream->delegate release]; 1273 1296 stream->delegate = NULL; … … 1277 1300 stream->apool = NULL; 1278 1301 } 1279 #endif 1302 #endif /* PJ_DARWINOS */ 1280 1303 pj_pool_release(stream->pool); 1281 1304 … … 1283 1306 return PJ_SUCCESS; 1284 1307 } 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 */ 1285 1350 1286 1351 #ifdef _MSC_VER … … 1288 1353 # if PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 1289 1354 # pragma comment(lib, "OpenGL32.lib") 1290 # endif 1291 #endif 1355 # endif /* PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL */ 1356 #endif /* _MSC_VER */ 1292 1357 1293 1358
Note: See TracChangeset
for help on using the changeset viewer.