overlay_base.c
来自「betaplayer_0.096源码 tcpmp老版本」· C语言 代码 · 共 647 行 · 第 1/2 页
C
647 行
/*****************************************************************************
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: overlay_base.c 153 2004-12-20 16:46:49Z picard $
*
* BetaPlayer Overlay plugin
* Copyright (c) 2004 Gabor Kovacs
*
****************************************************************************/
#include "../stdafx.h"
#if defined(_WIN32)
#ifndef STRICT
#define STRICT
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
void OvlInvalidate( overlay_base* p, const rect* Rect, bool_t Local )
{
POINT o;
RECT r;
if (Rect->Height>0 && Rect->Width>0)
{
DEBUG_MSG5(DEBUG_VIDEO,T("Invalidate %d,%d,%d,%d (%d)"),Rect->x,Rect->y,Rect->Width,Rect->Height,Local);
if (Local)
{
// only local invalidate
o.x = 0;
o.y = 0;
ClientToScreen(p->Wnd,&o);
DEBUG_MSG2(DEBUG_VIDEO,T("Invalidate local offset %d,%d"),o.x,o.y);
r.left = Rect->x - o.x;
r.top = Rect->y - o.y;
r.right = r.left + Rect->Width;
r.bottom = r.top + Rect->Height;
InvalidateRect(p->Wnd,&r,0);
}
else
GlobalInvalidate(Rect);
}
}
void OvlValidate( overlay_base* p, const rect* Rect )
{
POINT o;
RECT r;
if (Rect->Height>0 && Rect->Width>0)
{
DEBUG_MSG4(DEBUG_VIDEO,T("Validate %d,%d,%d,%d"),Rect->x,Rect->y,Rect->Width,Rect->Height);
o.x = 0;
o.y = 0;
ClientToScreen(p->Wnd,&o);
DEBUG_MSG2(DEBUG_VIDEO,T("Validate offset %d,%d"),o.x,o.y);
r.left = Rect->x - o.x;
r.top = Rect->y - o.y;
r.right = r.left+Rect->Width;
r.bottom = r.top+Rect->Height;
ValidateRect(p->Wnd,&r);
}
}
void OvlInit(overlay_base* p,int Id,int UseDLL,int Priority)
{
if (UseDLL && !p->Module)
return;
if (!p->VMT.Enum) p->VMT.Enum = OvlEnum;
if (!p->VMT.Get) p->VMT.Get = OvlGet;
if (!p->VMT.Set) p->VMT.Set = OvlSet;
if (!p->Blit) p->Blit = OvlBlitImage;
if (!p->Update) p->Update = OvlUpdateAlign;
p->Soft = NULL;
p->Id = Id;
p->Primary = 1;
p->Overlay = 0;
memset(&p->OrigFX,0,sizeof(blitfx));
p->OrigFX.ScaleX = SCALE_ONE;
p->OrigFX.ScaleY = SCALE_ONE;
p->AutoPrerotate = 1;
p->ColorKey = -1;
p->Aspect.Num = p->Aspect.Den = 1;
NodeRegister(&p->VMT,Priority);
}
void OvlDone(overlay_base* p)
{
BlitRelease(p->Soft);
NodeUnRegister(&p->VMT);
if (p->Module)
{
FreeLibrary(p->Module);
p->Module = NULL;
}
}
int OvlEnum(overlay_base* p,int No,datadef* DataType)
{
return NodeEnumType(&No,DataType,NodeParams,FlowParams,OutputParams,VOutputParams,p->Params,NULL);
}
void OvlClearBorder( overlay_base* p )
{
planes Planes;
if (p->Lock && p->Lock(p,Planes,0) == ERR_NONE)
{
uint32_t c = RGBToFormat(0,&p->Output.Pixel);
rect Viewport;
VirtToPhy(&p->Viewport,&Viewport,&p->Output);
FillColor(Planes[0],p->Output.Pitch,Viewport.x,Viewport.y,
Viewport.Width,p->DstAlignedRect.y-Viewport.y,
p->Output.Pixel.BitCount,c);
FillColor(Planes[0],p->Output.Pitch,Viewport.x,p->DstAlignedRect.y,
p->DstAlignedRect.x-Viewport.x,p->DstAlignedRect.Height,
p->Output.Pixel.BitCount,c);
FillColor(Planes[0],p->Output.Pitch,p->DstAlignedRect.x+p->DstAlignedRect.Width,p->DstAlignedRect.y,
(Viewport.x+Viewport.Width)-(p->DstAlignedRect.x+p->DstAlignedRect.Width),p->DstAlignedRect.Height,
p->Output.Pixel.BitCount,c);
FillColor(Planes[0],p->Output.Pitch,Viewport.x,p->DstAlignedRect.y+p->DstAlignedRect.Height,
Viewport.Width,(Viewport.y+Viewport.Height)-(p->DstAlignedRect.y+p->DstAlignedRect.Height),
p->Output.Pixel.BitCount,c);
p->Unlock(p);
}
}
int OvlUpdateAlign( overlay_base* p )
{
rect OldGUI = p->GUIAlignedRect;
rect Old = p->DstAlignedRect;
rect FullScreen;
DEBUG_MSG4(DEBUG_TEST,T("BLIT Viewport:%d %d %d %d"),p->Viewport.x,p->Viewport.y,p->Viewport.Width,p->Viewport.Height);
PhyToVirt(NULL,&FullScreen,&p->Output);
p->FullScreenViewport = EqRect(&FullScreen,&p->Viewport);
VirtToPhy(&p->Viewport,&p->DstAlignedRect,&p->Output);
VirtToPhy(NULL,&p->SrcAlignedRect,&p->Input);
BlitRelease(p->Soft);
p->Soft = BlitCreate(&p->Output,&p->Input,&p->FX,&p->Caps);
p->InputHintDir = p->Input.Direction; // default
if (p->FX.Flags & BLITFX_AVOIDTEARING) // only suggest input dir when avoid tearing is set
p->InputHintDir ^= p->FX.Direction;
BlitAlign(p->Soft,&p->DstAlignedRect, &p->SrcAlignedRect );
PhyToVirt(&p->DstAlignedRect,&p->GUIAlignedRect,&p->Output);
//DEBUG_MSG4(DEBUG_TEST,T("BLIT DstRect:%d %d %d %d"),p->DstAlignedRect.x,p->DstAlignedRect.y,p->DstAlignedRect.Width,p->DstAlignedRect.Height);
//DEBUG_MSG4(DEBUG_TEST,T("BLIT SrcRect:%d %d %d %d"),p->SrcAlignedRect.x,p->SrcAlignedRect.y,p->SrcAlignedRect.Width,p->SrcAlignedRect.Height);
if (!EqRect(&Old,&p->DstAlignedRect) && p->Show && p->Primary)
{
OvlInvalidate(p,&OldGUI,0);
OvlInvalidate(p,&p->Viewport,1);
OvlValidate(p,&p->GUIAlignedRect);
}
if (p->FullScreenViewport || !p->Primary)
OvlClearBorder(p);
return ERR_NONE;
}
int OvlGet(overlay_base* p,int No,void* Data,int Size)
{
int Result = ERR_INVALID_PARAM;
switch (No)
{
case NODE_ID: GETVALUE(p->Id,int); break;
case VOUT_PRIMARY: GETVALUE(p->Primary,bool_t); break;
case VOUT_OVERLAY: GETVALUE(p->Overlay,bool_t); break;
case VOUT_INPUT|PACKET_FORMAT: GETVALUE(p->Input,video); break;
case VOUT_INPUT|PACKET_PREF_FORMAT: GETVALUE(p->PrefInput,video); break;
case VOUT_OUTPUT|PACKET_FORMAT: GETVALUE(p->Output,video); break;
case VOUT_ACCEL_IDCT: GETVALUE(p->AccelIDCT,idct*); break;
case VOUT_WND: GETVALUE(p->Wnd,void*); break;
case VOUT_VISIBLE: GETVALUE(p->Visible,bool_t); break;
case VOUT_CLIPPING: GETVALUE(p->Clipping,bool_t); break;
case VOUT_FX: GETVALUE(p->OrigFX,blitfx); break;
case VOUT_VIEWPORT: GETVALUE(p->Viewport,rect); break;
case VOUT_OUTPUTRECT: GETVALUE(p->GUIAlignedRect,rect); break;
case VOUT_AUTOPREROTATE: GETVALUE(p->AutoPrerotate,bool_t); break;
case VOUT_UPDATING: GETVALUE(p->Updating,bool_t); break;
case VOUT_PLAY: GETVALUE(p->Play,bool_t); break;
case VOUT_DIRTY: GETVALUE(p->Dirty,bool_t); break;
case VOUT_CAPS: GETVALUE(p->Caps,int); break;
case VOUT_COLORKEY: GETVALUECOND(p->ColorKey,int32_t,!p->Disabled && p->ColorKey!=-1); break;
case VOUT_ASPECT: GETVALUE(p->Aspect,fraction); break;
case VOUT_INPUT_DIR: GETVALUE(p->InputHintDir,int); break;
case VOUT_ORIENTATION:
if (Size==sizeof(int) && p->QueryOrientation && !p->DisableOrientation)
{
*(int*)Data = p->QueryOrientation(p);
Result = ERR_NONE;
}
break;
}
return Result;
}
int OvlUpdateFX(overlay_base* p, bool_t ForceUpdate)
{
blitfx LastFX = p->FX;
int Width,Height,ScaleX,ScaleY;
if (!p->Inited) return ERR_INVALID_PARAM;
if (p->Updating) return ERR_NONE;
p->FX = p->OrigFX;
p->FX.Flags |= p->SetFX;
p->FX.Flags &= ~p->ClearFX;
p->FX.Direction = CombineDir(p->InputDirection,p->OrigFX.Direction,p->Output.Direction);
p->PrefInput.Direction = CombineDir(p->FX.Direction,0,p->Input.Direction);
if (p->OrigFX.ScaleX<=0)
{
int v = p->OrigFX.ScaleX;
Width = p->Viewport.Width;
Height = p->Viewport.Height;
if ((p->InputDirection ^ p->OrigFX.Direction) & DIR_SWAPXY)
SwapInt(&Width,&Height);
if (p->PreRotate)
{
ScaleX = Scale(Width,SCALE_ONE,p->Input.Width);
ScaleY = Scale(Height,SCALE_ONE,Scale(p->Input.Height,p->Aspect.Num,p->Aspect.Den));
}
else
{
ScaleX = Scale(Width,SCALE_ONE,Scale(p->Input.Width,p->Aspect.Num,p->Aspect.Den));
ScaleY = Scale(Height,SCALE_ONE,p->Input.Height);
}
if (p->PreRotate && (v == -1 || v == -2))
v = -3-v;
if ((v == -2) || (v != -1 && ScaleX>ScaleY))
ScaleX = ScaleY;
if (v<-2)
ScaleX = Scale(ScaleX,-v,SCALE_ONE);
p->FX.ScaleY = ScaleX;
p->FX.ScaleX = Scale(ScaleX,p->Aspect.Num,p->Aspect.Den);
if (p->PreRotate)
SwapInt(&p->FX.ScaleX,&p->FX.ScaleY);
}
else
{
// prefer source horizontal scaling (because of smooth scale option)
if (p->PreRotate)
p->FX.ScaleY = Scale(p->FX.ScaleY,p->Aspect.Num,p->Aspect.Den);
else
p->FX.ScaleX = Scale(p->FX.ScaleX,p->Aspect.Num,p->Aspect.Den);
}
if (p->Output.Pixel.Flags & PF_PIXELDOUBLE)
{
p->FX.ScaleX >>= 1;
p->FX.ScaleY >>= 1;
}
if ((p->FX.Flags & BLITFX_ONLYDIFF) && p->FX.ScaleX < (SCALE_ONE*2)/3)
p->FX.Flags &= ~BLITFX_ONLYDIFF;
if (ForceUpdate || !EqBlitFX(&p->FX,&LastFX))
{
p->Update(p);
p->Dirty = 1;
p->LastTime = -1;
}
return ERR_NONE;
}
static int UpdateInputDirection(overlay_base* p,bool_t Update)
{
if (p->Inited && !p->Updating)
{
p->InputDirection = p->Input.Direction;
p->PreRotate = 0;
if (p->AutoPrerotate)
{
rect r;
PhyToVirt(NULL,&r,&p->Input);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?