📄 videorendereroverlay.cpp
字号:
{
if(this->lpdd && this->lpddsOverlay) {
this->lpddsOverlay->UpdateOverlay(NULL, this->lpddsPrimary, NULL, DDOVER_HIDE, NULL);
}
return MP_RESULT_OK;
}
media_video_mode_t MediaVideoRendererOverlay::GetVideoMode()
{
return this->videoMode;
}
RECT *MediaVideoRendererOverlay::GetFullscreenRects()
{
DWORD width, height;
switch(options.aspect_ratio) {
case ASPECT_RATIO_FREE:
case ASPECT_RATIO_ORIGINAL:
width = this->width;
height = this->height;
break;
case ASPECT_RATIO_TV:
case ASPECT_RATIO_WIDE:
case ASPECT_RATIO_CUSTOM:
if(aspectRatios[options.aspect_ratio].yFactor < aspectRatios[options.aspect_ratio].xFactor) {
width = this->width;
height = this->width*aspectRatios[options.aspect_ratio].yFactor/aspectRatios[options.aspect_ratio].xFactor;
}
else {
height = this->height;
width = this->height*aspectRatios[options.aspect_ratio].xFactor/aspectRatios[options.aspect_ratio].yFactor;
}
break;
}
if(this->fullscreenWidth * height / width > this->fullscreenHeight) {
this->fullRects[0].left = 0;
this->fullRects[0].right = (this->fullscreenWidth - (width * this->fullscreenHeight / height)) / 2;
this->fullRects[0].top = 0;
this->fullRects[0].bottom = this->fullscreenHeight + 10;
this->fullRects[1].left = (this->fullscreenWidth - (width * this->fullscreenHeight / height)) / 2;
this->fullRects[1].right = (width * this->fullscreenHeight / height);
this->fullRects[1].top = 0;
this->fullRects[1].bottom = this->fullscreenHeight + 10;
this->fullRects[2].left = this->fullRects[1].left + this->fullRects[1].right;
this->fullRects[2].right = (this->fullscreenWidth - (width * this->fullscreenHeight / height)) / 2;
this->fullRects[2].top = 0;
this->fullRects[2].bottom = this->fullscreenHeight + 10;
}
else {
this->fullRects[0].left = 0;
this->fullRects[0].right = this->fullscreenWidth;
this->fullRects[0].top = 0;
this->fullRects[0].bottom = (this->fullscreenHeight - (this->fullscreenWidth * height / width)) / 2;
this->fullRects[1].left = 0;
this->fullRects[1].right = this->fullscreenWidth;
this->fullRects[1].top = (this->fullscreenHeight - (this->fullscreenWidth * height / width)) / 2;
this->fullRects[1].bottom = this->fullscreenWidth * height / width;
this->fullRects[2].left = 0;
this->fullRects[2].right = this->fullscreenWidth;
this->fullRects[2].top = this->fullRects[1].top + this->fullRects[1].bottom;
this->fullRects[2].bottom = (this->fullscreenHeight - (this->fullscreenWidth * height / width)) / 2;
}
return this->fullRects;
}
MP_RESULT MediaVideoRendererOverlay::Draw(MediaBuffer *buffer, RECT *rect, int frameNumber, int invertFlag)
{
if(buffer && rect && this->lpdd && this->lpddsPrimary && this->lpddsOverlay) {
POINT pt;
HRESULT ddrval;
RECT rs, rd;
DDOVERLAYFX ovfx;
DDSURFACEDESC2 ddsd;
DDCAPS capsDrv;
unsigned int uStretchFactor1000, i;
unsigned int uDestSizeAlign, uSrcSizeAlign;
DWORD dwUpdateFlags;
subtitles_t *sub;
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddrval = this->lpddsOverlay->Lock( NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
if(invertFlag) {
for(i = 0; i < ddsd.dwHeight; i++) {
memcpy((char *) ddsd.lpSurface + i*ddsd.lPitch, ((char *) buffer->GetData()) + (this->height - i - 1)*ddsd.dwWidth*this->bpp/8, ddsd.dwWidth*this->bpp/8);
}
}
else {
if(ddsd.dwWidth == ddsd.lPitch || this->videoMode == VIDEO_MODE_YUV12) {
memcpy(ddsd.lpSurface, buffer->GetData(), this->width*this->height*this->bpp/8);
}
else {
for(i = 0; i < ddsd.dwHeight; i++) {
memcpy((char *) ddsd.lpSurface + i*ddsd.lPitch, ((char *) buffer->GetData()) + i*ddsd.dwWidth*this->bpp/8, ddsd.dwWidth*this->bpp/8);
}
}
}
this->lpddsOverlay->Unlock(NULL);
ZeroMemory(&capsDrv, sizeof(DDCAPS));
capsDrv.dwSize = sizeof(DDCAPS);
ddrval = this->lpdd->GetCaps(&capsDrv, NULL);
if (FAILED(ddrval))
return MP_RESULT_ERROR;
uStretchFactor1000 = capsDrv.dwMinOverlayStretch > 1000 ? capsDrv.dwMinOverlayStretch : 1000;
uDestSizeAlign = capsDrv.dwAlignSizeDest;
uSrcSizeAlign = capsDrv.dwAlignSizeSrc;
dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE;
if (capsDrv.dwCKeyCaps & DDCKEYCAPS_SRCOVERLAY)
dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;
ZeroMemory(&ovfx, sizeof(DDOVERLAYFX));
ovfx.dwSize = sizeof(DDOVERLAYFX);
switch(this->physicalDepth) {
case 16:
ovfx.dckSrcColorkey.dwColorSpaceLowValue = DD_OVERLAY_COLORKEY_16BPP;
ovfx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
ovfx.dckDestColorkey.dwColorSpaceLowValue = DD_OVERLAY_COLORKEY_16BPP;
ovfx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
break;
case 24:
case 32:
default:
ovfx.dckSrcColorkey.dwColorSpaceLowValue = DD_OVERLAY_COLORKEY_32BPP;
ovfx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_32BPP;
ovfx.dckDestColorkey.dwColorSpaceLowValue = DD_OVERLAY_COLORKEY_32BPP;
ovfx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_32BPP;
break;
}
pt.x = 0;
pt.y = 0;
ClientToScreen(this->hwndPlayback, &pt);
rd.left = pt.x + rect->left;
rd.top = pt.y + rect->top;
rd.right = pt.x + rect->left + (rect->right * uStretchFactor1000 + 999) / 1000;
rd.bottom = pt.y + rect->bottom * uStretchFactor1000 / 1000;
if (capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST && uDestSizeAlign)
rd.right = (int)((rd.right + uDestSizeAlign - 1) / uDestSizeAlign) * uDestSizeAlign;
rs.left = 0;
rs.top = 0;
rs.right = this->width;
rs.bottom = this->height;
if(rd.right < this->fullscreenWidth && rd.left > 0 && rd.top > 0 && rd.bottom < this->fullscreenHeight) {
}
else {
if(rd.right > this->fullscreenWidth) {
rs.right = (this->fullscreenWidth - rd.left) * this->width / (rd.right - rd.left);
rd.right = this->fullscreenWidth;
}
if(rd.left < 0) {
rs.left = -rd.left * this->width / (rd.right - rd.left);
rd.left = 0;
}
if(rd.bottom > this->fullscreenHeight) {
rs.bottom = (this->fullscreenHeight - rd.top) * this->height / (rd.bottom - rd.top);
rd.bottom = this->fullscreenHeight;
}
if(rd.top < 0) {
rs.top = -rd.top * this->height / (rd.bottom - rd.top);
rd.top = 0;
}
}
if (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC && uSrcSizeAlign)
rs.right -= rs.right % uSrcSizeAlign;
ddrval = this->lpddsOverlay->UpdateOverlay(&rs, this->lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
return MP_RESULT_OK;
}
return MP_RESULT_ERROR;
}
MP_RESULT MediaVideoRendererOverlay::DrawFullscreen(MediaBuffer *buffer, int frameNumber, int invertFlag, int desktop)
{
if(buffer && this->lpdd && this->lpddsPrimary && this->lpddsOverlay) {
HRESULT ddrval;
RECT rs, rd;
DDOVERLAYFX ovfx;
DDSURFACEDESC2 ddsd;
DDCAPS capsDrv;
unsigned int uStretchFactor1000, i;
unsigned int uDestSizeAlign, uSrcSizeAlign;
DWORD dwUpdateFlags;
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddrval = this->lpddsOverlay->Lock( NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
if(invertFlag) {
for(i = 0; i < ddsd.dwHeight; i++) {
memcpy((char *) ddsd.lpSurface + i*ddsd.lPitch, ((char *) buffer->GetData()) + (this->height - i - 1)*ddsd.dwWidth*this->bpp/8, ddsd.dwWidth*this->bpp/8);
}
}
else {
if(ddsd.dwWidth == ddsd.lPitch) {
memcpy(ddsd.lpSurface, buffer->GetData(), this->width*this->height*this->bpp/8);
}
else {
for(i = 0; i < ddsd.dwHeight; i++) {
memcpy((char *) ddsd.lpSurface + i*ddsd.lPitch, ((char *) buffer->GetData()) + i*ddsd.dwWidth*this->bpp/8, ddsd.dwWidth*this->bpp/8);
}
}
}
this->lpddsOverlay->Unlock(NULL);
ZeroMemory(&capsDrv, sizeof(DDCAPS));
capsDrv.dwSize = sizeof(DDCAPS);
ddrval = this->lpdd->GetCaps(&capsDrv, NULL);
if (FAILED(ddrval))
return MP_RESULT_ERROR;
uStretchFactor1000 = capsDrv.dwMinOverlayStretch > 1000 ? capsDrv.dwMinOverlayStretch : 1000;
uDestSizeAlign = capsDrv.dwAlignSizeDest;
uSrcSizeAlign = capsDrv.dwAlignSizeSrc;
dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE;
if (capsDrv.dwCKeyCaps & DDCKEYCAPS_SRCOVERLAY)
dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;
ZeroMemory(&ovfx, sizeof(DDOVERLAYFX));
ovfx.dwSize = sizeof(DDOVERLAYFX);
switch(this->physicalDepth) {
case 16:
ovfx.dckSrcColorkey.dwColorSpaceLowValue = DD_OVERLAY_COLORKEY_16BPP;
ovfx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
ovfx.dckDestColorkey.dwColorSpaceLowValue = DD_OVERLAY_COLORKEY_16BPP;
ovfx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
break;
case 24:
case 32:
default:
ovfx.dckSrcColorkey.dwColorSpaceLowValue = DD_OVERLAY_COLORKEY_32BPP;
ovfx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_32BPP;
ovfx.dckDestColorkey.dwColorSpaceLowValue = DD_OVERLAY_COLORKEY_32BPP;
ovfx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_32BPP;
break;
}
rs.left = 0;
rs.top = 0;
rs.right = this->width;
rs.bottom = this->height;
if (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC && uSrcSizeAlign)
rs.right -= rs.right % uSrcSizeAlign;
DWORD height;
DWORD width;
switch(options.aspect_ratio) {
case ASPECT_RATIO_FREE:
case ASPECT_RATIO_ORIGINAL:
width = this->width;
height = this->height;
break;
case ASPECT_RATIO_TV:
case ASPECT_RATIO_WIDE:
case ASPECT_RATIO_CUSTOM:
if(aspectRatios[options.aspect_ratio].yFactor < aspectRatios[options.aspect_ratio].xFactor) {
width = this->width;
height = this->width*aspectRatios[options.aspect_ratio].yFactor/aspectRatios[options.aspect_ratio].xFactor;
}
else {
height = this->height;
width = this->height*aspectRatios[options.aspect_ratio].xFactor/aspectRatios[options.aspect_ratio].yFactor;
}
break;
}
if(this->fullscreenWidth * height / width > this->fullscreenHeight) {
rd.left = (this->fullscreenWidth - (this->fullscreenHeight * width / this->height)) / 2;
rd.top = 0;
rd.right = rd.left + (this->fullscreenHeight * width / height);
rd.bottom = this->fullscreenHeight;
}
else {
rd.left = 0;
rd.top = (this->fullscreenHeight - (this->fullscreenWidth * height / width)) / 2;
rd.right = this->fullscreenWidth;
rd.bottom = rd.top + (this->fullscreenWidth * height / width);
}
if (capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST && uDestSizeAlign)
rd.right = (int)((rd.right + uDestSizeAlign - 1) / uDestSizeAlign) * uDestSizeAlign;
ddrval = this->lpddsOverlay->UpdateOverlay(&rs, this->lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
if(FAILED(ddrval)) {
return MP_RESULT_ERROR;
}
return MP_RESULT_OK;
}
return MP_RESULT_ERROR;
}
MP_RESULT MediaVideoRendererOverlay::Close()
{
if(this->lpdd) {
this->lpdd->RestoreDisplayMode();
this->lpdd->SetCooperativeLevel(this->hwndPlayback, DDSCL_NORMAL);
}
if(this->lpddsOverlay) {
this->lpddsOverlay->Release();
this->lpddsOverlay = NULL;
}
if(this->lpddsPrimary) {
this->lpddsPrimary->Release();
this->lpddsPrimary = NULL;
}
if(this->lpdd) {
this->lpdd->Release();
this->lpdd = NULL;
}
this->invertFlag = FALSE;
return MP_RESULT_ERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -