123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865 |
- #include "video.h"
- #include <multimon.h>
- #include "subtitles.h"
- #define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x))
- DDrawVideoOutput::DDrawVideoOutput() {
- lpDD=NULL;
- lpddsOverlay=NULL;
- lastresizerect.bottom=0;
- lastresizerect.top=0;
- lastresizerect.left=0;
- lastresizerect.right=0;
- lpddsPrimary=NULL;
- lpddsClipper=NULL;
- lpddsSTTemp=NULL;
- is_fullscreen=0;
- m_parent=NULL;
- initing=false;
- needchange=0;
- m_palette=NULL;
- m_lastsubtitle=NULL;
- sttmp_w=sttmp_h=0;
- subFont=NULL;
- m_sub_needremeasure=0;
- m_fontsize=0;
- memset(&winRect,0,sizeof(winRect));
- }
- DDrawVideoOutput::~DDrawVideoOutput() {
- // LPDIRECTDRAWSURFACE o=lpddsOverlay;
- lpddsOverlay=NULL;
- // if(o) o->Release();
- // if (lpddsSTTemp) lpddsSTTemp->Release();
- //if(lpddsPrimary) lpddsPrimary->Release();
- // if(lpddsClipper) lpddsClipper->Release();
- if (lpDD) lpDD->Release(); // BU added NULL check in response to talkback
- if(subFont) DeleteObject(subFont);
- if (is_fullscreen) removeFullScreen();
- }
- void DDrawVideoOutput::drawSubtitle(SubsItem *item)
- {
- m_lastsubtitle=item;
- m_sub_needremeasure=1;
- }
- int DDrawVideoOutput::create(VideoOutput *parent, int w, int h, unsigned int ptype, int flipit, double aspectratio) {
- m_lastsubtitle=NULL;
- type=ptype;
- width=w;
- height=h;
- flip=flipit;
- m_parent=parent;
- initing=true;
- HWND hwnd=parent->getHwnd();
- if (lpDD) lpDD->Release();
- lpDD=NULL;
- update_monitor_coords(parent);
- if(!m_found_devguid) DirectDrawCreate(NULL,&lpDD,NULL);
- else DirectDrawCreate(&m_devguid,&lpDD,NULL);
- if(!lpDD) {
- initing=false;
- return 0;
- }
-
- lpDD->SetCooperativeLevel(hwnd,DDSCL_NOWINDOWCHANGES|DDSCL_NORMAL);
- DDSURFACEDESC ddsd;
- INIT_DIRECTDRAW_STRUCT(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- HRESULT ddrval = lpDD->CreateSurface(&ddsd, &lpddsPrimary, NULL );
- HRESULT v=-1;
- DDSURFACEDESC DDsd={sizeof(DDsd),};
- lpddsPrimary->GetSurfaceDesc(&ddsd);
- DDsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT; //create the surface at screen depth
- DDsd.dwWidth=w;
- DDsd.dwHeight=h;
- DDsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
- if (parent->vid_ddraw) v=lpDD->CreateSurface(&DDsd, &lpddsOverlay, NULL);
- if(!parent->vid_ddraw || FAILED(v)) {
- // fall back to system memory if video mem doesn't work
- DDsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
- v=lpDD->CreateSurface(&DDsd, &lpddsOverlay, NULL);
- }
- if(FAILED(v)) {
- // this video card sucks then :)
- lpddsOverlay=NULL;
- initing=false;
- return 0;
- }
- // get the depth
- m_depth=8;
- INIT_DIRECTDRAW_STRUCT(m_ddpf);
- if(lpddsOverlay->GetPixelFormat(&m_ddpf)>=0) {
- m_depth=m_ddpf.dwRGBBitCount;
- if (m_depth==16 && m_ddpf.dwGBitMask==0x03e0) m_depth=15;
- }
- lpDD->CreateClipper(0,&lpddsClipper,NULL);
- lpddsClipper->SetHWnd(0,hwnd);
- lpddsPrimary->SetClipper(lpddsClipper);
- initing=false;
- return 1;
- }
- int DDrawVideoOutput::onPaint(HWND hwnd, HDC hdc) {
- return 0;
- }
- void DDrawVideoOutput::displayFrame(const char *buf, int size, int time) {
- DDSURFACEDESC dd={sizeof(dd),};
- if (m_parent->vid_vsync) lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
- HRESULT result;
- if ((result=lpddsOverlay->Lock(NULL,&dd,DDLOCK_WAIT,NULL)) != DD_OK) {
- needchange=1;
- return;
- }
- if(type==NSV_MAKETYPE('Y','V','1','2')) {
- const YV12_PLANES *planes=(YV12_PLANES *)buf;
- // convert yv12 to rgb
- int bytes = m_depth >> 3;
- if(m_depth==15) bytes=2;
- int i, j, y00, y01, y10, y11, u, v;
- unsigned char *pY = (unsigned char *)planes->y.baseAddr;
- unsigned char *pU = (unsigned char *)planes->u.baseAddr;
- unsigned char *pV = (unsigned char *)planes->v.baseAddr;
- unsigned char *pOut = (unsigned char*)dd.lpSurface;
- const int rvScale = 91881;
- const int guScale = -22553;
- const int gvScale = -46801;
- const int buScale = 116129;
- const int yScale = 65536;
- int addOut=dd.lPitch*2-width*bytes;
- int yrb=planes->y.rowBytes;
- int addL=dd.lPitch;
- /* LIMIT: convert a 16.16 fixed-point value to a byte, with clipping. */
- #define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
- if(flip) {
- pOut+=(dd.lPitch)*(height-1);
- addOut=-dd.lPitch*2 - width*bytes;
- addL=-addL;
- }
- for (j = 0; j <= height - 2; j += 2) {
- for (i = 0; i <= width - 2; i += 2) {
- y00 = *pY;
- y01 = *(pY + 1);
- y10 = *(pY + yrb);
- y11 = *(pY + yrb + 1);
- u = (*pU++) - 128;
- v = (*pV++) - 128;
- {
- int r, g, b;
- g = guScale * v + gvScale * u;
- r = buScale * v;
- b = rvScale * u;
- y00 *= yScale; y01 *= yScale;
- y10 *= yScale; y11 *= yScale;
- switch(m_depth) {
- case 15:
- {
- unsigned short *rgb=(unsigned short *)pOut;
- rgb[0]=((LIMIT(r+y00)>>3)<<10)|((LIMIT(g+y00)>>3)<<5)|(LIMIT(b+y00)>>3);
- rgb[1]=((LIMIT(r+y01)>>3)<<10)|((LIMIT(g+y01)>>3)<<5)|(LIMIT(b+y01)>>3);
- rgb+=addL/2;
- rgb[0]=((LIMIT(r+y10)>>3)<<10)|((LIMIT(g+y10)>>3)<<5)|(LIMIT(b+y10)>>3);
- rgb[1]=((LIMIT(r+y11)>>3)<<10)|((LIMIT(g+y11)>>3)<<5)|(LIMIT(b+y11)>>3);
- }
- break;
- case 16:
- {
- unsigned short *rgb=(unsigned short *)pOut;
- rgb[0]=((LIMIT(r+y00)>>3)<<11)|((LIMIT(g+y00)>>2)<<5)|(LIMIT(b+y00)>>3);
- rgb[1]=((LIMIT(r+y01)>>3)<<11)|((LIMIT(g+y01)>>2)<<5)|(LIMIT(b+y01)>>3);
- rgb+=addL/2;
- rgb[0]=((LIMIT(r+y10)>>3)<<11)|((LIMIT(g+y10)>>2)<<5)|(LIMIT(b+y10)>>3);
- rgb[1]=((LIMIT(r+y11)>>3)<<11)|((LIMIT(g+y11)>>2)<<5)|(LIMIT(b+y11)>>3);
- }
- break;
- case 24:
- {
- unsigned char *rgb=pOut;
- /* Write out top two pixels */
- rgb[0] = LIMIT(b+y00); rgb[1] = LIMIT(g+y00); rgb[2] = LIMIT(r+y00);
- rgb[3] = LIMIT(b+y01); rgb[4] = LIMIT(g+y01); rgb[5] = LIMIT(r+y01);
- /* Skip down to next line to write out bottom two pixels */
- rgb += addL;
- rgb[0] = LIMIT(b+y10); rgb[1] = LIMIT(g+y10); rgb[2] = LIMIT(r+y10);
- rgb[3] = LIMIT(b+y11); rgb[4] = LIMIT(g+y11); rgb[5] = LIMIT(r+y11);
- }
- break;
- case 32:
- {
- unsigned char *rgb=pOut;
- /* Write out top two pixels */
- rgb[0] = LIMIT(b+y00); rgb[1] = LIMIT(g+y00); rgb[2] = LIMIT(r+y00);
- rgb[4] = LIMIT(b+y01); rgb[5] = LIMIT(g+y01); rgb[6] = LIMIT(r+y01);
- /* Skip down to next line to write out bottom two pixels */
- rgb += addL;
- rgb[0] = LIMIT(b+y10); rgb[1] = LIMIT(g+y10); rgb[2] = LIMIT(r+y10);
- rgb[4] = LIMIT(b+y11); rgb[5] = LIMIT(g+y11); rgb[6] = LIMIT(r+y11);
- }
- break;
- }
- }
-
- pY += 2;
- pOut += 2 * bytes;
- }
- pY += yrb+yrb-width;
- pU += planes->u.rowBytes-width/2;
- pV += planes->v.rowBytes-width/2;
- pOut += addOut;
- }
- } else if(type==NSV_MAKETYPE('R','G','3','2')) {
- //FUCKO: do we need to support 8bits depth?
- switch(m_depth) {
- case 15:
- { // convert RGB32 -> RGB16 (555)
- const char *a=buf;
- char *b=(char *)dd.lpSurface;
- int l=width*4,l2=dd.lPitch;
- int ladj=l;
- if (flip) { a+=l*(height-1); ladj=-ladj; }
- for(int i=0;i<height;i++) {
- short *dest=(short *)b;
- int *src=(int *)a;
- for(int j=0;j<width;j++) {
- int c=*(src++);
- int r=c>>16;
- int g=(c>>8) & 0xff;
- int b=(c) & 0xff;
- *(dest++)=((r>>3)<<10)|((g>>3)<<5)|(b>>3);
- }
- a+=ladj; b+=l2;
- }
- }
- break;
- case 16:
- { // convert RGB32 -> RGB16
- //FUCKO: this assumes 565
- const char *a=buf;
- char *b=(char *)dd.lpSurface;
- int l=width*4,l2=dd.lPitch;
- int ladj=l;
- if (flip) { a+=l*(height-1); ladj=-ladj; }
- for(int i=0;i<height;i++) {
- short *dest=(short *)b;
- int *src=(int *)a;
- for(int j=0;j<width;j++) {
- //FUCKO: optimize here
- int c=*(src++);
- int r=c>>16;
- int g=(c>>8) & 0xff;
- int b=(c) & 0xff;
- *(dest++)=((r>>3)<<11)|((g>>2)<<5)|(b>>3);
- }
- a+=ladj; b+=l2;
- }
- }
- break;
- case 24:
- { // convert RGB32 -> RGB24
- const char *a=buf;
- char *b=(char *)dd.lpSurface;
- int l=width*4,l2=dd.lPitch;
- int ladj=l;
- if (flip) { a+=l*(height-1); ladj=-ladj; }
- for(int i=0;i<height;i++) {
- char *dest=(char *)b;
- int *src=(int *)a;
- for(int j=0;j<width;j++) {
- //FUCKO: optimize here
- int c=*(src++);
- int r=c>>16;
- int g=(c>>8) & 0xff;
- int b=(c) & 0xff;
- *dest++=b;
- *dest++=g;
- *dest++=r;
- }
- a+=ladj; b+=l2;
- }
- }
- break;
- case 32:
- { // straight RGB32 copy
- const char *a=buf;
- char *b=(char *)dd.lpSurface;
- int l=width*4,l2=dd.lPitch;
- int ladj=l;
- if (flip) { a+=l*(height-1); ladj=-ladj; }
- for(int i=0;i<height;i++) {
- memcpy(b,a,l);
- a+=ladj; b+=l2;
- }
- }
- break;
- }
- } else if(type==NSV_MAKETYPE('Y','U','Y','2') || type==NSV_MAKETYPE('U','Y','V','Y')) {
- const char *a=buf;
- char *b=(char *)dd.lpSurface;
- int l=width*2,l2=dd.lPitch;
- if(flip) {
- b+=(height-1)*l2;
- l2=-l2;
- }
- switch(m_depth) {
- case 15:
- {
- // yuy2->rgb16 (555) conversion
- unsigned char *src=(unsigned char *)buf;
- unsigned short *dst=(unsigned short *)dd.lpSurface;
- int line, col;//, linewidth;
- int y, yy;
- int u, v;
- int vr, ug, vg, ub;
- unsigned char *py, *pu, *pv;
- //linewidth = width - (width >> 1);
- py = src;
- pu = src + 1;
- pv = src + 3;
- int pitchadd=dd.lPitch/2-width;
- for (line = 0; line < height; line++) {
- for (col = 0; col < width; col++) {
- #undef LIMIT
- #define LIMIT(x) ( (x) > 0xffff ? 0xff : ( (x) <= 0xff ? 0 : ( (x) >> 8 ) ) )
- y = *py;
- yy = y << 8;
- u = *pu - 128;
- ug = 88 * u;
- ub = 454 * u;
- v = *pv - 128;
- vg = 183 * v;
- vr = 359 * v;
-
- unsigned char b=LIMIT(yy + ub );
- unsigned char g=LIMIT(yy - ug - vg);
- unsigned char r=LIMIT(yy + vr);
- *(dst++)=((r>>3)<<10)|((g>>3)<<5)|(b>>3);
-
- py += 2;
- if ( (col & 1) == 1) {
- pu += 4; // skip yvy every second y
- pv += 4; // skip yuy every second y
- }
- } // ..for col
- dst+=pitchadd;
- } /* ..for line */
- }
- break;
- case 16:
- {
- // yuy2->rgb16 conversion
- //FUCKO: only supports 565
- unsigned char *src=(unsigned char *)buf;
- unsigned short *dst=(unsigned short *)dd.lpSurface;
- int line, col;//, linewidth;
- int y, yy;
- int u, v;
- int vr, ug, vg, ub;
- unsigned char *py, *pu, *pv;
- //linewidth = width - (width >> 1);
- py = src;
- pu = src + 1;
- pv = src + 3;
- int pitchadd=dd.lPitch/2-width;
- for (line = 0; line < height; line++) {
- for (col = 0; col < width; col++) {
- #undef LIMIT
- #define LIMIT(x) ( (x) > 0xffff ? 0xff : ( (x) <= 0xff ? 0 : ( (x) >> 8 ) ) )
- y = *py;
- yy = y << 8;
- u = *pu - 128;
- ug = 88 * u;
- ub = 454 * u;
- v = *pv - 128;
- vg = 183 * v;
- vr = 359 * v;
-
- unsigned char b=LIMIT(yy + ub );
- unsigned char g=LIMIT(yy - ug - vg);
- unsigned char r=LIMIT(yy + vr);
- *(dst++)=((r>>3)<<11)|((g>>2)<<5)|(b>>3);
-
- py += 2;
- if ( (col & 1) ) {
- pu += 4; // skip yvy every second y
- pv += 4; // skip yuy every second y
- }
- } // ..for col
- dst+=pitchadd;
- } /* ..for line */ }
- break;
- case 24:
- {
- // yuy2->rgb24 conversion
- unsigned char *src=(unsigned char *)buf;
- unsigned char *dst=(unsigned char *)dd.lpSurface;
- int line, col;//, linewidth;
- int y, yy;
- int u, v;
- int vr, ug, vg, ub;
- unsigned char *py, *pu, *pv;
- //linewidth = width - (width >> 1);
- py = src;
- pu = src + 1;
- pv = src + 3;
- int pitchadd=dd.lPitch-(width*3);
- for (line = 0; line < height; line++) {
- for (col = 0; col < width; col++) {
- #undef LIMIT
- #define LIMIT(x) ( (x) > 0xffff ? 0xff : ( (x) <= 0xff ? 0 : ( (x) >> 8 ) ) )
- y = *py;
- yy = y << 8;
- u = *pu - 128;
- ug = 88 * u;
- ub = 454 * u;
- v = *pv - 128;
- vg = 183 * v;
- vr = 359 * v;
-
- *(dst++)=LIMIT(yy + ub );
- *(dst++)=LIMIT(yy - ug - vg);
- *(dst++)=LIMIT(yy + vr);
-
- py += 2;
- if ( (col & 1) == 1) {
- pu += 4; // skip yvy every second y
- pv += 4; // skip yuy every second y
- }
- } // ..for col
- dst+=pitchadd;
- } /* ..for line */ }
- break;
- case 32:
- {
- // yuy2->rgb32 conversion
- unsigned char *src=(unsigned char *)buf;
- unsigned char *dst=(unsigned char *)dd.lpSurface;
- int line, col;//, linewidth;
- int y, yy;
- int u, v;
- int vr, ug, vg, ub;
- unsigned char *py, *pu, *pv;
- //linewidth = width - (width >> 1);
- py = src;
- pu = src + 1;
- pv = src + 3;
- int pitchadd=dd.lPitch-(width*4);
- for (line = 0; line < height; line++) {
- for (col = 0; col < width; col++) {
- #undef LIMIT
- #define LIMIT(x) ( (x) > 0xffff ? 0xff : ( (x) <= 0xff ? 0 : ( (x) >> 8 ) ) )
- y = *py;
- yy = y << 8;
- u = *pu - 128;
- ug = 88 * u;
- ub = 454 * u;
- v = *pv - 128;
- vg = 183 * v;
- vr = 359 * v;
-
- *dst++ = LIMIT(yy + ub ); // b
- *dst++ = LIMIT(yy - ug - vg); // g
- *dst++ = LIMIT(yy + vr); // r
- dst++;
-
- py += 2;
- if ( (col & 1) == 1) {
- pu += 4; // skip yvy every second y
- pv += 4; // skip yuy every second y
- }
- } // ..for col
- dst+=pitchadd;
- } /* ..for line */
- }
- break;
- }
- } else if(type==NSV_MAKETYPE('R','G','2','4')) {
- //FUCKO: only ->RGB32 conversion supported
- switch(m_depth) {
- case 32:
- {
- const char *a=buf;
- char *b=(char *)dd.lpSurface;
- int l=width,l2=dd.lPitch;
- int ladj=l*3;
- if (flip) { a+=(l*3)*(height-1); ladj=-(ladj+l*3); }
- l2-=l*4;
- for(int i=0;i<height;i++) {
- //memcpy(b,a,l);
- for(int j=0;j<l;j++) {
- b[0]=a[0];
- b[1]=a[1];
- b[2]=a[2];
- b+=4; a+=3;
- }
- a+=ladj; b+=l2;
- }
- }
- break;
- }
- } else if(type==NSV_MAKETYPE('R','G','B','8') && m_palette) {
- unsigned char *d=(unsigned char *)dd.lpSurface;
- int pitch=dd.lPitch;
- unsigned char *src=(unsigned char *)buf;
- int newwidth=(width+3)&0xfffc;
- src+=newwidth*height-1;
- for(int j=0;j<height;j++) {
- switch(m_depth) {
- case 15:
- case 16:
- {
- unsigned short *dest=(unsigned short *)d;
- for(int i=0;i<newwidth;i++) {
- unsigned char c=src[-newwidth+1+i];
- RGBQUAD *rgb=&m_palette[c];
- switch(m_depth) {
- case 15: *(dest++)=((rgb->rgbRed>>3)<<10)|((rgb->rgbGreen>>3)<<5)|(rgb->rgbBlue>>3); break;
- case 16: *(dest++)=((rgb->rgbRed>>3)<<11)|((rgb->rgbGreen>>2)<<5)|(rgb->rgbBlue>>3); break;
- }
- }
- }
- break;
- case 24:
- case 32:
- {
- unsigned char *dest=d;
- for(int i=0;i<newwidth;i++) {
- unsigned char c=src[-newwidth+1+i];
- RGBQUAD *rgb=&m_palette[c];
- *dest++=rgb->rgbBlue;
- *dest++=rgb->rgbGreen;
- *dest++=rgb->rgbRed;
- if(m_depth==32) dest++;
- }
- }
- break;
- }
- d+=pitch;
- src-=newwidth;
- }
- }
- lpddsOverlay->Unlock(&dd);
- RECT r;
- HWND hwnd=m_parent->getHwnd();
- if (!IsWindow(hwnd)) return;
- if(GetParent(hwnd)) hwnd=GetParent(hwnd);
- GetClientRect(hwnd,&r);
- RECT fullr=r;
- m_parent->adjustAspect(r);
- if (r.left != lastresizerect.left || r.right != lastresizerect.right || r.top != lastresizerect.top ||
- r.bottom != lastresizerect.bottom)
- {
- if (r.left != 0)
- {
- RECT tmp={0,0,r.left,fullr.bottom};
- InvalidateRect(hwnd,&tmp,TRUE);
- }
-
- if (r.right != fullr.right)
- {
- RECT tmp={r.right,0,fullr.right,fullr.bottom};
- InvalidateRect(hwnd,&tmp,TRUE);
- }
- if (r.top != 0)
- {
- RECT tmp={r.left,0,r.right,r.top};
- InvalidateRect(hwnd,&tmp,TRUE);
- }
- if (r.bottom != fullr.bottom)
- {
- RECT tmp={r.left,r.bottom,r.right,fullr.bottom};
- InvalidateRect(hwnd,&tmp,TRUE);
- }
- lastresizerect=r;
- }
- ClientToScreen(hwnd,(LPPOINT)&r);
- ClientToScreen(hwnd,((LPPOINT)&r) + 1);
- // transform coords from windows desktop coords (where 0,0==upper-left corner of box encompassing all monitors)
- // to the coords for the monitor we're displaying on:
- r.left-=m_mon_x;
- r.right-=m_mon_x;
- r.top-=m_mon_y;
- r.bottom-=m_mon_y;
- HDC hdc = NULL;
- HDC inhdc = NULL;
- RECT srcrect;
- RECT *pSrcRect = NULL;
- if (m_parent->osdShowing() && m_parent->osdReady())
- {
- // squish image upward to make room for the OSD.
- int vert_margin = ((fullr.bottom-fullr.top) - (r.bottom-r.top)) / 2;
- int pixels_to_clip = max(0, m_parent->getOSDbarHeight() - vert_margin);
- // adjust source rectangle:
- int src_y0 = (int)(height*pixels_to_clip/(float)(r.bottom-r.top) + 0.5f);
- int src_y1 = height - src_y0;
- SetRect(&srcrect, 0, SHOW_STREAM_TITLE_AT_TOP ? src_y0 : 0, width, src_y1);
- pSrcRect = &srcrect;
- // adjust destination rectangle:
- r.bottom -= pixels_to_clip;
- #if (SHOW_STREAM_TITLE_AT_TOP)
- r.top += pixels_to_clip;
- #endif
- }
- int needst=0;
- SubsItem *mlst=m_lastsubtitle;
- if (mlst)
- {
- int curw=r.right-r.left, curh=r.bottom-r.top;
- if (!lpddsSTTemp || sttmp_w != curw || sttmp_h != curh)
- {
- if (lpddsSTTemp) lpddsSTTemp->Release();
- lpddsSTTemp=0;
- HRESULT v=-1;
- DDSURFACEDESC DDsd={sizeof(DDsd),};
- DDSURFACEDESC ddsd;
- INIT_DIRECTDRAW_STRUCT(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- lpddsPrimary->GetSurfaceDesc(&ddsd);
- DDsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT; //create the surface at screen depth
- DDsd.dwWidth=sttmp_w=curw;
- DDsd.dwHeight=sttmp_h=curh;
- DDsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
- if (m_parent->vid_ddraw) v=lpDD->CreateSurface(&DDsd, &lpddsSTTemp, NULL);
- if (!m_parent->vid_ddraw || FAILED(v)) {
- // fall back to system memory if video mem doesn't work
- DDsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
- v=lpDD->CreateSurface(&DDsd, &lpddsSTTemp, NULL);
- }
- m_sub_needremeasure=1;
- }
- if (lpddsSTTemp) needst=1;
- }
- if (needst)
- {
- HDC tmpdc=NULL;
- if (!m_parent->vid_ddraw || lpddsSTTemp->Blt(NULL,lpddsOverlay,NULL,DDBLT_WAIT,0) != DD_OK) {
- // as a last resort, BitBlt().
- HDC tmpdc2;
- if (lpddsOverlay->GetDC(&tmpdc2)==DD_OK) {
- if (lpddsSTTemp->GetDC(&tmpdc)==DD_OK) {
- BitBlt(tmpdc,0,0,sttmp_w,sttmp_h,tmpdc2,0,0,SRCCOPY);
- }
- }
- }
- if (tmpdc||lpddsSTTemp->GetDC(&tmpdc)==DD_OK)
- {
- int m_lastsubxp=mlst->xPos;
- int m_lastsubyp=mlst->yPos;
- RECT oldwinRect=winRect;
- GetClientRect(hwnd,&winRect);
- if(!subFont || ((winRect.bottom-winRect.top)!=(oldwinRect.bottom-oldwinRect.top)) || m_fontsize!=mlst->fontSize) {
- if(subFont) DeleteObject(subFont);
- m_fontsize=mlst->fontSize;
- subFont=CreateFont(14+m_fontsize+18*(winRect.bottom-winRect.top)/768,0,0,0,FW_SEMIBOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Arial");
- }
- HWND hwnd=m_parent->getHwnd();
- HGDIOBJ oldobj=SelectObject(tmpdc,subFont);
- int centerflags=0;
- if (m_lastsubxp < 127) centerflags |= DT_LEFT;
- else if (m_lastsubxp > 127) centerflags |= DT_RIGHT;
- else centerflags |= DT_CENTER;
- if (m_lastsubyp < 127) centerflags |= DT_TOP;
- else if (m_lastsubyp > 127) centerflags |= DT_BOTTOM;
- if (m_sub_needremeasure)
- {
- subRect=r;
- subRect.bottom-=subRect.top;
- subRect.right -=subRect.left;
- subRect.top=subRect.left=0;
- SIZE s;
- GetTextExtentPoint32(tmpdc,mlst->text,strlen(mlst->text),&s);
- // calcul for multiline text
- const char *p=mlst->text;
- int n=0;
- while(*p!=0) if(*p++=='\n') n++;
- if(n) s.cy*=(n+1);
-
- if (m_lastsubxp > 127) // towards the right
- {
- subRect.right -= ((subRect.right-subRect.left) * (255-m_lastsubxp)) / 256;
- }
- else if (m_lastsubxp < 127)
- {
- subRect.left += ((subRect.right-subRect.left) * m_lastsubxp) / 256;
- }
- subRect.top += ((subRect.bottom-s.cy-subRect.top) * m_lastsubyp)/255;
- subRect.bottom=subRect.top + s.cy;
- }
-
- SetBkMode(tmpdc,TRANSPARENT);
-
- // draw outline
- SetTextColor(tmpdc,RGB(0,0,0));
- int y=1;
- int x=1;
- RECT r2={subRect.left+x,subRect.top+y,subRect.right+x,subRect.bottom+y};
- DrawText(tmpdc,mlst->text,-1,&r2,centerflags|DT_NOCLIP|DT_NOPREFIX);
- // draw text
- SetTextColor(tmpdc,RGB(mlst->colorRed,mlst->colorGreen,mlst->colorBlue));
- DrawText(tmpdc,mlst->text,-1,&subRect,centerflags|DT_NOCLIP|DT_NOPREFIX);
- SelectObject(tmpdc,oldobj);
- lpddsSTTemp->ReleaseDC(tmpdc);
- }
- if (!m_parent->vid_ddraw || lpddsPrimary->Blt(&r,lpddsSTTemp,pSrcRect,DDBLT_WAIT,0) != DD_OK) {
- // as a last resort, BitBlt().
- if (lpddsSTTemp->GetDC(&inhdc)==DD_OK) {
- if (lpddsPrimary->GetDC(&hdc)==DD_OK) {
- int src_w = width;
- int src_h = pSrcRect ? (pSrcRect->bottom - pSrcRect->top) : height;
- if (r.right-r.left == src_w && r.bottom-r.top == src_h)
- BitBlt(hdc,r.left,r.top,r.right-r.left,r.bottom-r.top,inhdc,0,0,SRCCOPY);
- else
- StretchBlt(hdc,r.left,r.top,r.right-r.left,r.bottom-r.top,inhdc,0,0,src_w,src_h,SRCCOPY);
- }
- }
- }
- }
- else
- {
- if (!m_parent->vid_ddraw || lpddsPrimary->Blt(&r,lpddsOverlay,pSrcRect,DDBLT_WAIT,0) != DD_OK) {
- // as a last resort, BitBlt().
- if (lpddsOverlay->GetDC(&inhdc)==DD_OK) {
- if (lpddsPrimary->GetDC(&hdc)==DD_OK) {
- int src_w = width;
- int src_h = pSrcRect ? (pSrcRect->bottom - pSrcRect->top) : height;
- if (r.right-r.left == src_w && r.bottom-r.top == src_h)
- BitBlt(hdc,r.left,r.top,r.right-r.left,r.bottom-r.top,inhdc,0,0,SRCCOPY);
- else
- StretchBlt(hdc,r.left,r.top,r.right-r.left,r.bottom-r.top,inhdc,0,0,src_w,src_h,SRCCOPY);
- }
- }
- }
- }
- #if 0 //faster style
- if (m_parent->osdShowing())
- {
- if (hdc || lpddsPrimary->GetDC(&hdc)==DD_OK)
- m_parent->drawOSD(hdc, &r);
- }
- #endif
- if (hdc) { lpddsPrimary->ReleaseDC(hdc); hdc = NULL; }
- if (inhdc) { lpddsOverlay->ReleaseDC(inhdc); inhdc = NULL; }
- #if 1 // safer style
- if (m_parent->osdShowing())
- {
- HWND h=m_parent->getHwnd();
- hdc=GetDC(h);
- m_parent->drawOSD(hdc, &r);
- ReleaseDC(h,hdc);
- }
- #endif
- }
- void DDrawVideoOutput::goFullScreen() {
- }
- void DDrawVideoOutput::removeFullScreen() {
- }
- void DDrawVideoOutput::timerCallback() {
- }
- int DDrawVideoOutput::showOSD() {
- return 1;
- }
- void DDrawVideoOutput::hideOSD() {
- // repaint the client area, to black, where there is no video
- // (otherwise the OSD might be left painted there)
- RECT r;
- HWND hwnd=m_parent->getHwnd();
- if(GetParent(hwnd)) hwnd=GetParent(hwnd);
- GetClientRect(hwnd,&r);
- HDC hdc = GetDC(hwnd);
- if (hdc) {
- HGDIOBJ oldobj1=SelectObject(hdc,CreateSolidBrush(RGB(0,0,0)));
- HGDIOBJ oldobj2=SelectObject(hdc,CreatePen(PS_SOLID,0,RGB(0,0,0)));
- int margin = ((r.bottom - r.top) - (lastresizerect.bottom - lastresizerect.top) + 1) / 2;
- Rectangle(hdc,r.left,r.top,r.right,r.top + margin);
- Rectangle(hdc,r.left,r.bottom - margin,r.right,r.bottom);
- margin = ((r.right - r.left) - (lastresizerect.right - lastresizerect.left) + 1) / 2;
- Rectangle(hdc,r.left,r.top,r.left + margin,r.bottom);
- Rectangle(hdc,r.right - margin,r.top,r.right,r.bottom);
- DeleteObject(SelectObject(hdc,oldobj2));
- DeleteObject(SelectObject(hdc,oldobj1));
-
- ReleaseDC(hwnd, hdc);
- }
- }
- void DDrawVideoOutput::resetSubtitle()
- {
- m_lastsubtitle=0;
- }
|