diff --git a/linphone/mediastreamer2/src/videoout.c b/linphone/mediastreamer2/src/videoout.c index 43ef00b3e5d3d1fa4a7a68b88ed3a1ce1ac5955a..c31846d1a09e52374cc0278715fa69a3518c6a4f 100644 --- a/linphone/mediastreamer2/src/videoout.c +++ b/linphone/mediastreamer2/src/videoout.c @@ -254,6 +254,9 @@ typedef struct _WinDisplay{ MSPicture fb; MSDisplayEvent last_rsz; uint8_t *rgb; + uint8_t *black; + int last_rect_w; + int last_rect_h; int rgb_len; struct SwsContext *sws; bool_t new_ev; @@ -346,10 +349,14 @@ static bool_t win_display_init(MSDisplay *obj, MSPicture *fbuf){ wd->fb.planes[2]=NULL; wd->fb.planes[3]=NULL; if (wd->rgb) ms_free(wd->rgb); + if (wd->black) ms_free(wd->black); wd->rgb=NULL; + wd->black=NULL; wd->rgb_len=0; sws_freeContext(wd->sws); wd->sws=NULL; + wd->last_rect_w=0; + wd->last_rect_h=0; } else wd=(WinDisplay*)ms_new0(WinDisplay,1); @@ -389,6 +396,7 @@ static bool_t win_display_init(MSDisplay *obj, MSPicture *fbuf){ /*allocate yuv and rgb buffers*/ if (wd->fb.planes[0]) ms_free(wd->fb.planes[0]); if (wd->rgb) ms_free(wd->rgb); + if (wd->black) ms_free(wd->black); ysize=wd->fb.w*wd->fb.h; usize=ysize/4; fbuf->planes[0]=wd->fb.planes[0]=(uint8_t*)ms_malloc0(ysize+2*usize); @@ -402,6 +410,9 @@ static bool_t win_display_init(MSDisplay *obj, MSPicture *fbuf){ wd->rgb_len=ysize*3; wd->rgb=(uint8_t*)ms_malloc0(wd->rgb_len); + wd->black = (uint8_t*)ms_malloc0(wd->rgb_len); + wd->last_rect_w=0; + wd->last_rect_h=0; return TRUE; } @@ -431,6 +442,21 @@ void yuv420p_to_rgb(WinDisplay *wd, MSPicture *src, uint8_t *rgb){ } } +int gcd(int m, int n) +{ + if(n == 0) + return m; + else + return gcd(n, m % n); +} + +void reduce(int *num, int *denom) +{ + int divisor = gcd(*num, *denom); + *num /= divisor; + *denom /= divisor; +} + static void win_display_update(MSDisplay *obj){ WinDisplay *wd=(WinDisplay*)obj->data; HDC hdc; @@ -447,14 +473,7 @@ static void win_display_update(MSDisplay *obj){ memset(&bi,0,sizeof(bi)); bi.biSize=sizeof(bi); GetClientRect(wd->window,&rect); - /* - bi.biWidth=wd->fb.w; - bi.biHeight=wd->fb.h; - bi.biPlanes=3; - bi.biBitCount=12; - bi.biCompression=MAKEFOURCC('I','4','2','0'); - bi.biSizeImage=(wd->fb.w*wd->fb.h*3)/2; - */ + bi.biWidth=wd->fb.w; bi.biHeight=wd->fb.h; bi.biPlanes=1; @@ -462,16 +481,44 @@ static void win_display_update(MSDisplay *obj){ bi.biCompression=BI_RGB; bi.biSizeImage=wd->rgb_len; - //if (bi.biHeight>rect.bottom) - // bi.biHeight=rect.bottom; - //bi.biSizeImage=(bi.biWidth*bi.biHeight)*3; + if (wd->last_rect_w!=rect.right || wd->last_rect_h!=rect.bottom) + { + ret=DrawDibDraw(wd->ddh,hdc,00,00, + rect.right,rect.bottom, + &bi,wd->black, + 0,0,bi.biWidth,bi.biHeight,0); + wd->last_rect_w=rect.right; + wd->last_rect_h=rect.bottom; + } - ret=DrawDibDraw(wd->ddh,hdc,0,0, - //bi.biWidth,bi.biHeight, - rect.right,rect.bottom, + int ratiow=wd->fb.w; + int ratioh=wd->fb.h; + reduce(&ratiow, &ratioh); + int w = rect.right/ratiow*ratiow; + int h = rect.bottom/ratioh*ratioh; + + if (h*ratiow>w*ratioh) + { + w = w; + h = w*ratioh/ratiow; + } + else + { + h = h; + w = h*ratiow/ratioh; + } + + if (h*wd->fb.w!=w*wd->fb.h) + ms_error("wrong ratio"); + + ret=DrawDibDraw(wd->ddh,hdc, + rect.right/2-(w/2), + rect.bottom/2-(h/2), + w, + h, &bi,wd->rgb, - //0,0,rect.right,rect.bottom,0); 0,0,bi.biWidth,bi.biHeight,0); + if (!ret) ms_error("DrawDibDraw failed."); ReleaseDC(NULL,hdc); @@ -485,6 +532,7 @@ static void win_display_uninit(MSDisplay *obj){ if (wd->ddh) DrawDibClose(wd->ddh); if (wd->fb.planes[0]) ms_free(wd->fb.planes[0]); if (wd->rgb) ms_free(wd->rgb); + if (wd->black) ms_free(wd->black); if (wd->sws) sws_freeContext(wd->sws); ms_free(wd); }