git-svn-id: http://pcsx2.googlecode.com/svn/trunk@404 96395faa-99c1-11dd-bbfe-3dabce05a288

This commit is contained in:
gabest11 2009-02-04 14:21:40 +00:00
parent b0907169a4
commit 5587ee7640
158 changed files with 0 additions and 62816 deletions

View File

@ -1,441 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSdx9.h"
#include "GS.h"
#include "GSRendererHW.h"
#include "GSRendererSoft.h"
#include "GSRendererNull.h"
#include "GSWnd.h"
#include "GSSettingsDlg.h"
#define PS2E_LT_GS 0x01
#define PS2E_GS_VERSION 0x0006
#define PS2E_DLL_VERSION 0x09
#define PS2E_X86 0x01 // 32 bit
#define PS2E_X86_64 0x02 // 64 bit
EXPORT_C_(UINT32) PS2EgetLibType()
{
return PS2E_LT_GS;
}
EXPORT_C_(char*) PS2EgetLibName()
{
CString str = _T("GSdx9");
#if _M_AMD64
str += _T(" 64-bit");
#endif
CList<CString> sl;
#ifdef __INTEL_COMPILER
CString s;
s.Format(_T("Intel C++ %d.%02d"), __INTEL_COMPILER/100, __INTEL_COMPILER%100);
sl.AddTail(s);
#elif _MSC_VER
CString s;
s.Format(_T("MSVC %d.%02d"), _MSC_VER/100, _MSC_VER%100);
sl.AddTail(s);
#endif
#if _M_IX86_FP >= 2
sl.AddTail(_T("SSE2"));
#elif _M_IX86_FP >= 1
sl.AddTail(_T("SSE"));
#endif
#ifdef _OPENMP
sl.AddTail(_T("OpenMP"));
#endif
POSITION pos = sl.GetHeadPosition();
while(pos)
{
if(pos == sl.GetHeadPosition()) str += _T(" (");
str += sl.GetNext(pos);
str += pos ? _T(", ") : _T(")");
}
static char buff[256];
strncpy(buff, CStringA(str), min(countof(buff)-1, str.GetLength()));
return buff;
}
EXPORT_C_(UINT32) PS2EgetLibVersion2(UINT32 type)
{
return (PS2E_GS_VERSION<<16)|(0x00<<8)|PS2E_DLL_VERSION;
}
EXPORT_C_(UINT32) PS2EgetCpuPlatform()
{
#if _M_AMD64
return PS2E_X86_64;
#else
return PS2E_X86;
#endif
}
//////////////////
#define REPLAY_TITLE "Replay"
static HRESULT s_hrCoInit = E_FAIL;
static CGSWnd s_hWnd;
static CAutoPtr<GSState> s_gs;
static void (*s_fpGSirq)() = NULL;
BYTE* g_pBasePS2Mem = NULL;
EXPORT_C GSsetBaseMem(BYTE* pBasePS2Mem)
{
g_pBasePS2Mem = pBasePS2Mem - 0x12000000;
}
EXPORT_C_(INT32) GSinit()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return 0;
}
EXPORT_C GSshutdown()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
}
EXPORT_C_(INT32) GSopen(void* pDsp, char* Title, int multithread)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//
s_hrCoInit = ::CoInitialize(0);
ASSERT(!s_gs);
s_gs.Free();
if(!s_hWnd.Create(_T("PCSX2")))
return -1;
HRESULT hr;
switch(AfxGetApp()->GetProfileInt(_T("Settings"), _T("Renderer"), RENDERER_D3D_HW))
{
case RENDERER_D3D_HW: s_gs.Attach(new GSRendererHW(s_hWnd, hr)); break;
// case RENDERER_D3D_SW_FX: s_gs.Attach(new GSRendererSoftFX(s_hWnd, hr)); break;
case RENDERER_D3D_SW_FP: s_gs.Attach(new GSRendererSoftFP(s_hWnd, hr)); break;
case RENDERER_D3D_NULL: s_gs.Attach(new GSRendererNull(s_hWnd, hr)); break;
}
if(!s_gs || FAILED(hr))
{
s_gs.Free();
s_hWnd.DestroyWindow();
return -1;
}
//
if(!IsWindow(s_hWnd))
return -1;
*(HWND*)pDsp = s_hWnd;
s_gs->ResetDevice();
s_gs->GSirq(s_fpGSirq);
s_gs->m_fMultiThreaded = !!multithread;
if((!Title || strcmp(Title, REPLAY_TITLE) != 0)
&& AfxGetApp()->GetProfileInt(_T("Settings"), _T("RecordState"), FALSE))
{
CPath spath = AfxGetApp()->GetProfileString(_T("Settings"), _T("RecordStatePath"), _T(""));
CString fn;
fn.Format(_T("gsdx9_%s.gs"), CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S")));
spath.Append(fn);
s_gs->CaptureState(spath);
}
s_hWnd.SetWindowText(CString(Title));
s_hWnd.Show();
return 0;
}
EXPORT_C GSclose()
{
s_hWnd.Show(false);
ASSERT(s_gs);
s_gs.Free();
s_hWnd.DestroyWindow();
if(SUCCEEDED(s_hrCoInit)) ::CoUninitialize();
}
EXPORT_C GSreset()
{
s_gs->Reset();
}
EXPORT_C GSwriteCSR(UINT32 csr)
{
s_gs->WriteCSR(csr);
}
EXPORT_C GSreadFIFO(BYTE* pMem)
{
s_gs->ReadFIFO(pMem);
}
EXPORT_C GSgifTransfer1(BYTE* pMem, UINT32 addr)
{
s_gs->Transfer1(pMem, addr);
}
EXPORT_C GSgifTransfer2(BYTE* pMem, UINT32 size)
{
s_gs->Transfer2(pMem, size);
}
EXPORT_C GSgifTransfer3(BYTE* pMem, UINT32 size)
{
s_gs->Transfer3(pMem, size);
}
extern int Path3hack;
EXPORT_C GSgetLastTag(UINT64* ptag)
{
*(UINT32*)ptag = Path3hack;
Path3hack = 0;
}
EXPORT_C GSvsync(int field)
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// TODO
// Sleep(40);
s_gs->VSync(field);
break;
}
}
}
////////
EXPORT_C_(UINT32) GSmakeSnapshot(char* path)
{
return s_gs->MakeSnapshot(path);
}
EXPORT_C GSkeyEvent(keyEvent* ev)
{
if(ev->event != KEYPRESS) return;
switch(ev->key)
{
case VK_INSERT:
s_gs->Capture();
break;
case VK_DELETE:
s_gs->ToggleOSD();
break;
default:
break;
}
}
EXPORT_C_(INT32) GSfreeze(int mode, freezeData* data)
{
if(mode == FREEZE_SAVE)
{
return s_gs->Freeze(data, false);
}
else if(mode == FREEZE_SIZE)
{
return s_gs->Freeze(data, true);
}
else if(mode == FREEZE_LOAD)
{
return s_gs->Defrost(data);
}
return 0;
}
EXPORT_C GSconfigure()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if(IDOK == CGSSettingsDlg().DoModal())
{
GSshutdown();
GSinit();
}
}
EXPORT_C_(INT32) GStest()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
int ret = 0;
D3DCAPS9 caps;
ZeroMemory(&caps, sizeof(caps));
caps.PixelShaderVersion = D3DPS_VERSION(0, 0);
if(CComPtr<IDirect3D9> pD3D = Direct3DCreate9(D3D_SDK_VERSION))
{
pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, &caps);
LPCTSTR yep = _T("^_^"), nope = _T(":'(");
CString str, tmp;
if(caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
ret = -1;
tmp.Format(_T("%s Pixel Shader version %d.%d\n"),
caps.PixelShaderVersion >= D3DPS_VERSION(1, 4) ? yep : nope,
D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion),
D3DSHADER_VERSION_MINOR(caps.PixelShaderVersion));
str += tmp;
if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND))
ret = -1;
tmp.Format(_T("%s Separate Alpha Blend\n"),
!!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) ? yep : nope);
str += tmp;
if(!(caps.SrcBlendCaps & D3DPBLENDCAPS_BLENDFACTOR)
|| !(caps.DestBlendCaps & D3DPBLENDCAPS_BLENDFACTOR))
ret = -1;
tmp.Format(_T("%s Source Blend Factor\n"),
!!(caps.SrcBlendCaps & D3DPBLENDCAPS_BLENDFACTOR) ? yep : nope);
str += tmp;
tmp.Format(_T("%s Destination Blend Factor\n"),
!!(caps.DestBlendCaps & D3DPBLENDCAPS_BLENDFACTOR) ? yep : nope);
str += tmp;
AfxMessageBox(str);
}
else
{
ret = -1;
}
return ret;
}
EXPORT_C GSabout()
{
}
EXPORT_C GSirqCallback(void (*fpGSirq)())
{
s_fpGSirq = fpGSirq;
// if(s_gs) s_gs->GSirq(fpGSirq);
}
/////////////////
/*
EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
if(!GSinit())
{
HWND hWnd = NULL;
if(!GSopen((void*)&hWnd, REPLAY_TITLE))
{
if(FILE* sfp = _tfopen(lpszCmdLine, _T("rb")))
{
BYTE* buff = (BYTE*)_aligned_malloc(4*1024*1024, 16);
while(!feof(sfp))
{
switch(fgetc(sfp))
{
case ST_WRITE:
{
GS_REG mem;
UINT64 value, mask;
fread(&mem, 4, 1, sfp);
fread(&value, 8, 1, sfp);
fread(&mask, 8, 1, sfp);
switch(mask)
{
case 0xff: GSwrite8(mem, (UINT8)value); break;
case 0xffff: GSwrite16(mem, (UINT16)value); break;
case 0xffffffff: GSwrite32(mem, (UINT32)value); break;
case 0xffffffffffffffff: GSwrite64(mem, value); break;
}
break;
}
case ST_TRANSFER:
{
UINT32 size = 0;
fread(&size, 4, 1, sfp);
UINT32 len = 0;
fread(&len, 4, 1, sfp);
if(len > 4*1024*1024) {ASSERT(0); break;}
fread(buff, len, 1, sfp);
GSgifTransfer3(buff, size);
break;
}
case ST_VSYNC:
GSvsync();
break;
}
}
_aligned_free(buff);
}
GSclose();
}
GSshutdown();
}
}
*/

View File

@ -1,945 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* Special Notes:
*
* Register definitions and most of the enums originate from sps2dev-0.4.0
* Copyright (C) 2002 Terratron Technologies Inc. All Rights Reserved.
*
*/
#pragma once
//
#pragma pack(push, 1)
//
// sps2registers.h
//
enum GS_REG
{
GS_PMODE = 0x12000000,
GS_SMODE1 = 0x12000010,
GS_SMODE2 = 0x12000020,
GS_SRFSH = 0x12000030,
GS_SYNCH1 = 0x12000040,
GS_SYNCH2 = 0x12000050,
GS_SYNCV = 0x12000060,
GS_DISPFB1 = 0x12000070,
GS_DISPLAY1 = 0x12000080,
GS_DISPFB2 = 0x12000090,
GS_DISPLAY2 = 0x120000a0,
GS_EXTBUF = 0x120000b0,
GS_EXTDATA = 0x120000c0,
GS_EXTWRITE = 0x120000d0,
GS_BGCOLOR = 0x120000e0,
GS_UNKNOWN = 0x12000400,
GS_CSR = 0x12001000,
GS_IMR = 0x12001010,
GS_BUSDIR = 0x12001040,
GS_SIGLBLID = 0x12001080
};
enum GS_PRIM
{
GS_POINTLIST = 0,
GS_LINELIST = 1,
GS_LINESTRIP = 2,
GS_TRIANGLELIST = 3,
GS_TRIANGLESTRIP = 4,
GS_TRIANGLEFAN = 5,
GS_SPRITE = 6,
GS_INVALID = 7,
};
enum GIF_REG
{
GIF_REG_PRIM = 0x00,
GIF_REG_RGBA = 0x01,
GIF_REG_STQ = 0x02,
GIF_REG_UV = 0x03,
GIF_REG_XYZF2 = 0x04,
GIF_REG_XYZ2 = 0x05,
GIF_REG_TEX0_1 = 0x06,
GIF_REG_TEX0_2 = 0x07,
GIF_REG_CLAMP_1 = 0x08,
GIF_REG_CLAMP_2 = 0x09,
GIF_REG_FOG = 0x0a,
GIF_REG_XYZF3 = 0x0c,
GIF_REG_XYZ3 = 0x0d,
GIF_REG_A_D = 0x0e,
GIF_REG_NOP = 0x0f,
};
enum GIF_A_D_REG
{
GIF_A_D_REG_PRIM = 0x00,
GIF_A_D_REG_RGBAQ = 0x01,
GIF_A_D_REG_ST = 0x02,
GIF_A_D_REG_UV = 0x03,
GIF_A_D_REG_XYZF2 = 0x04,
GIF_A_D_REG_XYZ2 = 0x05,
GIF_A_D_REG_TEX0_1 = 0x06,
GIF_A_D_REG_TEX0_2 = 0x07,
GIF_A_D_REG_CLAMP_1 = 0x08,
GIF_A_D_REG_CLAMP_2 = 0x09,
GIF_A_D_REG_FOG = 0x0a,
GIF_A_D_REG_XYZF3 = 0x0c,
GIF_A_D_REG_XYZ3 = 0x0d,
GIF_A_D_REG_NOP = 0x0f,
GIF_A_D_REG_TEX1_1 = 0x14,
GIF_A_D_REG_TEX1_2 = 0x15,
GIF_A_D_REG_TEX2_1 = 0x16,
GIF_A_D_REG_TEX2_2 = 0x17,
GIF_A_D_REG_XYOFFSET_1 = 0x18,
GIF_A_D_REG_XYOFFSET_2 = 0x19,
GIF_A_D_REG_PRMODECONT = 0x1a,
GIF_A_D_REG_PRMODE = 0x1b,
GIF_A_D_REG_TEXCLUT = 0x1c,
GIF_A_D_REG_SCANMSK = 0x22,
GIF_A_D_REG_MIPTBP1_1 = 0x34,
GIF_A_D_REG_MIPTBP1_2 = 0x35,
GIF_A_D_REG_MIPTBP2_1 = 0x36,
GIF_A_D_REG_MIPTBP2_2 = 0x37,
GIF_A_D_REG_TEXA = 0x3b,
GIF_A_D_REG_FOGCOL = 0x3d,
GIF_A_D_REG_TEXFLUSH = 0x3f,
GIF_A_D_REG_SCISSOR_1 = 0x40,
GIF_A_D_REG_SCISSOR_2 = 0x41,
GIF_A_D_REG_ALPHA_1 = 0x42,
GIF_A_D_REG_ALPHA_2 = 0x43,
GIF_A_D_REG_DIMX = 0x44,
GIF_A_D_REG_DTHE = 0x45,
GIF_A_D_REG_COLCLAMP = 0x46,
GIF_A_D_REG_TEST_1 = 0x47,
GIF_A_D_REG_TEST_2 = 0x48,
GIF_A_D_REG_PABE = 0x49,
GIF_A_D_REG_FBA_1 = 0x4a,
GIF_A_D_REG_FBA_2 = 0x4b,
GIF_A_D_REG_FRAME_1 = 0x4c,
GIF_A_D_REG_FRAME_2 = 0x4d,
GIF_A_D_REG_ZBUF_1 = 0x4e,
GIF_A_D_REG_ZBUF_2 = 0x4f,
GIF_A_D_REG_BITBLTBUF = 0x50,
GIF_A_D_REG_TRXPOS = 0x51,
GIF_A_D_REG_TRXREG = 0x52,
GIF_A_D_REG_TRXDIR = 0x53,
GIF_A_D_REG_HWREG = 0x54,
GIF_A_D_REG_SIGNAL = 0x60,
GIF_A_D_REG_FINISH = 0x61,
GIF_A_D_REG_LABEL = 0x62,
};
enum GIF_FLG
{
GIF_FLG_PACKED = 0,
GIF_FLG_REGLIST = 1,
GIF_FLG_IMAGE = 2,
GIF_FLG_IMAGE2 = 3
};
enum PSM
{
PSM_PSMCT32 = 0,
PSM_PSMCT24 = 1,
PSM_PSMCT16 = 2,
PSM_PSMCT16S = 10,
PSM_PSMT8 = 19,
PSM_PSMT4 = 20,
PSM_PSMT8H = 27,
PSM_PSMT4HL = 36,
PSM_PSMT4HH = 44,
PSM_PSMZ32 = 48,
PSM_PSMZ24 = 49,
PSM_PSMZ16 = 50,
PSM_PSMZ16S = 58,
};
//
// sps2regstructs.h
//
#define REG64(name) \
union name \
{ \
UINT64 i64; \
UINT32 ai32[2]; \
struct { \
#define REG128(name)\
union name \
{ \
UINT64 ai64[2]; \
UINT32 ai32[4]; \
struct { \
#define REG64_(prefix, name) REG64(prefix##name)
#define REG128_(prefix, name) REG128(prefix##name)
#define REG_END }; };
#define REG_END2 };
#define REG64_SET(name) \
union name \
{ \
UINT64 i64; \
UINT32 ai32[2]; \
#define REG128_SET(name)\
union name \
{ \
UINT64 ai64[2]; \
UINT32 ai32[4]; \
#define REG_SET_END };
REG64_(GSReg, BGCOLOR)
UINT32 R:8;
UINT32 G:8;
UINT32 B:8;
UINT32 _PAD1:8;
UINT32 _PAD2:32;
REG_END
REG64_(GSReg, BUSDIR)
UINT32 DIR:1;
UINT32 _PAD1:31;
UINT32 _PAD2:32;
REG_END
REG64_(GSReg, CSR)
UINT32 rSIGNAL:1;
UINT32 rFINISH:1;
UINT32 rHSINT:1;
UINT32 rVSINT:1;
UINT32 rEDWINT:1;
UINT32 rZERO1:1;
UINT32 rZERO2:1;
UINT32 r_PAD1:1;
UINT32 rFLUSH:1;
UINT32 rRESET:1;
UINT32 r_PAD2:2;
UINT32 rNFIELD:1;
UINT32 rFIELD:1;
UINT32 rFIFO:2;
UINT32 rREV:8;
UINT32 rID:8;
UINT32 wSIGNAL:1;
UINT32 wFINISH:1;
UINT32 wHSINT:1;
UINT32 wVSINT:1;
UINT32 wEDWINT:1;
UINT32 wZERO1:1;
UINT32 wZERO2:1;
UINT32 w_PAD1:1;
UINT32 wFLUSH:1;
UINT32 wRESET:1;
UINT32 w_PAD2:2;
UINT32 wNFIELD:1;
UINT32 wFIELD:1;
UINT32 wFIFO:2;
UINT32 wREV:8;
UINT32 wID:8;
REG_END
REG64_(GSReg, DISPFB) // (-1/2)
UINT32 FBP:9;
UINT32 FBW:6;
UINT32 PSM:5;
UINT32 _PAD:12;
UINT32 DBX:11;
UINT32 DBY:11;
UINT32 _PAD2:10;
REG_END
REG64_(GSReg, DISPLAY) // (-1/2)
UINT32 DX:12;
UINT32 DY:11;
UINT32 MAGH:4;
UINT32 MAGV:2;
UINT32 _PAD:3;
UINT32 DW:12;
UINT32 DH:11;
UINT32 _PAD2:9;
REG_END
REG64_(GSReg, EXTBUF)
UINT32 EXBP:14;
UINT32 EXBW:6;
UINT32 FBIN:2;
UINT32 WFFMD:1;
UINT32 EMODA:2;
UINT32 EMODC:2;
UINT32 _PAD1:5;
UINT32 WDX:11;
UINT32 WDY:11;
UINT32 _PAD2:10;
REG_END
REG64_(GSReg, EXTDATA)
UINT32 SX:12;
UINT32 SY:11;
UINT32 SMPH:4;
UINT32 SMPV:2;
UINT32 _PAD1:3;
UINT32 WW:12;
UINT32 WH:11;
UINT32 _PAD2:9;
REG_END
REG64_(GSReg, EXTWRITE)
UINT32 WRITE:1;
UINT32 _PAD1:31;
UINT32 _PAD2:32;
REG_END
REG64_(GSReg, IMR)
UINT32 _PAD1:8;
UINT32 SIGMSK:1;
UINT32 FINISHMSK:1;
UINT32 HSMSK:1;
UINT32 VSMSK:1;
UINT32 EDWMSK:1;
UINT32 _PAD2:19;
UINT32 _PAD3:32;
REG_END
REG64_(GSReg, PMODE)
UINT32 EN1:1;
UINT32 EN2:1;
UINT32 CRTMD:3;
UINT32 MMOD:1;
UINT32 AMOD:1;
UINT32 SLBG:1;
UINT32 ALP:8;
UINT32 _PAD:16;
UINT32 _PAD1:32;
REG_END
REG64_(GSReg, SIGLBLID)
UINT32 SIGID:32;
UINT32 LBLID:32;
REG_END
REG64_(GSReg, SMODE1)
UINT32 RC:3;
UINT32 LC:7;
UINT32 T1248:2;
UINT32 SLCK:1;
UINT32 CMOD:2;
UINT32 EX:1;
UINT32 PRST:1;
UINT32 SINT:1;
UINT32 XPCK:1;
UINT32 PCK2:2;
UINT32 SPML:4;
UINT32 GCONT:1;
UINT32 PHS:1;
UINT32 PVS:1;
UINT32 PEHS:1;
UINT32 PEVS:1;
UINT32 CLKSEL:2;
UINT32 NVCK:1;
UINT32 SLCK2:1;
UINT32 VCKSEL:2;
UINT32 VHP:1;
UINT32 _PAD1:27;
REG_END
REG64_(GSReg, SMODE2)
UINT32 INT:1;
UINT32 FFMD:1;
UINT32 DPMS:2;
UINT32 _PAD2:28;
UINT32 _PAD3:32;
REG_END
REG64_SET(GSReg)
GSRegBGCOLOR BGCOLOR;
GSRegBUSDIR BUSDIR;
GSRegCSR CSR;
GSRegDISPFB DISPFB;
GSRegDISPLAY DISPLAY;
GSRegEXTBUF EXTBUF;
GSRegEXTDATA EXTDATA;
GSRegEXTWRITE EXTWRITE;
GSRegIMR IMR;
GSRegPMODE PMODE;
GSRegSIGLBLID SIGLBLID;
GSRegSMODE1 SMODE1;
GSRegSMODE2 SMODE2;
REG_SET_END
//
// sps2tags.h
//
#define SET_GIF_REG(gifTag, iRegNo, uiValue) \
{((GIFTag*)&gifTag)->ai64[1] |= (((uiValue) & 0xf) << ((iRegNo) << 2));}
#ifdef _M_AMD64
#define GET_GIF_REG(tag, reg) \
(((tag).ai64[1] >> ((reg) << 2)) & 0xf)
#else
#define GET_GIF_REG(tag, reg) \
(((tag).ai32[2 + ((reg) >> 3)] >> (((reg) & 7) << 2)) & 0xf)
#endif
//
// GIFTag
REG128(GIFTag)
UINT32 NLOOP:15;
UINT32 EOP:1;
UINT32 _PAD1:16;
UINT32 _PAD2:14;
UINT32 PRE:1;
UINT32 PRIM:11;
UINT32 FLG:2; // enum GIF_FLG
UINT32 NREG:4;
UINT64 REGS:64;
REG_END
// GIFReg
REG64_(GIFReg, ALPHA)
UINT32 A:2;
UINT32 B:2;
UINT32 C:2;
UINT32 D:2;
UINT32 _PAD1:24;
UINT32 FIX:8;
UINT32 _PAD2:24;
REG_END
REG64_(GIFReg, BITBLTBUF)
UINT32 SBP:14;
UINT32 _PAD1:2;
UINT32 SBW:6;
UINT32 _PAD2:2;
UINT32 SPSM:6;
UINT32 _PAD3:2;
UINT32 DBP:14;
UINT32 _PAD4:2;
UINT32 DBW:6;
UINT32 _PAD5:2;
UINT32 DPSM:6;
UINT32 _PAD6:2;
REG_END
REG64_(GIFReg, CLAMP)
UINT64 WMS:2;
UINT64 WMT:2;
UINT64 MINU:10;
UINT64 MAXU:10;
UINT64 MINV:10;
UINT64 MAXV:10;
UINT64 _PAD:20;
REG_END
REG64_(GIFReg, COLCLAMP)
UINT32 CLAMP:1;
UINT32 _PAD1:31;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, DIMX)
UINT32 DM00:3;
UINT32 _PAD00:1;
UINT32 DM01:3;
UINT32 _PAD01:1;
UINT32 DM02:3;
UINT32 _PAD02:1;
UINT32 DM03:3;
UINT32 _PAD03:1;
UINT32 DM10:3;
UINT32 _PAD10:1;
UINT32 DM11:3;
UINT32 _PAD11:1;
UINT32 DM12:3;
UINT32 _PAD12:1;
UINT32 DM13:3;
UINT32 _PAD13:1;
UINT32 DM20:3;
UINT32 _PAD20:1;
UINT32 DM21:3;
UINT32 _PAD21:1;
UINT32 DM22:3;
UINT32 _PAD22:1;
UINT32 DM23:3;
UINT32 _PAD23:1;
UINT32 DM30:3;
UINT32 _PAD30:1;
UINT32 DM31:3;
UINT32 _PAD31:1;
UINT32 DM32:3;
UINT32 _PAD32:1;
UINT32 DM33:3;
UINT32 _PAD33:1;
REG_END
REG64_(GIFReg, DTHE)
UINT32 DTHE:1;
UINT32 _PAD1:31;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, FBA)
UINT32 FBA:1;
UINT32 _PAD1:31;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, FINISH)
UINT32 _PAD1:32;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, FOG)
UINT32 _PAD1:32;
UINT32 _PAD2:24;
UINT32 F:8;
REG_END
REG64_(GIFReg, FOGCOL)
UINT32 FCR:8;
UINT32 FCG:8;
UINT32 FCB:8;
UINT32 _PAD1:8;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, FRAME)
UINT32 FBP:9;
UINT32 _PAD1:7;
UINT32 FBW:6;
UINT32 _PAD2:2;
UINT32 PSM:6;
UINT32 _PAD3:2;
UINT32 FBMSK:32;
REG_END2
UINT32 Block() {return FBP<<5;}
REG_END2
REG64_(GIFReg, HWREG)
UINT32 DATA_LOWER:32;
UINT32 DATA_UPPER:32;
REG_END
REG64_(GIFReg, LABEL)
UINT32 ID:32;
UINT32 IDMSK:32;
REG_END
REG64_(GIFReg, MIPTBP1)
UINT64 TBP1:14;
UINT64 TBW1:6;
UINT64 TBP2:14;
UINT64 TBW2:6;
UINT64 TBP3:14;
UINT64 TBW3:6;
UINT64 _PAD:4;
REG_END
REG64_(GIFReg, MIPTBP2)
UINT64 TBP4:14;
UINT64 TBW4:6;
UINT64 TBP5:14;
UINT64 TBW5:6;
UINT64 TBP6:14;
UINT64 TBW6:6;
UINT64 _PAD:4;
REG_END
REG64_(GIFReg, NOP)
UINT32 _PAD1:32;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, PABE)
UINT32 PABE:1;
UINT32 _PAD1:31;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, PRIM)
UINT32 PRIM:3;
UINT32 IIP:1;
UINT32 TME:1;
UINT32 FGE:1;
UINT32 ABE:1;
UINT32 AA1:1;
UINT32 FST:1;
UINT32 CTXT:1;
UINT32 FIX:1;
UINT32 _PAD1:21;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, PRMODE)
UINT32 _PRIM:3;
UINT32 IIP:1;
UINT32 TME:1;
UINT32 FGE:1;
UINT32 ABE:1;
UINT32 AA1:1;
UINT32 FST:1;
UINT32 CTXT:1;
UINT32 FIX:1;
UINT32 _PAD2:21;
UINT32 _PAD3:32;
REG_END
REG64_(GIFReg, PRMODECONT)
UINT32 AC:1;
UINT32 _PAD1:31;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, RGBAQ)
UINT32 R:8;
UINT32 G:8;
UINT32 B:8;
UINT32 A:8;
float Q;
REG_END
REG64_(GIFReg, SCANMSK)
UINT32 MSK:2;
UINT32 _PAD1:30;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, SCISSOR)
UINT32 SCAX0:11;
UINT32 _PAD1:5;
UINT32 SCAX1:11;
UINT32 _PAD2:5;
UINT32 SCAY0:11;
UINT32 _PAD3:5;
UINT32 SCAY1:11;
UINT32 _PAD4:5;
REG_END
REG64_(GIFReg, SIGNAL)
UINT32 ID:32;
UINT32 IDMSK:32;
REG_END
REG64_(GIFReg, ST)
float S;
float T;
REG_END
REG64_(GIFReg, TEST)
UINT32 ATE:1;
UINT32 ATST:3;
UINT32 AREF:8;
UINT32 AFAIL:2;
UINT32 DATE:1;
UINT32 DATM:1;
UINT32 ZTE:1;
UINT32 ZTST:2;
UINT32 _PAD1:13;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, TEX0)
UINT64 TBP0:14;
UINT64 TBW:6;
UINT64 PSM:6;
UINT64 TW:4;
UINT64 TH:4;
UINT64 TCC:1;
UINT64 TFX:2;
UINT64 CBP:14;
UINT64 CPSM:4;
UINT64 CSM:1;
UINT64 CSA:5;
UINT64 CLD:3;
REG_END
REG64_(GIFReg, TEX1)
UINT32 LCM:1;
UINT32 _PAD1:1;
UINT32 MXL:3;
UINT32 MMAG:1;
UINT32 MMIN:3;
UINT32 MTBA:1;
UINT32 _PAD2:9;
UINT32 L:2;
UINT32 _PAD3:11;
UINT32 K:12;
UINT32 _PAD4:20;
REG_END
REG64_(GIFReg, TEX2)
UINT32 _PAD1:20;
UINT32 PSM:6;
UINT32 _PAD2:6;
UINT32 _PAD3:5;
UINT32 CBP:14;
UINT32 CPSM:4;
UINT32 CSM:1;
UINT32 CSA:5;
UINT32 CLD:3;
REG_END
REG64_(GIFReg, TEXA)
UINT32 TA0:8;
UINT32 _PAD1:7;
UINT32 AEM:1;
UINT32 _PAD2:16;
UINT32 TA1:8;
UINT32 _PAD3:24;
REG_END
REG64_(GIFReg, TEXCLUT)
UINT32 CBW:6;
UINT32 COU:6;
UINT32 COV:10;
UINT32 _PAD1:10;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, TEXFLUSH)
UINT32 _PAD1:32;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, TRXDIR)
UINT32 XDIR:2;
UINT32 _PAD1:30;
UINT32 _PAD2:32;
REG_END
REG64_(GIFReg, TRXPOS)
UINT32 SSAX:11;
UINT32 _PAD1:5;
UINT32 SSAY:11;
UINT32 _PAD2:5;
UINT32 DSAX:11;
UINT32 _PAD3:5;
UINT32 DSAY:11;
UINT32 DIR:2;
UINT32 _PAD4:3;
REG_END
REG64_(GIFReg, TRXREG)
UINT32 RRW:12;
UINT32 _PAD1:20;
UINT32 RRH:12;
UINT32 _PAD2:20;
REG_END
REG64_(GIFReg, UV)
UINT32 U:14;
UINT32 _PAD1:2;
UINT32 V:14;
UINT32 _PAD2:2;
UINT32 _PAD3:32;
REG_END
REG64_(GIFReg, XYOFFSET)
UINT32 OFX:16;
UINT32 _PAD1:16;
UINT32 OFY:16;
UINT32 _PAD2:16;
REG_END
REG64_(GIFReg, XYZ)
UINT32 X:16;
UINT32 Y:16;
UINT32 Z:32;
REG_END
REG64_(GIFReg, XYZF)
UINT32 X:16;
UINT32 Y:16;
UINT32 Z:24;
UINT32 F:8;
REG_END
REG64_(GIFReg, ZBUF)
UINT32 ZBP:9;
UINT32 _PAD1:15;
// UINT32 PSM:4;
// UINT32 _PAD2:4;
UINT32 PSM:6;
UINT32 _PAD2:2;
UINT32 ZMSK:1;
UINT32 _PAD3:31;
REG_END
REG64_SET(GIFReg)
GIFRegALPHA ALPHA;
GIFRegBITBLTBUF BITBLTBUF;
GIFRegCLAMP CLAMP;
GIFRegCOLCLAMP COLCLAMP;
GIFRegDIMX DIMX;
GIFRegDTHE DTHE;
GIFRegFBA FBA;
GIFRegFINISH FINISH;
GIFRegFOG FOG;
GIFRegFOGCOL FOGCOL;
GIFRegFRAME FRAME;
GIFRegHWREG HWREG;
GIFRegLABEL LABEL;
GIFRegMIPTBP1 MIPTBP1;
GIFRegMIPTBP2 MIPTBP2;
GIFRegNOP NOP;
GIFRegPABE PABE;
GIFRegPRIM PRIM;
GIFRegPRMODE PRMODE;
GIFRegPRMODECONT PRMODECONT;
GIFRegRGBAQ RGBAQ;
GIFRegSCANMSK SCANMSK;
GIFRegSCISSOR SCISSOR;
GIFRegSIGNAL SIGNAL;
GIFRegST ST;
GIFRegTEST TEST;
GIFRegTEX0 TEX0;
GIFRegTEX1 TEX1;
GIFRegTEX2 TEX2;
GIFRegTEXA TEXA;
GIFRegTEXCLUT TEXCLUT;
GIFRegTEXFLUSH TEXFLUSH;
GIFRegTRXDIR TRXDIR;
GIFRegTRXPOS TRXPOS;
GIFRegTRXREG TRXREG;
GIFRegUV UV;
GIFRegXYOFFSET XYOFFSET;
GIFRegXYZ XYZ;
GIFRegXYZF XYZF;
GIFRegZBUF ZBUF;
REG_SET_END
// GIFPacked
REG128_(GIFPacked, PRIM)
UINT32 PRIM:11;
UINT32 _PAD1:21;
UINT32 _PAD2:32;
UINT32 _PAD3:32;
UINT32 _PAD4:32;
REG_END
REG128_(GIFPacked, RGBA)
UINT32 R:8;
UINT32 _PAD1:24;
UINT32 G:8;
UINT32 _PAD2:24;
UINT32 B:8;
UINT32 _PAD3:24;
UINT32 A:8;
UINT32 _PAD4:24;
REG_END
REG128_(GIFPacked, STQ)
float S;
float T;
float Q;
UINT32 _PAD1:32;
REG_END
REG128_(GIFPacked, UV)
UINT32 U:14;
UINT32 _PAD1:18;
UINT32 V:14;
UINT32 _PAD2:18;
UINT32 _PAD3:32;
UINT32 _PAD4:32;
REG_END
REG128_(GIFPacked, XYZF2)
UINT32 X:16;
UINT32 _PAD1:16;
UINT32 Y:16;
UINT32 _PAD2:16;
UINT32 _PAD3:4;
UINT32 Z:24;
UINT32 _PAD4:4;
UINT32 _PAD5:4;
UINT32 F:8;
UINT32 _PAD6:3;
UINT32 ADC:1;
UINT32 _PAD7:16;
REG_END
REG128_(GIFPacked, XYZ2)
UINT32 X:16;
UINT32 _PAD1:16;
UINT32 Y:16;
UINT32 _PAD2:16;
UINT32 Z:32;
UINT32 _PAD3:15;
UINT32 ADC:1;
UINT32 _PAD4:16;
REG_END
REG128_(GIFPacked, FOG)
UINT32 _PAD1:32;
UINT32 _PAD2:32;
UINT32 _PAD3:32;
UINT32 _PAD4:4;
UINT32 F:8;
UINT32 _PAD5:20;
REG_END
REG128_(GIFPacked, A_D)
UINT64 DATA:64;
UINT32 ADDR:8; // enum GIF_A_D_REG
UINT32 _PAD1:24;
UINT32 _PAD2:32;
REG_END
REG128_(GIFPacked, NOP)
UINT32 _PAD1:32;
UINT32 _PAD2:32;
UINT32 _PAD3:32;
UINT32 _PAD4:32;
REG_END
REG128_SET(GIFPackedReg)
GIFReg r;
GIFPackedPRIM PRIM;
GIFPackedRGBA RGBA;
GIFPackedSTQ STQ;
GIFPackedUV UV;
GIFPackedXYZF2 XYZF2;
GIFPackedXYZ2 XYZ2;
GIFPackedFOG FOG;
GIFPackedA_D A_D;
GIFPackedNOP NOP;
REG_SET_END
#pragma pack(pop)
enum {KEYPRESS=1, KEYRELEASE=2};
struct keyEvent {UINT32 key, event;};
enum {FREEZE_LOAD=0, FREEZE_SAVE=1, FREEZE_SIZE=2};
struct freezeData {int size; BYTE* data;};
enum stateType {ST_WRITE, ST_TRANSFER, ST_VSYNC};

View File

@ -1,309 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "StdAfx.h"
#include "GSCapture.h"
#include "GSCaptureDlg.h"
#include <initguid.h>
#include <uuids.h>
//
// GSSource
//
#ifdef __INTEL_COMPILER
interface __declspec(uuid("59C193BB-C520-41F3-BC1D-E245B80A86FA"))
#else
[uuid("59C193BB-C520-41F3-BC1D-E245B80A86FA")] interface
#endif
IGSSource : public IUnknown
{
STDMETHOD(DeliverNewSegment)() PURE;
STDMETHOD(DeliverFrame)(D3DLOCKED_RECT& r) PURE;
STDMETHOD(DeliverEOS)() PURE;
};
#ifdef __INTEL_COMPILER
class __declspec(uuid("F8BB6F4F-0965-4ED4-BA74-C6A01E6E6C77"))
#else
[uuid("F8BB6F4F-0965-4ED4-BA74-C6A01E6E6C77")] class
#endif
GSSource : public CBaseFilter, public IGSSource
{
CCritSec m_csLock;
CAutoPtr<CBaseOutputPin> m_pOutput;
CSize m_size;
REFERENCE_TIME m_rtAvgTimePerFrame, m_rtNow;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
return
QI(IGSSource)
__super::NonDelegatingQueryInterface(riid, ppv);
}
class GSSourceOutputPin : public CBaseOutputPin
{
CMediaType m_mt;
public:
GSSourceOutputPin(CMediaType& mt, CBaseFilter* pFilter, CCritSec* pLock, HRESULT& hr)
: CBaseOutputPin("GSSourceOutputPin", pFilter, pLock, &hr, L"Output")
, m_mt(mt)
{
}
HRESULT GSSourceOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
{
ASSERT(pAlloc && pProperties);
HRESULT hr;
pProperties->cBuffers = 1;
pProperties->cbBuffer = m_mt.lSampleSize;
ALLOCATOR_PROPERTIES Actual;
if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr;
if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL;
ASSERT(Actual.cBuffers == pProperties->cBuffers);
return S_OK;
}
HRESULT CheckMediaType(const CMediaType* pmt)
{
return pmt->majortype == MEDIATYPE_Video && pmt->subtype == MEDIASUBTYPE_RGB32 ? S_OK : E_FAIL;
}
HRESULT GetMediaType(int iPosition, CMediaType* pmt)
{
CheckPointer(pmt, E_POINTER);
if(iPosition < 0) return E_INVALIDARG;
if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
*pmt = m_mt;
return S_OK;
}
STDMETHODIMP Notify(IBaseFilter* pSender, Quality q)
{
return E_NOTIMPL;
}
};
public:
GSSource(int w, int h, int fps, IUnknown* pUnk, HRESULT& hr)
: CBaseFilter(NAME("GSSource"), pUnk, &m_csLock, __uuidof(this), &hr)
, m_pOutput(NULL)
, m_size(w, h)
, m_rtAvgTimePerFrame(10000000i64/fps)
, m_rtNow(0)
{
CMediaType mt;
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB32;
mt.formattype = FORMAT_VideoInfo;
mt.lSampleSize = w*h*4;
VIDEOINFOHEADER vih;
memset(&vih, 0, sizeof(vih));
vih.AvgTimePerFrame = m_rtAvgTimePerFrame;
vih.bmiHeader.biSize = sizeof(vih.bmiHeader);
vih.bmiHeader.biCompression = BI_RGB;
vih.bmiHeader.biPlanes = 1;
vih.bmiHeader.biWidth = w;
vih.bmiHeader.biHeight = -h;
vih.bmiHeader.biBitCount = 32;
vih.bmiHeader.biSizeImage = w*h*4;
mt.SetFormat((BYTE*)&vih, sizeof(vih));
m_pOutput.Attach(new GSSourceOutputPin(mt, this, &m_csLock, hr));
}
DECLARE_IUNKNOWN;
int GetPinCount() {return 1;}
CBasePin* GetPin(int n) {return n == 0 ? m_pOutput.m_p : NULL;}
// IGSSource
STDMETHODIMP DeliverNewSegment()
{
return m_pOutput->DeliverNewSegment(m_rtNow = 0, _I64_MAX, 1.0);
}
STDMETHODIMP DeliverFrame(D3DLOCKED_RECT& r)
{
HRESULT hr;
if(!m_pOutput || !m_pOutput->IsConnected()) return E_UNEXPECTED;
CComPtr<IMediaSample> pSample;
if(FAILED(hr = m_pOutput->GetDeliveryBuffer(&pSample, NULL, NULL, 0)))
return hr;
REFERENCE_TIME rtStart = m_rtNow, rtStop = m_rtNow + m_rtAvgTimePerFrame;
pSample->SetTime(&rtStart, &rtStop);
pSample->SetSyncPoint(TRUE);
BYTE* pSrc = (BYTE*)r.pBits;
int srcpitch = r.Pitch;
BYTE* pDst = NULL;
pSample->GetPointer(&pDst);
CMediaType mt;
m_pOutput->GetMediaType(0, &mt);
int dstpitch = ((VIDEOINFOHEADER*)mt.Format())->bmiHeader.biWidth*4;
int minpitch = min(srcpitch, dstpitch);
for(int y = 0; y < m_size.cy; y++, pDst += dstpitch, pSrc += srcpitch)
memcpy(pDst, pSrc, minpitch);
if(FAILED(hr = m_pOutput->Deliver(pSample)))
return hr;
m_rtNow = rtStop;
return S_OK;
}
STDMETHODIMP DeliverEOS()
{
return m_pOutput->DeliverEndOfStream();
}
};
//
// GSCapture
//
GSCapture::GSCapture()
{
}
bool GSCapture::BeginCapture(IDirect3DDevice9* pD3Dev, int fps)
{
ASSERT(pD3Dev != NULL && fps != 0);
EndCapture();
AFX_MANAGE_STATE(AfxGetStaticModuleState());
GSCaptureDlg dlg;
dlg.DoModal();
//if(IDOK != dlg.DoModal())
// return false;
HRESULT hr;
int w, h;
w = 640, h = 480; // TODO
CComPtr<IDirect3DSurface9> pRTSurf;
if(FAILED(hr = pD3Dev->CreateRenderTarget(w, h, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRTSurf, NULL)))
return false;
if(FAILED(hr = pD3Dev->CreateOffscreenPlainSurface(w, h, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &m_pSysMemSurf, NULL)))
return false;
//
m_pGB.CoCreateInstance(CLSID_FilterGraph);
if(!m_pGB) return false;
CComPtr<ICaptureGraphBuilder2> pCGB;
pCGB.CoCreateInstance(CLSID_CaptureGraphBuilder2);
if(!pCGB) return false;
pCGB->SetFiltergraph(m_pGB);
CComPtr<IBaseFilter> pMux;
if(FAILED(hr = pCGB->SetOutputFileName(&MEDIASUBTYPE_Avi, CStringW(dlg.m_filename), &pMux, NULL)))
return false;
m_pSrc = new GSSource(w, h, fps, NULL, hr);
if(FAILED(hr = m_pGB->AddFilter(m_pSrc, L"Source")))
return false;
if(FAILED(hr = m_pGB->AddFilter(dlg.m_pVidEnc, L"Encoder")))
return false;
if(FAILED(hr = pCGB->RenderStream(NULL, NULL, m_pSrc, dlg.m_pVidEnc, pMux)))
return false;
hr = CComQIPtr<IMediaControl>(m_pGB)->Run();
hr = CComQIPtr<IGSSource>(m_pSrc)->DeliverNewSegment();
m_pRTSurf = pRTSurf;
return true;
}
bool GSCapture::BeginFrame(int& w, int& h, IDirect3DSurface9** pRTSurf)
{
if(!m_pRTSurf || !pRTSurf) return false;
// FIXME: remember w, h from BeginCapture
D3DSURFACE_DESC desc;
if(FAILED(m_pRTSurf->GetDesc(&desc))) return false;
w = desc.Width;
h = desc.Height;
(*pRTSurf = m_pRTSurf)->AddRef();
return true;
}
bool GSCapture::EndFrame()
{
if(m_pRTSurf == NULL || m_pSysMemSurf == NULL) {ASSERT(0); return false;}
CComPtr<IDirect3DDevice9> pD3DDev;
D3DLOCKED_RECT r;
if(FAILED(m_pRTSurf->GetDevice(&pD3DDev))
|| FAILED(pD3DDev->GetRenderTargetData(m_pRTSurf, m_pSysMemSurf))
|| FAILED(m_pSysMemSurf->LockRect(&r, NULL, D3DLOCK_READONLY)))
return false;
CComQIPtr<IGSSource>(m_pSrc)->DeliverFrame(r);
m_pSysMemSurf->UnlockRect();
return true;
}
bool GSCapture::EndCapture()
{
m_pRTSurf = NULL;
m_pSysMemSurf = NULL;
if(m_pSrc) CComQIPtr<IGSSource>(m_pSrc)->DeliverEOS();
if(m_pGB) CComQIPtr<IMediaControl>(m_pGB)->Stop();
m_pSrc = NULL;
m_pGB = NULL;
return true;
}

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
class GSCapture
{
CComPtr<IDirect3DSurface9> m_pRTSurf, m_pSysMemSurf;
CComPtr<IGraphBuilder> m_pGB;
CComPtr<IBaseFilter> m_pSrc;
public:
GSCapture();
bool BeginCapture(IDirect3DDevice9* pD3Dev, int fps);
bool BeginFrame(int& w, int& h, IDirect3DSurface9** pRTSurf);
bool EndFrame();
bool EndCapture();
bool IsCapturing() {return !!m_pRTSurf;}
};

View File

@ -1,230 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
// GSCaptureDlg.cpp : implementation file
//
#include "stdafx.h"
#include <afxpriv.h>
#include "GSCaptureDlg.h"
// GSCaptureDlg dialog
IMPLEMENT_DYNAMIC(GSCaptureDlg, CDialog)
GSCaptureDlg::GSCaptureDlg(CWnd* pParent /*=NULL*/)
: CDialog(GSCaptureDlg::IDD, pParent)
{
m_filename = AfxGetApp()->GetProfileString(_T("Capture"), _T("FileName"));
}
GSCaptureDlg::~GSCaptureDlg()
{
}
int GSCaptureDlg::GetSelCodec(Codec& c)
{
int iSel = m_codeclist.GetCurSel();
if(iSel < 0) return 0;
POSITION pos = (POSITION)m_codeclist.GetItemDataPtr(iSel);
if(pos == NULL) return 2;
c = m_codecs.GetAt(pos);
if(!c.pBF)
{
c.pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.pBF);
if(!c.pBF) return 0;
}
return 1;
}
LRESULT GSCaptureDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT ret = __super::DefWindowProc(message, wParam, lParam);
if(message == WM_INITDIALOG) SendMessage(WM_KICKIDLE);
return(ret);
}
void GSCaptureDlg::DoDataExchange(CDataExchange* pDX)
{
__super::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_filename);
DDX_Control(pDX, IDC_COMBO1, m_codeclist);
}
BOOL GSCaptureDlg::OnInitDialog()
{
__super::OnInitDialog();
m_codecs.RemoveAll();
m_codeclist.ResetContent();
m_codeclist.SetItemDataPtr(m_codeclist.AddString(_T("Uncompressed")), NULL);
BeginEnumSysDev(CLSID_VideoCompressorCategory, pMoniker)
{
Codec c;
c.pMoniker = pMoniker;
LPOLESTR strName = NULL;
if(FAILED(pMoniker->GetDisplayName(NULL, NULL, &strName)))
continue;
c.DisplayName = strName;
CoTaskMemFree(strName);
CComPtr<IPropertyBag> pPB;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB);
CComVariant var;
if(FAILED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
continue;
c.FriendlyName = var.bstrVal;
CStringW str = CStringW(c.DisplayName).MakeLower();
if(str.Find(L"@device:dmo:") == 0)
c.FriendlyName = _T("(DMO) ") + c.FriendlyName;
else if(str.Find(L"@device:sw:") == 0)
c.FriendlyName = _T("(DS) ") + c.FriendlyName;
else if(str.Find(L"@device:cm:") == 0)
c.FriendlyName = _T("(VfW) ") + c.FriendlyName;
m_codeclist.SetItemDataPtr(m_codeclist.AddString(c.FriendlyName), m_codecs.AddTail(c));
}
EndEnumSysDev
//
CString DisplayNameToFind = AfxGetApp()->GetProfileString(_T("Capture"), _T("VideoCodecDisplayName"));
for(int i = 0; i < m_codeclist.GetCount(); i++)
{
CString DisplayName;
POSITION pos = (POSITION)m_codeclist.GetItemDataPtr(i);
if(pos) DisplayName = m_codecs.GetAt(pos).DisplayName;
if(DisplayName == DisplayNameToFind)
{
m_codeclist.SetCurSel(i);
break;
}
}
//
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
BEGIN_MESSAGE_MAP(GSCaptureDlg, CDialog)
ON_MESSAGE_VOID(WM_KICKIDLE, OnKickIdle)
ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButton2)
ON_BN_CLICKED(IDOK, OnBnClickedOk)
ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOK)
END_MESSAGE_MAP()
// GSCaptureDlg message handlers
void GSCaptureDlg::OnKickIdle()
{
UpdateDialogControls(this, false);
}
void GSCaptureDlg::OnBnClickedButton1()
{
UpdateData();
CFileDialog fd(FALSE, _T("avi"), m_filename,
OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
_T("Avi files (*.avi)|*.avi||"), this, 0);
if(fd.DoModal() == IDOK)
{
m_filename = fd.GetPathName();
UpdateData(FALSE);
}
}
void GSCaptureDlg::OnBnClickedButton2()
{
Codec c;
if(GetSelCodec(c) != 1) return;
if(CComQIPtr<ISpecifyPropertyPages> pSPP = c.pBF)
{
CAUUID caGUID;
caGUID.pElems = NULL;
if(SUCCEEDED(pSPP->GetPages(&caGUID)))
{
IUnknown* lpUnk = NULL;
pSPP.QueryInterface(&lpUnk);
OleCreatePropertyFrame(
m_hWnd, 0, 0, CStringW(c.FriendlyName),
1, (IUnknown**)&lpUnk,
caGUID.cElems, caGUID.pElems,
0, 0, NULL);
lpUnk->Release();
if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
}
}
else if(CComQIPtr<IAMVfwCompressDialogs> pAMVfWCD = c.pBF)
{
if(pAMVfWCD->ShowDialog(VfwCompressDialog_QueryConfig, NULL) == S_OK)
pAMVfWCD->ShowDialog(VfwCompressDialog_Config, m_hWnd);
}
}
void GSCaptureDlg::OnUpdateButton2(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_codeclist.GetCurSel() >= 0 && m_codeclist.GetItemDataPtr(m_codeclist.GetCurSel()) != NULL);
}
void GSCaptureDlg::OnBnClickedOk()
{
UpdateData();
Codec c;
if(GetSelCodec(c) == 0) return;
m_pVidEnc = c.pBF;
AfxGetApp()->WriteProfileString(_T("Capture"), _T("FileName"), m_filename);
AfxGetApp()->WriteProfileString(_T("Capture"), _T("VideoCodecDisplayName"), CString(c.DisplayName));
OnOK();
}
void GSCaptureDlg::OnUpdateOK(CCmdUI* pCmdUI)
{
CString str;
GetDlgItem(IDC_EDIT1)->GetWindowText(str);
pCmdUI->Enable(!str.IsEmpty() && m_codeclist.GetCurSel() >= 0);
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "resource.h"
#include "afxwin.h"
// GSCaptureDlg dialog
class GSCaptureDlg : public CDialog
{
DECLARE_DYNAMIC(GSCaptureDlg)
private:
struct Codec
{
CComPtr<IMoniker> pMoniker;
CComPtr<IBaseFilter> pBF;
CString FriendlyName;
CComBSTR DisplayName;
};
CList<Codec> m_codecs;
int GetSelCodec(Codec& c);
public:
GSCaptureDlg(CWnd* pParent = NULL); // standard constructor
virtual ~GSCaptureDlg();
CComPtr<IBaseFilter> m_pVidEnc;
// Dialog Data
enum { IDD = IDD_CAPTURE };
CString m_filename;
CComboBox m_codeclist;
protected:
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnKickIdle();
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnUpdateButton2(CCmdUI* pCmdUI);
afx_msg void OnBnClickedOk();
afx_msg void OnUpdateOK(CCmdUI* pCmdUI);
};

View File

@ -1,181 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
static const DWORD s_crctable[256] =
{
0x00000000l, 0x90910101l, 0x91210201l, 0x01b00300l,
0x92410401l, 0x02d00500l, 0x03600600l, 0x93f10701l,
0x94810801l, 0x04100900l, 0x05a00a00l, 0x95310b01l,
0x06c00c00l, 0x96510d01l, 0x97e10e01l, 0x07700f00l,
0x99011001l, 0x09901100l, 0x08201200l, 0x98b11301l,
0x0b401400l, 0x9bd11501l, 0x9a611601l, 0x0af01700l,
0x0d801800l, 0x9d111901l, 0x9ca11a01l, 0x0c301b00l,
0x9fc11c01l, 0x0f501d00l, 0x0ee01e00l, 0x9e711f01l,
0x82012001l, 0x12902100l, 0x13202200l, 0x83b12301l,
0x10402400l, 0x80d12501l, 0x81612601l, 0x11f02700l,
0x16802800l, 0x86112901l, 0x87a12a01l, 0x17302b00l,
0x84c12c01l, 0x14502d00l, 0x15e02e00l, 0x85712f01l,
0x1b003000l, 0x8b913101l, 0x8a213201l, 0x1ab03300l,
0x89413401l, 0x19d03500l, 0x18603600l, 0x88f13701l,
0x8f813801l, 0x1f103900l, 0x1ea03a00l, 0x8e313b01l,
0x1dc03c00l, 0x8d513d01l, 0x8ce13e01l, 0x1c703f00l,
0xb4014001l, 0x24904100l, 0x25204200l, 0xb5b14301l,
0x26404400l, 0xb6d14501l, 0xb7614601l, 0x27f04700l,
0x20804800l, 0xb0114901l, 0xb1a14a01l, 0x21304b00l,
0xb2c14c01l, 0x22504d00l, 0x23e04e00l, 0xb3714f01l,
0x2d005000l, 0xbd915101l, 0xbc215201l, 0x2cb05300l,
0xbf415401l, 0x2fd05500l, 0x2e605600l, 0xbef15701l,
0xb9815801l, 0x29105900l, 0x28a05a00l, 0xb8315b01l,
0x2bc05c00l, 0xbb515d01l, 0xbae15e01l, 0x2a705f00l,
0x36006000l, 0xa6916101l, 0xa7216201l, 0x37b06300l,
0xa4416401l, 0x34d06500l, 0x35606600l, 0xa5f16701l,
0xa2816801l, 0x32106900l, 0x33a06a00l, 0xa3316b01l,
0x30c06c00l, 0xa0516d01l, 0xa1e16e01l, 0x31706f00l,
0xaf017001l, 0x3f907100l, 0x3e207200l, 0xaeb17301l,
0x3d407400l, 0xadd17501l, 0xac617601l, 0x3cf07700l,
0x3b807800l, 0xab117901l, 0xaaa17a01l, 0x3a307b00l,
0xa9c17c01l, 0x39507d00l, 0x38e07e00l, 0xa8717f01l,
0xd8018001l, 0x48908100l, 0x49208200l, 0xd9b18301l,
0x4a408400l, 0xdad18501l, 0xdb618601l, 0x4bf08700l,
0x4c808800l, 0xdc118901l, 0xdda18a01l, 0x4d308b00l,
0xdec18c01l, 0x4e508d00l, 0x4fe08e00l, 0xdf718f01l,
0x41009000l, 0xd1919101l, 0xd0219201l, 0x40b09300l,
0xd3419401l, 0x43d09500l, 0x42609600l, 0xd2f19701l,
0xd5819801l, 0x45109900l, 0x44a09a00l, 0xd4319b01l,
0x47c09c00l, 0xd7519d01l, 0xd6e19e01l, 0x46709f00l,
0x5a00a000l, 0xca91a101l, 0xcb21a201l, 0x5bb0a300l,
0xc841a401l, 0x58d0a500l, 0x5960a600l, 0xc9f1a701l,
0xce81a801l, 0x5e10a900l, 0x5fa0aa00l, 0xcf31ab01l,
0x5cc0ac00l, 0xcc51ad01l, 0xcde1ae01l, 0x5d70af00l,
0xc301b001l, 0x5390b100l, 0x5220b200l, 0xc2b1b301l,
0x5140b400l, 0xc1d1b501l, 0xc061b601l, 0x50f0b700l,
0x5780b800l, 0xc711b901l, 0xc6a1ba01l, 0x5630bb00l,
0xc5c1bc01l, 0x5550bd00l, 0x54e0be00l, 0xc471bf01l,
0x6c00c000l, 0xfc91c101l, 0xfd21c201l, 0x6db0c300l,
0xfe41c401l, 0x6ed0c500l, 0x6f60c600l, 0xfff1c701l,
0xf881c801l, 0x6810c900l, 0x69a0ca00l, 0xf931cb01l,
0x6ac0cc00l, 0xfa51cd01l, 0xfbe1ce01l, 0x6b70cf00l,
0xf501d001l, 0x6590d100l, 0x6420d200l, 0xf4b1d301l,
0x6740d400l, 0xf7d1d501l, 0xf661d601l, 0x66f0d700l,
0x6180d800l, 0xf111d901l, 0xf0a1da01l, 0x6030db00l,
0xf3c1dc01l, 0x6350dd00l, 0x62e0de00l, 0xf271df01l,
0xee01e001l, 0x7e90e100l, 0x7f20e200l, 0xefb1e301l,
0x7c40e400l, 0xecd1e501l, 0xed61e601l, 0x7df0e700l,
0x7a80e800l, 0xea11e901l, 0xeba1ea01l, 0x7b30eb00l,
0xe8c1ec01l, 0x7850ed00l, 0x79e0ee00l, 0xe971ef01l,
0x7700f000l, 0xe791f101l, 0xe621f201l, 0x76b0f300l,
0xe541f401l, 0x75d0f500l, 0x7460f600l, 0xe4f1f701l,
0xe381f801l, 0x7310f900l, 0x72a0fa00l, 0xe231fb01l,
0x71c0fc00l, 0xe151fd01l, 0xe0e1fe01l, 0x7070ff00l
};
DWORD hash_crc(const CRect& r, int pitch, BYTE* p)
{
if(r.Width() == 0) {ASSERT(0); return 0;}
DWORD hash = 0xffffffff;
for(int j = r.top; j < r.bottom; j++, p += pitch)
{
for(int i = r.left, x = 0; i < r.right; i++, x += 4)
{
hash = s_crctable[(hash ^ p[x+0]) & 0xff] ^ (hash >> 8);
hash = s_crctable[(hash ^ p[x+1]) & 0xff] ^ (hash >> 8);
hash = s_crctable[(hash ^ p[x+2]) & 0xff] ^ (hash >> 8);
hash = s_crctable[(hash ^ p[x+3]) & 0xff] ^ (hash >> 8);
}
}
return hash;
}
#define MOD_ADLER 65521
DWORD hash_adler(const CRect& r, int pitch, BYTE* p)
{
if(r.Width() == 0) {ASSERT(0); return 0;}
DWORD a = 1, b = 0;
for(int j = r.top; j < r.bottom; j++, p += pitch)
{
for(int i = r.left, x = 0; i < r.right; i++, x += 4)
{
a += p[x+0]; b += a;
a += p[x+1]; b += a;
a += p[x+2]; b += a;
a += p[x+3]; b += a;
}
a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER);
b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
}
// a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER);
if(a >= MOD_ADLER) a -= MOD_ADLER;
b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
if(b >= MOD_ADLER) b -= MOD_ADLER;
return b << 16 | a;
}
DWORD hash_checksum(const CRect& r, int pitch, BYTE* p)
{
if(r.Width() == 0) {ASSERT(0); return 0;}
DWORD hash = 0;
#if defined(_M_AMD64) || _M_IX86_FP >= 2
if(r.Width() >= 4 && !((DWORD_PTR)p & 0xf) && !(pitch & 0xf))
{
__m128i hash128 = _mm_setzero_si128();
for(int j = r.top; j < r.bottom; j++, p += pitch)
{
hash128 = _mm_add_epi32(hash128, _mm_set1_epi32(j));
for(int i = r.left, x = 0; i < r.right; i += 4, x++)
{
hash128 = _mm_shuffle_epi32(hash128, 0x93);
////hash128 = _mm_shufflelo_epi16(hash128, 0x93);
//hash128 = _mm_shufflehi_epi16(hash128, 0x93);
hash128 = _mm_add_epi32(hash128, _mm_load_si128(&((__m128i*)p)[x]));
}
}
hash128 = _mm_add_epi32(hash128, _mm_srli_si128(hash128, 8));
hash128 = _mm_add_epi32(hash128, _mm_srli_si128(hash128, 4));
hash += _mm_cvtsi128_si32(hash128);
}
else
#endif
{
for(int j = r.top; j < r.bottom; j++, p += pitch)
{
hash += j;
for(int i = r.left, x = 0; i < r.right; i++, x++)
{
hash += ((DWORD*)p)[x];
}
}
}
return hash;
}

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
extern DWORD hash_crc(const CRect& r, int pitch, BYTE* p);
extern DWORD hash_adler(const CRect& r, int pitch, BYTE* p);
extern DWORD hash_checksum(const CRect& r, int pitch, BYTE* p);

File diff suppressed because it is too large Load Diff

View File

@ -1,321 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#pragma warning(disable: 4244) // warning C4244: '=' : conversion from 'const UINT64' to 'int', possible loss of data
#include "GS.h"
#include "GSTables.h"
class GSLocalMemory
{
public:
typedef DWORD (__fastcall *pixelAddress)(int x, int y, DWORD bp, DWORD bw);
typedef void (GSLocalMemory::*writePixel)(int x, int y, DWORD c, DWORD bp, DWORD bw);
typedef void (GSLocalMemory::*writeFrame)(int x, int y, DWORD c, DWORD bp, DWORD bw);
typedef DWORD (GSLocalMemory::*readPixel)(int x, int y, DWORD bp, DWORD bw);
typedef DWORD (GSLocalMemory::*readTexel)(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
typedef void (GSLocalMemory::*writePixelAddr)(DWORD addr, DWORD c);
typedef void (GSLocalMemory::*writeFrameAddr)(DWORD addr, DWORD c);
typedef DWORD (GSLocalMemory::*readPixelAddr)(DWORD addr);
typedef DWORD (GSLocalMemory::*readTexelAddr)(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
typedef void (GSLocalMemory::*SwizzleTexture)(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
typedef void (GSLocalMemory::*unSwizzleTexture)(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
typedef void (GSLocalMemory::*readTexture)(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP);
typedef union
{
struct
{
pixelAddress pa, ba, pga;
readPixel rp;
readPixelAddr rpa;
writePixel wp;
writePixelAddr wpa;
readTexel rt, rtP, rtNP;
readTexelAddr rta;
writeFrameAddr wfa;
SwizzleTexture st;
unSwizzleTexture ust, ustP, ustNP;
DWORD bpp, pal, trbpp;
CSize bs;
int* rowOffset[8];
};
BYTE dummy[128];
} psmtbl_t;
static psmtbl_t m_psmtbl[64];
protected:
static DWORD pageOffset32[32][32][64];
static DWORD pageOffset32Z[32][32][64];
static DWORD pageOffset16[32][64][64];
static DWORD pageOffset16S[32][64][64];
static DWORD pageOffset16Z[32][64][64];
static DWORD pageOffset16SZ[32][64][64];
static DWORD pageOffset8[32][64][128];
static DWORD pageOffset4[32][128][128];
static int rowOffset32[2048];
static int rowOffset32Z[2048];
static int rowOffset16[2048];
static int rowOffset16S[2048];
static int rowOffset16Z[2048];
static int rowOffset16SZ[2048];
static int rowOffset8[2][2048];
static int rowOffset4[2][2048];
union {BYTE* m_vm8; WORD* m_vm16; DWORD* m_vm32;};
DWORD m_CBP[2];
WORD* m_pCLUT;
DWORD* m_pCLUT32;
UINT64* m_pCLUT64;
GIFRegTEX0 m_prevTEX0;
GIFRegTEXCLUT m_prevTEXCLUT;
bool m_fCLUTMayBeDirty;
public:
GSLocalMemory();
virtual ~GSLocalMemory();
static void RoundDown(CSize& s, CSize bs);
static void RoundUp(CSize& s, CSize bs);
static DWORD Expand24To32(DWORD c, BYTE TCC, GIFRegTEXA& TEXA)
{
BYTE A = (!TEXA.AEM|(c&0xffffff)) ? TEXA.TA0 : 0;
return (A<<24) | (c&0xffffff);
}
static DWORD Expand16To32(WORD c, GIFRegTEXA& TEXA)
{
BYTE A = (c&0x8000) ? TEXA.TA1 : (!TEXA.AEM|c) ? TEXA.TA0 : 0;
return (A << 24) | ((c&0x7c00) << 9) | ((c&0x03e0) << 6) | ((c&0x001f) << 3);
}
BYTE* GetVM() {return m_vm8;}
// address
static DWORD __fastcall pageAddress32(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pageAddress16(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pageAddress8(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pageAddress4(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall blockAddress32(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall blockAddress16(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall blockAddress16S(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall blockAddress8(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall blockAddress4(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall blockAddress32Z(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall blockAddress16Z(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall blockAddress16SZ(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddressOrg32(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddressOrg16(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddressOrg16S(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddressOrg8(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddressOrg4(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddressOrg32Z(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddressOrg16Z(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddressOrg16SZ(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddress32(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddress16(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddress16S(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddress8(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddress4(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddress32Z(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddress16Z(int x, int y, DWORD bp, DWORD bw);
static DWORD __fastcall pixelAddress16SZ(int x, int y, DWORD bp, DWORD bw);
// raw pixel R/W
void writePixel32(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel24(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel16(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel16S(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel8(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel8H(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel4(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel4HL(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel4HH(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel32Z(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel24Z(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel16Z(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writePixel16SZ(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writeFrame16(int x, int y, DWORD c, DWORD bp, DWORD bw);
void writeFrame16S(int x, int y, DWORD c, DWORD bp, DWORD bw);
DWORD readPixel32(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel24(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel16(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel16S(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel8(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel8H(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel4(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel4HL(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel4HH(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel32Z(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel24Z(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel16Z(int x, int y, DWORD bp, DWORD bw);
DWORD readPixel16SZ(int x, int y, DWORD bp, DWORD bw);
void writePixel32(DWORD addr, DWORD c) {m_vm32[addr] = c;}
void writePixel24(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff);}
void writePixel16(DWORD addr, DWORD c) {m_vm16[addr] = (WORD)c;}
void writePixel16S(DWORD addr, DWORD c) {m_vm16[addr] = (WORD)c;}
void writePixel8(DWORD addr, DWORD c) {m_vm8[addr] = (BYTE)c;}
void writePixel8H(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0x00ffffff) | (c << 24);}
void writePixel4(DWORD addr, DWORD c) {int shift = (addr&1) << 2; addr >>= 1; m_vm8[addr] = (BYTE)((m_vm8[addr] & (0xf0 >> shift)) | ((c & 0x0f) << shift));}
void writePixel4HL(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0xf0ffffff) | ((c & 0x0f) << 24);}
void writePixel4HH(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0x0fffffff) | ((c & 0x0f) << 28);}
void writePixel32Z(DWORD addr, DWORD c) {m_vm32[addr] = c;}
void writePixel24Z(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff);}
void writePixel16Z(DWORD addr, DWORD c) {m_vm16[addr] = (WORD)c;}
void writePixel16SZ(DWORD addr, DWORD c) {m_vm16[addr] = (WORD)c;}
void writeFrame16(DWORD addr, DWORD c) {writePixel16(addr, ((c>>16)&0x8000)|((c>>9)&0x7c00)|((c>>6)&0x03e0)|((c>>3)&0x001f));}
void writeFrame16S(DWORD addr, DWORD c) {writePixel16S(addr, ((c>>16)&0x8000)|((c>>9)&0x7c00)|((c>>6)&0x03e0)|((c>>3)&0x001f));}
DWORD readPixel32(DWORD addr) {return m_vm32[addr];}
DWORD readPixel24(DWORD addr) {return m_vm32[addr] & 0x00ffffff;}
DWORD readPixel16(DWORD addr) {return (DWORD)m_vm16[addr];}
DWORD readPixel16S(DWORD addr) {return (DWORD)m_vm16[addr];}
DWORD readPixel8(DWORD addr) {return (DWORD)m_vm8[addr];}
DWORD readPixel8H(DWORD addr) {return m_vm32[addr] >> 24;}
DWORD readPixel4(DWORD addr) {return (m_vm8[addr>>1] >> ((addr&1) << 2)) & 0x0f;}
DWORD readPixel4HL(DWORD addr) {return (m_vm32[addr] >> 24) & 0x0f;}
DWORD readPixel4HH(DWORD addr) {return (m_vm32[addr] >> 28) & 0x0f;}
DWORD readPixel32Z(DWORD addr) {return m_vm32[addr];}
DWORD readPixel24Z(DWORD addr) {return m_vm32[addr] & 0x00ffffff;}
DWORD readPixel16Z(DWORD addr) {return (DWORD)m_vm16[addr];}
DWORD readPixel16SZ(DWORD addr) {return (DWORD)m_vm16[addr];}
// FillRect
bool FillRect(const CRect& r, DWORD c, DWORD psm, DWORD fbp, DWORD fbw);
// CLUT
void InvalidateCLUT() {m_fCLUTMayBeDirty = true;}
void WriteCLUT(GIFRegTEX0 TEX0, GIFRegTEXCLUT TEXCLUT);
void ReadCLUT(GIFRegTEX0 TEX0, GIFRegTEXA TEXA, DWORD* pCLUT32);
void SetupCLUT(GIFRegTEX0 TEX0, GIFRegTEXA TEXA);
// expands 16->32
void ReadCLUT32(GIFRegTEX0 TEX0, GIFRegTEXA TEXA, DWORD* pCLUT32);
void SetupCLUT32(GIFRegTEX0 TEX0, GIFRegTEXA TEXA);
void CopyCLUT32(DWORD* pCLUT32, int nPaletteEntries);
// 32-only
DWORD readTexel32(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel24(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel16(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel16S(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel8(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel8H(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel4(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel4HL(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel4HH(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel32(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_vm32[addr];}
DWORD readTexel24(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return Expand24To32(m_vm32[addr], TEX0.ai32[1]&4, TEXA);}
DWORD readTexel16(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return Expand16To32(m_vm16[addr], TEXA);}
DWORD readTexel16S(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return Expand16To32(m_vm16[addr], TEXA);}
DWORD readTexel8(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel8(addr)];}
DWORD readTexel8H(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel8H(addr)];}
DWORD readTexel4(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel4(addr)];}
DWORD readTexel4HL(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel4HL(addr)];}
DWORD readTexel4HH(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel4HH(addr)];}
void SwizzleTexture32(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTexture24(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTexture16(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTexture16S(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTexture8(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTexture8H(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTexture4(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTexture4HL(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTexture4HH(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void SwizzleTextureX(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
void unSwizzleTexture32(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture24(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture16(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture16S(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture8(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture8H(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4HL(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4HH(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void ReadTexture(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP);
// 32/16/8P
DWORD readTexel16P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel16SP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel8P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel8HP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel4P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel4HLP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
DWORD readTexel4HHP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture16P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture16SP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture8P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture8HP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4HLP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4HHP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void ReadTextureP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP);
// 32/16
void unSwizzleTexture8NP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture8HNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4NP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4HLNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void unSwizzleTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP);
//
static DWORD m_xtbl[1024], m_ytbl[1024];
template<typename DstT>
void ReadTexture(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP, readTexel rt, unSwizzleTexture st);
//
HRESULT SaveBMP(IDirect3DDevice9* pDev, LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h);
};
#pragma warning(default: 4244)

View File

@ -1,109 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "StdAfx.h"
#include "GSPerfMon.h"
#if _MSC_VER >= 1400
extern "C" unsigned __int64 __rdtsc();
#else
__declspec(naked) unsigned __int64 __rdtsc() {__asm rdtsc __asm ret}
#endif
GSPerfMon::GSPerfMon()
: m_total(0), m_begin(0)
, m_frame(0), m_lastframe(0)
{
}
void GSPerfMon::IncCounter(counter_t c, double val)
{
if(c == c_frame)
{
clock_t now = clock();
if(m_lastframe != 0)
m_counters[c].AddTail(now - m_lastframe);
m_lastframe = now;
m_frame++;
}
else
{
m_counters[c].AddTail(val);
}
}
void GSPerfMon::StartTimer()
{
m_start = __rdtsc();
if(m_begin == 0) m_begin = m_start;
}
void GSPerfMon::StopTimer()
{
if(m_start > 0)
{
m_total += __rdtsc() - m_start;
m_start = 0;
}
}
CString GSPerfMon::ToString(double expected_fps)
{
if(m_counters[c_frame].IsEmpty())
return _T("");
double stats[c_last];
for(int i = 0; i < countof(m_counters); i++)
{
double sum = 0;
POSITION pos = m_counters[i].GetHeadPosition();
while(pos) sum += m_counters[i].GetNext(pos);
stats[i] = sum / m_counters[c_frame].GetCount();
}
UINT64 start = m_start;
if(start > 0) StopTimer();
double fps = 1000.0 / stats[c_frame];
double cpu = 100.0 * m_total / (__rdtsc() - m_begin);
CString str;
str.Format(_T("frame: %I64d | cpu: %d%% | %.2f fps (%d%%) | %d ppf | %.2f kbpf | %.2f kbpf | %.2f kbpf"),
m_frame,
(int)(cpu),
(float)(fps),
(int)(100.0 * fps / expected_fps),
(int)(stats[c_prim]),
(float)(stats[c_swizzle] / 1024),
(float)(stats[c_unswizzle] / 1024),
(float)(stats[c_texture] / 1024));
for(int i = 0; i < countof(m_counters); i++)
m_counters[i].RemoveAll();
m_total = m_begin = 0;
if(start > 0) StartTimer();
return str;
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "x86.h"
class GSPerfMon
{
public:
enum counter_t {c_frame, c_prim, c_swizzle, c_unswizzle, c_texture, c_last};
protected:
CAtlList<double> m_counters[c_last];
UINT64 m_begin, m_total, m_start, m_frame;
clock_t m_lastframe;
public:
GSPerfMon();
void IncCounter(counter_t c, double val = 0);
void StartTimer(), StopTimer();
CString ToString(double expected_fps);
UINT64 GetFrame() {return m_frame;}
};
class GSPerfMonAutoTimer
{
GSPerfMon* m_pm;
public:
GSPerfMonAutoTimer(GSPerfMon& pm) {(m_pm = &pm)->StartTimer();}
~GSPerfMonAutoTimer() {m_pm->StopTimer();}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "StdAfx.h"
#include "GSRenderer.h"

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GSState.h"
template <class VERTEX>
class GSRenderer : public GSState
{
protected:
GSVertexList<VERTEX> m_vl;
VERTEX* m_pVertices;
int m_nMaxVertices, m_nVertices, m_nPrims;
void Reset()
{
m_nVertices = m_nPrims = 0;
m_vl.RemoveAll();
__super::Reset();
}
void VertexKick(bool fSkip)
{
LOG(_T("VertexKick(%d)\n"), fSkip);
static const int vmin[8] = {1, 2, 2, 3, 3, 3, 2, 1};
while(m_vl.GetCount() >= vmin[m_pPRIM->PRIM])
{
if(m_nVertices+6 > m_nMaxVertices)
{
VERTEX* pVertices = (VERTEX*)_aligned_malloc(sizeof(VERTEX) * (m_nMaxVertices <<= 1), 16);
memcpy(pVertices, m_pVertices, m_nVertices*sizeof(VERTEX));
_aligned_free(m_pVertices);
m_pVertices = pVertices;
}
LOG(_T("DrawingKick %d\n"), m_pPRIM->PRIM);
if(m_PRIM != m_pPRIM->PRIM && m_nVertices > 0) FlushPrimInternal();
m_PRIM = m_pPRIM->PRIM;
LOG2(_T("Prim (%d) %05x %05x %05x %04x\n"),
m_PRIM,
m_ctxt->FRAME.Block(),
m_pPRIM->TME ? (UINT32)m_ctxt->TEX0.TBP0 : 0xfffff,
m_pPRIM->TME ? (UINT32)m_ctxt->TEX0.CBP : 0xfffff,
(m_pPRIM->ABE || (m_PRIM == 1 || m_PRIM == 2) && m_pPRIM->AA1)
? ((m_ctxt->ALPHA.A<<12)|(m_ctxt->ALPHA.B<<8)|(m_ctxt->ALPHA.C<<4)|m_ctxt->ALPHA.D)
: 0xffff);
m_nVertices += DrawingKick(fSkip);
#ifdef DEBUG_RENDERTARGETS
if(::GetAsyncKeyState(VK_SPACE)&0x80000000) {FlushPrimInternal(); Flip();}
#endif
}
}
void NewPrim() {m_vl.RemoveAll();}
void FlushPrim() {m_PRIM = 8; m_nVertices = 0;}
public:
GSRenderer(int w, int h, HWND hWnd, HRESULT& hr)
: GSState(w, h, hWnd, hr)
{
m_pVertices = (VERTEX*)_aligned_malloc(sizeof(VERTEX) * (m_nMaxVertices = 256), 16);
Reset();
}
~GSRenderer()
{
_aligned_free(m_pVertices);
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GSRenderer.h"
#pragma pack(push, 1)
__declspec(align(16)) union GSVertexHW
{
struct
{
float x, y, z, rhw;
union {struct {BYTE r, g, b, a;}; D3DCOLOR color;};
D3DCOLOR fog;
float tu, tv;
};
struct {__m128i xmm[2];};
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
GSVertexHW& operator = (GSVertexHW& v) {xmm[0] = v.xmm[0]; xmm[1] = v.xmm[1]; return *this;}
#endif
};
#pragma pack(pop)
class GSRendererHW : public GSRenderer<GSVertexHW>
{
protected:
CSurfMap<IDirect3DTexture9> m_pRTs;
CSurfMap<IDirect3DSurface9> m_pDSs;
CAtlMap<DWORD, CGSWnd*> m_pRenderWnds;
GSTextureCache m_tc;
void SetupTexture(const GSTextureBase& t, float tsx, float tsy);
void SetupAlphaBlend();
void SetupColorMask();
void SetupZBuffer();
void SetupAlphaTest();
void SetupScissor(scale_t& s);
void Reset();
void VertexKick(bool fSkip);
int DrawingKick(bool fSkip);
void FlushPrim();
void Flip();
void EndFrame();
void InvalidateTexture(const GIFRegBITBLTBUF& BITBLTBUF, CRect r);
void InvalidateLocalMem(DWORD BP, DWORD TBP0, DWORD PSM, CRect r);
void MinMaxUV(int w, int h, CRect& r);
D3DPRIMITIVETYPE m_primtype;
public:
GSRendererHW(HWND hWnd, HRESULT& hr);
~GSRendererHW();
HRESULT ResetDevice(bool fForceWindowed = false);
void LOGVERTEX(GSVertexHW& v, LPCTSTR type)
{
int tw = 1, th = 1;
if(m_pPRIM->TME) {tw = 1<<m_ctxt->TEX0.TW; th = 1<<m_ctxt->TEX0.TH;}
LOG2(_T("\t %s (%.2f, %.2f, %.2f, %.2f) (%08x) (%f, %f) (%f, %f)\n"),
type,
v.x, v.y, v.z, v.rhw,
v.color, v.tu, v.tv,
v.tu*tw, v.tv*th);
}
};

View File

@ -1,101 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "StdAfx.h"
#include "GSRendererNull.h"
GSRendererNull::GSRendererNull(HWND hWnd, HRESULT& hr)
: GSRenderer<NULLVERTEX>(256, 256, hWnd, hr)
{
}
GSRendererNull::~GSRendererNull()
{
}
void GSRendererNull::VertexKick(bool fSkip)
{
NULLVERTEX v;
m_vl.AddTail(v);
__super::VertexKick(fSkip);
}
int GSRendererNull::DrawingKick(bool fSkip)
{
NULLVERTEX v;
switch(m_PRIM)
{
case 3: // triangle list
m_vl.RemoveAt(0, v);
m_vl.RemoveAt(0, v);
m_vl.RemoveAt(0, v);
break;
case 4: // triangle strip
m_vl.RemoveAt(0, v);
m_vl.GetAt(0, v);
m_vl.GetAt(1, v);
break;
case 5: // triangle fan
m_vl.GetAt(0, v);
m_vl.RemoveAt(1, v);
m_vl.GetAt(1, v);
break;
case 6: // sprite
m_vl.RemoveAt(0, v);
m_vl.RemoveAt(0, v);
break;
case 1: // line
m_vl.RemoveAt(0, v);
m_vl.RemoveAt(0, v);
break;
case 2: // line strip
m_vl.RemoveAt(0, v);
m_vl.GetAt(0, v);
break;
case 0: // point
m_vl.RemoveAt(0, v);
break;
default:
ASSERT(0);
m_vl.RemoveAll();
return 0;
}
if(!fSkip)
{
m_perfmon.IncCounter(GSPerfMon::c_prim, 1);
}
return 0;
}
void GSRendererNull::Flip()
{
FlipInfo rt[2];
FinishFlip(rt);
}
void GSRendererNull::EndFrame()
{
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GSRenderer.h"
#pragma pack(push, 1)
struct NULLVERTEX {/*DWORD dummy;*/};
#pragma pack(pop)
class GSRendererNull : public GSRenderer<NULLVERTEX>
{
protected:
void VertexKick(bool fSkip);
int DrawingKick(bool fSkip);
void Flip();
void EndFrame();
public:
GSRendererNull(HWND hWnd, HRESULT& hr);
~GSRendererNull();
};

File diff suppressed because it is too large Load Diff

View File

@ -1,112 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GSRenderer.h"
template <class Vertex>
class GSRendererSoft : public GSRenderer<Vertex>
{
protected:
void Reset();
int DrawingKick(bool fSkip);
void FlushPrim();
void Flip();
void EndFrame();
enum {PRIM_NONE, PRIM_SPRITE, PRIM_TRIANGLE, PRIM_LINE, PRIM_POINT} m_primtype;
DWORD m_faddr_x0, m_faddr;
DWORD m_zaddr_x0, m_zaddr;
int* m_faddr_ro;
int* m_zaddr_ro;
int m_fx, m_fy;
void RowInit(int x, int y);
void RowStep();
void DrawPoint(Vertex* v);
void DrawLine(Vertex* v);
void DrawTriangle(Vertex* v);
void DrawSprite(Vertex* v);
bool DrawFilledRect(int left, int top, int right, int bottom, const Vertex& v);
template <int iZTST, int iATST>
void DrawVertex(const Vertex& v);
typedef void (GSRendererSoft<Vertex>::*DrawVertexPtr)(const Vertex& v);
DrawVertexPtr m_dv[4][8], m_pDrawVertex;
template <int iLOD, bool bLCM, bool bTCC, int iTFX>
void DrawVertexTFX(typename Vertex::Vector& Cf, const Vertex& v);
typedef void (GSRendererSoft<Vertex>::*DrawVertexTFXPtr)(typename Vertex::Vector& Cf, const Vertex& v);
DrawVertexTFXPtr m_dvtfx[4][2][2][4], m_pDrawVertexTFX;
CComPtr<IDirect3DTexture9> m_pRT[2];
DWORD* m_pTexture;
void SetupTexture();
struct uv_wrap_t {union {struct {short min[8], max[8];}; struct {short and[8], or[8];};}; unsigned short mask[8];}* m_uv;
CRect m_scissor;
BYTE m_clip[65536];
BYTE m_mask[65536];
BYTE* m_clamp;
public:
GSRendererSoft(HWND hWnd, HRESULT& hr);
~GSRendererSoft();
HRESULT ResetDevice(bool fForceWindowed = false);
void LOGVERTEX(Vertex& v, LPCTSTR type)
{
int tw = 1, th = 1;
if(m_de.PRIM.TME) {tw = 1<<m_ctxt->TEX0.TW; th = 1<<m_ctxt->TEX0.TH;}
LOG2(_T("- %s (%.2f, %.2f, %.2f, %.2f) (%08x) (%.3f, %.3f) (%.2f, %.2f)\n"),
type,
(float)v.p.x, (float)v.p.y, (float)v.p.z / UINT_MAX, (float)v.t.q,
(DWORD)v.c,
(float)v.t.x/tw, (float)v.t.y/th, (float)v.t.x, (float)v.t.y);
}
};
class GSRendererSoftFP : public GSRendererSoft<GSSoftVertexFP>
{
protected:
void VertexKick(bool fSkip);
public:
GSRendererSoftFP(HWND hWnd, HRESULT& hr);
};
/*
class GSRendererSoftFX : public GSRendererSoft<GSSoftVertexFX>
{
protected:
void VertexKick(bool fSkip);
//void DrawVertex(int x, int y, GSSoftVertexFX& v);
public:
GSRendererSoftFX(HWND hWnd, HRESULT& hr);
};
*/

View File

@ -1,239 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSdx9.h"
#include "GSSettingsDlg.h"
#include <shlobj.h>
static struct {int id; const TCHAR* name;} s_renderers[] =
{
{RENDERER_D3D_HW, "Direct3D"},
// {RENDERER_D3D_SW_FX, "Software (fixed)"},
{RENDERER_D3D_SW_FP, "Software (float)"},
{RENDERER_D3D_NULL, "Do not render"},
};
static struct {DWORD id; const TCHAR* name;} s_psversions[] =
{
{D3DPS_VERSION(3, 0), _T("Pixel Shader 3.0")},
{D3DPS_VERSION(2, 0), _T("Pixel Shader 2.0")},
{D3DPS_VERSION(1, 4), _T("Pixel Shader 1.4")},
{D3DPS_VERSION(1, 1), _T("Pixel Shader 1.1")},
{D3DPS_VERSION(0, 0), _T("Fixed Pipeline (bogus)")},
};
IMPLEMENT_DYNAMIC(CGSSettingsDlg, CDialog)
CGSSettingsDlg::CGSSettingsDlg(CWnd* pParent /*=NULL*/)
: CDialog(CGSSettingsDlg::IDD, pParent)
, m_fEnablePalettizedTextures(FALSE)
, m_fEnableTvOut(FALSE)
, m_fNloopHack(FALSE)
, m_fRecordState(FALSE)
, m_fLinearTexFilter(TRUE)
{
}
CGSSettingsDlg::~CGSSettingsDlg()
{
}
void CGSSettingsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO3, m_resolution);
DDX_Control(pDX, IDC_COMBO1, m_renderer);
DDX_Control(pDX, IDC_COMBO4, m_psversion);
DDX_Check(pDX, IDC_CHECK1, m_fEnablePalettizedTextures);
DDX_Check(pDX, IDC_CHECK3, m_fEnableTvOut);
DDX_Check(pDX, IDC_CHECK2, m_fRecordState);
DDX_Check(pDX, IDC_CHECK5, m_fNloopHack);
DDX_Text(pDX, IDC_EDIT1, m_strRecordState);
DDX_Check(pDX, IDC_CHECK4, m_fLinearTexFilter);
}
BEGIN_MESSAGE_MAP(CGSSettingsDlg, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
END_MESSAGE_MAP()
// CGSSettingsDlg message handlers
BOOL CGSSettingsDlg::OnInitDialog()
{
__super::OnInitDialog();
CWinApp* pApp = AfxGetApp();
D3DCAPS9 caps;
ZeroMemory(&caps, sizeof(caps));
caps.PixelShaderVersion = D3DPS_VERSION(0, 0);
m_modes.RemoveAll();
// windowed
{
D3DDISPLAYMODE mode;
memset(&mode, 0, sizeof(mode));
m_modes.AddTail(mode);
int iItem = m_resolution.AddString(_T("Windowed"));
m_resolution.SetItemDataPtr(iItem, m_modes.GetTailPosition());
m_resolution.SetCurSel(iItem);
}
// fullscreen
if(CComPtr<IDirect3D9> pD3D = Direct3DCreate9(D3D_SDK_VERSION))
{
int ModeWidth = pApp->GetProfileInt(_T("Settings"), _T("ModeWidth"), 0);
int ModeHeight = pApp->GetProfileInt(_T("Settings"), _T("ModeHeight"), 0);
int ModeRefreshRate = pApp->GetProfileInt(_T("Settings"), _T("ModeRefreshRate"), 0);
UINT nModes = pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
for(UINT i = 0; i < nModes; i++)
{
D3DDISPLAYMODE mode;
if(S_OK == pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode))
{
CString str;
str.Format(_T("%dx%d %dHz"), mode.Width, mode.Height, mode.RefreshRate);
int iItem = m_resolution.AddString(str);
m_modes.AddTail(mode);
m_resolution.SetItemDataPtr(iItem, m_modes.GetTailPosition());
if(ModeWidth == mode.Width && ModeHeight == mode.Height && ModeRefreshRate == mode.RefreshRate)
m_resolution.SetCurSel(iItem);
}
}
pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, &caps);
}
// renderer
int renderer_id = pApp->GetProfileInt(_T("Settings"), _T("Renderer"), RENDERER_D3D_HW);
for(int i = 0; i < countof(s_renderers); i++)
{
int iItem = m_renderer.AddString(s_renderers[i].name);
m_renderer.SetItemData(iItem, s_renderers[i].id);
if(s_renderers[i].id == renderer_id) m_renderer.SetCurSel(iItem);
}
// shader
DWORD psversion_id = pApp->GetProfileInt(_T("Settings"), _T("PixelShaderVersion2"), D3DPS_VERSION(2, 0));
for(int i = 0; i < countof(s_psversions); i++)
{
if(s_psversions[i].id > caps.PixelShaderVersion) continue;
int iItem = m_psversion.AddString(s_psversions[i].name);
m_psversion.SetItemData(iItem, s_psversions[i].id);
if(s_psversions[i].id == psversion_id) m_psversion.SetCurSel(iItem);
}
//
m_fEnablePalettizedTextures = pApp->GetProfileInt(_T("Settings"), _T("fEnablePalettizedTextures"), FALSE);
//
m_fLinearTexFilter = (D3DTEXTUREFILTERTYPE)pApp->GetProfileInt(_T("Settings"), _T("TexFilter"), D3DTEXF_LINEAR) == D3DTEXF_LINEAR;
//
m_fEnableTvOut = pApp->GetProfileInt(_T("Settings"), _T("fEnableTvOut"), FALSE);
//
m_fNloopHack = pApp->GetProfileInt(_T("Settings"), _T("fNloopHack"), FALSE);
//
m_fRecordState = pApp->GetProfileInt(_T("Settings"), _T("RecordState"), FALSE);
m_strRecordState = pApp->GetProfileString(_T("Settings"), _T("RecordStatePath"), _T(""));
//
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CGSSettingsDlg::OnOK()
{
CWinApp* pApp = AfxGetApp();
UpdateData();
if(m_resolution.GetCurSel() >= 0)
{
D3DDISPLAYMODE& mode = m_modes.GetAt((POSITION)m_resolution.GetItemData(m_resolution.GetCurSel()));
pApp->WriteProfileInt(_T("Settings"), _T("ModeWidth"), mode.Width);
pApp->WriteProfileInt(_T("Settings"), _T("ModeHeight"), mode.Height);
pApp->WriteProfileInt(_T("Settings"), _T("ModeRefreshRate"), mode.RefreshRate);
}
if(m_renderer.GetCurSel() >= 0)
{
pApp->WriteProfileInt(_T("Settings"), _T("Renderer"), m_renderer.GetItemData(m_renderer.GetCurSel()));
}
if(m_psversion.GetCurSel() >= 0)
{
pApp->WriteProfileInt(_T("Settings"), _T("PixelShaderVersion2"), m_psversion.GetItemData(m_psversion.GetCurSel()));
}
pApp->WriteProfileInt(_T("Settings"), _T("fEnablePalettizedTextures"), m_fEnablePalettizedTextures);
pApp->WriteProfileInt(_T("Settings"), _T("TexFilter"), m_fLinearTexFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
pApp->WriteProfileInt(_T("Settings"), _T("fEnableTvOut"), m_fEnableTvOut);
pApp->WriteProfileInt(_T("Settings"), _T("fNloopHack"), m_fNloopHack);
pApp->WriteProfileInt(_T("Settings"), _T("RecordState"), m_fRecordState);
pApp->WriteProfileString(_T("Settings"), _T("RecordStatePath"), m_strRecordState);
__super::OnOK();
}
void CGSSettingsDlg::OnBnClickedButton1()
{
TCHAR path[MAX_PATH];
BROWSEINFO bi;
bi.hwndOwner = m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = path;
bi.lpszTitle = _T("Select path for the state file");
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_VALIDATE | BIF_USENEWUI;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
LPITEMIDLIST iil;
if(iil = SHBrowseForFolder(&bi))
{
SHGetPathFromIDList(iil, path);
m_strRecordState = path;
UpdateData(FALSE);
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "resource.h"
#include "afxwin.h"
class CGSSettingsDlg : public CDialog
{
DECLARE_DYNAMIC(CGSSettingsDlg)
private:
CList<D3DDISPLAYMODE> m_modes;
public:
CGSSettingsDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CGSSettingsDlg();
// Dialog Data
enum { IDD = IDD_CONFIG };
CComboBox m_resolution;
CComboBox m_renderer;
CComboBox m_psversion;
BOOL m_fEnablePalettizedTextures;
BOOL m_fEnableTvOut;
BOOL m_fRecordState;
BOOL m_fNloopHack;
CString m_strRecordState;
BOOL m_fLinearTexFilter;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog();
virtual void OnOK();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
};

View File

@ -1,27 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "StdAfx.h"
#include "GSSoftVertex.h"
const __m128i _80000000 = _mm_set1_epi32(0x80000000);
const __m128i _4b000000 = _mm_set1_epi32(0x4b000000);
const __m128i _3f800000 = _mm_set1_epi32(0x3f800000);

View File

@ -1,309 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
//
// GSSoftVertexFP
//
extern const __m128i _80000000, _4b000000, _3f800000;
__declspec(align(16)) union GSSoftVertexFP
{
class __declspec(novtable) Scalar
{
float val;
public:
Scalar() {}
explicit Scalar(float f) {val = f;}
explicit Scalar(int i) {val = (float)i;}
float Value() const {return val;}
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
void sat() {_mm_store_ss(&val, _mm_min_ss(_mm_max_ss(_mm_set_ss(val), _mm_setzero_ps()), _mm_set_ss(255)));}
void rcp() {_mm_store_ss(&val, _mm_rcp_ss(_mm_set_ss(val)));}
#else
void sat() {val = val < 0 ? 0 : val > 255 ? 255 : val;}
void rcp() {val = 1.0f / val;}
#endif
void abs() {val = fabs(val);}
Scalar floor_s() const {return Scalar(floor(val));}
int floor_i() const {return (int)floor(val);}
Scalar ceil_s() const {return Scalar(-floor(-val));}
int ceil_i() const {return -(int)floor(-val);}
void operator = (float f) {val = f;}
void operator = (int i) {val = (float)i;}
operator float() const {return val;}
operator int() const {return (int)val;}
void operator += (const Scalar& s) {val += s.val;}
void operator -= (const Scalar& s) {val -= s.val;}
void operator *= (const Scalar& s) {val *= s.val;}
void operator /= (const Scalar& s) {val /= s.val;}
friend Scalar operator + (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val + s2.val);}
friend Scalar operator - (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val - s2.val);}
friend Scalar operator * (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val * s2.val);}
friend Scalar operator / (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val / s2.val);}
friend Scalar operator + (const Scalar& s, int i) {return Scalar(s.val + i);}
friend Scalar operator - (const Scalar& s, int i) {return Scalar(s.val - i);}
friend Scalar operator * (const Scalar& s, int i) {return Scalar(s.val * i);}
friend Scalar operator / (const Scalar& s, int i) {return Scalar(s.val / i);}
friend Scalar operator << (const Scalar& s, int i) {return Scalar(s.val * (1<<i));}
friend Scalar operator >> (const Scalar& s, int i) {return Scalar(s.val / (1<<i));}
friend bool operator == (const Scalar& s1, const Scalar& s2) {return s1.val == s2.val;}
friend bool operator <= (const Scalar& s1, const Scalar& s2) {return s1.val <= s2.val;}
friend bool operator < (const Scalar& s1, const Scalar& s2) {return s1.val < s2.val;}
};
__declspec(align(16)) class __declspec(novtable) Vector
{
public:
union
{
union {struct {Scalar x, y, z, q;}; struct {Scalar r, g, b, a;};};
union {struct {Scalar v[4];}; struct {Scalar c[4];};};
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
union {__m128 xyzq; __m128 rgba;};
#endif
};
Vector() {}
Vector(const Vector& v) {*this = v;}
Vector(Scalar s) {*this = s;}
Vector(Scalar s0, Scalar s1, Scalar s2, Scalar s3) {x = s0; y = s1; z = s2; q = s3;}
explicit Vector(DWORD dw) {*this = dw;}
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
Vector(__m128 f0123) {*this = f0123;}
#endif
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
void operator = (const Vector& v) {xyzq = v.xyzq;}
void operator = (Scalar s) {xyzq = _mm_set1_ps(s);}
void operator = (__m128 f0123) {xyzq = f0123;}
operator __m128() const {return xyzq;}
void operator = (DWORD dw) {__m128i zero = _mm_setzero_si128(); xyzq = _mm_cvtepi32_ps(_mm_unpacklo_epi16(_mm_unpacklo_epi8(_mm_cvtsi32_si128(dw), zero), zero));}
operator DWORD() const {__m128i r0 = _mm_cvttps_epi32(xyzq); r0 = _mm_packs_epi32(r0, r0); r0 = _mm_packus_epi16(r0, r0); return (DWORD)_mm_cvtsi128_si32(r0);}
operator UINT64() const {__m128i r0 = _mm_cvttps_epi32(xyzq); r0 = _mm_packs_epi32(r0, r0); return *(UINT64*)&r0;}
void sat() {xyzq = _mm_min_ps(_mm_max_ps(xyzq, _mm_setzero_ps()), _mm_set1_ps(255));}
void rcp() {xyzq = _mm_rcp_ps(xyzq);}
Vector floor()
{
__m128 sign = _mm_and_ps(xyzq, *(__m128*)&_80000000);
__m128 r0 = _mm_or_ps(sign, *(__m128*)&_4b000000);
__m128 r1 = _mm_sub_ps(_mm_add_ps(xyzq, r0), r0);
__m128 r2 = _mm_sub_ps(r1, xyzq);
__m128 r3 = _mm_and_ps(_mm_cmpnle_ps(r2, sign), *(__m128*)&_3f800000);
__m128 r4 = _mm_sub_ps(r1, r3);
return r4;
}
void operator += (const Vector& v) {xyzq = _mm_add_ps(xyzq, v);}
void operator -= (const Vector& v) {xyzq = _mm_sub_ps(xyzq, v);}
void operator *= (const Vector& v) {xyzq = _mm_mul_ps(xyzq, v);}
void operator /= (const Vector& v) {xyzq = _mm_div_ps(xyzq, v);}
#else
void operator = (const Vector& v) {x = v.x; y = v.y; z = v.z; q = v.q;}
void operator = (Scalar s) {x = y = z = q = s;}
void operator = (DWORD dw)
{
x = Scalar((int)((dw>>0)&0xff));
y = Scalar((int)((dw>>8)&0xff));
z = Scalar((int)((dw>>16)&0xff));
q = Scalar((int)((dw>>24)&0xff));
}
operator DWORD() const
{
return (DWORD)(
(((DWORD)(int)x&0xff)<<0) |
(((DWORD)(int)y&0xff)<<8) |
(((DWORD)(int)z&0xff)<<16) |
(((DWORD)(int)q&0xff)<<24));
}
operator UINT64() const
{
return (DWORD)(
(((UINT64)(int)x&0xffff)<<0) |
(((UINT64)(int)y&0xffff)<<16) |
(((UINT64)(int)z&0xffff)<<32) |
(((UINT64)(int)q&0xffff)<<48));
}
void sat() {x.sat(); y.sat(); z.sat(); q.sat();}
void rcp() {x.rcp(); y.rcp(); z.rcp(); q.rcp();}
Vector floor() {return Vector(x.floor_s(), y.floor_s(), z.floor_s(), q.floor_s());}
void operator += (const Vector& v) {*this = *this + v;}
void operator -= (const Vector& v) {*this = *this - v;}
void operator *= (const Vector& v) {*this = *this * v;}
void operator /= (const Vector& v) {*this = *this / v;}
#endif
friend Vector operator + (const Vector& v1, const Vector& v2);
friend Vector operator - (const Vector& v1, const Vector& v2);
friend Vector operator * (const Vector& v1, const Vector& v2);
friend Vector operator / (const Vector& v1, const Vector& v2);
friend Vector operator + (const Vector& v, Scalar s);
friend Vector operator - (const Vector& v, Scalar s);
friend Vector operator * (const Vector& v, Scalar s);
friend Vector operator / (const Vector& v, Scalar s);
};
struct {__declspec(align(16)) Vector c, p, t;};
struct {__declspec(align(16)) Vector sv[3];};
struct {__declspec(align(16)) Scalar s[12];};
GSSoftVertexFP() {}
GSSoftVertexFP(const GSSoftVertexFP& v) {*this = v;}
void operator = (const GSSoftVertexFP& v) {c = v.c; p = v.p; t = v.t;}
void operator += (const GSSoftVertexFP& v) {c += v.c; p += v.p; t += v.t;}
operator CPoint() const {return CPoint((int)p.x, (int)p.y);}
__forceinline DWORD GetZ() const
{
ASSERT((float)p.z >= 0 && (float)p.q >= 0);
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
__m128 z = _mm_shuffle_ps(p, p, _MM_SHUFFLE(2,2,2,2));
__m128 q = _mm_shuffle_ps(p, p, _MM_SHUFFLE(3,3,3,3));
// TODO: check if our floor is faster than doing ss->si->ss
int zh = _mm_cvttss_si32(z);
__m128 zhi = _mm_cvtsi32_ss(zhi, zh);
__m128 zhf = _mm_mul_ss(_mm_sub_ss(z, zhi), _mm_set_ss(65536));
int zl = _mm_cvtss_si32(_mm_add_ss(zhf, q));
return ((DWORD)zh << 16) + (DWORD)zl;
#else
// return ((DWORD)(int)p.z << 16) + (DWORD)(int)((p.z - p.z.floor_s())*65536 + p.q);
int z = (int)p.z;
return ((DWORD)z << 16) + (DWORD)(((float)p.z - z)*65536 + (float)p.q);
#endif
}
};
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_add_ps(v1, v2));}
__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_sub_ps(v1, v2));}
__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_mul_ps(v1, v2));}
__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_div_ps(v1, v2));}
__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_add_ps(v, _mm_set1_ps(s)));}
__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_sub_ps(v, _mm_set1_ps(s)));}
__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps(s)));}
__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_div_ps(v, _mm_set1_ps(s)));}
__forceinline GSSoftVertexFP::Vector operator << (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps((float)(1 << i))));}
__forceinline GSSoftVertexFP::Vector operator >> (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps(1.0f / (1 << i))));}
#else
__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.q + v2.q);}
__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.q - v2.q);}
__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.q * v2.q);}
__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.q / v2.q);}
__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x + s, v.y + s, v.z + s, v.q + s);}
__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x - s, v.y - s, v.z - s, v.q - s);}
__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x * s, v.y * s, v.z * s, v.q * s);}
__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x / s, v.y / s, v.z / s, v.q / s);}
__forceinline GSSoftVertexFP::Vector operator << (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(v.x << i, v.y << i, v.z << i, v.q << i);}
__forceinline GSSoftVertexFP::Vector operator >> (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(v.x >> i, v.y >> i, v.z >> i, v.q >> i);}
#endif
//
template <class Vertex>
__forceinline Vertex operator + (const Vertex& v1, const Vertex& v2)
{
Vertex v0;
v0.c = v1.c + v2.c;
v0.p = v1.p + v2.p;
v0.t = v1.t + v2.t;
return v0;
}
template <class Vertex>
__forceinline Vertex operator - (const Vertex& v1, const Vertex& v2)
{
Vertex v0;
v0.c = v1.c - v2.c;
v0.p = v1.p - v2.p;
v0.t = v1.t - v2.t;
return v0;
}
template <class Vertex>
__forceinline Vertex operator * (const Vertex& v, typename Vertex::Scalar s)
{
Vertex v0;
Vertex::Vector vs(s);
v0.c = v.c * vs;
v0.p = v.p * vs;
v0.t = v.t * vs;
return v0;
}
template <class Vertex>
__forceinline Vertex operator / (const Vertex& v, typename Vertex::Scalar s)
{
Vertex v0;
Vertex::Vector vs(s);
v0.c = v.c / vs;
v0.p = v.p / vs;
v0.t = v.t / vs;
return v0;
}
template <class Vertex>
__forceinline void Exchange(Vertex* RESTRICT v1, Vertex* RESTRICT v2)
{
typename Vertex::Vector c = v1->c, p = v1->p, t = v1->t;
v1->c = v2->c; v1->p = v2->p; v1->t = v2->t;
v2->c = c; v2->p = p; v2->t = t;
}

View File

@ -1,259 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
//
// GSSoftVertexFP
//
__declspec(align(16)) union GSSoftVertexFP
{
class __declspec(novtable) Scalar
{
float val;
public:
Scalar() {}
explicit Scalar(float f) {val = f;}
explicit Scalar(int i) {val = (float)i;}
float Value() const {return val;}
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
void sat() {_mm_store_ss(&val, _mm_min_ss(_mm_max_ss(_mm_set_ss(val), _mm_setzero_ps()), _mm_set_ss(255)));}
void rcp() {_mm_store_ss(&val, _mm_rcp_ss(_mm_set_ss(val)));}
#else
void sat() {val = val < 0 ? 0 : val > 255 ? 255 : val;}
void rcp() {val = 1.0f / val;}
#endif
void abss() {val = abs(val);}
Scalar floors() const {return Scalar(floor(val));}
int floori() const {return (int)floor(val);}
Scalar ceils() const {return Scalar(-floor(-val));}
int ceili() const {return -(int)floor(-val);}
void operator = (float f) {val = f;}
void operator = (int i) {val = (float)i;}
operator float() const {return val;}
operator int() const {return (int)val;}
void operator += (const Scalar& s) {val += s.val;}
void operator -= (const Scalar& s) {val -= s.val;}
void operator *= (const Scalar& s) {val *= s.val;}
void operator /= (const Scalar& s) {val /= s.val;}
friend Scalar operator + (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val + s2.val);}
friend Scalar operator - (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val - s2.val);}
friend Scalar operator * (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val * s2.val);}
friend Scalar operator / (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val / s2.val);}
friend Scalar operator + (const Scalar& s1, int i) {return Scalar(s1.val + i);}
friend Scalar operator - (const Scalar& s1, int i) {return Scalar(s1.val - i);}
friend Scalar operator * (const Scalar& s1, int i) {return Scalar(s1.val * i);}
friend Scalar operator / (const Scalar& s1, int i) {return Scalar(s1.val / i);}
friend bool operator == (const Scalar& s1, const Scalar& s2) {return s1.val == s2.val;}
friend bool operator <= (const Scalar& s1, const Scalar& s2) {return s1.val <= s2.val;}
friend bool operator < (const Scalar& s1, const Scalar& s2) {return s1.val < s2.val;}
};
__declspec(align(16)) class __declspec(novtable) Vector
{
public:
union
{
union {struct {Scalar x, y, z, q;}; struct {Scalar r, g, b, a;};};
union {struct {Scalar v[4];}; struct {Scalar c[4];};};
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
union {__m128 xyzq; __m128 rgba;};
#endif
};
Vector() {}
Vector(const Vector& v) {*this = v;}
Vector(Scalar s) {*this = s;}
Vector(Scalar s0, Scalar s1, Scalar s2, Scalar s3) {x = s0; y = s1; z = s2; q = s3;}
explicit Vector(DWORD dw) {*this = dw;}
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
Vector(__m128 f0123) {*this = f0123;}
#endif
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
void operator = (const Vector& v) {xyzq = v.xyzq;}
void operator = (__m128 f0123) {xyzq = f0123;}
void operator = (Scalar s) {xyzq = _mm_set1_ps(s);}
void operator = (DWORD dw) {__m128i zero = _mm_setzero_si128(); xyzq = _mm_cvtepi32_ps(_mm_unpacklo_epi16(_mm_unpacklo_epi8(_mm_cvtsi32_si128(dw), zero), zero));}
operator __m128() const {return xyzq;}
operator DWORD() const {__m128i r0 = _mm_cvttps_epi32(xyzq); r0 = _mm_packs_epi32(r0, r0); r0 = _mm_packus_epi16(r0, r0); return (DWORD)_mm_cvtsi128_si32(r0);}
void sat() {xyzq = _mm_min_ps(_mm_max_ps(xyzq, _mm_setzero_ps()), _mm_set1_ps(255));}
void rcp() {xyzq = _mm_rcp_ps(xyzq);}
void operator += (const Vector& v) {xyzq = _mm_add_ps(xyzq, v);}
void operator -= (const Vector& v) {xyzq = _mm_sub_ps(xyzq, v);}
void operator *= (const Vector& v) {xyzq = _mm_mul_ps(xyzq, v);}
void operator /= (const Vector& v) {xyzq = _mm_div_ps(xyzq, v);}
#else
void operator = (const Vector& v) {x = v.x; y = v.y; z = v.z; q = v.q;}
void operator = (Scalar s) {x = y = z = q = s;}
void operator = (DWORD dw)
{
x = Scalar((int)(dw&0xff));
y = Scalar((int)((dw>>8)&0xff));
z = Scalar((int)((dw>>16)&0xff));
q = Scalar((int)((dw>>24)&0xff));
}
operator DWORD() const
{
return (DWORD)((((DWORD)(int)x&0xff)<<0) | (((DWORD)(int)y&0xff)<<8) | (((DWORD)(int)z&0xff)<<16) | (((DWORD)(int)q&0xff)<<24));
}
void sat() {x.sat(); y.sat(); z.sat(); q.sat();}
void rcp() {x.rcp(); y.rcp(); z.rcp(); q.rcp();}
void operator += (const Vector& v) {*this = *this + v;}
void operator -= (const Vector& v) {*this = *this - v;}
void operator *= (const Vector& v) {*this = *this * v;}
void operator /= (const Vector& v) {*this = *this / v;}
#endif
void absv() {x.abss(); y.abss(); z.abss(); q.abss();}
friend Vector operator + (const Vector& v1, const Vector& v2);
friend Vector operator - (const Vector& v1, const Vector& v2);
friend Vector operator * (const Vector& v1, const Vector& v2);
friend Vector operator / (const Vector& v1, const Vector& v2);
friend Vector operator + (const Vector& v, Scalar s);
friend Vector operator - (const Vector& v, Scalar s);
friend Vector operator * (const Vector& v, Scalar s);
friend Vector operator / (const Vector& v, Scalar s);
};
struct {__declspec(align(16)) Vector c, p, t;};
struct {__declspec(align(16)) Vector sv[3];};
struct {__declspec(align(16)) Scalar s[12];};
GSSoftVertexFP() {}
GSSoftVertexFP(const GSSoftVertexFP& v) {*this = v;}
void operator = (const GSSoftVertexFP& v) {c = v.c; p = v.p; t = v.t;}
void operator += (const GSSoftVertexFP& v) {c += v.c; p += v.p; t += v.t;}
operator CPoint() const {return CPoint((int)p.x, (int)p.y);}
friend GSSoftVertexFP operator + (const GSSoftVertexFP& v1, const GSSoftVertexFP& v2);
friend GSSoftVertexFP operator - (const GSSoftVertexFP& v1, const GSSoftVertexFP& v2);
friend GSSoftVertexFP operator * (const GSSoftVertexFP& v, Scalar s);
friend GSSoftVertexFP operator / (const GSSoftVertexFP& v, Scalar s);
static void Exchange(GSSoftVertexFP* __restrict v1, GSSoftVertexFP* __restrict v2)
{
// GSSoftVertexFP v = *v1; *v1 = *v2; *v2 = v;
Vector c = v1->c, p = v1->p, t = v1->t;
v1->c = v2->c; v1->p = v2->p; v1->t = v2->t;
v2->c = c; v2->p = p; v2->t = t;
}
//__forceinline DWORD GetZ() const {return ((DWORD)p.z<<16) + (DWORD)((p.z - floorf(p.z))*65536 + p.q);}
__forceinline DWORD GetZ() const
{
ASSERT((float)p.z >= 0 && (float)p.q >= 0);
int z = (int)p.z;
return ((DWORD)z << 16) + (DWORD)(((float)p.z - z)*65536 + (float)p.q);
}
};
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_add_ps(v1, v2));}
__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_sub_ps(v1, v2));}
__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_mul_ps(v1, v2));}
__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_div_ps(v1, v2));}
__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_add_ps(v, _mm_set1_ps(s)));}
__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_sub_ps(v, _mm_set1_ps(s)));}
__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps(s)));}
__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_div_ps(v, _mm_set1_ps(s)));}
#else
__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.q + v2.q);}
__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.q - v2.q);}
__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.q * v2.q);}
__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.q / v2.q);}
__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x + s, v.y + s, v.z + s, v.q + s);}
__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x - s, v.y - s, v.z - s, v.q - s);}
__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x * s, v.y * s, v.z * s, v.q * s);}
__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x / s, v.y / s, v.z / s, v.q / s);}
#endif
__forceinline GSSoftVertexFP operator + (const GSSoftVertexFP& v1, const GSSoftVertexFP& v2)
{
GSSoftVertexFP v0;
v0.c = v1.c + v2.c;
v0.p = v1.p + v2.p;
v0.t = v1.t + v2.t;
return v0;
}
__forceinline GSSoftVertexFP operator - (const GSSoftVertexFP& v1, const GSSoftVertexFP& v2)
{
GSSoftVertexFP v0;
v0.c = v1.c - v2.c;
v0.p = v1.p - v2.p;
v0.t = v1.t - v2.t;
return v0;
}
__forceinline GSSoftVertexFP operator * (const GSSoftVertexFP& v, GSSoftVertexFP::Scalar s)
{
GSSoftVertexFP v0;
GSSoftVertexFP::Vector vs(s);
v0.c = v.c * vs;
v0.p = v.p * vs;
v0.t = v.t * vs;
return v0;
}
__forceinline GSSoftVertexFP operator / (const GSSoftVertexFP& v, GSSoftVertexFP::Scalar s)
{
GSSoftVertexFP v0;
GSSoftVertexFP::Vector vs(s);
v0.c = v.c / vs;
v0.p = v.p / vs;
v0.t = v.t / vs;
return v0;
}

View File

@ -1,377 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
/*
inline int fixmul(int x, int y)
{
#ifndef _M_AMD64
__asm
{
mov eax, x
imul y
add eax, 0x8000
adc edx, 0
shrd eax, edx, 16
}
#else
return (int)(((__int64)x * y + 0x8000) >> 16);
#endif
}
*/
inline int fixmul(int x, int y)
{
#ifndef _M_AMD64
_asm
{
mov eax, x
imul y
shrd eax, edx, 16
sar edx, 15
jz Out2
cmp edx, -1
jz Out2
; call _set_errno_erange
mov eax, 0x7FFFFFFF
cmp x, 0
jge Out1
neg eax
Out1:
cmp y, 0
jge Out2
neg eax
Out2:
}
#else
return (int)(((__int64)x * y + 0x8000) >> 16);
#endif
}
inline int fixdiv(int x, int y)
{
#ifndef _M_AMD64
_asm
{
push esi
mov ecx, y
xor esi, esi
mov eax, x
or eax, eax
jns Out1
neg eax
inc esi
Out1:
or ecx, ecx
jns Out2
neg ecx
inc esi
Out2:
mov edx, eax
shr edx, 0x10
shl eax, 0x10
cmp edx, ecx
jae Out3
div ecx
or eax, eax
jns Out4
Out3:
; call _set_errno_erange
mov eax, 0x7FFFFFFF
Out4:
test esi, 1
je Out5
neg eax
Out5:
pop esi
}
#else
return (int)(((__int64)x << 16) / y);
#endif
}
//
// GSSoftVertexFX
//
__declspec(align(16)) union GSSoftVertexFX
{
class __declspec(novtable) Scalar
{
int val;
public:
Scalar() {}
explicit Scalar(float f) {val = (int)(f*65536);}
explicit Scalar(int i) {val = i;}
int Value() const {return val;}
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
void sat() {ASSERT(0); val = val < 0 ? 0 : val > (255<<16) ? (255<<16) : val;} // TODO
void rcp() {val = (int)(65536.0f*65536.0f / val);} // TODO
#else
void sat() {val = val < 0 ? 0 : val > (255<<16) ? (255<<16) : val;}
void rcp() {val = (int)(65536.0f*65536.0f / val);}
#endif
void abss() {val = abs(val);}
Scalar floors() const {Scalar s; s.val = val & 0xffff0000; return s;}
int floori() const {return val >> 16;}
Scalar ceils() const {Scalar s; s.val = (val + 0xffff) & 0xffff0000; return s;}
int ceili() const {return (val + 0xffff) >> 16;}
void operator = (float f) {val = (int)(f*65536);}
void operator = (int i) {val = i;}
operator float() const {return (float)val / 65536;}
operator int() const {return val >> 16;}
void operator += (const Scalar& s) {val += s.val;}
void operator -= (const Scalar& s) {val -= s.val;}
void operator *= (const Scalar& s) {val = fixmul(val, s.val);}
void operator /= (const Scalar& s) {val = fixdiv(val, s.val);}
friend Scalar operator + (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val + s2.val);}
friend Scalar operator - (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val - s2.val);}
friend Scalar operator * (const Scalar& s1, const Scalar& s2) {return Scalar(fixmul(s1.val, s2.val));}
friend Scalar operator / (const Scalar& s1, const Scalar& s2) {return Scalar(fixdiv(s1.val, s2.val));}
friend Scalar operator + (const Scalar& s1, int i) {return Scalar(s1.val + i);}
friend Scalar operator - (const Scalar& s1, int i) {return Scalar(s1.val - i);}
friend Scalar operator * (const Scalar& s1, int i) {return Scalar(s1.val * i);}
friend Scalar operator / (const Scalar& s1, int i) {return Scalar(s1.val / i);}
friend bool operator == (const Scalar& s1, const Scalar& s2) {return s1.val == s2.val;}
friend bool operator <= (const Scalar& s1, const Scalar& s2) {return s1.val <= s2.val;}
friend bool operator < (const Scalar& s1, const Scalar& s2) {return s1.val < s2.val;}
};
__declspec(align(16)) class __declspec(novtable) Vector
{
public:
union
{
union {struct {Scalar x, y, z, q;}; struct {Scalar r, g, b, a;};};
union {struct {Scalar v[4];}; struct {Scalar c[4];};};
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
union {__m128i xyzq; __m128i rgba;};
#endif
};
Vector() {}
Vector(const Vector& v) {*this = v;}
Vector(Scalar s) {*this = s;}
Vector(Scalar s0, Scalar s1, Scalar s2, Scalar s3) {x = s0; y = s1; z = s2; q = s3;}
explicit Vector(DWORD dw) {*this = dw;}
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
Vector(__m128i i0123) {*this = i0123;}
#endif
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
void operator = (const Vector& v) {xyzq = v.xyzq;}
void operator = (__m128i i0123) {xyzq = i0123;}
void operator = (Scalar s) {xyzq = _mm_set1_epi32(s.Value());}
void operator = (DWORD dw)
{
__m128i zero = _mm_setzero_si128();
xyzq = _mm_unpacklo_epi16(zero, _mm_unpacklo_epi8(_mm_cvtsi32_si128(dw), zero));
}
operator __m128i() const {return xyzq;}
operator DWORD() const
{
__m128i r0 = xyzq;
r0 = _mm_srli_si128(r0, 2);
r0 = _mm_packs_epi32(r0, r0);
r0 = _mm_packus_epi16(r0, r0);
return (DWORD)_mm_cvtsi128_si32(r0);
}
void sat() {xyzq = _mm_and_si128(_mm_min_epi16(_mm_max_epi16(xyzq, _mm_setzero_si128()), _mm_set1_epi32(0x00ff0000)), _mm_set1_epi32(0xffff0000));}
void rcp() {ASSERT(0);} // TODO {xyzq = _mm_rcp_ps(xyzq);}
#else
void operator = (const Vector& v) {x = v.x; y = v.y; z = v.z; q = v.q;}
void operator = (Scalar s) {x = y = z = q = s;}
void operator = (DWORD dw)
{
x = (int)((dw & 0x000000ff) << 16);
y = (int)((dw & 0x0000ff00) << 8);
z = (int)((dw & 0x00ff0000) << 0);
q = (int)((dw & 0xff000000) >> 8);
}
operator DWORD() const
{
return (DWORD)((((DWORD)(int)x&0xff)<<0) | (((DWORD)(int)y&0xff)<<8) | (((DWORD)(int)z&0xff)<<16) | (((DWORD)(int)q&0xff)<<24));
}
void sat() {x.sat(); y.sat(); z.sat(); q.sat();}
void rcp() {x.rcp(); y.rcp(); z.rcp(); q.rcp();}
#endif
// TODO
void operator += (const Vector& v) {*this = *this + v;}
void operator -= (const Vector& v) {*this = *this - v;}
void operator *= (const Vector& v) {*this = *this * v;}
void operator /= (const Vector& v) {*this = *this / v;}
void absv() {x.abss(); y.abss(); z.abss(); q.abss();}
friend Vector operator + (const Vector& v1, const Vector& v2);
friend Vector operator - (const Vector& v1, const Vector& v2);
friend Vector operator * (const Vector& v1, const Vector& v2);
friend Vector operator / (const Vector& v1, const Vector& v2);
friend Vector operator + (const Vector& v, Scalar s);
friend Vector operator - (const Vector& v, Scalar s);
friend Vector operator * (const Vector& v, Scalar s);
friend Vector operator / (const Vector& v, Scalar s);
};
struct {__declspec(align(16)) Vector c, p, t;};
struct {__declspec(align(16)) Vector sv[3];};
struct {__declspec(align(16)) Scalar s[12];};
GSSoftVertexFX() {}
GSSoftVertexFX(const GSSoftVertexFX& v) {*this = v;}
void operator = (const GSSoftVertexFX& v) {c = v.c; p = v.p; t = v.t;}
void operator += (const GSSoftVertexFX& v) {c += v.c; p += v.p; t += v.t;}
operator CPoint() const {return CPoint((int)p.x, (int)p.y);}
friend GSSoftVertexFX operator + (const GSSoftVertexFX& v1, const GSSoftVertexFX& v2);
friend GSSoftVertexFX operator - (const GSSoftVertexFX& v1, const GSSoftVertexFX& v2);
friend GSSoftVertexFX operator * (const GSSoftVertexFX& v, Scalar s);
friend GSSoftVertexFX operator / (const GSSoftVertexFX& v, Scalar s);
static void Exchange(GSSoftVertexFX* __restrict v1, GSSoftVertexFX* __restrict v2)
{
// GSSoftVertexFX v = *v1; *v1 = *v2; *v2 = v;
Vector c = v1->c, p = v1->p, t = v1->t;
v1->c = v2->c; v1->p = v2->p; v1->t = v2->t;
v2->c = c; v2->p = p; v2->t = t;
}
__forceinline DWORD GetZ() const
{
ASSERT((int)p.z >= 0 && (int)p.q >= 0);
return ((DWORD)(int)p.z << 1) + ((DWORD)(int)p.q >> 15);
}
};
#if _M_IX86_FP >= 2 || defined(_M_AMD64)
__forceinline GSSoftVertexFX::Vector operator + (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(_mm_add_epi32(v1, v2));}
__forceinline GSSoftVertexFX::Vector operator - (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(_mm_sub_epi32(v1, v2));}
__forceinline GSSoftVertexFX::Vector operator * (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2)
{
// TODO
__m128 r1 = _mm_mul_ps(_mm_cvtepi32_ps(v1), _mm_set1_ps(1.0f/65536));
__m128 r2 = _mm_cvtepi32_ps(v2);
__m128i r0 = _mm_cvtps_epi32(_mm_mul_ps(r1, r2));
return GSSoftVertexFX::Vector(r0);
}
__forceinline GSSoftVertexFX::Vector operator / (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2)
{
// TODO
__m128 r1 = _mm_mul_ps(_mm_cvtepi32_ps(v1), _mm_set1_ps(65536));
__m128 r2 = _mm_cvtepi32_ps(v2);
__m128i r0 = _mm_cvtps_epi32(_mm_div_ps(r1, r2));
return GSSoftVertexFX::Vector(r0);
}
__forceinline GSSoftVertexFX::Vector operator + (const GSSoftVertexFX::Vector& v, const GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(_mm_add_epi32(v, _mm_set1_epi32(s.Value())));}
__forceinline GSSoftVertexFX::Vector operator - (const GSSoftVertexFX::Vector& v, const GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(_mm_sub_epi32(v, _mm_set1_epi32(s.Value())));}
__forceinline GSSoftVertexFX::Vector operator * (const GSSoftVertexFX::Vector& v, const GSSoftVertexFX::Scalar s)
{
// TODO
__m128 r1 = _mm_mul_ps(_mm_cvtepi32_ps(v), _mm_set1_ps(1.0f/65536));
__m128 r2 = _mm_cvtepi32_ps(_mm_set1_epi32(s.Value()));
__m128i r0 = _mm_cvtps_epi32(_mm_mul_ps(r1, r2));
return GSSoftVertexFX::Vector(r0);
}
__forceinline GSSoftVertexFX::Vector operator / (const GSSoftVertexFX::Vector& v, const GSSoftVertexFX::Scalar s)
{
// TODO
__m128 r1 = _mm_mul_ps(_mm_cvtepi32_ps(v), _mm_set1_ps(65536));
__m128 r2 = _mm_cvtepi32_ps(_mm_set1_epi32(s.Value()));
__m128i r0 = _mm_cvtps_epi32(_mm_div_ps(r1, r2));
return GSSoftVertexFX::Vector(r0);
}
#else
__forceinline GSSoftVertexFX::Vector operator + (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.q + v2.q);}
__forceinline GSSoftVertexFX::Vector operator - (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.q - v2.q);}
__forceinline GSSoftVertexFX::Vector operator * (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.q * v2.q);}
__forceinline GSSoftVertexFX::Vector operator / (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.q / v2.q);}
__forceinline GSSoftVertexFX::Vector operator + (const GSSoftVertexFX::Vector& v, GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(v.x + s, v.y + s, v.z + s, v.q + s);}
__forceinline GSSoftVertexFX::Vector operator - (const GSSoftVertexFX::Vector& v, GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(v.x - s, v.y - s, v.z - s, v.q - s);}
__forceinline GSSoftVertexFX::Vector operator * (const GSSoftVertexFX::Vector& v, GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(v.x * s, v.y * s, v.z * s, v.q * s);}
__forceinline GSSoftVertexFX::Vector operator / (const GSSoftVertexFX::Vector& v, GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(v.x / s, v.y / s, v.z / s, v.q / s);}
#endif
__forceinline GSSoftVertexFX operator + (const GSSoftVertexFX& v1, const GSSoftVertexFX& v2)
{
GSSoftVertexFX v0;
v0.c = v1.c + v2.c;
v0.p = v1.p + v2.p;
v0.t = v1.t + v2.t;
return v0;
}
__forceinline GSSoftVertexFX operator - (const GSSoftVertexFX& v1, const GSSoftVertexFX& v2)
{
GSSoftVertexFX v0;
v0.c = v1.c - v2.c;
v0.p = v1.p - v2.p;
v0.t = v1.t - v2.t;
return v0;
}
__forceinline GSSoftVertexFX operator * (const GSSoftVertexFX& v, GSSoftVertexFX::Scalar s)
{
GSSoftVertexFX v0;
GSSoftVertexFX::Vector vs(s);
v0.c = v.c * vs;
v0.p = v.p * vs;
v0.t = v.t * vs;
return v0;
}
__forceinline GSSoftVertexFX operator / (const GSSoftVertexFX& v, GSSoftVertexFX::Scalar s)
{
GSSoftVertexFX v0;
GSSoftVertexFX::Vector vs(s);
v0.c = v.c / vs;
v0.p = v.p / vs;
v0.t = v.t / vs;
return v0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,446 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GS.h"
#include "GSWnd.h"
#include "GSLocalMemory.h"
#include "GSTextureCache.h"
#include "GSSoftVertex.h"
#include "GSVertexList.h"
#include "GSCapture.h"
#include "GSPerfMon.h"
//
//#define ENABLE_CAPTURE_STATE
//
/*
//#define DEBUG_SAVETEXTURES
#define DEBUG_LOG
#define DEBUG_LOG2
#define DEBUG_LOGVERTICES
#define DEBUG_RENDERTARGETS
*/
#define D3DCOLORWRITEENABLE_RGB (D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE)
#define D3DCOLORWRITEENABLE_RGBA (D3DCOLORWRITEENABLE_RGB|D3DCOLORWRITEENABLE_ALPHA)
struct GSDrawingContext
{
struct GSDrawingContext() {memset(this, 0, sizeof(*this));}
GIFRegXYOFFSET XYOFFSET;
GIFRegTEX0 TEX0;
GIFRegTEX1 TEX1;
GIFRegTEX2 TEX2;
GIFRegCLAMP CLAMP;
GIFRegMIPTBP1 MIPTBP1;
GIFRegMIPTBP2 MIPTBP2;
GIFRegSCISSOR SCISSOR;
GIFRegALPHA ALPHA;
GIFRegTEST TEST;
GIFRegFBA FBA;
GIFRegFRAME FRAME;
GIFRegZBUF ZBUF;
GSLocalMemory::psmtbl_t* ftbl;
GSLocalMemory::psmtbl_t* ztbl;
GSLocalMemory::psmtbl_t* ttbl;
};
struct GSDrawingEnvironment
{
struct GSDrawingEnvironment() {memset(this, 0, sizeof(*this));}
GIFRegPRIM PRIM;
GIFRegPRMODE PRMODE;
GIFRegPRMODECONT PRMODECONT;
GIFRegTEXCLUT TEXCLUT;
GIFRegSCANMSK SCANMSK;
GIFRegTEXA TEXA;
GIFRegFOGCOL FOGCOL;
GIFRegDIMX DIMX;
GIFRegDTHE DTHE;
GIFRegCOLCLAMP COLCLAMP;
GIFRegPABE PABE;
GSDrawingContext CTXT[2];
GIFRegBITBLTBUF BITBLTBUF;
GIFRegTRXDIR TRXDIR;
GIFRegTRXPOS TRXPOS;
GIFRegTRXREG TRXREG, TRXREG2;
};
struct GSRegSet
{
GSRegPMODE* pPMODE;
GSRegSMODE1* pSMODE1;
GSRegSMODE2* pSMODE2;
GSRegDISPFB* pDISPFB[2];
GSRegDISPLAY* pDISPLAY[2];
GSRegEXTBUF* pEXTBUF;
GSRegEXTDATA* pEXTDATA;
GSRegEXTWRITE* pEXTWRITE;
GSRegBGCOLOR* pBGCOLOR;
GSRegCSR* pCSR;
GSRegIMR* pIMR;
GSRegBUSDIR* pBUSDIR;
GSRegSIGLBLID* pSIGLBLID;
struct GSRegSet()
{
memset(this, 0, sizeof(*this));
extern BYTE* g_pBasePS2Mem;
ASSERT(g_pBasePS2Mem);
pPMODE = (GSRegPMODE*)(g_pBasePS2Mem + GS_PMODE);
pSMODE1 = (GSRegSMODE1*)(g_pBasePS2Mem + GS_SMODE1);
pSMODE2 = (GSRegSMODE2*)(g_pBasePS2Mem + GS_SMODE2);
// pSRFSH = (GSRegPMODE*)(g_pBasePS2Mem + GS_SRFSH);
// pSYNCH1 = (GSRegPMODE*)(g_pBasePS2Mem + GS_SYNCH1);
// pSYNCH2 = (GSRegPMODE*)(g_pBasePS2Mem + GS_SYNCH2);
// pSYNCV = (GSRegPMODE*)(g_pBasePS2Mem + GS_SYNCV);
pDISPFB[0] = (GSRegDISPFB*)(g_pBasePS2Mem + GS_DISPFB1);
pDISPFB[1] = (GSRegDISPFB*)(g_pBasePS2Mem + GS_DISPFB2);
pDISPLAY[0] = (GSRegDISPLAY*)(g_pBasePS2Mem + GS_DISPLAY1);
pDISPLAY[1] = (GSRegDISPLAY*)(g_pBasePS2Mem + GS_DISPLAY2);
pEXTBUF = (GSRegEXTBUF*)(g_pBasePS2Mem + GS_EXTBUF);
pEXTDATA = (GSRegEXTDATA*)(g_pBasePS2Mem + GS_EXTDATA);
pEXTWRITE = (GSRegEXTWRITE*)(g_pBasePS2Mem + GS_EXTWRITE);
pBGCOLOR = (GSRegBGCOLOR*)(g_pBasePS2Mem + GS_BGCOLOR);
pCSR = (GSRegCSR*)(g_pBasePS2Mem + GS_CSR);
pIMR = (GSRegIMR*)(g_pBasePS2Mem + GS_IMR);
pBUSDIR = (GSRegBUSDIR*)(g_pBasePS2Mem + GS_BUSDIR);
pSIGLBLID = (GSRegSIGLBLID*)(g_pBasePS2Mem + GS_SIGLBLID);
}
CSize GetDispSize(int en)
{
ASSERT(en >= 0 && en < 2);
CSize size;
size.cx = (pDISPLAY[en]->DW + 1) / (pDISPLAY[en]->MAGH + 1);
size.cy = (pDISPLAY[en]->DH + 1) / (pDISPLAY[en]->MAGV + 1);
//if(pSMODE2->INT && pSMODE2->FFMD && size.cy > 1) size.cy >>= 1;
return size;
}
CRect GetDispRect(int en)
{
ASSERT(en >= 0 && en < 2);
return CRect(CPoint(pDISPFB[en]->DBX, pDISPFB[en]->DBY), GetDispSize(en));
}
bool IsEnabled(int en)
{
ASSERT(en >= 0 && en < 2);
if(en == 0 && pPMODE->EN1) {return(pDISPLAY[0]->DW || pDISPLAY[0]->DH);}
else if(en == 1 && pPMODE->EN2) {return(pDISPLAY[1]->DW || pDISPLAY[1]->DH);}
return(false);
}
int GetFPS()
{
return ((pSMODE1->CMOD&1) ? 50 : 60) / (pSMODE2->INT ? 1 : 2);
}
};
struct GSVertex
{
GIFRegRGBAQ RGBAQ;
GIFRegST ST;
GIFRegUV UV;
GIFRegXYZ XYZ;
GIFRegFOG FOG;
};
struct GIFPath
{
GIFTag m_tag;
int m_nreg;
};
class GSState
{
friend class GSTextureCache;
protected:
static const int m_version = 4;
GIFPath m_path[3];
GSLocalMemory m_lm;
GSDrawingEnvironment m_de;
GSDrawingContext* m_ctxt;
GSRegSet m_rs;
GSVertex m_v;
float m_q;
GSPerfMon m_perfmon;
GSCapture m_capture;
private:
static const int m_nTrMaxBytes = 1024*1024*4;
int m_nTrBytes;
BYTE* m_pTrBuff;
int m_x, m_y;
void WriteStep();
void ReadStep();
void WriteTransfer(BYTE* pMem, int len);
void FlushWriteTransfer();
void ReadTransfer(BYTE* pMem, int len);
void MoveTransfer();
protected:
HWND m_hWnd;
int m_width, m_height;
CComPtr<IDirect3D9> m_pD3D;
CComPtr<IDirect3DDevice9> m_pD3DDev;
CComPtr<ID3DXFont> m_pD3DXFont;
CComPtr<IDirect3DSurface9> m_pOrgRenderTarget;
CComPtr<IDirect3DTexture9> m_pTmpRenderTarget;
CComPtr<IDirect3DPixelShader9> m_pPixelShaders[20];
CComPtr<IDirect3DPixelShader9> m_pHLSLTFX[38], m_pHLSLMerge[3], m_pHLSLRedBlue;
enum {PS11_EN11 = 12, PS11_EN01 = 13, PS11_EN10 = 14, PS11_EN00 = 15};
enum {PS14_EN11 = 16, PS14_EN01 = 17, PS14_EN10 = 18, PS14_EN00 = 19};
enum {PS_M16 = 0, PS_M24 = 1, PS_M32 = 2};
D3DPRESENT_PARAMETERS m_d3dpp;
DDCAPS m_ddcaps;
D3DCAPS9 m_caps;
D3DSURFACE_DESC m_bd;
D3DFORMAT m_fmtDepthStencil;
bool m_fEnablePalettizedTextures;
bool m_fNloopHack;
bool m_fField;
D3DTEXTUREFILTERTYPE m_texfilter;
virtual void VertexKick(bool fSkip) = 0;
virtual int DrawingKick(bool fSkip) = 0;
virtual void NewPrim() = 0;
virtual void FlushPrim() = 0;
virtual void Flip() = 0;
virtual void EndFrame() = 0;
virtual void InvalidateTexture(const GIFRegBITBLTBUF& BITBLTBUF, CRect r) {}
virtual void InvalidateLocalMem(DWORD TBP0, DWORD BW, DWORD PSM, CRect r) {}
virtual void MinMaxUV(int w, int h, CRect& r) {r.SetRect(0, 0, w, h);}
struct FlipInfo {CComPtr<IDirect3DTexture9> pRT; D3DSURFACE_DESC rd; scale_t scale;};
void FinishFlip(FlipInfo rt[2]);
void FlushPrimInternal();
//
// FIXME: savestate
GIFRegPRIM* m_pPRIM;
UINT32 m_PRIM;
void (*m_fpGSirq)();
typedef void (__fastcall GSState::*GIFPackedRegHandler)(GIFPackedReg* r);
GIFPackedRegHandler m_fpGIFPackedRegHandlers[16];
void __fastcall GIFPackedRegHandlerNull(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerPRIM(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerRGBA(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerSTQ(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerUV(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerXYZF2(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerXYZ2(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerTEX0_1(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerTEX0_2(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerCLAMP_1(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerCLAMP_2(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerFOG(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerXYZF3(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerXYZ3(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerA_D(GIFPackedReg* r);
void __fastcall GIFPackedRegHandlerNOP(GIFPackedReg* r);
typedef void (__fastcall GSState::*GIFRegHandler)(GIFReg* r);
GIFRegHandler m_fpGIFRegHandlers[256];
void __fastcall GIFRegHandlerNull(GIFReg* r);
void __fastcall GIFRegHandlerPRIM(GIFReg* r);
void __fastcall GIFRegHandlerRGBAQ(GIFReg* r);
void __fastcall GIFRegHandlerST(GIFReg* r);
void __fastcall GIFRegHandlerUV(GIFReg* r);
void __fastcall GIFRegHandlerXYZF2(GIFReg* r);
void __fastcall GIFRegHandlerXYZ2(GIFReg* r);
void __fastcall GIFRegHandlerTEX0_1(GIFReg* r);
void __fastcall GIFRegHandlerTEX0_2(GIFReg* r);
void __fastcall GIFRegHandlerCLAMP_1(GIFReg* r);
void __fastcall GIFRegHandlerCLAMP_2(GIFReg* r);
void __fastcall GIFRegHandlerFOG(GIFReg* r);
void __fastcall GIFRegHandlerXYZF3(GIFReg* r);
void __fastcall GIFRegHandlerXYZ3(GIFReg* r);
void __fastcall GIFRegHandlerNOP(GIFReg* r);
void __fastcall GIFRegHandlerTEX1_1(GIFReg* r);
void __fastcall GIFRegHandlerTEX1_2(GIFReg* r);
void __fastcall GIFRegHandlerTEX2_1(GIFReg* r);
void __fastcall GIFRegHandlerTEX2_2(GIFReg* r);
void __fastcall GIFRegHandlerXYOFFSET_1(GIFReg* r);
void __fastcall GIFRegHandlerXYOFFSET_2(GIFReg* r);
void __fastcall GIFRegHandlerPRMODECONT(GIFReg* r);
void __fastcall GIFRegHandlerPRMODE(GIFReg* r);
void __fastcall GIFRegHandlerTEXCLUT(GIFReg* r);
void __fastcall GIFRegHandlerSCANMSK(GIFReg* r);
void __fastcall GIFRegHandlerMIPTBP1_1(GIFReg* r);
void __fastcall GIFRegHandlerMIPTBP1_2(GIFReg* r);
void __fastcall GIFRegHandlerMIPTBP2_1(GIFReg* r);
void __fastcall GIFRegHandlerMIPTBP2_2(GIFReg* r);
void __fastcall GIFRegHandlerTEXA(GIFReg* r);
void __fastcall GIFRegHandlerFOGCOL(GIFReg* r);
void __fastcall GIFRegHandlerTEXFLUSH(GIFReg* r);
void __fastcall GIFRegHandlerSCISSOR_1(GIFReg* r);
void __fastcall GIFRegHandlerSCISSOR_2(GIFReg* r);
void __fastcall GIFRegHandlerALPHA_1(GIFReg* r);
void __fastcall GIFRegHandlerALPHA_2(GIFReg* r);
void __fastcall GIFRegHandlerDIMX(GIFReg* r);
void __fastcall GIFRegHandlerDTHE(GIFReg* r);
void __fastcall GIFRegHandlerCOLCLAMP(GIFReg* r);
void __fastcall GIFRegHandlerTEST_1(GIFReg* r);
void __fastcall GIFRegHandlerTEST_2(GIFReg* r);
void __fastcall GIFRegHandlerPABE(GIFReg* r);
void __fastcall GIFRegHandlerFBA_1(GIFReg* r);
void __fastcall GIFRegHandlerFBA_2(GIFReg* r);
void __fastcall GIFRegHandlerFRAME_1(GIFReg* r);
void __fastcall GIFRegHandlerFRAME_2(GIFReg* r);
void __fastcall GIFRegHandlerZBUF_1(GIFReg* r);
void __fastcall GIFRegHandlerZBUF_2(GIFReg* r);
void __fastcall GIFRegHandlerBITBLTBUF(GIFReg* r);
void __fastcall GIFRegHandlerTRXPOS(GIFReg* r);
void __fastcall GIFRegHandlerTRXREG(GIFReg* r);
void __fastcall GIFRegHandlerTRXDIR(GIFReg* r);
void __fastcall GIFRegHandlerHWREG(GIFReg* r);
void __fastcall GIFRegHandlerSIGNAL(GIFReg* r);
void __fastcall GIFRegHandlerFINISH(GIFReg* r);
void __fastcall GIFRegHandlerLABEL(GIFReg* r);
public:
GSState(int w, int h, HWND hWnd, HRESULT& hr);
virtual ~GSState();
bool m_fMultiThreaded;
virtual HRESULT ResetDevice(bool fForceWindowed = false);
UINT32 Freeze(freezeData* fd, bool fSizeOnly);
UINT32 Defrost(const freezeData* fd);
virtual void Reset();
void WriteCSR(UINT32 csr);
void ReadFIFO(BYTE* pMem);
void Transfer1(BYTE* pMem, UINT32 addr);
void Transfer2(BYTE* pMem, UINT32 size);
void Transfer3(BYTE* pMem, UINT32 size);
void Transfer(BYTE* pMem, UINT32 size, GIFPath& path);
void VSync(int field);
void GSirq(void (*fpGSirq)()) {m_fpGSirq = fpGSirq;}
UINT32 MakeSnapshot(char* path);
void Capture();
CString m_strDefaultTitle;
int m_iOSD;
void ToggleOSD();
// state
void CaptureState(CString fn);
FILE* m_sfp;
// logging
FILE* m_fp;
#ifdef DEBUG_LOGVERTICES
#define LOGV(_x_) LOGVERTEX _x_
#else
#define LOGV(_x_)
#endif
#ifdef DEBUG_LOG
void LOG(LPCTSTR fmt, ...)
{
va_list args;
va_start(args, fmt);
////////////
/*
if(_tcsstr(fmt, _T("VSync"))
|| _tcsstr(fmt, _T("*** WARNING ***"))
// || _tcsstr(fmt, _T("Flush"))
|| _tcsstr(fmt, _T("CSR"))
|| _tcsstr(fmt, _T("DISP"))
|| _tcsstr(fmt, _T("FRAME"))
|| _tcsstr(fmt, _T("ZBUF"))
|| _tcsstr(fmt, _T("SMODE"))
|| _tcsstr(fmt, _T("PMODE"))
|| _tcsstr(fmt, _T("BITBLTBUF"))
|| _tcsstr(fmt, _T("TRX"))
// || _tcsstr(fmt, _T("PRIM"))
// || _tcsstr(fmt, _T("RGB"))
// || _tcsstr(fmt, _T("XYZ"))
// || _tcsstr(fmt, _T("ST"))
// || _tcsstr(fmt, _T("XYOFFSET"))
// || _tcsstr(fmt, _T("TEX"))
|| _tcsstr(fmt, _T("TEX0"))
// || _tcsstr(fmt, _T("TEX2"))
// || _tcsstr(fmt, _T("TEXFLUSH"))
// || _tcsstr(fmt, _T("UV"))
// || _tcsstr(fmt, _T("FOG"))
// || _tcsstr(fmt, _T("ALPHA"))
// || _tcsstr(fmt, _T("TBP0")) == fmt
// || _tcsstr(fmt, _T("CBP")) == fmt
// || _tcsstr(fmt, _T("*TC2 ")) == fmt
)
*/
if(m_fp)
{
TCHAR buff[2048];
_stprintf(buff, _T("%d: "), clock());
_vstprintf(buff + strlen(buff), fmt, args);
_fputts(buff, m_fp);
fflush(m_fp);
}
va_end(args);
}
#else
#define LOG __noop
#endif
#ifdef DEBUG_LOG2
void LOG2(LPCTSTR fmt, ...)
{
va_list args;
va_start(args, fmt);
if(m_fp)
{
TCHAR buff[2048];
_stprintf(buff, _T("%d: "), clock());
_vstprintf(buff + strlen(buff), fmt, args);
_fputts(buff, m_fp);
}
va_end(args);
}
#else
#define LOG2 __noop
#endif
};

View File

@ -1,231 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "StdAfx.h"
#include "gstables.h"
DWORD blockTable32[4][8] = {
{ 0, 1, 4, 5, 16, 17, 20, 21},
{ 2, 3, 6, 7, 18, 19, 22, 23},
{ 8, 9, 12, 13, 24, 25, 28, 29},
{ 10, 11, 14, 15, 26, 27, 30, 31}
};
DWORD blockTable32Z[4][8] = {
{ 24, 25, 28, 29, 8, 9, 12, 13},
{ 26, 27, 30, 31, 10, 11, 14, 15},
{ 16, 17, 20, 21, 0, 1, 4, 5},
{ 18, 19, 22, 23, 2, 3, 6, 7}
};
DWORD blockTable16[8][4] = {
{ 0, 2, 8, 10 },
{ 1, 3, 9, 11 },
{ 4, 6, 12, 14 },
{ 5, 7, 13, 15 },
{ 16, 18, 24, 26 },
{ 17, 19, 25, 27 },
{ 20, 22, 28, 30 },
{ 21, 23, 29, 31 }
};
DWORD blockTable16S[8][4] = {
{ 0, 2, 16, 18 },
{ 1, 3, 17, 19 },
{ 8, 10, 24, 26 },
{ 9, 11, 25, 27 },
{ 4, 6, 20, 22 },
{ 5, 7, 21, 23 },
{ 12, 14, 28, 30 },
{ 13, 15, 29, 31 }
};
DWORD blockTable16Z[8][4] = {
{ 24, 26, 16, 18 },
{ 25, 27, 17, 19 },
{ 28, 30, 20, 22 },
{ 29, 31, 21, 23 },
{ 8, 10, 0, 2 },
{ 9, 11, 1, 3 },
{ 12, 14, 4, 6 },
{ 13, 15, 5, 7 }
};
DWORD blockTable16SZ[8][4] = {
{ 24, 26, 8, 10 },
{ 25, 27, 9, 11 },
{ 16, 18, 0, 2 },
{ 17, 19, 1, 3 },
{ 28, 30, 12, 14 },
{ 29, 31, 13, 15 },
{ 20, 22, 4, 6 },
{ 21, 23, 5, 7 }
};
DWORD blockTable8[4][8] = {
{ 0, 1, 4, 5, 16, 17, 20, 21},
{ 2, 3, 6, 7, 18, 19, 22, 23},
{ 8, 9, 12, 13, 24, 25, 28, 29},
{ 10, 11, 14, 15, 26, 27, 30, 31}
};
DWORD blockTable4[8][4] = {
{ 0, 2, 8, 10 },
{ 1, 3, 9, 11 },
{ 4, 6, 12, 14 },
{ 5, 7, 13, 15 },
{ 16, 18, 24, 26 },
{ 17, 19, 25, 27 },
{ 20, 22, 28, 30 },
{ 21, 23, 29, 31 }
};
DWORD columnTable32[8][8] = {
{ 0, 1, 4, 5, 8, 9, 12, 13 },
{ 2, 3, 6, 7, 10, 11, 14, 15 },
{ 16, 17, 20, 21, 24, 25, 28, 29 },
{ 18, 19, 22, 23, 26, 27, 30, 31 },
{ 32, 33, 36, 37, 40, 41, 44, 45 },
{ 34, 35, 38, 39, 42, 43, 46, 47 },
{ 48, 49, 52, 53, 56, 57, 60, 61 },
{ 50, 51, 54, 55, 58, 59, 62, 63 },
};
DWORD columnTable16[8][16] = {
{ 0, 2, 8, 10, 16, 18, 24, 26,
1, 3, 9, 11, 17, 19, 25, 27 },
{ 4, 6, 12, 14, 20, 22, 28, 30,
5, 7, 13, 15, 21, 23, 29, 31 },
{ 32, 34, 40, 42, 48, 50, 56, 58,
33, 35, 41, 43, 49, 51, 57, 59 },
{ 36, 38, 44, 46, 52, 54, 60, 62,
37, 39, 45, 47, 53, 55, 61, 63 },
{ 64, 66, 72, 74, 80, 82, 88, 90,
65, 67, 73, 75, 81, 83, 89, 91 },
{ 68, 70, 76, 78, 84, 86, 92, 94,
69, 71, 77, 79, 85, 87, 93, 95 },
{ 96, 98, 104, 106, 112, 114, 120, 122,
97, 99, 105, 107, 113, 115, 121, 123 },
{ 100, 102, 108, 110, 116, 118, 124, 126,
101, 103, 109, 111, 117, 119, 125, 127 },
};
DWORD columnTable8[16][16] = {
{ 0, 4, 16, 20, 32, 36, 48, 52, // column 0
2, 6, 18, 22, 34, 38, 50, 54 },
{ 8, 12, 24, 28, 40, 44, 56, 60,
10, 14, 26, 30, 42, 46, 58, 62 },
{ 33, 37, 49, 53, 1, 5, 17, 21,
35, 39, 51, 55, 3, 7, 19, 23 },
{ 41, 45, 57, 61, 9, 13, 25, 29,
43, 47, 59, 63, 11, 15, 27, 31 },
{ 96, 100, 112, 116, 64, 68, 80, 84, // column 1
98, 102, 114, 118, 66, 70, 82, 86 },
{ 104, 108, 120, 124, 72, 76, 88, 92,
106, 110, 122, 126, 74, 78, 90, 94 },
{ 65, 69, 81, 85, 97, 101, 113, 117,
67, 71, 83, 87, 99, 103, 115, 119 },
{ 73, 77, 89, 93, 105, 109, 121, 125,
75, 79, 91, 95, 107, 111, 123, 127 },
{ 128, 132, 144, 148, 160, 164, 176, 180, // column 2
130, 134, 146, 150, 162, 166, 178, 182 },
{ 136, 140, 152, 156, 168, 172, 184, 188,
138, 142, 154, 158, 170, 174, 186, 190 },
{ 161, 165, 177, 181, 129, 133, 145, 149,
163, 167, 179, 183, 131, 135, 147, 151 },
{ 169, 173, 185, 189, 137, 141, 153, 157,
171, 175, 187, 191, 139, 143, 155, 159 },
{ 224, 228, 240, 244, 192, 196, 208, 212, // column 3
226, 230, 242, 246, 194, 198, 210, 214 },
{ 232, 236, 248, 252, 200, 204, 216, 220,
234, 238, 250, 254, 202, 206, 218, 222 },
{ 193, 197, 209, 213, 225, 229, 241, 245,
195, 199, 211, 215, 227, 231, 243, 247 },
{ 201, 205, 217, 221, 233, 237, 249, 253,
203, 207, 219, 223, 235, 239, 251, 255 },
};
DWORD columnTable4[16][32] = {
{ 0, 8, 32, 40, 64, 72, 96, 104, // column 0
2, 10, 34, 42, 66, 74, 98, 106,
4, 12, 36, 44, 68, 76, 100, 108,
6, 14, 38, 46, 70, 78, 102, 110 },
{ 16, 24, 48, 56, 80, 88, 112, 120,
18, 26, 50, 58, 82, 90, 114, 122,
20, 28, 52, 60, 84, 92, 116, 124,
22, 30, 54, 62, 86, 94, 118, 126 },
{ 65, 73, 97, 105, 1, 9, 33, 41,
67, 75, 99, 107, 3, 11, 35, 43,
69, 77, 101, 109, 5, 13, 37, 45,
71, 79, 103, 111, 7, 15, 39, 47 },
{ 81, 89, 113, 121, 17, 25, 49, 57,
83, 91, 115, 123, 19, 27, 51, 59,
85, 93, 117, 125, 21, 29, 53, 61,
87, 95, 119, 127, 23, 31, 55, 63 },
{ 192, 200, 224, 232, 128, 136, 160, 168, // column 1
194, 202, 226, 234, 130, 138, 162, 170,
196, 204, 228, 236, 132, 140, 164, 172,
198, 206, 230, 238, 134, 142, 166, 174 },
{ 208, 216, 240, 248, 144, 152, 176, 184,
210, 218, 242, 250, 146, 154, 178, 186,
212, 220, 244, 252, 148, 156, 180, 188,
214, 222, 246, 254, 150, 158, 182, 190 },
{ 129, 137, 161, 169, 193, 201, 225, 233,
131, 139, 163, 171, 195, 203, 227, 235,
133, 141, 165, 173, 197, 205, 229, 237,
135, 143, 167, 175, 199, 207, 231, 239 },
{ 145, 153, 177, 185, 209, 217, 241, 249,
147, 155, 179, 187, 211, 219, 243, 251,
149, 157, 181, 189, 213, 221, 245, 253,
151, 159, 183, 191, 215, 223, 247, 255 },
{ 256, 264, 288, 296, 320, 328, 352, 360, // column 2
258, 266, 290, 298, 322, 330, 354, 362,
260, 268, 292, 300, 324, 332, 356, 364,
262, 270, 294, 302, 326, 334, 358, 366 },
{ 272, 280, 304, 312, 336, 344, 368, 376,
274, 282, 306, 314, 338, 346, 370, 378,
276, 284, 308, 316, 340, 348, 372, 380,
278, 286, 310, 318, 342, 350, 374, 382 },
{ 321, 329, 353, 361, 257, 265, 289, 297,
323, 331, 355, 363, 259, 267, 291, 299,
325, 333, 357, 365, 261, 269, 293, 301,
327, 335, 359, 367, 263, 271, 295, 303 },
{ 337, 345, 369, 377, 273, 281, 305, 313,
339, 347, 371, 379, 275, 283, 307, 315,
341, 349, 373, 381, 277, 285, 309, 317,
343, 351, 375, 383, 279, 287, 311, 319 },
{ 448, 456, 480, 488, 384, 392, 416, 424, // column 3
450, 458, 482, 490, 386, 394, 418, 426,
452, 460, 484, 492, 388, 396, 420, 428,
454, 462, 486, 494, 390, 398, 422, 430 },
{ 464, 472, 496, 504, 400, 408, 432, 440,
466, 474, 498, 506, 402, 410, 434, 442,
468, 476, 500, 508, 404, 412, 436, 444,
470, 478, 502, 510, 406, 414, 438, 446 },
{ 385, 393, 417, 425, 449, 457, 481, 489,
387, 395, 419, 427, 451, 459, 483, 491,
389, 397, 421, 429, 453, 461, 485, 493,
391, 399, 423, 431, 455, 463, 487, 495 },
{ 401, 409, 433, 441, 465, 473, 497, 505,
403, 411, 435, 443, 467, 475, 499, 507,
405, 413, 437, 445, 469, 477, 501, 509,
407, 415, 439, 447, 471, 479, 503, 511 },
};

View File

@ -1,35 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
extern DWORD blockTable32[4][8];
extern DWORD blockTable32Z[4][8];
extern DWORD blockTable16[8][4];
extern DWORD blockTable16S[8][4];
extern DWORD blockTable16Z[8][4];
extern DWORD blockTable16SZ[8][4];
extern DWORD blockTable8[4][8];
extern DWORD blockTable4[8][4];
extern DWORD columnTable32[8][8];
extern DWORD columnTable16[8][16];
extern DWORD columnTable8[16][16];
extern DWORD columnTable4[16][32];

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GS.h"
#include "GSLocalMemory.h"
template <class T> class CSurfMap : public CMap<DWORD, DWORD, CComPtr<T>, CComPtr<T>& > {};
extern bool IsRenderTarget(IDirect3DTexture9* pTexture);
extern bool HasSharedBits(DWORD sbp, DWORD spsm, DWORD dbp, DWORD dpsm);
// TODO: get rid of this *PrivateData
#ifdef __INTEL_COMPILER
struct __declspec(uuid("5D5EFE0E-5407-4BCF-855D-C46CBCD075FA"))
#else
[uuid("5D5EFE0E-5407-4BCF-855D-C46CBCD075FA")] struct
#endif
scale_t
{
float x, y;
struct scale_t() {x = y = 1;}
struct scale_t(float x, float y) {this->x = x; this->y = y;}
struct scale_t(IDirect3DResource9* p) {Get(p);}
bool operator == (const struct scale_t& s) {return fabs(x - s.x) < 0.001 && fabs(y - s.y) < 0.001;}
void Set(IDirect3DResource9* p) {p->SetPrivateData(__uuidof(*this), this, sizeof(*this), 0);}
void Get(IDirect3DResource9* p) {DWORD size = sizeof(*this); p->GetPrivateData(__uuidof(*this), this, &size);}
};
class GSDirtyRect
{
DWORD m_PSM;
CRect m_rcDirty;
public:
GSDirtyRect() : m_PSM(PSM_PSMCT32), m_rcDirty(0, 0, 0, 0) {}
GSDirtyRect(DWORD PSM, CRect r);
CRect GetDirtyRect(const GIFRegTEX0& TEX0);
};
class GSDirtyRectList : public CAtlList<GSDirtyRect>
{
public:
GSDirtyRectList() {}
GSDirtyRectList(const GSDirtyRectList& l) {*this = l;}
void operator = (const GSDirtyRectList& l);
CRect GetDirtyRect(const GIFRegTEX0& TEX0);
};
struct GSTextureBase
{
CComPtr<IDirect3DTexture9> m_pTexture, m_pPalette;
scale_t m_scale;
bool m_fRT;
D3DSURFACE_DESC m_desc;
GSTextureBase();
};
struct GSTexture : public GSTextureBase
{
GIFRegCLAMP m_CLAMP;
GIFRegTEX0 m_TEX0;
GIFRegTEXA m_TEXA; // *
DWORD m_clut[256]; // *
GSDirtyRectList m_rcDirty;
CRect m_rcValid;
CRect m_rcHash;
DWORD m_dwHash, m_nHashDiff, m_nHashSame;
DWORD m_nBytes;
int m_nAge, m_nVsyncs;
CInterfaceList<IDirect3DTexture9> m_pSubTextures;
bool m_fTemp;
GSTexture();
};
class GSState;
class GSTextureCache : private CAtlList<GSTexture*>
{
protected:
CInterfaceList<IDirect3DTexture9> m_pTexturePool;
HRESULT CreateTexture(GSState* s, GSTexture* pt, DWORD PSM, DWORD CPSM = PSM_PSMCT32);
bool IsTextureInCache(IDirect3DTexture9* pTexture);
void RemoveOldTextures(GSState* s);
bool GetDirtyRect(GSState* s, GSTexture* pt, CRect& r);
DWORD HashTexture(const CRect& r, int pitch, void* bits);
HRESULT UpdateTexture(GSState* s, GSTexture* pt, GSLocalMemory::readTexture rt);
GSTexture* ConvertRT(GSState* s, GSTexture* pt);
GSTexture* ConvertRTPitch(GSState* s, GSTexture* pt);
GSTexture* ConvertRTWidthHeight(GSState* s, GSTexture* pt);
CInterfaceList<IDirect3DTexture9> m_pRTPool;
HRESULT CreateRT(GSState* s, int w, int h, IDirect3DTexture9** ppRT);
public:
GSTextureCache();
~GSTextureCache();
bool Fetch(GSState* s, GSTextureBase& t);
bool FetchP(GSState* s, GSTextureBase& t);
bool FetchNP(GSState* s, GSTextureBase& t);
void IncAge(CSurfMap<IDirect3DTexture9>& pRTs);
void ResetAge(DWORD TBP0);
void RemoveAll();
void InvalidateTexture(GSState* s, const GIFRegBITBLTBUF& BITBLTBUF, const CRect& r);
void InvalidateLocalMem(GSState* s, DWORD TBP0, DWORD BW, DWORD PSM, const CRect& r);
void AddRT(GIFRegTEX0& TEX0, IDirect3DTexture9* pRT, scale_t scale);
};

View File

@ -1,216 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSState.h"
void GSState::WriteStep()
{
// if(m_y == m_de.TRXREG.RRH && m_x == m_de.TRXPOS.DSAX) ASSERT(0);
if(++m_x == m_de.TRXREG.RRW)
{
m_x = m_de.TRXPOS.DSAX;
m_y++;
}
}
void GSState::ReadStep()
{
// if(m_y == m_de.TRXREG.RRH && m_x == m_de.TRXPOS.SSAX) ASSERT(0);
if(++m_x == m_de.TRXREG.RRW)
{
m_x = m_de.TRXPOS.SSAX;
m_y++;
}
}
void GSState::WriteTransfer(BYTE* pMem, int len)
{
LOG(_T("*TC2 WriteTransfer %d,%d (psm=%d rr=%dx%d len=%d)\n"), m_x, m_y, m_de.BITBLTBUF.DPSM, m_de.TRXREG.RRW, m_de.TRXREG.RRH, len);
if(len == 0) return;
// TODO: hmmmm
if(m_pPRIM->TME && (m_de.BITBLTBUF.DBP == m_ctxt->TEX0.TBP0 || m_de.BITBLTBUF.DBP == m_ctxt->TEX0.CBP))
FlushPrim();
int bpp = GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.DPSM].trbpp;
int pitch = (m_de.TRXREG.RRW - m_de.TRXPOS.DSAX)*bpp>>3;
int height = len / pitch;
if(m_nTrBytes > 0 || height < m_de.TRXREG.RRH - m_de.TRXPOS.DSAY)
{
LOG(_T("*TC2 WriteTransfer delayed\n"));
ASSERT(len <= m_nTrMaxBytes); // transferring more than 4mb into a 4mb local mem doesn't make any sense
len = min(m_nTrMaxBytes, len);
if(m_nTrBytes + len > m_nTrMaxBytes)
FlushWriteTransfer();
memcpy(&m_pTrBuff[m_nTrBytes], pMem, len);
m_nTrBytes += len;
}
else
{
int x = m_x, y = m_y;
(m_lm.*GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.DPSM].st)(m_x, m_y, pMem, len, m_de.BITBLTBUF, m_de.TRXPOS, m_de.TRXREG);
m_perfmon.IncCounter(GSPerfMon::c_swizzle, len);
//ASSERT(m_de.TRXREG.RRH >= m_y - y);
CRect r(m_de.TRXPOS.DSAX, y, m_de.TRXREG.RRW, min(m_x == m_de.TRXPOS.DSAX ? m_y : m_y+1, m_de.TRXREG.RRH));
InvalidateTexture(m_de.BITBLTBUF, r);
m_lm.InvalidateCLUT();
}
}
void GSState::FlushWriteTransfer()
{
if(!m_nTrBytes) return;
int x = m_x, y = m_y;
LOG(_T("*TC2 FlushWriteTransfer %d,%d-%d,%d (psm=%d rr=%dx%d len=%d)\n"), x, y, m_x, m_y, m_de.BITBLTBUF.DPSM, m_de.TRXREG.RRW, m_de.TRXREG.RRH, m_nTrBytes);
(m_lm.*GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.DPSM].st)(m_x, m_y, m_pTrBuff, m_nTrBytes, m_de.BITBLTBUF, m_de.TRXPOS, m_de.TRXREG);
m_perfmon.IncCounter(GSPerfMon::c_swizzle, m_nTrBytes);
m_nTrBytes = 0;
//ASSERT(m_de.TRXREG.RRH >= m_y - y);
CRect r(m_de.TRXPOS.DSAX, y, m_de.TRXREG.RRW, min(m_x == m_de.TRXPOS.DSAX ? m_y : m_y+1, m_de.TRXREG.RRH));
InvalidateTexture(m_de.BITBLTBUF, r);
m_lm.InvalidateCLUT();
}
void GSState::ReadTransfer(BYTE* pMem, int len)
{
BYTE* pb = (BYTE*)pMem;
WORD* pw = (WORD*)pMem;
DWORD* pd = (DWORD*)pMem;
if(m_y >= (int)m_de.TRXREG.RRH) {ASSERT(0); return;}
if(m_x == m_de.TRXPOS.SSAX && m_y == m_de.TRXPOS.SSAY)
{
CRect r(m_de.TRXPOS.SSAX, m_de.TRXPOS.SSAY, m_de.TRXREG.RRW, m_de.TRXREG.RRH);
InvalidateLocalMem(m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW, m_de.BITBLTBUF.SPSM, r);
}
switch(m_de.BITBLTBUF.SPSM)
{
case PSM_PSMCT32:
for(len /= 4; len-- > 0; ReadStep(), pd++)
*pd = m_lm.readPixel32(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
break;
case PSM_PSMCT24:
for(len /= 3; len-- > 0; ReadStep(), pb+=3)
{
DWORD dw = m_lm.readPixel24(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
pb[0] = ((BYTE*)&dw)[0]; pb[1] = ((BYTE*)&dw)[1]; pb[2] = ((BYTE*)&dw)[2];
}
break;
case PSM_PSMCT16:
for(len /= 2; len-- > 0; ReadStep(), pw++)
*pw = (WORD)m_lm.readPixel16(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
break;
case PSM_PSMCT16S:
for(len /= 2; len-- > 0; ReadStep(), pw++)
*pw = (WORD)m_lm.readPixel16S(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
break;
case PSM_PSMT8:
for(; len-- > 0; ReadStep(), pb++)
*pb = (BYTE)m_lm.readPixel8(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
break;
case PSM_PSMT4:
for(; len-- > 0; ReadStep(), ReadStep(), pb++)
*pb = (BYTE)(m_lm.readPixel4(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)&0x0f)
| (BYTE)(m_lm.readPixel4(m_x+1, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)<<4);
break;
case PSM_PSMT8H:
for(; len-- > 0; ReadStep(), pb++)
*pb = (BYTE)m_lm.readPixel8H(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
break;
case PSM_PSMT4HL:
for(; len-- > 0; ReadStep(), ReadStep(), pb++)
*pb = (BYTE)(m_lm.readPixel4HL(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)&0x0f)
| (BYTE)(m_lm.readPixel4HL(m_x+1, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)<<4);
break;
case PSM_PSMT4HH:
for(; len-- > 0; ReadStep(), ReadStep(), pb++)
*pb = (BYTE)(m_lm.readPixel4HH(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)&0x0f)
| (BYTE)(m_lm.readPixel4HH(m_x+1, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)<<4);
break;
case PSM_PSMZ32:
for(len /= 4; len-- > 0; ReadStep(), pd++)
*pd = m_lm.readPixel32Z(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
break;
case PSM_PSMZ24:
for(len /= 3; len-- > 0; ReadStep(), pb+=3)
{
DWORD dw = m_lm.readPixel24Z(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
pb[0] = ((BYTE*)&dw)[0]; pb[1] = ((BYTE*)&dw)[1]; pb[2] = ((BYTE*)&dw)[2];
}
break;
case PSM_PSMZ16:
for(len /= 2; len-- > 0; ReadStep(), pw++)
*pw = (WORD)m_lm.readPixel16Z(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
break;
case PSM_PSMZ16S:
for(len /= 2; len-- > 0; ReadStep(), pw++)
*pw = (WORD)m_lm.readPixel16SZ(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW);
break;
}
}
void GSState::MoveTransfer()
{
GSLocalMemory::readPixel rp = GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.SPSM].rp;
GSLocalMemory::writePixel wp = GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.DPSM].wp;
int sx = m_de.TRXPOS.SSAX;
int dx = m_de.TRXPOS.DSAX;
int sy = m_de.TRXPOS.SSAY;
int dy = m_de.TRXPOS.DSAY;
int w = m_de.TRXREG.RRW;
int h = m_de.TRXREG.RRH;
int xinc = 1;
int yinc = 1;
if(sx < dx) sx += w-1, dx += w-1, xinc = -1;
if(sy < dy) sy += h-1, dy += h-1, yinc = -1;
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc*w, dx -= xinc*w)
for(int x = 0; x < w; x++, sx += xinc, dx += xinc)
(m_lm.*wp)(dx, dy, (m_lm.*rp)(sx, sy, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW), m_de.BITBLTBUF.DBP, m_de.BITBLTBUF.DBW);
}

View File

@ -1,79 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSdx9.h"
#include "GSState.h"
BOOL IsDepthFormatOk(IDirect3D9* pD3D, D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat)
{
// Verify that the depth format exists.
HRESULT hr = pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, AdapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, DepthFormat);
if(FAILED(hr)) return FALSE;
// Verify that the depth format is compatible.
hr = pD3D->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, AdapterFormat, BackBufferFormat, DepthFormat);
return SUCCEEDED(hr);
}
HRESULT CompileShaderFromResource(IDirect3DDevice9* pD3DDev, UINT id, CString entry, CString target, UINT flags, IDirect3DPixelShader9** ppPixelShader)
{
CheckPointer(pD3DDev, E_POINTER);
CheckPointer(ppPixelShader, E_POINTER);
CComPtr<ID3DXBuffer> pShader, pErrorMsgs;
HRESULT hr = D3DXCompileShaderFromResource(
AfxGetResourceHandle(), MAKEINTRESOURCE(id),
NULL, NULL,
entry, target, flags,
&pShader, &pErrorMsgs, NULL);
ASSERT(SUCCEEDED(hr));
if(SUCCEEDED(hr))
{
hr = pD3DDev->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), ppPixelShader);
ASSERT(SUCCEEDED(hr));
}
return hr;
}
HRESULT AssembleShaderFromResource(IDirect3DDevice9* pD3DDev, UINT id, UINT flags, IDirect3DPixelShader9** ppPixelShader)
{
CheckPointer(pD3DDev, E_POINTER);
CheckPointer(ppPixelShader, E_POINTER);
CComPtr<ID3DXBuffer> pShader, pErrorMsgs;
HRESULT hr = D3DXAssembleShaderFromResource(
AfxGetResourceHandle(), MAKEINTRESOURCE(id),
NULL, NULL,
flags,
&pShader, &pErrorMsgs);
ASSERT(SUCCEEDED(hr));
if(SUCCEEDED(hr))
{
hr = pD3DDev->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), ppPixelShader);
ASSERT(SUCCEEDED(hr));
}
return hr;
}

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
extern BOOL IsDepthFormatOk(IDirect3D9* pD3D, D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat);
extern HRESULT CompileShaderFromResource(IDirect3DDevice9* pD3DDev, UINT id, CString entry, CString target, UINT flags, IDirect3DPixelShader9** ppPixelShader);
extern HRESULT AssembleShaderFromResource(IDirect3DDevice9* pD3DDev, UINT id, UINT flags, IDirect3DPixelShader9** ppPixelShader);

View File

@ -1,23 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "StdAfx.h"
#include "GSVertexList.h"

View File

@ -1,82 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
template <class VERTEX> class GSVertexList
{
VERTEX* m_v;
int m_head, m_tail, m_count;
public:
GSVertexList()
{
m_v = (VERTEX*)_aligned_malloc(sizeof(VERTEX)*4, 16);
RemoveAll();
}
~GSVertexList()
{
_aligned_free(m_v);
}
void RemoveAll()
{
m_head = m_tail = m_count = 0;
}
VERTEX& AddTail()
{
ASSERT(m_count < 4);
VERTEX& v = m_v[m_tail];
m_tail = (m_tail+1)&3;
m_count++;
return v;
}
void AddTail(VERTEX& v)
{
ASSERT(m_count < 4);
m_v[m_tail] = v;
m_tail = (m_tail+1)&3;
m_count++;
}
void RemoveAt(int i, VERTEX& v)
{
GetAt(i, v);
i = (m_head+i)&3;
if(i == m_head) m_head = (m_head+1)&3;
else for(m_tail = (m_tail+4-1)&3; i != m_tail; i = (i+1)&3) m_v[i] = m_v[(i+1)&3];
m_count--;
}
void GetAt(int i, VERTEX& v)
{
ASSERT(m_count > 0);
v = m_v[(m_head+i)&3];
}
int GetCount()
{
return m_count;
}
};

View File

@ -1,62 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSWnd.h"
IMPLEMENT_DYNCREATE(CGSWnd, CWnd)
CGSWnd::CGSWnd()
{
}
BOOL CGSWnd::Create(LPCSTR pTitle)
{
CRect r;
GetDesktopWindow()->GetWindowRect(r);
// r.DeflateRect(r.Width()*3/8, r.Height()*3/8);
r.DeflateRect(r.Width()/3, r.Height()/3);
LPCTSTR wndclass = AfxRegisterWndClass(CS_VREDRAW|CS_HREDRAW|CS_DBLCLKS, AfxGetApp()->LoadStandardCursor(IDC_ARROW), 0/*(HBRUSH)(COLOR_BTNFACE + 1)*/, 0);
return CreateEx(0, wndclass, pTitle, WS_OVERLAPPEDWINDOW, r, NULL, 0);
}
void CGSWnd::Show(bool bShow)
{
if(bShow)
{
SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
SetForegroundWindow();
ShowWindow(SW_SHOWNORMAL);
}
else
{
ShowWindow(SW_HIDE);
}
}
BEGIN_MESSAGE_MAP(CGSWnd, CWnd)
ON_WM_CLOSE()
END_MESSAGE_MAP()
void CGSWnd::OnClose()
{
PostMessage(WM_QUIT);
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
class CGSWnd : public CWnd
{
DECLARE_DYNCREATE(CGSWnd)
public:
CGSWnd();
BOOL Create(LPCSTR pTitle);
void Show(bool bShow = true);
DECLARE_MESSAGE_MAP()
afx_msg void OnClose();
};

View File

@ -1,93 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* Special Notes:
*
*/
#include "stdafx.h"
#include "afxwin.h"
#include "GSdx9.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
// Note!
//
// If this DLL is dynamically linked against the MFC
// DLLs, any functions exported from this DLL which
// call into MFC must have the AFX_MANAGE_STATE macro
// added at the very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
//
// It is very important that this macro appear in each
// function, prior to any calls into MFC. This means that
// it must appear as the first statement within the
// function, even before any object variable declarations
// as their constructors may generate calls into the MFC
// DLL.
//
// Please see MFC Technical Notes 33 and 58 for additional
// details.
//
// CGSdx9App
BEGIN_MESSAGE_MAP(CGSdx9App, CWinApp)
END_MESSAGE_MAP()
D3DDEVTYPE CGSdx9App::D3DDEVTYPE_X;
// CGSdx9App construction
CGSdx9App::CGSdx9App()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CGSdx9App object
CGSdx9App theApp;
// CGSdx9App initialization
BOOL CGSdx9App::InitInstance()
{
__super::InitInstance();
D3DDEVTYPE_X = D3DDEVTYPE_HAL;
if(GetSystemMetrics(SM_REMOTESESSION))
{
D3DDEVTYPE_X = D3DDEVTYPE_REF;
}
return TRUE;
}

View File

@ -1,31 +0,0 @@
; GSdx9.def : Declares the module parameters for the DLL.
LIBRARY "GSdx9"
EXPORTS
; Explicit exports can go here
PS2EgetLibType
PS2EgetLibName
PS2EgetLibVersion2
PS2EgetCpuPlatform
GSsetBaseMem
GSinit
GSshutdown
GSopen
GSclose
GSreset
GSwriteCSR
GSgifTransfer1
GSgifTransfer2
GSgifTransfer3
GSvsync
GSmakeSnapshot
GSkeyEvent
GSfreeze
GSconfigure
GStest
GSabout
GSreadFIFO
GSirqCallback
GSgetLastTag
; GSReplay

View File

@ -1,55 +0,0 @@
/*
* Copyright (C) 2003-2005 Gabest
* http://www.gabest.org
*
* 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, 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 GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
// CGSdx9App
// See GSdx9.cpp for the implementation of this class
//
class CGSdx9App : public CWinApp
{
public:
CGSdx9App();
static D3DDEVTYPE D3DDEVTYPE_X;
// Overrides
public:
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
};
enum
{
RENDERER_D3D_NULL,
RENDERER_D3D_SW_FX,
RENDERER_D3D_SW_FP,
RENDERER_D3D_HW
};

View File

@ -1,539 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Intel C++ Project"
Version="9.0"
Name="GSdx9"
ProjectGUID="{4A1B2A9C-A696-4523-B0A4-8046FC423932}"
VCNestedProjectGUID="{345C9F24-0B9A-4289-B375-ADD3B63461B7}"
VCNestedProjectFileName="GSdx9.vcproj"
Keyword="MFCDLLProj">
<Configurations>
<Configuration
Name="Debug|Win32">
<Tool
Name="GeneralTool"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="1"
CharacterSet="2"/>
<Tool
Name="DebugTool"/>
<Tool
Name="CppCmplrTool"
Optimization="0"
OptimizeForProcessor="2"
PreprocessorDefinitions="D3D_DEBUG_INFO;WIN32;_WINDOWS;_DEBUG;_USRDLL"
MinimalRebuild="1"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="0"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="1"
DebugInformationFormat="4"
RecognizeRestrictKeyword="1"/>
<Tool
Name="LinkerTool"
DelayImpLib="DelayImp.lib"
AdditionalDependencies="d3d9.lib d3dx9.lib ddraw.lib strmbaseD.lib"
OutputFile="$(OutDir)\GSdx9.dll"
LinkIncremental="2"
ModuleDefinitionFile=".\GSdx9.def"
GenerateDebugInformation="1"
SubSystem="2"
ImportLibrary="$(OutDir)/GSdx9.lib"
TargetMachine="1"/>
<Tool
Name="LibrarianTool"/>
<Tool
Name="ResCmplrTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
AdditionalIncludeDirectories="$(IntDir)"/>
<Tool
Name="MidlCmplrTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="0"/>
<Tool
Name="BscMakeTool"/>
<Tool
Name="PreBuildEventTool"/>
<Tool
Name="PreLinkEventTool"/>
<Tool
Name="PostBuildEventTool"/>
<Tool
Name="CustomTool"/>
<Tool
Name="CustomNodeTool"/>
</Configuration>
<Configuration
Name="Release|Win32">
<Tool
Name="GeneralTool"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="1"
CharacterSet="2"/>
<Tool
Name="DebugTool"/>
<Tool
Name="CppCmplrTool"
Optimization="2"
GlobalOptimizations="1"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="1"
FavorSizeOrSpeed="1"
OmitFramePointers="1"
OptimizeForProcessor="2"
OptimizeForWindowsApplication="1"
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL"
StringPooling="1"
RuntimeLibrary="0"
TreatWChar_tAsBuiltInType="0"
ForceConformanceInForLoopScope="1"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="1"
DebugInformationFormat="3"
RecognizeRestrictKeyword="1"/>
<Tool
Name="LinkerTool"
DelayImpLib="DelayImp.lib"
AdditionalDependencies="d3d9.lib d3dx9.lib ddraw.lib strmbaseR.lib"
OutputFile="$(OutDir)\GSdx9.dll"
LinkIncremental="1"
ModuleDefinitionFile=".\GSdx9.def"
GenerateDebugInformation="1"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/GSdx9.lib"
TargetMachine="1"/>
<Tool
Name="LibrarianTool"/>
<Tool
Name="ResCmplrTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
AdditionalIncludeDirectories="$(IntDir)"/>
<Tool
Name="MidlCmplrTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="0"/>
<Tool
Name="BscMakeTool"/>
<Tool
Name="PreBuildEventTool"/>
<Tool
Name="PreLinkEventTool"/>
<Tool
Name="PostBuildEventTool"/>
<Tool
Name="CustomTool"/>
<Tool
Name="CustomNodeTool"/>
</Configuration>
<Configuration
Name="DebugSSE2|Win32">
<Tool
Name="GeneralTool"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="1"
CharacterSet="2"/>
<Tool
Name="DebugTool"/>
<Tool
Name="CppCmplrTool"
Optimization="0"
OptimizeForProcessor="3"
PreprocessorDefinitions="_M_IX86_FP=2;D3D_DEBUG_INFO;WIN32;_WINDOWS;_DEBUG;_USRDLL"
MinimalRebuild="1"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
EnableEnhancedInstructionSet="2"
TreatWChar_tAsBuiltInType="0"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="1"
DebugInformationFormat="4"
RecognizeRestrictKeyword="1"/>
<Tool
Name="LinkerTool"
DelayImpLib="DelayImp.lib"
AdditionalDependencies="d3d9.lib d3dx9.lib ddraw.lib strmbaseD.lib"
OutputFile="$(OutDir)\GSdx9.dll"
LinkIncremental="2"
ModuleDefinitionFile=".\GSdx9.def"
GenerateDebugInformation="1"
SubSystem="2"
ImportLibrary="$(OutDir)/GSdx9.lib"
TargetMachine="1"/>
<Tool
Name="LibrarianTool"/>
<Tool
Name="ResCmplrTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
AdditionalIncludeDirectories="$(IntDir)"/>
<Tool
Name="MidlCmplrTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="0"/>
<Tool
Name="BscMakeTool"/>
<Tool
Name="PreBuildEventTool"/>
<Tool
Name="PreLinkEventTool"/>
<Tool
Name="PostBuildEventTool"/>
<Tool
Name="CustomTool"/>
<Tool
Name="CustomNodeTool"/>
</Configuration>
<Configuration
Name="ReleaseSSE2|Win32">
<Tool
Name="GeneralTool"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="1"
CharacterSet="2"/>
<Tool
Name="DebugTool"/>
<Tool
Name="CppCmplrTool"
Optimization="1000"
GlobalOptimizations="1"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="1"
FavorSizeOrSpeed="1"
OmitFramePointers="1"
OptimizeForProcessor="3"
OptimizeForWindowsApplication="1"
PreprocessorDefinitions="_M_IX86_FP=2;WIN32;_WINDOWS;NDEBUG;_USRDLL"
StringPooling="1"
RuntimeLibrary="0"
EnableEnhancedInstructionSet="2"
TreatWChar_tAsBuiltInType="0"
ForceConformanceInForLoopScope="1"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="1"
DebugInformationFormat="3"
UseProcExt="2"
RecognizeRestrictKeyword="1"/>
<Tool
Name="LinkerTool"
DelayImpLib="DelayImp.lib"
AdditionalDependencies="d3d9.lib d3dx9.lib ddraw.lib strmbaseR.lib"
OutputFile="$(OutDir)\GSdx9.dll"
LinkIncremental="1"
ModuleDefinitionFile=".\GSdx9.def"
GenerateDebugInformation="1"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/GSdx9.lib"
TargetMachine="1"/>
<Tool
Name="LibrarianTool"/>
<Tool
Name="ResCmplrTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
AdditionalIncludeDirectories="$(IntDir)"/>
<Tool
Name="MidlCmplrTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="0"/>
<Tool
Name="BscMakeTool"/>
<Tool
Name="PreBuildEventTool"/>
<Tool
Name="PreLinkEventTool"/>
<Tool
Name="PostBuildEventTool"/>
<Tool
Name="CustomTool"/>
<Tool
Name="CustomNodeTool"/>
</Configuration>
</Configurations>
<Files>
<File
RelativePath=".\GS.cpp"/>
<File
RelativePath=".\GSCapture.cpp"/>
<File
RelativePath=".\GSCaptureDlg.cpp"/>
<File
RelativePath=".\GSdx9.cpp"/>
<File
RelativePath=".\GSdx9.def"/>
<File
RelativePath=".\GSHash.cpp">
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="CppCmplrTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSLocalMemory.cpp">
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="CppCmplrTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSPerfMon.cpp"/>
<File
RelativePath=".\GSRegs.cpp"/>
<File
RelativePath=".\GSRenderer.cpp"/>
<File
RelativePath=".\GSRendererHW.cpp">
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="CppCmplrTool"
GeneratePreprocessedFile="0"/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSRendererNull.cpp"/>
<File
RelativePath=".\GSRendererSoft.cpp">
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="CppCmplrTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File>
<File
RelativePath=".\gssettingsdlg.cpp"/>
<File
RelativePath=".\GSSoftVertex.cpp"/>
<File
RelativePath=".\GSState.cpp">
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="CppCmplrTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File>
<File
RelativePath=".\GSTables.cpp"/>
<File
RelativePath=".\GSTextureCache.cpp"/>
<File
RelativePath=".\GSTransfer.cpp"/>
<File
RelativePath=".\GSUtil.cpp"/>
<File
RelativePath=".\GSVertexList.cpp"/>
<File
RelativePath=".\GSWnd.cpp"/>
<File
RelativePath=".\stdafx.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="CppCmplrTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="CppCmplrTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="DebugSSE2|Win32">
<Tool
Name="CppCmplrTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="CppCmplrTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
<File
RelativePath=".\x86-32.asm">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="CustomTool"
CommandLine="ml /nologo /c /Zi /Fo&quot;$(IntDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;
"
Outputs="$(IntDir)\$(InputName).obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="CustomTool"
CommandLine="ml /nologo /c /Zi /Fo&quot;$(IntDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;
"
Outputs="$(IntDir)\$(InputName).obj"/>
</FileConfiguration>
<FileConfiguration
Name="DebugSSE2|Win32">
<Tool
Name="CustomTool"
CommandLine="ml /nologo /c /Zi /Fo&quot;$(IntDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;
"
Outputs="$(IntDir)\$(InputName).obj"/>
</FileConfiguration>
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="CustomTool"
CommandLine="ml /nologo /c /Zi /Fo&quot;$(IntDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;
"
Outputs="$(IntDir)\$(InputName).obj"/>
</FileConfiguration>
</File>
<File
RelativePath=".\x86-64.asm">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="GeneralTool"
ExcludedFromBuild="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="GeneralTool"
ExcludedFromBuild="1"/>
</FileConfiguration>
<FileConfiguration
Name="DebugSSE2|Win32">
<Tool
Name="GeneralTool"
ExcludedFromBuild="1"/>
</FileConfiguration>
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="GeneralTool"
ExcludedFromBuild="1"/>
</FileConfiguration>
</File>
<File
RelativePath=".\x86.cpp">
<FileConfiguration
Name="ReleaseSSE2|Win32">
<Tool
Name="CppCmplrTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File>
<File
RelativePath=".\gs.h"/>
<File
RelativePath=".\GSCapture.h"/>
<File
RelativePath=".\GSCaptureDlg.h"/>
<File
RelativePath=".\GSdx9.h"/>
<File
RelativePath=".\GSHash.h"/>
<File
RelativePath=".\gslocalmemory.h"/>
<File
RelativePath=".\GSPerfMon.h"/>
<File
RelativePath=".\GSRenderer.h"/>
<File
RelativePath=".\GSRendererHW.h"/>
<File
RelativePath=".\GSRendererNull.h"/>
<File
RelativePath=".\GSRendererSoft.h"/>
<File
RelativePath=".\gssettingsdlg.h"/>
<File
RelativePath=".\GSSoftVertex.h"/>
<File
RelativePath=".\GSSoftVertexFP.h"/>
<File
RelativePath=".\GSSoftVertexFX.h"/>
<File
RelativePath=".\GSState.h"/>
<File
RelativePath=".\GSTables.h"/>
<File
RelativePath=".\GSTextureCache.h"/>
<File
RelativePath=".\GSUtil.h"/>
<File
RelativePath=".\GSVertexList.h"/>
<File
RelativePath=".\GSWnd.h"/>
<File
RelativePath=".\resource.h"/>
<File
RelativePath=".\stdafx.h"/>
<File
RelativePath=".\x86.h"/>
<File
RelativePath=".\GSdx9.rc"/>
<File
RelativePath=".\res\GSdx9.rc2"/>
<File
RelativePath=".\res\ps11_en00.psh"/>
<File
RelativePath=".\res\ps11_en01.psh"/>
<File
RelativePath=".\res\ps11_en10.psh"/>
<File
RelativePath=".\res\ps11_en11.psh"/>
<File
RelativePath=".\res\ps11_tfx000.psh"/>
<File
RelativePath=".\res\ps11_tfx010.psh"/>
<File
RelativePath=".\res\ps11_tfx011.psh"/>
<File
RelativePath=".\res\ps11_tfx1x0.psh"/>
<File
RelativePath=".\res\ps11_tfx1x1.psh"/>
<File
RelativePath=".\res\ps11_tfx200.psh"/>
<File
RelativePath=".\res\ps11_tfx210.psh"/>
<File
RelativePath=".\res\ps11_tfx211.psh"/>
<File
RelativePath=".\res\ps11_tfx300.psh"/>
<File
RelativePath=".\res\ps11_tfx310.psh"/>
<File
RelativePath=".\res\ps11_tfx311.psh"/>
<File
RelativePath=".\res\ps11_tfx4xx.psh"/>
<File
RelativePath=".\res\ps20_merge.fx"/>
<File
RelativePath=".\res\ps20_tfx.fx"/>
</Files>
</VisualStudioProject>

View File

@ -1,220 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Hungarian resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HUN)
#ifdef _WIN32
LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
#pragma code_page(1250)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#include ""res\\GSdx9.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Hungarian resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_LOGO1 BITMAP "res\\logo1.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CONFIG DIALOGEX 0, 0, 189, 209
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Settings..."
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Cancel",IDCANCEL,43,188,50,14
DEFPUSHBUTTON "OK",IDOK,98,188,50,14
COMBOBOX IDC_COMBO1,64,72,118,69,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
LTEXT "Renderer:",IDC_STATIC,7,74,34,8
LTEXT "Resolution:",IDC_STATIC,7,59,37,8
COMBOBOX IDC_COMBO3,64,57,118,125,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
LTEXT "Shader:",IDC_STATIC,7,89,26,8
COMBOBOX IDC_COMBO4,64,87,118,98,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
EDITTEXT IDC_EDIT1,64,158,100,13,ES_AUTOHSCROLL | ES_READONLY
PUSHBUTTON "...",IDC_BUTTON1,165,158,17,14
CONTROL "Record state",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,7,158,53,10
CONTROL "Enable tv-out",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,7,132,57,10
CONTROL "Enable palettized textures (D3D PS v2.0+, slow)",
IDC_CHECK1,"Button",BS_AUTOCHECKBOX | BS_TOP |
WS_TABSTOP,7,105,175,10
LTEXT """rundll32 gsdx9.dll,GSReplay gsdx9_*.gs"" to replay",
IDC_STATIC,14,174,168,9
CONTROL "Linear texture filtering",IDC_CHECK4,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,118,87,10
CONTROL 2024,IDC_STATIC,"Static",SS_BITMAP,7,7,175,44
CONTROL "NLOOP 0 hack (fixes FFX)",IDC_CHECK5,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,145,98,10
END
IDD_CAPTURE DIALOGEX 0, 0, 279, 67
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Capture settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,140,46,50,14
PUSHBUTTON "Cancel",IDCANCEL,88,46,50,14
COMBOBOX IDC_COMBO1,7,27,207,122,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
EDITTEXT IDC_EDIT1,7,7,207,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse...",IDC_BUTTON1,222,7,50,14
PUSHBUTTON "Config...",IDC_BUTTON2,222,26,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 182
VERTGUIDE, 64
VERTGUIDE, 182
TOPMARGIN, 7
BOTTOMMARGIN, 202
HORZGUIDE, 150
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,9
PRODUCTVERSION 1,0,0,9
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "Comments", "http://gabest.org/"
VALUE "CompanyName", "Gabest"
VALUE "FileDescription", "GS plugin for ps2 emulators"
VALUE "FileVersion", "1, 0, 0, 9"
VALUE "InternalName", "GSdx9.dll"
VALUE "LegalCopyright", "Copyright (c) 2004-2005 Gabest. All rights reserved."
VALUE "OriginalFilename", "GSdx9.dll"
VALUE "ProductName", "GSdx9"
VALUE "ProductVersion", "1, 0, 0, 9"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1
#pragma code_page(1252)
#include "res\GSdx9.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -1,54 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GSdx9", "GSdx9_vs2005.vcproj", "{345C9F24-0B9A-4289-B375-ADD3B63461B7}"
ProjectSection(ProjectDependencies) = postProject
{7CDC5863-9F36-468D-A634-6D7799E0A15E} = {7CDC5863-9F36-468D-A634-6D7799E0A15E}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseClasses", "baseclasses\baseclasses.vcproj", "{7CDC5863-9F36-468D-A634-6D7799E0A15E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
DebugSSE2|Win32 = DebugSSE2|Win32
DebugSSE2|x64 = DebugSSE2|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
ReleaseSSE2|Win32 = ReleaseSSE2|Win32
ReleaseSSE2|x64 = ReleaseSSE2|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.Debug|Win32.ActiveCfg = Debug|Win32
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.Debug|Win32.Build.0 = Debug|Win32
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.Debug|x64.ActiveCfg = Debug|x64
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.Debug|x64.Build.0 = Debug|x64
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.DebugSSE2|Win32.ActiveCfg = DebugSSE2|Win32
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.DebugSSE2|Win32.Build.0 = DebugSSE2|Win32
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.DebugSSE2|x64.ActiveCfg = DebugSSE2|x64
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.DebugSSE2|x64.Build.0 = DebugSSE2|x64
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.Release|Win32.ActiveCfg = Release|Win32
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.Release|Win32.Build.0 = Release|Win32
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.Release|x64.ActiveCfg = Release|x64
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.Release|x64.Build.0 = Release|x64
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.ReleaseSSE2|Win32.ActiveCfg = ReleaseSSE2|Win32
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.ReleaseSSE2|Win32.Build.0 = ReleaseSSE2|Win32
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.ReleaseSSE2|x64.ActiveCfg = ReleaseSSE2|x64
{345C9F24-0B9A-4289-B375-ADD3B63461B7}.ReleaseSSE2|x64.Build.0 = ReleaseSSE2|x64
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.Debug|Win32.ActiveCfg = Debug|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.Debug|Win32.Build.0 = Debug|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.Debug|x64.ActiveCfg = Debug|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.DebugSSE2|Win32.ActiveCfg = Debug|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.DebugSSE2|Win32.Build.0 = Debug|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.DebugSSE2|x64.ActiveCfg = Debug|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.Release|Win32.ActiveCfg = Release|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.Release|Win32.Build.0 = Release|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.Release|x64.ActiveCfg = Release|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.ReleaseSSE2|Win32.ActiveCfg = Release|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.ReleaseSSE2|Win32.Build.0 = Release|Win32
{7CDC5863-9F36-468D-A634-6D7799E0A15E}.ReleaseSSE2|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff

View File

@ -1,433 +0,0 @@
//------------------------------------------------------------------------------
// File: AMVideo.h
//
// Desc: Video related definitions and interfaces for ActiveMovie.
//
// Copyright (c) 1992 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __AMVIDEO__
#define __AMVIDEO__
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <ddraw.h>
// This is an interface on the video renderer that provides information about
// DirectDraw with respect to its use by the renderer. For example it allows
// an application to get details of the surface and any hardware capabilities
// that are available. It also allows someone to adjust the surfaces that the
// renderer should use and furthermore even set the DirectDraw instance. We
// allow someone to set the DirectDraw instance because DirectDraw can only
// be opened once per process so it helps resolve conflicts. There is some
// duplication in this interface as the hardware/emulated/FOURCCs available
// can all be found through the IDirectDraw interface, this interface allows
// simple access to that information without calling the DirectDraw provider
// itself. The AMDDS prefix is ActiveMovie DirectDraw Switches abbreviated.
#define AMDDS_NONE 0x00 // No use for DCI/DirectDraw
#define AMDDS_DCIPS 0x01 // Use DCI primary surface
#define AMDDS_PS 0x02 // Use DirectDraw primary
#define AMDDS_RGBOVR 0x04 // RGB overlay surfaces
#define AMDDS_YUVOVR 0x08 // YUV overlay surfaces
#define AMDDS_RGBOFF 0x10 // RGB offscreen surfaces
#define AMDDS_YUVOFF 0x20 // YUV offscreen surfaces
#define AMDDS_RGBFLP 0x40 // RGB flipping surfaces
#define AMDDS_YUVFLP 0x80 // YUV flipping surfaces
#define AMDDS_ALL 0xFF // ALL the previous flags
#define AMDDS_DEFAULT AMDDS_ALL // Use all available surfaces
#define AMDDS_YUV (AMDDS_YUVOFF | AMDDS_YUVOVR | AMDDS_YUVFLP)
#define AMDDS_RGB (AMDDS_RGBOFF | AMDDS_RGBOVR | AMDDS_RGBFLP)
#define AMDDS_PRIMARY (AMDDS_DCIPS | AMDDS_PS)
// be nice to our friends in C
#undef INTERFACE
#define INTERFACE IDirectDrawVideo
DECLARE_INTERFACE_(IDirectDrawVideo, IUnknown)
{
// IUnknown methods
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
// IDirectDrawVideo methods
STDMETHOD(GetSwitches)(THIS_ DWORD *pSwitches) PURE;
STDMETHOD(SetSwitches)(THIS_ DWORD Switches) PURE;
STDMETHOD(GetCaps)(THIS_ DDCAPS *pCaps) PURE;
STDMETHOD(GetEmulatedCaps)(THIS_ DDCAPS *pCaps) PURE;
STDMETHOD(GetSurfaceDesc)(THIS_ DDSURFACEDESC *pSurfaceDesc) PURE;
STDMETHOD(GetFourCCCodes)(THIS_ DWORD *pCount,DWORD *pCodes) PURE;
STDMETHOD(SetDirectDraw)(THIS_ LPDIRECTDRAW pDirectDraw) PURE;
STDMETHOD(GetDirectDraw)(THIS_ LPDIRECTDRAW *ppDirectDraw) PURE;
STDMETHOD(GetSurfaceType)(THIS_ DWORD *pSurfaceType) PURE;
STDMETHOD(SetDefault)(THIS) PURE;
STDMETHOD(UseScanLine)(THIS_ long UseScanLine) PURE;
STDMETHOD(CanUseScanLine)(THIS_ long *UseScanLine) PURE;
STDMETHOD(UseOverlayStretch)(THIS_ long UseOverlayStretch) PURE;
STDMETHOD(CanUseOverlayStretch)(THIS_ long *UseOverlayStretch) PURE;
STDMETHOD(UseWhenFullScreen)(THIS_ long UseWhenFullScreen) PURE;
STDMETHOD(WillUseFullScreen)(THIS_ long *UseWhenFullScreen) PURE;
};
// be nice to our friends in C
#undef INTERFACE
#define INTERFACE IQualProp
DECLARE_INTERFACE_(IQualProp, IUnknown)
{
// IUnknown methods
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
// Compare these with the functions in class CGargle in gargle.h
STDMETHOD(get_FramesDroppedInRenderer)(THIS_ int *pcFrames) PURE; // Out
STDMETHOD(get_FramesDrawn)(THIS_ int *pcFramesDrawn) PURE; // Out
STDMETHOD(get_AvgFrameRate)(THIS_ int *piAvgFrameRate) PURE; // Out
STDMETHOD(get_Jitter)(THIS_ int *iJitter) PURE; // Out
STDMETHOD(get_AvgSyncOffset)(THIS_ int *piAvg) PURE; // Out
STDMETHOD(get_DevSyncOffset)(THIS_ int *piDev) PURE; // Out
};
// This interface allows an application or plug in distributor to control a
// full screen renderer. The Modex renderer supports this interface. When
// connected a renderer should load the display modes it has available
// The number of modes available can be obtained through CountModes. Then
// information on each individual mode is available by calling GetModeInfo
// and IsModeAvailable. An application may enable and disable any modes
// by calling the SetEnabled flag with OATRUE or OAFALSE (not C/C++ TRUE
// and FALSE values) - the current value may be queried by IsModeEnabled
// A more generic way of setting the modes enabled that is easier to use
// when writing applications is the clip loss factor. This defines the
// amount of video that can be lost when deciding which display mode to
// use. Assuming the decoder cannot compress the video then playing an
// MPEG file (say 352x288) into a 320x200 display will lose about 25% of
// the image. The clip loss factor specifies the upper range permissible.
// To allow typical MPEG video to be played in 320x200 it defaults to 25%
// be nice to our friends in C
#undef INTERFACE
#define INTERFACE IFullScreenVideo
DECLARE_INTERFACE_(IFullScreenVideo, IUnknown)
{
// IUnknown methods
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
// IFullScreenVideo methods
STDMETHOD(CountModes)(THIS_ long *pModes) PURE;
STDMETHOD(GetModeInfo)(THIS_ long Mode,long *pWidth,long *pHeight,long *pDepth) PURE;
STDMETHOD(GetCurrentMode)(THIS_ long *pMode) PURE;
STDMETHOD(IsModeAvailable)(THIS_ long Mode) PURE;
STDMETHOD(IsModeEnabled)(THIS_ long Mode) PURE;
STDMETHOD(SetEnabled)(THIS_ long Mode,long bEnabled) PURE;
STDMETHOD(GetClipFactor)(THIS_ long *pClipFactor) PURE;
STDMETHOD(SetClipFactor)(THIS_ long ClipFactor) PURE;
STDMETHOD(SetMessageDrain)(THIS_ HWND hwnd) PURE;
STDMETHOD(GetMessageDrain)(THIS_ HWND *hwnd) PURE;
STDMETHOD(SetMonitor)(THIS_ long Monitor) PURE;
STDMETHOD(GetMonitor)(THIS_ long *Monitor) PURE;
STDMETHOD(HideOnDeactivate)(THIS_ long Hide) PURE;
STDMETHOD(IsHideOnDeactivate)(THIS) PURE;
STDMETHOD(SetCaption)(THIS_ BSTR strCaption) PURE;
STDMETHOD(GetCaption)(THIS_ BSTR *pstrCaption) PURE;
STDMETHOD(SetDefault)(THIS) PURE;
};
// This adds the accelerator table capabilities in fullscreen. This is being
// added between the original runtime release and the full SDK release. We
// cannot just add the method to IFullScreenVideo as we don't want to force
// applications to have to ship the ActiveMovie support DLLs - this is very
// important to applications that plan on being downloaded over the Internet
// be nice to our friends in C
#undef INTERFACE
#define INTERFACE IFullScreenVideoEx
DECLARE_INTERFACE_(IFullScreenVideoEx, IFullScreenVideo)
{
// IUnknown methods
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
// IFullScreenVideo methods
STDMETHOD(CountModes)(THIS_ long *pModes) PURE;
STDMETHOD(GetModeInfo)(THIS_ long Mode,long *pWidth,long *pHeight,long *pDepth) PURE;
STDMETHOD(GetCurrentMode)(THIS_ long *pMode) PURE;
STDMETHOD(IsModeAvailable)(THIS_ long Mode) PURE;
STDMETHOD(IsModeEnabled)(THIS_ long Mode) PURE;
STDMETHOD(SetEnabled)(THIS_ long Mode,long bEnabled) PURE;
STDMETHOD(GetClipFactor)(THIS_ long *pClipFactor) PURE;
STDMETHOD(SetClipFactor)(THIS_ long ClipFactor) PURE;
STDMETHOD(SetMessageDrain)(THIS_ HWND hwnd) PURE;
STDMETHOD(GetMessageDrain)(THIS_ HWND *hwnd) PURE;
STDMETHOD(SetMonitor)(THIS_ long Monitor) PURE;
STDMETHOD(GetMonitor)(THIS_ long *Monitor) PURE;
STDMETHOD(HideOnDeactivate)(THIS_ long Hide) PURE;
STDMETHOD(IsHideOnDeactivate)(THIS) PURE;
STDMETHOD(SetCaption)(THIS_ BSTR strCaption) PURE;
STDMETHOD(GetCaption)(THIS_ BSTR *pstrCaption) PURE;
STDMETHOD(SetDefault)(THIS) PURE;
// IFullScreenVideoEx
STDMETHOD(SetAcceleratorTable)(THIS_ HWND hwnd,HACCEL hAccel) PURE;
STDMETHOD(GetAcceleratorTable)(THIS_ HWND *phwnd,HACCEL *phAccel) PURE;
STDMETHOD(KeepPixelAspectRatio)(THIS_ long KeepAspect) PURE;
STDMETHOD(IsKeepPixelAspectRatio)(THIS_ long *pKeepAspect) PURE;
};
// The SDK base classes contain a base video mixer class. Video mixing in a
// software environment is tricky because we typically have multiple streams
// each sending data at unpredictable times. To work with this we defined a
// pin that is the lead pin, when data arrives on this pin we do a mix. As
// an alternative we may not want to have a lead pin but output samples at
// predefined spaces, like one every 1/15 of a second, this interfaces also
// supports that mode of operations (there is a working video mixer sample)
// be nice to our friends in C
#undef INTERFACE
#define INTERFACE IBaseVideoMixer
DECLARE_INTERFACE_(IBaseVideoMixer, IUnknown)
{
STDMETHOD(SetLeadPin)(THIS_ int iPin) PURE;
STDMETHOD(GetLeadPin)(THIS_ int *piPin) PURE;
STDMETHOD(GetInputPinCount)(THIS_ int *piPinCount) PURE;
STDMETHOD(IsUsingClock)(THIS_ int *pbValue) PURE;
STDMETHOD(SetUsingClock)(THIS_ int bValue) PURE;
STDMETHOD(GetClockPeriod)(THIS_ int *pbValue) PURE;
STDMETHOD(SetClockPeriod)(THIS_ int bValue) PURE;
};
#define iPALETTE_COLORS 256 // Maximum colours in palette
#define iEGA_COLORS 16 // Number colours in EGA palette
#define iMASK_COLORS 3 // Maximum three components
#define iTRUECOLOR 16 // Minimum true colour device
#define iRED 0 // Index position for RED mask
#define iGREEN 1 // Index position for GREEN mask
#define iBLUE 2 // Index position for BLUE mask
#define iPALETTE 8 // Maximum colour depth using a palette
#define iMAXBITS 8 // Maximum bits per colour component
// Used for true colour images that also have a palette
typedef struct tag_TRUECOLORINFO {
DWORD dwBitMasks[iMASK_COLORS];
RGBQUAD bmiColors[iPALETTE_COLORS];
} TRUECOLORINFO;
// The BITMAPINFOHEADER contains all the details about the video stream such
// as the actual image dimensions and their pixel depth. A source filter may
// also request that the sink take only a section of the video by providing a
// clipping rectangle in rcSource. In the worst case where the sink filter
// forgets to check this on connection it will simply render the whole thing
// which isn't a disaster. Ideally a sink filter will check the rcSource and
// if it doesn't support image extraction and the rectangle is not empty then
// it will reject the connection. A filter should use SetRectEmpty to reset a
// rectangle to all zeroes (and IsRectEmpty to later check the rectangle).
// The rcTarget specifies the destination rectangle for the video, for most
// source filters they will set this to all zeroes, a downstream filter may
// request that the video be placed in a particular area of the buffers it
// supplies in which case it will call QueryAccept with a non empty target
typedef struct tagVIDEOINFOHEADER {
RECT rcSource; // The bit we really want to use
RECT rcTarget; // Where the video should go
DWORD dwBitRate; // Approximate bit data rate
DWORD dwBitErrorRate; // Bit error rate for this stream
REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units)
BITMAPINFOHEADER bmiHeader;
} VIDEOINFOHEADER;
// make sure the pbmi is initialized before using these macros
#define TRUECOLOR(pbmi) ((TRUECOLORINFO *)(((LPBYTE)&((pbmi)->bmiHeader)) \
+ (pbmi)->bmiHeader.biSize))
#define COLORS(pbmi) ((RGBQUAD *)(((LPBYTE)&((pbmi)->bmiHeader)) \
+ (pbmi)->bmiHeader.biSize))
#define BITMASKS(pbmi) ((DWORD *)(((LPBYTE)&((pbmi)->bmiHeader)) \
+ (pbmi)->bmiHeader.biSize))
// All the image based filters use this to communicate their media types. It's
// centred principally around the BITMAPINFO. This structure always contains a
// BITMAPINFOHEADER followed by a number of other fields depending on what the
// BITMAPINFOHEADER contains. If it contains details of a palettised format it
// will be followed by one or more RGBQUADs defining the palette. If it holds
// details of a true colour format then it may be followed by a set of three
// DWORD bit masks that specify where the RGB data can be found in the image
// (For more information regarding BITMAPINFOs see the Win32 documentation)
// The rcSource and rcTarget fields are not for use by filters supplying the
// data. The destination (target) rectangle should be set to all zeroes. The
// source may also be zero filled or set with the dimensions of the video. So
// if the video is 352x288 pixels then set it to (0,0,352,288). These fields
// are mainly used by downstream filters that want to ask the source filter
// to place the image in a different position in an output buffer. So when
// using for example the primary surface the video renderer may ask a filter
// to place the video images in a destination position of (100,100,452,388)
// on the display since that's where the window is positioned on the display
// !!! WARNING !!!
// DO NOT use this structure unless you are sure that the BITMAPINFOHEADER
// has a normal biSize == sizeof(BITMAPINFOHEADER) !
// !!! WARNING !!!
typedef struct tagVIDEOINFO {
RECT rcSource; // The bit we really want to use
RECT rcTarget; // Where the video should go
DWORD dwBitRate; // Approximate bit data rate
DWORD dwBitErrorRate; // Bit error rate for this stream
REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units)
BITMAPINFOHEADER bmiHeader;
union {
RGBQUAD bmiColors[iPALETTE_COLORS]; // Colour palette
DWORD dwBitMasks[iMASK_COLORS]; // True colour masks
TRUECOLORINFO TrueColorInfo; // Both of the above
};
} VIDEOINFO;
// These macros define some standard bitmap format sizes
#define SIZE_EGA_PALETTE (iEGA_COLORS * sizeof(RGBQUAD))
#define SIZE_PALETTE (iPALETTE_COLORS * sizeof(RGBQUAD))
#define SIZE_MASKS (iMASK_COLORS * sizeof(DWORD))
#define SIZE_PREHEADER (FIELD_OFFSET(VIDEOINFOHEADER,bmiHeader))
#define SIZE_VIDEOHEADER (sizeof(BITMAPINFOHEADER) + SIZE_PREHEADER)
// !!! for abnormal biSizes
// #define SIZE_VIDEOHEADER(pbmi) ((pbmi)->bmiHeader.biSize + SIZE_PREHEADER)
// DIBSIZE calculates the number of bytes required by an image
#define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8)
#define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((DWORD)(bi).biWidth * (DWORD)(bi).biBitCount)
#define _DIBSIZE(bi) (DIBWIDTHBYTES(bi) * (DWORD)(bi).biHeight)
#define DIBSIZE(bi) ((bi).biHeight < 0 ? (-1)*(_DIBSIZE(bi)) : _DIBSIZE(bi))
// This compares the bit masks between two VIDEOINFOHEADERs
#define BIT_MASKS_MATCH(pbmi1,pbmi2) \
(((pbmi1)->dwBitMasks[iRED] == (pbmi2)->dwBitMasks[iRED]) && \
((pbmi1)->dwBitMasks[iGREEN] == (pbmi2)->dwBitMasks[iGREEN]) && \
((pbmi1)->dwBitMasks[iBLUE] == (pbmi2)->dwBitMasks[iBLUE]))
// These zero fill different parts of the VIDEOINFOHEADER structure
// Only use these macros for pbmi's with a normal BITMAPINFOHEADER biSize
#define RESET_MASKS(pbmi) (ZeroMemory((PVOID)(pbmi)->dwBitFields,SIZE_MASKS))
#define RESET_HEADER(pbmi) (ZeroMemory((PVOID)(pbmi),SIZE_VIDEOHEADER))
#define RESET_PALETTE(pbmi) (ZeroMemory((PVOID)(pbmi)->bmiColors,SIZE_PALETTE));
#if 0
// !!! This is the right way to do it, but may break existing code
#define RESET_MASKS(pbmi) (ZeroMemory((PVOID)(((LPBYTE)(pbmi)->bmiHeader) + \
(pbmi)->bmiHeader.biSize,SIZE_MASKS)))
#define RESET_HEADER(pbmi) (ZeroMemory((PVOID)(pbmi), SIZE_PREHEADER + \
sizeof(BITMAPINFOHEADER)))
#define RESET_PALETTE(pbmi) (ZeroMemory((PVOID)(((LPBYTE)(pbmi)->bmiHeader) + \
(pbmi)->bmiHeader.biSize,SIZE_PALETTE))
#endif
// Other (hopefully) useful bits and bobs
#define PALETTISED(pbmi) ((pbmi)->bmiHeader.biBitCount <= iPALETTE)
#define PALETTE_ENTRIES(pbmi) ((DWORD) 1 << (pbmi)->bmiHeader.biBitCount)
// Returns the address of the BITMAPINFOHEADER from the VIDEOINFOHEADER
#define HEADER(pVideoInfo) (&(((VIDEOINFOHEADER *) (pVideoInfo))->bmiHeader))
// MPEG variant - includes a DWORD length followed by the
// video sequence header after the video header.
//
// The sequence header includes the sequence header start code and the
// quantization matrices associated with the first sequence header in the
// stream so is a maximum of 140 bytes long.
typedef struct tagMPEG1VIDEOINFO {
VIDEOINFOHEADER hdr; // Compatible with VIDEOINFO
DWORD dwStartTimeCode; // 25-bit Group of pictures time code
// at start of data
DWORD cbSequenceHeader; // Length in bytes of bSequenceHeader
BYTE bSequenceHeader[1]; // Sequence header including
// quantization matrices if any
} MPEG1VIDEOINFO;
#define MAX_SIZE_MPEG1_SEQUENCE_INFO 140
#define SIZE_MPEG1VIDEOINFO(pv) (FIELD_OFFSET(MPEG1VIDEOINFO, bSequenceHeader[0]) + (pv)->cbSequenceHeader)
#define MPEG1_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->bSequenceHeader)
// Analog video variant - Use this when the format is FORMAT_AnalogVideo
//
// rcSource defines the portion of the active video signal to use
// rcTarget defines the destination rectangle
// both of the above are relative to the dwActiveWidth and dwActiveHeight fields
// dwActiveWidth is currently set to 720 for all formats (but could change for HDTV)
// dwActiveHeight is 483 for NTSC and 575 for PAL/SECAM (but could change for HDTV)
typedef struct tagAnalogVideoInfo {
RECT rcSource; // Width max is 720, height varies w/ TransmissionStd
RECT rcTarget; // Where the video should go
DWORD dwActiveWidth; // Always 720 (CCIR-601 active samples per line)
DWORD dwActiveHeight; // 483 for NTSC, 575 for PAL/SECAM
REFERENCE_TIME AvgTimePerFrame; // Normal ActiveMovie units (100 nS)
} ANALOGVIDEOINFO;
//
// AM_KSPROPSETID_FrameStep property set definitions
//
typedef enum {
// Step
AM_PROPERTY_FRAMESTEP_STEP = 0x01,
AM_PROPERTY_FRAMESTEP_CANCEL = 0x02,
// S_OK for these 2 means we can - S_FALSE if we can't
AM_PROPERTY_FRAMESTEP_CANSTEP = 0x03,
AM_PROPERTY_FRAMESTEP_CANSTEPMULTIPLE = 0x04
} AM_PROPERTY_FRAMESTEP;
typedef struct _AM_FRAMESTEP_STEP
{
// 1 means step 1 frame forward
// 0 is invalid
// n (n > 1) means skip n - 1 frames and show the nth
DWORD dwFramesToStep;
} AM_FRAMESTEP_STEP;
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __AMVIDEO__

View File

@ -1,142 +0,0 @@
//------------------------------------------------------------------------------
// File: Activex.rcv
//
// Desc: DirectShow base classes - this file defines the version resource
// used for the application.
//
// NOTE: All strings MUST have an explicit \0 for termination!
//
// For a complete description of the Version Resource, search the
// Microsoft Developer's Network (MSDN) CD-ROM for 'version resource'..
//
// Copyright (c) 1992 - 2002, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef _ACTIVEX_RCV_
#define _ACTIVEX_RCV_
#ifndef WIN32
#define WIN32
#endif
#include <winver.h>
#ifndef _ACTIVEX_VER_
#include <activex.ver>
#endif
//
// Version flags.
//
// OFFICIAL and FINAL should be defined when appropriate.
//
#ifndef OFFICIAL
#define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD
#else
#define VER_PRIVATEBUILD 0
#endif
#ifndef FINAL
#define VER_PRERELEASE VS_FF_PRERELEASE
#else
#define VER_PRERELEASE 0
#endif
#ifdef DEBUG
#define VER_DEBUG VS_FF_DEBUG
#else
#define VER_DEBUG 0
#endif
//
// Version definitions
//
#define VERSION_RES_FLAGSMASK 0x0030003FL
#define VERSION_RES_FLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG)
#ifndef VERSION_RES_OS
#define VERSION_RES_OS VOS__WINDOWS32
#endif
#ifndef VERSION_RES_TYPE
#define VERSION_RES_TYPE VFT_DLL
#endif
#ifndef VERSION_RES_SUBTYPE
#define VERSION_RES_SUBTYPE VFT2_UNKNOWN
#endif
#define VERSION_RES_LANGUAGE 0x409
#ifndef VERSION_RES_CHARSET
#ifdef UNICODE
#define VERSION_RES_CHARSET 1200
#else
#define VERSION_RES_CHARSET 1252
#endif
#endif
#ifndef VERSION_RES_ACTIVEX
#define VERSION_RES_ACTIVEX "Filter dll\0"
#endif
#ifdef AMOVIE_SELF_REGISTER
#ifndef OLE_SELF_REGISTER
#define OLE_SELF_REGISTER
#endif
#endif
#ifdef OLE_SELF_REGISTER
#ifdef AMOVIE_SELF_REGISTER
#define VERSION_RES_SELFREGISTER "AM20\0"
#else
#define VERSION_RES_SELFREGISTER "\0"
#endif
#endif
//
// Version resource
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_RES_MAJOR_VER, VERSION_RES_MINOR_VER, 0, VERSION_RES_BUILD
PRODUCTVERSION VERSION_RES_MAJOR_VER, VERSION_RES_MINOR_VER, 0, VERSION_RES_BUILD
FILEFLAGSMASK VERSION_RES_FLAGSMASK
FILEFLAGS VERSION_RES_FLAGS
FILEOS VERSION_RES_OS
FILETYPE VERSION_RES_TYPE
FILESUBTYPE VERSION_RES_SUBTYPE
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", VERSION_RES_COMPANY_NAME
VALUE "Comment", VERSION_RES_COMMENT
VALUE "FileDescription", VERSION_RES_BIN_DESCRIPTION
VALUE "FileVersion", VERSION_RES_STRING
VALUE "InternalName", VERSION_RES_BIN_NAME
VALUE "LegalCopyright", VERSION_RES_COPYRIGHT
VALUE "OriginalFilename", VERSION_RES_BIN_NAME
VALUE "ProductName", VERSION_RES_PRODUCT_NAME
#ifdef DEBUG
VALUE "ProductVersion", VERSION_RES_STRING_D
#else
VALUE "ProductVersion", VERSION_RES_STRING
#endif
VALUE "ActiveMovie", VERSION_RES_ACTIVEX
#ifdef OLE_SELF_REGISTER
VALUE "OLESelfRegister", VERSION_RES_SELFREGISTER
#endif
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", VERSION_RES_LANGUAGE, VERSION_RES_CHARSET
END
END
#endif
// _ACTIVEX_RCV_

View File

@ -1,56 +0,0 @@
//------------------------------------------------------------------------------
// File: Activex.ver
//
// Desc: DirectShow base classes - common versioning information for
// ACTIVEX binaries.
//
// Copyright (c) 1996-2002, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef _ACTIVEX_VER_
#define _ACTIVEX_VER_
// NOTE: all string resources that will be used in ACTIVEX.RCV for the
// version resource information *MUST* have an explicit \0 terminator!
#define VERSION_RES_MAJOR_VER 9
#define VERSION_RES_MINOR_VER 0
#define VERSION_RES_BUILD 0
#define VERSION_RES_STRING_D "9.00 (Debug)\0"
#define VERSION_RES_STRING "9.00\0"
#define VERSION_RES_PRODUCT_NAME "DirectX 9.0 Sample\0"
#define VERSION_RES_COMMENT "DirectShow Sample\0"
#define VERSION_RES_COMPANY_NAME "Microsoft Corporation\0"
#define VERSION_RES_COPYRIGHT "Copyright (C) 1992-2002 Microsoft Corporation\0"
// The following defines are required on a file-by-file basis
//
// #define VERSION_RES_BIN_NAME "sample.ax\0"
// #define VERSION_RES_BIN_DESCRIPTION "Sample Filter\0"
//
// Also required, if you don't want the defaults, are
//
// #define VERSION_RES_ACTIVEX "Filter dll\0" (the default value)
//
// A string defining the type of component.
//
// #define VERSION_RES_TYPE VFT_DLL (default)
// VFT_APP
// VFT_VXD
// VFT_DRV
// VFT_FONT
// VFT_STATIC_LIB
// VFT_UNKNOWN
//
// #define VERSION_RES_SUBTYPE VFT2_UNKNOWN (default)
// VFT2_DRV_INSTALLABLE
// VFT2_DRV_SOUND
// <several other options>
//
// See winver.h for further details
#endif

View File

@ -1,54 +0,0 @@
//------------------------------------------------------------------------------
// File: AMAudio.h
//
// Desc: Audio related definitions and interfaces for ActiveMovie.
//
// Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __AMAUDIO__
#define __AMAUDIO__
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <mmsystem.h>
#include <dsound.h>
// This is the interface the audio renderer supports to give the application
// access to the direct sound object and the buffers it is using, to allow the
// application to use things like the 3D features of Direct Sound for the
// soundtrack of a movie being played with Active Movie.
// be nice to our friends in C
#undef INTERFACE
#define INTERFACE IAMDirectSound
DECLARE_INTERFACE_(IAMDirectSound,IUnknown)
{
/* IUnknown methods */
STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/* IAMDirectSound methods */
STDMETHOD(GetDirectSoundInterface)(THIS_ LPDIRECTSOUND *lplpds) PURE;
STDMETHOD(GetPrimaryBufferInterface)(THIS_ LPDIRECTSOUNDBUFFER *lplpdsb) PURE;
STDMETHOD(GetSecondaryBufferInterface)(THIS_ LPDIRECTSOUNDBUFFER *lplpdsb) PURE;
STDMETHOD(ReleaseDirectSoundInterface)(THIS_ LPDIRECTSOUND lpds) PURE;
STDMETHOD(ReleasePrimaryBufferInterface)(THIS_ LPDIRECTSOUNDBUFFER lpdsb) PURE;
STDMETHOD(ReleaseSecondaryBufferInterface)(THIS_ LPDIRECTSOUNDBUFFER lpdsb) PURE;
STDMETHOD(SetFocusWindow)(THIS_ HWND, BOOL) PURE ;
STDMETHOD(GetFocusWindow)(THIS_ HWND *, BOOL*) PURE ;
};
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __AMAUDIO__

View File

@ -1,111 +0,0 @@
//------------------------------------------------------------------------------
// File: AMExtra.cpp
//
// Desc: DirectShow base classes - implements CRenderedInputPin class.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h> // DirectShow base class definitions
#include <mmsystem.h> // Needed for definition of timeGetTime
#include <limits.h> // Standard data type limit definitions
#include <measure.h> // Used for time critical log functions
#include "amextra.h"
#pragma warning(disable:4355)
// Implements CRenderedInputPin class
CRenderedInputPin::CRenderedInputPin(TCHAR *pObjectName,
CBaseFilter *pFilter,
CCritSec *pLock,
HRESULT *phr,
LPCWSTR pName) :
CBaseInputPin(pObjectName, pFilter, pLock, phr, pName),
m_bAtEndOfStream(FALSE),
m_bCompleteNotified(FALSE)
{
}
#ifdef UNICODE
CRenderedInputPin::CRenderedInputPin(CHAR *pObjectName,
CBaseFilter *pFilter,
CCritSec *pLock,
HRESULT *phr,
LPCWSTR pName) :
CBaseInputPin(pObjectName, pFilter, pLock, phr, pName),
m_bAtEndOfStream(FALSE),
m_bCompleteNotified(FALSE)
{
}
#endif
// Flush end of stream condition - caller should do any
// necessary stream level locking before calling this
STDMETHODIMP CRenderedInputPin::EndOfStream()
{
HRESULT hr = CheckStreaming();
// Do EC_COMPLETE handling for rendered pins
if (S_OK == hr && !m_bAtEndOfStream) {
m_bAtEndOfStream = TRUE;
FILTER_STATE fs;
EXECUTE_ASSERT(SUCCEEDED(m_pFilter->GetState(0, &fs)));
if (fs == State_Running) {
DoCompleteHandling();
}
}
return hr;
}
// Called to complete the flush
STDMETHODIMP CRenderedInputPin::EndFlush()
{
CAutoLock lck(m_pLock);
// Clean up renderer state
m_bAtEndOfStream = FALSE;
m_bCompleteNotified = FALSE;
return CBaseInputPin::EndFlush();
}
// Notify of Run() from filter
HRESULT CRenderedInputPin::Run(REFERENCE_TIME tStart)
{
UNREFERENCED_PARAMETER(tStart);
m_bCompleteNotified = FALSE;
if (m_bAtEndOfStream) {
DoCompleteHandling();
}
return S_OK;
}
// Clear status on going into paused state
HRESULT CRenderedInputPin::Active()
{
m_bAtEndOfStream = FALSE;
m_bCompleteNotified = FALSE;
return CBaseInputPin::Active();
}
// Do stuff to deliver end of stream
void CRenderedInputPin::DoCompleteHandling()
{
ASSERT(m_bAtEndOfStream);
if (!m_bCompleteNotified) {
m_bCompleteNotified = TRUE;
m_pFilter->NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)m_pFilter);
}
}

View File

@ -1,56 +0,0 @@
//------------------------------------------------------------------------------
// File: AMExtra.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __AMEXTRA__
#define __AMEXTRA__
// Simple rendered input pin
//
// NOTE if your filter queues stuff before rendering then it may not be
// appropriate to use this class
//
// In that case queue the end of stream condition until the last sample
// is actually rendered and flush the condition appropriately
class CRenderedInputPin : public CBaseInputPin
{
public:
CRenderedInputPin(TCHAR *pObjectName,
CBaseFilter *pFilter,
CCritSec *pLock,
HRESULT *phr,
LPCWSTR pName);
#ifdef UNICODE
CRenderedInputPin(CHAR *pObjectName,
CBaseFilter *pFilter,
CCritSec *pLock,
HRESULT *phr,
LPCWSTR pName);
#endif
// Override methods to track end of stream state
STDMETHODIMP EndOfStream();
STDMETHODIMP EndFlush();
HRESULT Active();
HRESULT Run(REFERENCE_TIME tStart);
protected:
// Member variables to track state
BOOL m_bAtEndOfStream; // Set by EndOfStream
BOOL m_bCompleteNotified; // Set when we notify for EC_COMPLETE
private:
void DoCompleteHandling();
};
#endif // __AMEXTRA__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,275 +0,0 @@
//------------------------------------------------------------------------------
// File: AMVideo.cpp
//
// Desc: DirectShow base classes - implements helper functions for
// bitmap formats.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <limits.h>
// These are bit field masks for true colour devices
const DWORD bits555[] = {0x007C00,0x0003E0,0x00001F};
const DWORD bits565[] = {0x00F800,0x0007E0,0x00001F};
const DWORD bits888[] = {0xFF0000,0x00FF00,0x0000FF};
// This maps bitmap subtypes into a bits per pixel value and also a
// name. unicode and ansi versions are stored because we have to
// return a pointer to a static string.
const struct {
const GUID *pSubtype;
WORD BitCount;
CHAR *pName;
WCHAR *wszName;
} BitCountMap[] = { &MEDIASUBTYPE_RGB1, 1, "RGB Monochrome", L"RGB Monochrome",
&MEDIASUBTYPE_RGB4, 4, "RGB VGA", L"RGB VGA",
&MEDIASUBTYPE_RGB8, 8, "RGB 8", L"RGB 8",
&MEDIASUBTYPE_RGB565, 16, "RGB 565 (16 bit)", L"RGB 565 (16 bit)",
&MEDIASUBTYPE_RGB555, 16, "RGB 555 (16 bit)", L"RGB 555 (16 bit)",
&MEDIASUBTYPE_RGB24, 24, "RGB 24", L"RGB 24",
&MEDIASUBTYPE_RGB32, 32, "RGB 32", L"RGB 32",
&MEDIASUBTYPE_ARGB32, 32, "ARGB 32", L"ARGB 32",
&MEDIASUBTYPE_Overlay, 0, "Overlay", L"Overlay",
&GUID_NULL, 0, "UNKNOWN", L"UNKNOWN"
};
// Return the size of the bitmap as defined by this header
STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader)
{
return DIBSIZE(*pHeader);
}
// This is called if the header has a 16 bit colour depth and needs to work
// out the detailed type from the bit fields (either RGB 565 or RGB 555)
STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader)
{
BITMAPINFO *pbmInfo = (BITMAPINFO *) pbmiHeader;
ASSERT(pbmiHeader->biBitCount == 16);
// If its BI_RGB then it's RGB 555 by default
if (pbmiHeader->biCompression == BI_RGB) {
return MEDIASUBTYPE_RGB555;
}
// Compare the bit fields with RGB 555
DWORD *pMask = (DWORD *) pbmInfo->bmiColors;
if (pMask[0] == bits555[0]) {
if (pMask[1] == bits555[1]) {
if (pMask[2] == bits555[2]) {
return MEDIASUBTYPE_RGB555;
}
}
}
// Compare the bit fields with RGB 565
pMask = (DWORD *) pbmInfo->bmiColors;
if (pMask[0] == bits565[0]) {
if (pMask[1] == bits565[1]) {
if (pMask[2] == bits565[2]) {
return MEDIASUBTYPE_RGB565;
}
}
}
return GUID_NULL;
}
// Given a BITMAPINFOHEADER structure this returns the GUID sub type that is
// used to describe it in format negotiations. For example a video codec fills
// in the format block with a VIDEOINFO structure, it also fills in the major
// type with MEDIATYPE_VIDEO and the subtype with a GUID that matches the bit
// count, for example if it is an eight bit image then MEDIASUBTYPE_RGB8
STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader)
{
ASSERT(pbmiHeader);
// If it's not RGB then create a GUID from the compression type
if (pbmiHeader->biCompression != BI_RGB) {
if (pbmiHeader->biCompression != BI_BITFIELDS) {
FOURCCMap FourCCMap(pbmiHeader->biCompression);
return (const GUID) FourCCMap;
}
}
// Map the RGB DIB bit depth to a image GUID
switch(pbmiHeader->biBitCount) {
case 1 : return MEDIASUBTYPE_RGB1;
case 4 : return MEDIASUBTYPE_RGB4;
case 8 : return MEDIASUBTYPE_RGB8;
case 16 : return GetTrueColorType(pbmiHeader);
case 24 : return MEDIASUBTYPE_RGB24;
case 32 : return MEDIASUBTYPE_RGB32;
}
return GUID_NULL;
}
// Given a video bitmap subtype we return the number of bits per pixel it uses
// We return a WORD bit count as thats what the BITMAPINFOHEADER uses. If the
// GUID subtype is not found in the table we return an invalid USHRT_MAX
STDAPI_(WORD) GetBitCount(const GUID *pSubtype)
{
ASSERT(pSubtype);
const GUID *pMediaSubtype;
INT iPosition = 0;
// Scan the mapping list seeing if the source GUID matches any known
// bitmap subtypes, the list is terminated by a GUID_NULL entry
while (TRUE) {
pMediaSubtype = BitCountMap[iPosition].pSubtype;
if (IsEqualGUID(*pMediaSubtype,GUID_NULL)) {
return USHRT_MAX;
}
if (IsEqualGUID(*pMediaSubtype,*pSubtype)) {
return BitCountMap[iPosition].BitCount;
}
iPosition++;
}
}
// Given a bitmap subtype we return a description name that can be used for
// debug purposes. In a retail build this function still returns the names
// If the subtype isn't found in the lookup table we return string UNKNOWN
int LocateSubtype(const GUID *pSubtype)
{
ASSERT(pSubtype);
const GUID *pMediaSubtype;
INT iPosition = 0;
// Scan the mapping list seeing if the source GUID matches any known
// bitmap subtypes, the list is terminated by a GUID_NULL entry
while (TRUE) {
pMediaSubtype = BitCountMap[iPosition].pSubtype;
if (IsEqualGUID(*pMediaSubtype,*pSubtype) ||
IsEqualGUID(*pMediaSubtype,GUID_NULL)
)
{
break;
}
iPosition++;
}
return iPosition;
}
STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype)
{
return BitCountMap[LocateSubtype(pSubtype)].wszName;
}
STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype)
{
return BitCountMap[LocateSubtype(pSubtype)].pName;
}
#ifndef GetSubtypeName
#error wxutil.h should have defined GetSubtypeName
#endif
#undef GetSubtypeName
// this is here for people that linked to it directly; most people
// would use the header file that picks the A or W version.
STDAPI_(CHAR *) GetSubtypeName(const GUID *pSubtype)
{
return GetSubtypeNameA(pSubtype);
}
// The mechanism for describing a bitmap format is with the BITMAPINFOHEADER
// This is really messy to deal with because it invariably has fields that
// follow it holding bit fields, palettes and the rest. This function gives
// the number of bytes required to hold a VIDEOINFO that represents it. This
// count includes the prefix information (like the rcSource rectangle) the
// BITMAPINFOHEADER field, and any other colour information on the end.
//
// WARNING If you want to copy a BITMAPINFOHEADER into a VIDEOINFO always make
// sure that you use the HEADER macro because the BITMAPINFOHEADER field isn't
// right at the start of the VIDEOINFO (there are a number of other fields),
//
// CopyMemory(HEADER(pVideoInfo),pbmi,sizeof(BITMAPINFOHEADER));
//
STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader)
{
// Everyone has this to start with this
LONG Size = SIZE_PREHEADER + pHeader->biSize;
ASSERT(pHeader->biSize >= sizeof(BITMAPINFOHEADER));
// Does this format use a palette, if the number of colours actually used
// is zero then it is set to the maximum that are allowed for that colour
// depth (an example is 256 for eight bits). Truecolour formats may also
// pass a palette with them in which case the used count is non zero
// This would scare me.
ASSERT(pHeader->biBitCount <= iPALETTE || pHeader->biClrUsed == 0);
if (pHeader->biBitCount <= iPALETTE || pHeader->biClrUsed) {
LONG Entries = (DWORD) 1 << pHeader->biBitCount;
if (pHeader->biClrUsed) {
Entries = pHeader->biClrUsed;
}
Size += Entries * sizeof(RGBQUAD);
}
// Truecolour formats may have a BI_BITFIELDS specifier for compression
// type which means that room for three DWORDs should be allocated that
// specify where in each pixel the RGB colour components may be found
if (pHeader->biCompression == BI_BITFIELDS) {
Size += SIZE_MASKS;
}
// A BITMAPINFO for a palettised image may also contain a palette map that
// provides the information to map from a source palette to a destination
// palette during a BitBlt for example, because this information is only
// ever processed during drawing you don't normally store the palette map
// nor have any way of knowing if it is present in the data structure
return Size;
}
// Returns TRUE if the VIDEOINFO contains a palette
STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo)
{
if (PALETTISED(pVideoInfo) == FALSE) {
if (pVideoInfo->bmiHeader.biClrUsed == 0) {
return FALSE;
}
}
return TRUE;
}
// Return a pointer to the first entry in a palette
STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo)
{
if (pVideoInfo->bmiHeader.biCompression == BI_BITFIELDS) {
return TRUECOLOR(pVideoInfo)->bmiColors;
}
return COLORS(pVideoInfo);
}

View File

@ -1,53 +0,0 @@
//------------------------------------------------------------------------------
// File: AudEvCod.h
//
// Desc: List of Audio device error event codes and the expected params.
//
// Copyright (c) 1999-2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __AUDEVCOD__
#define __AUDEVCOD__
#define EC_SND_DEVICE_ERROR_BASE 0x0200
typedef enum _tagSND_DEVICE_ERROR {
SNDDEV_ERROR_Open=1,
SNDDEV_ERROR_Close=2,
SNDDEV_ERROR_GetCaps=3,
SNDDEV_ERROR_PrepareHeader=4,
SNDDEV_ERROR_UnprepareHeader=5,
SNDDEV_ERROR_Reset=6,
SNDDEV_ERROR_Restart=7,
SNDDEV_ERROR_GetPosition=8,
SNDDEV_ERROR_Write=9,
SNDDEV_ERROR_Pause=10,
SNDDEV_ERROR_Stop=11,
SNDDEV_ERROR_Start=12,
SNDDEV_ERROR_AddBuffer=13,
SNDDEV_ERROR_Query=14,
} SNDDEV_ERR;
// Sound device error event codes
// ==============================
//
// All audio device error events are always passed on to the application, and are
// never processed by the filter graph
#define EC_SNDDEV_IN_ERROR (EC_SND_DEVICE_ERROR_BASE + 0x00)
#define EC_SNDDEV_OUT_ERROR (EC_SND_DEVICE_ERROR_BASE + 0x01)
// Parameters: ( DWORD, DWORD)
// lParam1 is an enum SND_DEVICE_ERROR which notifies the app how the device was
// being accessed when the failure occurred.
//
// lParam2 is the error returned from the sound device call.
//
#endif // __AUDEVCOD__

View File

@ -1,444 +0,0 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="BaseClasses"
ProjectGUID="{7CDC5863-9F36-468D-A634-6D7799E0A15E}"
RootNamespace="baseclasses"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
ManagedExtensions="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="."
PreprocessorDefinitions="_LIB;_WIN32_DCOM"
PrecompiledHeaderThrough="streams.h"
PrecompiledHeaderFile="$(OutDir)/baseclasses.pch"
CallingConvention="2"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG,WIN32"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="strmiids.lib winmm.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
ManagedExtensions="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="."
PreprocessorDefinitions="_LIB;_WIN32_DCOM"
PrecompiledHeaderThrough="streams.h"
PrecompiledHeaderFile="$(OutDir)/baseclasses.pch"
CallingConvention="2"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG,WIN32"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
AdditionalDependencies="strmiids.lib winmm.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath=".\amextra.cpp"
>
</File>
<File
RelativePath=".\amfilter.cpp"
>
</File>
<File
RelativePath=".\amvideo.cpp"
>
</File>
<File
RelativePath=".\combase.cpp"
>
</File>
<File
RelativePath=".\cprop.cpp"
>
</File>
<File
RelativePath=".\ctlutil.cpp"
>
</File>
<File
RelativePath=".\ddmm.cpp"
>
</File>
<File
RelativePath=".\dllentry.cpp"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\dllsetup.cpp"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\mtype.cpp"
>
</File>
<File
RelativePath=".\outputq.cpp"
>
</File>
<File
RelativePath=".\pstream.cpp"
>
</File>
<File
RelativePath=".\pullpin.cpp"
>
</File>
<File
RelativePath=".\refclock.cpp"
>
</File>
<File
RelativePath=".\renbase.cpp"
>
</File>
<File
RelativePath=".\schedule.cpp"
>
</File>
<File
RelativePath=".\seekpt.cpp"
>
</File>
<File
RelativePath=".\source.cpp"
>
</File>
<File
RelativePath=".\strmctl.cpp"
>
</File>
<File
RelativePath=".\sysclock.cpp"
>
</File>
<File
RelativePath=".\transfrm.cpp"
>
</File>
<File
RelativePath=".\transip.cpp"
>
</File>
<File
RelativePath=".\videoctl.cpp"
>
</File>
<File
RelativePath=".\vtrans.cpp"
>
</File>
<File
RelativePath=".\winctrl.cpp"
>
</File>
<File
RelativePath=".\winutil.cpp"
>
</File>
<File
RelativePath=".\wxdebug.cpp"
>
</File>
<File
RelativePath=".\wxlist.cpp"
>
</File>
<File
RelativePath=".\wxutil.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath=".\amextra.h"
>
</File>
<File
RelativePath=".\amfilter.h"
>
</File>
<File
RelativePath=".\cache.h"
>
</File>
<File
RelativePath=".\combase.h"
>
</File>
<File
RelativePath=".\cprop.h"
>
</File>
<File
RelativePath=".\ctlutil.h"
>
</File>
<File
RelativePath=".\ddmm.h"
>
</File>
<File
RelativePath=".\dllsetup.h"
>
</File>
<File
RelativePath=".\dsschedule.h"
>
</File>
<File
RelativePath=".\fourcc.h"
>
</File>
<File
RelativePath=".\measure.h"
>
</File>
<File
RelativePath=".\msgthrd.h"
>
</File>
<File
RelativePath=".\mtype.h"
>
</File>
<File
RelativePath=".\outputq.h"
>
</File>
<File
RelativePath=".\pstream.h"
>
</File>
<File
RelativePath=".\pullpin.h"
>
</File>
<File
RelativePath=".\refclock.h"
>
</File>
<File
RelativePath=".\reftime.h"
>
</File>
<File
RelativePath=".\renbase.h"
>
</File>
<File
RelativePath=".\schedule.h"
>
</File>
<File
RelativePath=".\seekpt.h"
>
</File>
<File
RelativePath=".\source.h"
>
</File>
<File
RelativePath=".\streams.h"
>
</File>
<File
RelativePath=".\strmctl.h"
>
</File>
<File
RelativePath=".\sysclock.h"
>
</File>
<File
RelativePath=".\transfrm.h"
>
</File>
<File
RelativePath=".\transip.h"
>
</File>
<File
RelativePath=".\videoctl.h"
>
</File>
<File
RelativePath=".\vtrans.h"
>
</File>
<File
RelativePath=".\winctrl.h"
>
</File>
<File
RelativePath=".\winutil.h"
>
</File>
<File
RelativePath=".\wxdebug.h"
>
</File>
<File
RelativePath=".\wxlist.h"
>
</File>
<File
RelativePath=".\wxutil.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="REFRACTION"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="REFRACTION"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,74 +0,0 @@
//------------------------------------------------------------------------------
// File: Cache.h
//
// Desc: DirectShow base classes - efines a non-MFC generic cache class.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
/* This class implements a simple cache. A cache object is instantiated
with the number of items it is to hold. An item is a pointer to an
object derived from CBaseObject (helps reduce memory leaks). The cache
can then have objects added to it and removed from it. The cache size
is fixed at construction time and may therefore run out or be flooded.
If it runs out it returns a NULL pointer, if it fills up it also returns
a NULL pointer instead of a pointer to the object just inserted */
/* Making these classes inherit from CBaseObject does nothing for their
functionality but it allows us to check there are no memory leaks */
/* WARNING Be very careful when using this class, what it lets you do is
store and retrieve objects so that you can minimise object creation
which in turns improves efficiency. However the object you store is
exactly the same as the object you get back which means that it short
circuits the constructor initialisation phase. This means any class
variables the object has (eg pointers) are highly likely to be invalid.
Therefore ensure you reinitialise the object before using it again */
#ifndef __CACHE__
#define __CACHE__
class CCache : CBaseObject {
/* Make copy constructor and assignment operator inaccessible */
CCache(const CCache &refCache);
CCache &operator=(const CCache &refCache);
private:
/* These are initialised in the constructor. The first variable points to
an array of pointers, each of which points to a CBaseObject derived
object. The m_iCacheSize is the static fixed size for the cache and the
m_iUsed defines the number of places filled with objects at any time.
We fill the array of pointers from the start (ie m_ppObjects[0] first)
and then only add and remove objects from the end position, so in this
respect the array of object pointers should be treated as a stack */
CBaseObject **m_ppObjects;
const INT m_iCacheSize;
INT m_iUsed;
public:
CCache(TCHAR *pName,INT iItems);
virtual ~CCache();
/* Add an item to the cache */
CBaseObject *AddToCache(CBaseObject *pObject);
/* Remove an item from the cache */
CBaseObject *RemoveFromCache();
/* Delete all the objects held in the cache */
void RemoveAll(void);
/* Return the cache size which is set during construction */
INT GetCacheSize(void) const {return m_iCacheSize;};
};
#endif /* __CACHE__ */

View File

@ -1,256 +0,0 @@
//------------------------------------------------------------------------------
// File: ComBase.cpp
//
// Desc: DirectShow base classes - implements class hierarchy for creating
// COM objects.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#pragma warning( disable : 4514 ) // Disable warnings re unused inline functions
/* Define the static member variable */
LONG CBaseObject::m_cObjects = 0;
/* Constructor */
CBaseObject::CBaseObject(const TCHAR *pName)
{
/* Increment the number of active objects */
InterlockedIncrement(&m_cObjects);
#ifdef DEBUG
#ifdef UNICODE
m_dwCookie = DbgRegisterObjectCreation(0, pName);
#else
m_dwCookie = DbgRegisterObjectCreation(pName, 0);
#endif
#endif
}
#ifdef UNICODE
CBaseObject::CBaseObject(const char *pName)
{
/* Increment the number of active objects */
InterlockedIncrement(&m_cObjects);
#ifdef DEBUG
m_dwCookie = DbgRegisterObjectCreation(pName, 0);
#endif
}
#endif
HINSTANCE hlibOLEAut32;
/* Destructor */
CBaseObject::~CBaseObject()
{
/* Decrement the number of objects active */
if (InterlockedDecrement(&m_cObjects) == 0) {
if (hlibOLEAut32) {
FreeLibrary(hlibOLEAut32);
hlibOLEAut32 = 0;
}
};
#ifdef DEBUG
DbgRegisterObjectDestruction(m_dwCookie);
#endif
}
static const TCHAR szOle32Aut[] = TEXT("OleAut32.dll");
HINSTANCE LoadOLEAut32()
{
if (hlibOLEAut32 == 0) {
hlibOLEAut32 = LoadLibrary(szOle32Aut);
}
return hlibOLEAut32;
}
/* Constructor */
// We know we use "this" in the initialization list, we also know we don't modify *phr.
#pragma warning( disable : 4355 4100 )
CUnknown::CUnknown(const TCHAR *pName, LPUNKNOWN pUnk)
: CBaseObject(pName)
/* Start the object with a reference count of zero - when the */
/* object is queried for it's first interface this may be */
/* incremented depending on whether or not this object is */
/* currently being aggregated upon */
, m_cRef(0)
/* Set our pointer to our IUnknown interface. */
/* If we have an outer, use its, otherwise use ours. */
/* This pointer effectivly points to the owner of */
/* this object and can be accessed by the GetOwner() method. */
, m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
/* Why the double cast? Well, the inner cast is a type-safe cast */
/* to pointer to a type from which we inherit. The second is */
/* type-unsafe but works because INonDelegatingUnknown "behaves */
/* like" IUnknown. (Only the names on the methods change.) */
{
// Everything we need to do has been done in the initializer list
}
// This does the same as above except it has a useless HRESULT argument
// use the previous constructor, this is just left for compatibility...
CUnknown::CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) :
CBaseObject(pName),
m_cRef(0),
m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
{
}
#ifdef UNICODE
CUnknown::CUnknown(const CHAR *pName, LPUNKNOWN pUnk)
: CBaseObject(pName), m_cRef(0),
m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
{ }
CUnknown::CUnknown(CHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) :
CBaseObject(pName), m_cRef(0),
m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
{ }
#endif
#pragma warning( default : 4355 4100 )
/* QueryInterface */
STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
{
CheckPointer(ppv,E_POINTER);
ValidateReadWritePtr(ppv,sizeof(PVOID));
/* We know only about IUnknown */
if (riid == IID_IUnknown) {
GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv);
return NOERROR;
} else {
*ppv = NULL;
return E_NOINTERFACE;
}
}
/* We have to ensure that we DON'T use a max macro, since these will typically */
/* lead to one of the parameters being evaluated twice. Since we are worried */
/* about concurrency, we can't afford to access the m_cRef twice since we can't */
/* afford to run the risk that its value having changed between accesses. */
template<class T> inline static T ourmax( const T & a, const T & b )
{
return a > b ? a : b;
}
/* AddRef */
STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef()
{
LONG lRef = InterlockedIncrement( &m_cRef );
ASSERT(lRef > 0);
DbgLog((LOG_MEMORY,3,TEXT(" Obj %d ref++ = %d"),
m_dwCookie, m_cRef));
return ourmax(ULONG(m_cRef), 1ul);
}
/* Release */
STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease()
{
/* If the reference count drops to zero delete ourselves */
LONG lRef = InterlockedDecrement( &m_cRef );
ASSERT(lRef >= 0);
DbgLog((LOG_MEMORY,3,TEXT(" Object %d ref-- = %d"),
m_dwCookie, m_cRef));
if (lRef == 0) {
// COM rules say we must protect against re-entrancy.
// If we are an aggregator and we hold our own interfaces
// on the aggregatee, the QI for these interfaces will
// addref ourselves. So after doing the QI we must release
// a ref count on ourselves. Then, before releasing the
// private interface, we must addref ourselves. When we do
// this from the destructor here it will result in the ref
// count going to 1 and then back to 0 causing us to
// re-enter the destructor. Hence we add an extra refcount here
// once we know we will delete the object.
// for an example aggregator see filgraph\distrib.cpp.
m_cRef++;
delete this;
return ULONG(0);
} else {
return ourmax(ULONG(m_cRef), 1ul);
}
}
/* Return an interface pointer to a requesting client
performing a thread safe AddRef as necessary */
STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv)
{
CheckPointer(ppv, E_POINTER);
*ppv = pUnk;
pUnk->AddRef();
return NOERROR;
}
/* Compares two interfaces and returns TRUE if they are on the same object */
BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond)
{
/* Different objects can't have the same interface pointer for
any interface
*/
if (pFirst == pSecond) {
return TRUE;
}
/* OK - do it the hard way - check if they have the same
IUnknown pointers - a single object can only have one of these
*/
LPUNKNOWN pUnknown1; // Retrieve the IUnknown interface
LPUNKNOWN pUnknown2; // Retrieve the other IUnknown interface
HRESULT hr; // General OLE return code
ASSERT(pFirst);
ASSERT(pSecond);
/* See if the IUnknown pointers match */
hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1);
ASSERT(SUCCEEDED(hr));
ASSERT(pUnknown1);
hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2);
ASSERT(SUCCEEDED(hr));
ASSERT(pUnknown2);
/* Release the extra interfaces we hold */
pUnknown1->Release();
pUnknown2->Release();
return (pUnknown1 == pUnknown2);
}

View File

@ -1,319 +0,0 @@
//------------------------------------------------------------------------------
// File: ComBase.h
//
// Desc: DirectShow base classes - defines a class hierarchy for creating
// COM objects.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
/*
a. Derive your COM object from CUnknown
b. Make a static CreateInstance function that takes an LPUNKNOWN, an HRESULT *
and a TCHAR *. The LPUNKNOWN defines the object to delegate IUnknown calls
to. The HRESULT * allows error codes to be passed around constructors and
the TCHAR * is a descriptive name that can be printed on the debugger.
It is important that constructors only change the HRESULT * if they have
to set an ERROR code, if it was successful then leave it alone or you may
overwrite an error code from an object previously created.
When you call a constructor the descriptive name should be in static store
as we do not copy the string. To stop large amounts of memory being used
in retail builds by all these static strings use the NAME macro,
CMyFilter = new CImplFilter(NAME("My filter"),pUnknown,phr);
if (FAILED(hr)) {
return hr;
}
In retail builds NAME(_x_) compiles to NULL, the base CBaseObject class
knows not to do anything with objects that don't have a name.
c. Have a constructor for your object that passes the LPUNKNOWN, HRESULT * and
TCHAR * to the CUnknown constructor. You can set the HRESULT if you have an
error, or just simply pass it through to the constructor.
The object creation will fail in the class factory if the HRESULT indicates
an error (ie FAILED(HRESULT) == TRUE)
d. Create a FactoryTemplate with your object's class id and CreateInstance
function.
Then (for each interface) either
Multiple inheritance
1. Also derive it from ISomeInterface
2. Include DECLARE_IUNKNOWN in your class definition to declare
implementations of QueryInterface, AddRef and Release that
call the outer unknown
3. Override NonDelegatingQueryInterface to expose ISomeInterface by
code something like
if (riid == IID_ISomeInterface) {
return GetInterface((ISomeInterface *) this, ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
4. Declare and implement the member functions of ISomeInterface.
or: Nested interfaces
1. Declare a class derived from CUnknown
2. Include DECLARE_IUNKNOWN in your class definition
3. Override NonDelegatingQueryInterface to expose ISomeInterface by
code something like
if (riid == IID_ISomeInterface) {
return GetInterface((ISomeInterface *) this, ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
4. Implement the member functions of ISomeInterface. Use GetOwner() to
access the COM object class.
And in your COM object class:
5. Make the nested class a friend of the COM object class, and declare
an instance of the nested class as a member of the COM object class.
NOTE that because you must always pass the outer unknown and an hResult
to the CUnknown constructor you cannot use a default constructor, in
other words you will have to make the member variable a pointer to the
class and make a NEW call in your constructor to actually create it.
6. override the NonDelegatingQueryInterface with code like this:
if (riid == IID_ISomeInterface) {
return m_pImplFilter->
NonDelegatingQueryInterface(IID_ISomeInterface, ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
You can have mixed classes which support some interfaces via multiple
inheritance and some via nested classes
*/
#ifndef __COMBASE__
#define __COMBASE__
// Filter Setup data structures no defined in axextend.idl
typedef REGPINTYPES
AMOVIESETUP_MEDIATYPE, * PAMOVIESETUP_MEDIATYPE, * FAR LPAMOVIESETUP_MEDIATYPE;
typedef REGFILTERPINS
AMOVIESETUP_PIN, * PAMOVIESETUP_PIN, * FAR LPAMOVIESETUP_PIN;
typedef struct _AMOVIESETUP_FILTER
{
const CLSID * clsID;
const WCHAR * strName;
DWORD dwMerit;
UINT nPins;
const AMOVIESETUP_PIN * lpPin;
}
AMOVIESETUP_FILTER, * PAMOVIESETUP_FILTER, * FAR LPAMOVIESETUP_FILTER;
/* The DLLENTRY module initialises the module handle on loading */
extern HINSTANCE g_hInst;
/* On DLL load remember which platform we are running on */
extern DWORD g_amPlatform;
extern OSVERSIONINFO g_osInfo; // Filled in by GetVersionEx
/* Version of IUnknown that is renamed to allow a class to support both
non delegating and delegating IUnknowns in the same COM object */
#ifndef INONDELEGATINGUNKNOWN_DEFINED
DECLARE_INTERFACE(INonDelegatingUnknown)
{
STDMETHOD(NonDelegatingQueryInterface) (THIS_ REFIID, LPVOID *) PURE;
STDMETHOD_(ULONG, NonDelegatingAddRef)(THIS) PURE;
STDMETHOD_(ULONG, NonDelegatingRelease)(THIS) PURE;
};
#define INONDELEGATINGUNKNOWN_DEFINED
#endif
typedef INonDelegatingUnknown *PNDUNKNOWN;
/* This is the base object class that supports active object counting. As
part of the debug facilities we trace every time a C++ object is created
or destroyed. The name of the object has to be passed up through the class
derivation list during construction as you cannot call virtual functions
in the constructor. The downside of all this is that every single object
constructor has to take an object name parameter that describes it */
class CBaseObject
{
private:
// Disable the copy constructor and assignment by default so you will get
// compiler errors instead of unexpected behaviour if you pass objects
// by value or assign objects.
CBaseObject(const CBaseObject& objectSrc); // no implementation
void operator=(const CBaseObject& objectSrc); // no implementation
private:
static LONG m_cObjects; /* Total number of objects active */
protected:
#ifdef DEBUG
DWORD m_dwCookie; /* Cookie identifying this object */
#endif
public:
/* These increment and decrement the number of active objects */
CBaseObject(const TCHAR *pName);
#ifdef UNICODE
CBaseObject(const char *pName);
#endif
~CBaseObject();
/* Call this to find if there are any CUnknown derived objects active */
static LONG ObjectsActive() {
return m_cObjects;
};
};
/* An object that supports one or more COM interfaces will be based on
this class. It supports counting of total objects for DLLCanUnloadNow
support, and an implementation of the core non delegating IUnknown */
class AM_NOVTABLE CUnknown : public INonDelegatingUnknown,
public CBaseObject
{
private:
const LPUNKNOWN m_pUnknown; /* Owner of this object */
protected: /* So we can override NonDelegatingRelease() */
volatile LONG m_cRef; /* Number of reference counts */
public:
CUnknown(const TCHAR *pName, LPUNKNOWN pUnk);
virtual ~CUnknown() {};
// This is redundant, just use the other constructor
// as we never touch the HRESULT in this anyway
CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr);
#ifdef UNICODE
CUnknown(const char *pName, LPUNKNOWN pUnk);
CUnknown(char *pName, LPUNKNOWN pUnk,HRESULT *phr);
#endif
/* Return the owner of this object */
LPUNKNOWN GetOwner() const {
return m_pUnknown;
};
/* Called from the class factory to create a new instance, it is
pure virtual so it must be overriden in your derived class */
/* static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *) */
/* Non delegating unknown implementation */
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void **);
STDMETHODIMP_(ULONG) NonDelegatingAddRef();
STDMETHODIMP_(ULONG) NonDelegatingRelease();
};
#if (_MSC_VER <= 1200)
#pragma warning(disable:4211)
/* The standard InterlockedXXX functions won't take volatiles */
static inline LONG WINAPI InterlockedIncrement( volatile LONG * plong )
{ return InterlockedIncrement( const_cast<LONG*>( plong ) ); }
static inline LONG WINAPI InterlockedDecrement( volatile LONG * plong )
{ return InterlockedDecrement( const_cast<LONG*>( plong ) ); }
#pragma warning(default:4211)
#endif
/* Return an interface pointer to a requesting client
performing a thread safe AddRef as necessary */
STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv);
/* A function that can create a new COM object */
typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
/* A function (can be NULL) which is called from the DLL entrypoint
routine for each factory template:
bLoading - TRUE on DLL load, FALSE on DLL unload
rclsid - the m_ClsID of the entry
*/
typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);
/* Create one of these per object class in an array so that
the default class factory code can create new instances */
class CFactoryTemplate {
public:
const WCHAR * m_Name;
const CLSID * m_ClsID;
LPFNNewCOMObject m_lpfnNew;
LPFNInitRoutine m_lpfnInit;
const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter;
BOOL IsClassID(REFCLSID rclsid) const {
return (IsEqualCLSID(*m_ClsID,rclsid));
};
CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) const {
CheckPointer(phr,NULL);
return m_lpfnNew(pUnk, phr);
};
};
/* You must override the (pure virtual) NonDelegatingQueryInterface to return
interface pointers (using GetInterface) to the interfaces your derived
class supports (the default implementation only supports IUnknown) */
#define DECLARE_IUNKNOWN \
STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \
return GetOwner()->QueryInterface(riid,ppv); \
}; \
STDMETHODIMP_(ULONG) AddRef() { \
return GetOwner()->AddRef(); \
}; \
STDMETHODIMP_(ULONG) Release() { \
return GetOwner()->Release(); \
};
HINSTANCE LoadOLEAut32();
#endif /* __COMBASE__ */

View File

@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// File: COMLite.h
//
// Desc: This header file is to provide a migration path for users of
// ActiveMovie betas 1 and 2.
//
// Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef _INC_COMLITE_
#define _INC_COMLITE_
#define QzInitialize CoInitialize
#define QzUninitialize CoUninitialize
#define QzFreeUnusedLibraries CoFreeUnusedLibraries
#define QzGetMalloc CoGetMalloc
#define QzTaskMemAlloc CoTaskMemAlloc
#define QzTaskMemRealloc CoTaskMemRealloc
#define QzTaskMemFree CoTaskMemFree
#define QzCreateFilterObject CoCreateInstance
#define QzCLSIDFromString CLSIDFromString
#define QzStringFromGUID2 StringFromGUID2
#endif // _INC_COMLITE_

View File

@ -1,380 +0,0 @@
//------------------------------------------------------------------------------
// File: CProp.cpp
//
// Desc: DirectShow base classes - implements CBasePropertyPage class.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
// Constructor for the base property page class. As described in the header
// file we must be initialised with dialog and title resource identifiers.
// The class supports IPropertyPage and overrides AddRef and Release calls
// to keep track of the reference counts. When the last count is released
// we call SetPageSite(NULL) and SetObjects(0,NULL) to release interfaces
// previously obtained by the property page when it had SetObjects called
CBasePropertyPage::CBasePropertyPage(TCHAR *pName, // Debug only name
LPUNKNOWN pUnk, // COM Delegator
int DialogId, // Resource ID
int TitleId) : // To get tital
CUnknown(pName,pUnk),
m_DialogId(DialogId),
m_TitleId(TitleId),
m_hwnd(NULL),
m_Dlg(NULL),
m_pPageSite(NULL),
m_bObjectSet(FALSE),
m_bDirty(FALSE)
{
}
#ifdef UNICODE
CBasePropertyPage::CBasePropertyPage(CHAR *pName, // Debug only name
LPUNKNOWN pUnk, // COM Delegator
int DialogId, // Resource ID
int TitleId) : // To get tital
CUnknown(pName,pUnk),
m_DialogId(DialogId),
m_TitleId(TitleId),
m_hwnd(NULL),
m_Dlg(NULL),
m_pPageSite(NULL),
m_bObjectSet(FALSE),
m_bDirty(FALSE)
{
}
#endif
// Increment our reference count
STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingAddRef()
{
LONG lRef = InterlockedIncrement(&m_cRef);
ASSERT(lRef > 0);
return max(ULONG(m_cRef),1ul);
}
// Release a reference count and protect against reentrancy
STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingRelease()
{
// If the reference count drops to zero delete ourselves
if (InterlockedDecrement(&m_cRef) == 0) {
m_cRef++;
SetPageSite(NULL);
SetObjects(0,NULL);
delete this;
return ULONG(0);
} else {
return max(ULONG(m_cRef),1ul);
}
}
// Expose our IPropertyPage interface
STDMETHODIMP
CBasePropertyPage::NonDelegatingQueryInterface(REFIID riid,void **ppv)
{
if (riid == IID_IPropertyPage) {
return GetInterface((IPropertyPage *)this,ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid,ppv);
}
}
// Get the page info so that the page site can size itself
STDMETHODIMP CBasePropertyPage::GetPageInfo(LPPROPPAGEINFO pPageInfo)
{
CheckPointer(pPageInfo,E_POINTER);
WCHAR wszTitle[STR_MAX_LENGTH];
WideStringFromResource(wszTitle,m_TitleId);
// Allocate dynamic memory for the property page title
LPOLESTR pszTitle;
HRESULT hr = AMGetWideString(wszTitle, &pszTitle);
if (FAILED(hr)) {
NOTE("No caption memory");
return hr;
}
pPageInfo->cb = sizeof(PROPPAGEINFO);
pPageInfo->pszTitle = pszTitle;
pPageInfo->pszDocString = NULL;
pPageInfo->pszHelpFile = NULL;
pPageInfo->dwHelpContext = 0;
// Set defaults in case GetDialogSize fails
pPageInfo->size.cx = 340;
pPageInfo->size.cy = 150;
GetDialogSize(m_DialogId, DialogProc,0L,&pPageInfo->size);
return NOERROR;
}
// Handles the messages for our property window
INT_PTR CALLBACK CBasePropertyPage::DialogProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
CBasePropertyPage *pPropertyPage;
switch (uMsg) {
case WM_INITDIALOG:
SetWindowLongPtr(hwnd, DWLP_USER, lParam);
// This pointer may be NULL when calculating size
pPropertyPage = (CBasePropertyPage *) lParam;
if (pPropertyPage == NULL) {
return (LRESULT) 1;
}
pPropertyPage->m_Dlg = hwnd;
}
// This pointer may be NULL when calculating size
pPropertyPage = (CBasePropertyPage *) GetWindowLongPtr(hwnd, DWLP_USER);
if (pPropertyPage == NULL) {
return (LRESULT) 1;
}
return pPropertyPage->OnReceiveMessage(hwnd,uMsg,wParam,lParam);
}
// Tells us the object that should be informed of the property changes
STDMETHODIMP CBasePropertyPage::SetObjects(ULONG cObjects,LPUNKNOWN *ppUnk)
{
if (cObjects == 1) {
if ((ppUnk == NULL) || (*ppUnk == NULL)) {
return E_POINTER;
}
// Set a flag to say that we have set the Object
m_bObjectSet = TRUE ;
return OnConnect(*ppUnk);
} else if (cObjects == 0) {
// Set a flag to say that we have not set the Object for the page
m_bObjectSet = FALSE ;
return OnDisconnect();
}
DbgBreak("No support for more than one object");
return E_UNEXPECTED;
}
// Create the window we will use to edit properties
STDMETHODIMP CBasePropertyPage::Activate(HWND hwndParent,
LPCRECT pRect,
BOOL fModal)
{
CheckPointer(pRect,E_POINTER);
// Return failure if SetObject has not been called.
if (m_bObjectSet == FALSE) {
return E_UNEXPECTED;
}
if (m_hwnd) {
return E_UNEXPECTED;
}
m_hwnd = CreateDialogParam(g_hInst,
MAKEINTRESOURCE(m_DialogId),
hwndParent,
DialogProc,
(LPARAM) this);
if (m_hwnd == NULL) {
return E_OUTOFMEMORY;
}
OnActivate();
Move(pRect);
return Show(SW_SHOWNORMAL);
}
// Set the position of the property page
STDMETHODIMP CBasePropertyPage::Move(LPCRECT pRect)
{
CheckPointer(pRect,E_POINTER);
if (m_hwnd == NULL) {
return E_UNEXPECTED;
}
MoveWindow(m_hwnd, // Property page handle
pRect->left, // x coordinate
pRect->top, // y coordinate
WIDTH(pRect), // Overall window width
HEIGHT(pRect), // And likewise height
TRUE); // Should we repaint it
return NOERROR;
}
// Display the property dialog
STDMETHODIMP CBasePropertyPage::Show(UINT nCmdShow)
{
// Have we been activated yet
if (m_hwnd == NULL) {
return E_UNEXPECTED;
}
// Ignore wrong show flags
if ((nCmdShow != SW_SHOW) && (nCmdShow != SW_SHOWNORMAL) && (nCmdShow != SW_HIDE)) {
return E_INVALIDARG;
}
ShowWindow(m_hwnd,nCmdShow);
InvalidateRect(m_hwnd,NULL,TRUE);
return NOERROR;
}
// Destroy the property page dialog
STDMETHODIMP CBasePropertyPage::Deactivate(void)
{
if (m_hwnd == NULL) {
return E_UNEXPECTED;
}
// Remove WS_EX_CONTROLPARENT before DestroyWindow call
DWORD dwStyle = GetWindowLong(m_hwnd, GWL_EXSTYLE);
dwStyle = dwStyle & (~WS_EX_CONTROLPARENT);
// Set m_hwnd to be NULL temporarily so the message handler
// for WM_STYLECHANGING doesn't add the WS_EX_CONTROLPARENT
// style back in
HWND hwnd = m_hwnd;
m_hwnd = NULL;
SetWindowLong(hwnd, GWL_EXSTYLE, dwStyle);
m_hwnd = hwnd;
OnDeactivate();
// Destroy the dialog window
DestroyWindow(m_hwnd);
m_hwnd = NULL;
return NOERROR;
}
// Tells the application property page site
STDMETHODIMP CBasePropertyPage::SetPageSite(LPPROPERTYPAGESITE pPageSite)
{
if (pPageSite) {
if (m_pPageSite) {
return E_UNEXPECTED;
}
m_pPageSite = pPageSite;
m_pPageSite->AddRef();
} else {
if (m_pPageSite == NULL) {
return E_UNEXPECTED;
}
m_pPageSite->Release();
m_pPageSite = NULL;
}
return NOERROR;
}
// Apply any changes so far made
STDMETHODIMP CBasePropertyPage::Apply()
{
// In ActiveMovie 1.0 we used to check whether we had been activated or
// not. This is too constrictive. Apply should be allowed as long as
// SetObject was called to set an object. So we will no longer check to
// see if we have been activated (ie., m_hWnd != NULL), but instead
// make sure that m_bObjectSet is TRUE (ie., SetObject has been called).
if (m_bObjectSet == FALSE) {
return E_UNEXPECTED;
}
// Must have had a site set
if (m_pPageSite == NULL) {
return E_UNEXPECTED;
}
// Has anything changed
if (m_bDirty == FALSE) {
return NOERROR;
}
// Commit derived class changes
HRESULT hr = OnApplyChanges();
if (SUCCEEDED(hr)) {
m_bDirty = FALSE;
}
return hr;
}
// Base class definition for message handling
INT_PTR CBasePropertyPage::OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
// we would like the TAB key to move around the tab stops in our property
// page, but for some reason OleCreatePropertyFrame clears the CONTROLPARENT
// style behind our back, so we need to switch it back on now behind its
// back. Otherwise the tab key will be useless in every page.
//
CBasePropertyPage *pPropertyPage;
{
pPropertyPage = (CBasePropertyPage *) GetWindowLongPtr(hwnd, DWLP_USER);
if (pPropertyPage->m_hwnd == NULL) {
return 0;
}
switch (uMsg) {
case WM_STYLECHANGING:
if (wParam == GWL_EXSTYLE) {
LPSTYLESTRUCT lpss = (LPSTYLESTRUCT)lParam;
lpss->styleNew |= WS_EX_CONTROLPARENT;
return 0;
}
}
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

View File

@ -1,95 +0,0 @@
//------------------------------------------------------------------------------
// File: CProp.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __CPROP__
#define __CPROP__
// Base property page class. Filters typically expose custom properties by
// implementing special control interfaces, examples are IDirectDrawVideo
// and IQualProp on renderers. This allows property pages to be built that
// use the given interface. Applications such as the ActiveMovie OCX query
// filters for the property pages they support and expose them to the user
//
// This class provides all the framework for a property page. A property
// page is a COM object that supports IPropertyPage. We should be created
// with a resource ID for the dialog which we will load when required. We
// should also be given in the constructor a resource ID for a title string
// we will load from the DLLs STRINGTABLE. The property page titles must be
// stored in resource files so that they can be easily internationalised
//
// We have a number of virtual methods (not PURE) that may be overriden in
// derived classes to query for interfaces and so on. These functions have
// simple implementations here that just return NOERROR. Derived classes
// will almost definately have to override the message handler method called
// OnReceiveMessage. We have a static dialog procedure that calls the method
// so that derived classes don't have to fiddle around with the this pointer
class AM_NOVTABLE CBasePropertyPage : public IPropertyPage, public CUnknown
{
protected:
LPPROPERTYPAGESITE m_pPageSite; // Details for our property site
HWND m_hwnd; // Window handle for the page
HWND m_Dlg; // Actual dialog window handle
BOOL m_bDirty; // Has anything been changed
int m_TitleId; // Resource identifier for title
int m_DialogId; // Dialog resource identifier
static INT_PTR CALLBACK DialogProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
private:
BOOL m_bObjectSet ; // SetObject has been called or not.
public:
CBasePropertyPage(TCHAR *pName, // Debug only name
LPUNKNOWN pUnk, // COM Delegator
int DialogId, // Resource ID
int TitleId); // To get tital
#ifdef UNICODE
CBasePropertyPage(CHAR *pName,
LPUNKNOWN pUnk,
int DialogId,
int TitleId);
#endif
virtual ~CBasePropertyPage() { };
DECLARE_IUNKNOWN
// Override these virtual methods
virtual HRESULT OnConnect(IUnknown *pUnknown) { return NOERROR; };
virtual HRESULT OnDisconnect() { return NOERROR; };
virtual HRESULT OnActivate() { return NOERROR; };
virtual HRESULT OnDeactivate() { return NOERROR; };
virtual HRESULT OnApplyChanges() { return NOERROR; };
virtual INT_PTR OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
// These implement an IPropertyPage interface
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv);
STDMETHODIMP_(ULONG) NonDelegatingRelease();
STDMETHODIMP_(ULONG) NonDelegatingAddRef();
STDMETHODIMP SetPageSite(LPPROPERTYPAGESITE pPageSite);
STDMETHODIMP Activate(HWND hwndParent,LPCRECT prect,BOOL fModal);
STDMETHODIMP Deactivate(void);
STDMETHODIMP GetPageInfo(LPPROPPAGEINFO pPageInfo);
STDMETHODIMP SetObjects(ULONG cObjects, LPUNKNOWN *ppUnk);
STDMETHODIMP Show(UINT nCmdShow);
STDMETHODIMP Move(LPCRECT prect);
STDMETHODIMP IsPageDirty(void) { return m_bDirty ? S_OK : S_FALSE; }
STDMETHODIMP Apply(void);
STDMETHODIMP Help(LPCWSTR lpszHelpDir) { return E_NOTIMPL; }
STDMETHODIMP TranslateAccelerator(LPMSG lpMsg) { return E_NOTIMPL; }
};
#endif // __CPROP__

File diff suppressed because it is too large Load Diff

View File

@ -1,919 +0,0 @@
//------------------------------------------------------------------------------
// File: CtlUtil.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// Base classes implementing IDispatch parsing for the basic control dual
// interfaces. Derive from these and implement just the custom method and
// property methods. We also implement CPosPassThru that can be used by
// renderers and transforms to pass by IMediaPosition and IMediaSeeking
#ifndef __CTLUTIL__
#define __CTLUTIL__
// OLE Automation has different ideas of TRUE and FALSE
#define OATRUE (-1)
#define OAFALSE (0)
// It's possible that we could replace this class with CreateStdDispatch
class CBaseDispatch
{
ITypeInfo * m_pti;
public:
CBaseDispatch() : m_pti(NULL) {}
~CBaseDispatch();
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
REFIID riid,
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid);
};
class AM_NOVTABLE CMediaControl :
public IMediaControl,
public CUnknown
{
CBaseDispatch m_basedisp;
public:
CMediaControl(const TCHAR *, LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr);
};
class AM_NOVTABLE CMediaEvent :
public IMediaEventEx,
public CUnknown
{
CBaseDispatch m_basedisp;
public:
CMediaEvent(const TCHAR *, LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr);
};
class AM_NOVTABLE CMediaPosition :
public IMediaPosition,
public CUnknown
{
CBaseDispatch m_basedisp;
public:
CMediaPosition(const TCHAR *, LPUNKNOWN);
CMediaPosition(const TCHAR *, LPUNKNOWN, HRESULT *phr);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr);
};
// OA-compatibility means that we must use double as the RefTime value,
// and REFERENCE_TIME (essentially a LONGLONG) within filters.
// this class converts between the two
class COARefTime : public CRefTime {
public:
COARefTime() {
};
COARefTime(CRefTime t)
: CRefTime(t)
{
};
COARefTime(REFERENCE_TIME t)
: CRefTime(t)
{
};
COARefTime(double d) {
m_time = (LONGLONG) (d * 10000000);
};
operator double() {
return double(m_time) / 10000000;
};
operator REFERENCE_TIME() {
return m_time;
};
COARefTime& operator=(const double& rd) {
m_time = (LONGLONG) (rd * 10000000);
return *this;
}
COARefTime& operator=(const REFERENCE_TIME& rt) {
m_time = rt;
return *this;
}
inline BOOL operator==(const COARefTime& rt)
{
return m_time == rt.m_time;
};
inline BOOL operator!=(const COARefTime& rt)
{
return m_time != rt.m_time;
};
inline BOOL operator < (const COARefTime& rt)
{
return m_time < rt.m_time;
};
inline BOOL operator > (const COARefTime& rt)
{
return m_time > rt.m_time;
};
inline BOOL operator >= (const COARefTime& rt)
{
return m_time >= rt.m_time;
};
inline BOOL operator <= (const COARefTime& rt)
{
return m_time <= rt.m_time;
};
inline COARefTime operator+(const COARefTime& rt)
{
return COARefTime(m_time + rt.m_time);
};
inline COARefTime operator-(const COARefTime& rt)
{
return COARefTime(m_time - rt.m_time);
};
inline COARefTime operator*(LONG l)
{
return COARefTime(m_time * l);
};
inline COARefTime operator/(LONG l)
{
return COARefTime(m_time / l);
};
private:
// Prevent bugs from constructing from LONG (which gets
// converted to double and then multiplied by 10000000
COARefTime(LONG);
int operator=(LONG);
};
// A utility class that handles IMediaPosition and IMediaSeeking on behalf
// of single-input pin renderers, or transform filters.
//
// Renderers will expose this from the filter; transform filters will
// expose it from the output pin and not the renderer.
//
// Create one of these, giving it your IPin* for your input pin, and delegate
// all IMediaPosition methods to it. It will query the input pin for
// IMediaPosition and respond appropriately.
//
// Call ForceRefresh if the pin connection changes.
//
// This class no longer caches the upstream IMediaPosition or IMediaSeeking
// it acquires it on each method call. This means ForceRefresh is not needed.
// The method is kept for source compatibility and to minimise the changes
// if we need to put it back later for performance reasons.
class CPosPassThru : public IMediaSeeking, public CMediaPosition
{
IPin *m_pPin;
HRESULT GetPeer(IMediaPosition **ppMP);
HRESULT GetPeerSeeking(IMediaSeeking **ppMS);
public:
CPosPassThru(const TCHAR *, LPUNKNOWN, HRESULT*, IPin *);
DECLARE_IUNKNOWN
HRESULT ForceRefresh() {
return S_OK;
};
// override to return an accurate current position
virtual HRESULT GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime) {
return E_FAIL;
}
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv);
// IMediaSeeking methods
STDMETHODIMP GetCapabilities( DWORD * pCapabilities );
STDMETHODIMP CheckCapabilities( DWORD * pCapabilities );
STDMETHODIMP SetTimeFormat(const GUID * pFormat);
STDMETHODIMP GetTimeFormat(GUID *pFormat);
STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat);
STDMETHODIMP IsFormatSupported( const GUID * pFormat);
STDMETHODIMP QueryPreferredFormat( GUID *pFormat);
STDMETHODIMP ConvertTimeFormat(LONGLONG * pTarget, const GUID * pTargetFormat,
LONGLONG Source, const GUID * pSourceFormat );
STDMETHODIMP SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags
, LONGLONG * pStop, DWORD StopFlags );
STDMETHODIMP GetPositions( LONGLONG * pCurrent, LONGLONG * pStop );
STDMETHODIMP GetCurrentPosition( LONGLONG * pCurrent );
STDMETHODIMP GetStopPosition( LONGLONG * pStop );
STDMETHODIMP SetRate( double dRate);
STDMETHODIMP GetRate( double * pdRate);
STDMETHODIMP GetDuration( LONGLONG *pDuration);
STDMETHODIMP GetAvailable( LONGLONG *pEarliest, LONGLONG *pLatest );
STDMETHODIMP GetPreroll( LONGLONG *pllPreroll );
// IMediaPosition properties
STDMETHODIMP get_Duration(REFTIME * plength);
STDMETHODIMP put_CurrentPosition(REFTIME llTime);
STDMETHODIMP get_StopTime(REFTIME * pllTime);
STDMETHODIMP put_StopTime(REFTIME llTime);
STDMETHODIMP get_PrerollTime(REFTIME * pllTime);
STDMETHODIMP put_PrerollTime(REFTIME llTime);
STDMETHODIMP get_Rate(double * pdRate);
STDMETHODIMP put_Rate(double dRate);
STDMETHODIMP get_CurrentPosition(REFTIME * pllTime);
STDMETHODIMP CanSeekForward(LONG *pCanSeekForward);
STDMETHODIMP CanSeekBackward(LONG *pCanSeekBackward);
private:
HRESULT GetSeekingLongLong( HRESULT (__stdcall IMediaSeeking::*pMethod)( LONGLONG * ),
LONGLONG * pll );
};
// Adds the ability to return a current position
class CRendererPosPassThru : public CPosPassThru
{
CCritSec m_PositionLock; // Locks access to our position
LONGLONG m_StartMedia; // Start media time last seen
LONGLONG m_EndMedia; // And likewise the end media
BOOL m_bReset; // Have media times been set
public:
// Used to help with passing media times through graph
CRendererPosPassThru(const TCHAR *, LPUNKNOWN, HRESULT*, IPin *);
HRESULT RegisterMediaTime(IMediaSample *pMediaSample);
HRESULT RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime);
HRESULT GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime);
HRESULT ResetMediaTime();
HRESULT EOS();
};
STDAPI CreatePosPassThru(
LPUNKNOWN pAgg,
BOOL bRenderer,
IPin *pPin,
IUnknown **ppPassThru
);
// A class that handles the IDispatch part of IBasicAudio and leaves the
// properties and methods themselves pure virtual.
class AM_NOVTABLE CBasicAudio : public IBasicAudio, public CUnknown
{
CBaseDispatch m_basedisp;
public:
CBasicAudio(const TCHAR *, LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr);
};
// A class that handles the IDispatch part of IBasicVideo and leaves the
// properties and methods themselves pure virtual.
class AM_NOVTABLE CBaseBasicVideo : public IBasicVideo2, public CUnknown
{
CBaseDispatch m_basedisp;
public:
CBaseBasicVideo(const TCHAR *, LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr);
STDMETHODIMP GetPreferredAspectRatio(
long *plAspectX,
long *plAspectY)
{
return E_NOTIMPL;
}
};
// A class that handles the IDispatch part of IVideoWindow and leaves the
// properties and methods themselves pure virtual.
class AM_NOVTABLE CBaseVideoWindow : public IVideoWindow, public CUnknown
{
CBaseDispatch m_basedisp;
public:
CBaseVideoWindow(const TCHAR *, LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr);
};
// abstract class to help source filters with their implementation
// of IMediaPosition. Derive from this and set the duration (and stop
// position). Also override NotifyChange to do something when the properties
// change.
class AM_NOVTABLE CSourcePosition : public CMediaPosition
{
public:
CSourcePosition(const TCHAR *, LPUNKNOWN, HRESULT*, CCritSec *);
// IMediaPosition methods
STDMETHODIMP get_Duration(REFTIME * plength);
STDMETHODIMP put_CurrentPosition(REFTIME llTime);
STDMETHODIMP get_StopTime(REFTIME * pllTime);
STDMETHODIMP put_StopTime(REFTIME llTime);
STDMETHODIMP get_PrerollTime(REFTIME * pllTime);
STDMETHODIMP put_PrerollTime(REFTIME llTime);
STDMETHODIMP get_Rate(double * pdRate);
STDMETHODIMP put_Rate(double dRate);
STDMETHODIMP CanSeekForward(LONG *pCanSeekForward);
STDMETHODIMP CanSeekBackward(LONG *pCanSeekBackward);
// override if you can return the data you are actually working on
STDMETHODIMP get_CurrentPosition(REFTIME * pllTime) {
return E_NOTIMPL;
};
protected:
// we call this to notify changes. Override to handle them
virtual HRESULT ChangeStart() PURE;
virtual HRESULT ChangeStop() PURE;
virtual HRESULT ChangeRate() PURE;
COARefTime m_Duration;
COARefTime m_Start;
COARefTime m_Stop;
double m_Rate;
CCritSec * m_pLock;
};
class AM_NOVTABLE CSourceSeeking :
public IMediaSeeking,
public CUnknown
{
public:
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
// IMediaSeeking methods
STDMETHODIMP IsFormatSupported(const GUID * pFormat);
STDMETHODIMP QueryPreferredFormat(GUID *pFormat);
STDMETHODIMP SetTimeFormat(const GUID * pFormat);
STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat);
STDMETHODIMP GetTimeFormat(GUID *pFormat);
STDMETHODIMP GetDuration(LONGLONG *pDuration);
STDMETHODIMP GetStopPosition(LONGLONG *pStop);
STDMETHODIMP GetCurrentPosition(LONGLONG *pCurrent);
STDMETHODIMP GetCapabilities( DWORD * pCapabilities );
STDMETHODIMP CheckCapabilities( DWORD * pCapabilities );
STDMETHODIMP ConvertTimeFormat( LONGLONG * pTarget, const GUID * pTargetFormat,
LONGLONG Source, const GUID * pSourceFormat );
STDMETHODIMP SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags
, LONGLONG * pStop, DWORD StopFlags );
STDMETHODIMP GetPositions( LONGLONG * pCurrent, LONGLONG * pStop );
STDMETHODIMP GetAvailable( LONGLONG * pEarliest, LONGLONG * pLatest );
STDMETHODIMP SetRate( double dRate);
STDMETHODIMP GetRate( double * pdRate);
STDMETHODIMP GetPreroll(LONGLONG *pPreroll);
protected:
// ctor
CSourceSeeking(const TCHAR *, LPUNKNOWN, HRESULT*, CCritSec *);
// we call this to notify changes. Override to handle them
virtual HRESULT ChangeStart() PURE;
virtual HRESULT ChangeStop() PURE;
virtual HRESULT ChangeRate() PURE;
CRefTime m_rtDuration; // length of stream
CRefTime m_rtStart; // source will start here
CRefTime m_rtStop; // source will stop here
double m_dRateSeeking;
// seeking capabilities
DWORD m_dwSeekingCaps;
CCritSec * m_pLock;
};
// Base classes supporting Deferred commands.
// Deferred commands are queued by calls to methods on the IQueueCommand
// interface, exposed by the filtergraph and by some filters. A successful
// call to one of these methods will return an IDeferredCommand interface
// representing the queued command.
//
// A CDeferredCommand object represents a single deferred command, and exposes
// the IDeferredCommand interface as well as other methods permitting time
// checks and actual execution. It contains a reference to the CCommandQueue
// object on which it is queued.
//
// CCommandQueue is a base class providing a queue of CDeferredCommand
// objects, and methods to add, remove, check status and invoke the queued
// commands. A CCommandQueue object would be part of an object that
// implemented IQueueCommand.
class CCmdQueue;
// take a copy of the params and store them. Release any allocated
// memory in destructor
class CDispParams : public DISPPARAMS
{
public:
CDispParams(UINT nArgs, VARIANT* pArgs, HRESULT *phr = NULL);
~CDispParams();
};
// CDeferredCommand lifetime is controlled by refcounts. Caller of
// InvokeAt.. gets a refcounted interface pointer, and the CCmdQueue
// object also holds a refcount on us. Calling Cancel or Invoke takes
// us off the CCmdQueue and thus reduces the refcount by 1. Once taken
// off the queue we cannot be put back on the queue.
class CDeferredCommand
: public CUnknown,
public IDeferredCommand
{
public:
CDeferredCommand(
CCmdQueue * pQ,
LPUNKNOWN pUnk, // aggregation outer unk
HRESULT * phr,
LPUNKNOWN pUnkExecutor, // object that will execute this cmd
REFTIME time,
GUID* iid,
long dispidMethod,
short wFlags,
long cArgs,
VARIANT* pDispParams,
VARIANT* pvarResult,
short* puArgErr,
BOOL bStream
);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
// IDeferredCommand methods
STDMETHODIMP Cancel();
STDMETHODIMP Confidence(
LONG* pConfidence);
STDMETHODIMP Postpone(
REFTIME newtime);
STDMETHODIMP GetHResult(
HRESULT* phrResult);
// other public methods
HRESULT Invoke();
// access methods
// returns TRUE if streamtime, FALSE if presentation time
BOOL IsStreamTime() {
return m_bStream;
};
CRefTime GetTime() {
return m_time;
};
REFIID GetIID() {
return *m_iid;
};
long GetMethod() {
return m_dispidMethod;
};
short GetFlags() {
return m_wFlags;
};
DISPPARAMS* GetParams() {
return &m_DispParams;
};
VARIANT* GetResult() {
return m_pvarResult;
};
protected:
CCmdQueue* m_pQueue;
// pUnk for the interface that we will execute the command on
LPUNKNOWN m_pUnk;
// stored command data
REFERENCE_TIME m_time;
GUID* m_iid;
long m_dispidMethod;
short m_wFlags;
VARIANT* m_pvarResult;
BOOL m_bStream;
CDispParams m_DispParams;
DISPID m_DispId; // For get and put
// we use this for ITypeInfo access
CBaseDispatch m_Dispatch;
// save retval here
HRESULT m_hrResult;
};
// a list of CDeferredCommand objects. this is a base class providing
// the basics of access to the list. If you want to use CDeferredCommand
// objects then your queue needs to be derived from this class.
class AM_NOVTABLE CCmdQueue
{
public:
CCmdQueue();
virtual ~CCmdQueue();
// returns a new CDeferredCommand object that will be initialised with
// the parameters and will be added to the queue during construction.
// returns S_OK if successfully created otherwise an error and
// no object has been queued.
virtual HRESULT New(
CDeferredCommand **ppCmd,
LPUNKNOWN pUnk,
REFTIME time,
GUID* iid,
long dispidMethod,
short wFlags,
long cArgs,
VARIANT* pDispParams,
VARIANT* pvarResult,
short* puArgErr,
BOOL bStream
);
// called by the CDeferredCommand object to add and remove itself
// from the queue
virtual HRESULT Insert(CDeferredCommand* pCmd);
virtual HRESULT Remove(CDeferredCommand* pCmd);
// Command-Due Checking
//
// There are two schemes of synchronisation: coarse and accurate. In
// coarse mode, you wait till the time arrives and then execute the cmd.
// In accurate mode, you wait until you are processing the sample that
// will appear at the time, and then execute the command. It's up to the
// filter which one it will implement. The filtergraph will always
// implement coarse mode for commands queued at the filtergraph.
//
// If you want coarse sync, you probably want to wait until there is a
// command due, and then execute it. You can do this by calling
// GetDueCommand. If you have several things to wait for, get the
// event handle from GetDueHandle() and when this is signalled then call
// GetDueCommand. Stream time will only advance between calls to Run and
// EndRun. Note that to avoid an extra thread there is no guarantee that
// if the handle is set there will be a command ready. Each time the
// event is signalled, call GetDueCommand (probably with a 0 timeout);
// This may return E_ABORT.
//
// If you want accurate sync, you must call GetCommandDueFor, passing
// as a parameter the stream time of the samples you are about to process.
// This will return:
// -- a stream-time command due at or before that stream time
// -- a presentation-time command due at or before the
// time that stream time will be presented (only between Run
// and EndRun calls, since outside of this, the mapping from
// stream time to presentation time is not known.
// -- any presentation-time command due now.
// This means that if you want accurate synchronisation on samples that
// might be processed during Paused mode, you need to use
// stream-time commands.
//
// In all cases, commands remain queued until Invoked or Cancelled. The
// setting and resetting of the event handle is managed entirely by this
// queue object.
// set the clock used for timing
virtual HRESULT SetSyncSource(IReferenceClock*);
// switch to run mode. Streamtime to Presentation time mapping known.
virtual HRESULT Run(REFERENCE_TIME tStreamTimeOffset);
// switch to Stopped or Paused mode. Time mapping not known.
virtual HRESULT EndRun();
// return a pointer to the next due command. Blocks for msTimeout
// milliseconds until there is a due command.
// Stream-time commands will only become due between Run and Endrun calls.
// The command remains queued until invoked or cancelled.
// Returns E_ABORT if timeout occurs, otherwise S_OK (or other error).
// Returns an AddRef-ed object
virtual HRESULT GetDueCommand(CDeferredCommand ** ppCmd, long msTimeout);
// return the event handle that will be signalled whenever
// there are deferred commands due for execution (when GetDueCommand
// will not block).
HANDLE GetDueHandle() {
return HANDLE(m_evDue);
};
// return a pointer to a command that will be due for a given time.
// Pass in a stream time here. The stream time offset will be passed
// in via the Run method.
// Commands remain queued until invoked or cancelled.
// This method will not block. It will report VFW_E_NOT_FOUND if there
// are no commands due yet.
// Returns an AddRef-ed object
virtual HRESULT GetCommandDueFor(REFERENCE_TIME tStream, CDeferredCommand**ppCmd);
// check if a given time is due (TRUE if it is due yet)
BOOL CheckTime(CRefTime time, BOOL bStream) {
// if no clock, nothing is due!
if (!m_pClock) {
return FALSE;
}
// stream time
if (bStream) {
// not valid if not running
if (!m_bRunning) {
return FALSE;
}
// add on known stream time offset to get presentation time
time += m_StreamTimeOffset;
}
CRefTime Now;
m_pClock->GetTime((REFERENCE_TIME*)&Now);
return (time <= Now);
};
protected:
// protect access to lists etc
CCritSec m_Lock;
// commands queued in presentation time are stored here
CGenericList<CDeferredCommand> m_listPresentation;
// commands queued in stream time are stored here
CGenericList<CDeferredCommand> m_listStream;
// set when any commands are due
CAMEvent m_evDue;
// creates an advise for the earliest time required, if any
void SetTimeAdvise(void);
// advise id from reference clock (0 if no outstanding advise)
DWORD_PTR m_dwAdvise;
// advise time is for this presentation time
CRefTime m_tCurrentAdvise;
// the reference clock we are using (addrefed)
IReferenceClock* m_pClock;
// true when running
BOOL m_bRunning;
// contains stream time offset when m_bRunning is true
CRefTime m_StreamTimeOffset;
};
#endif // __CTLUTIL__

View File

@ -1,129 +0,0 @@
//------------------------------------------------------------------------------
// File: DDMM.cpp
//
// Desc: DirectShow base classes - implements routines for using DirectDraw
// on a multimonitor system.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <ddraw.h>
#include "ddmm.h"
/*
* FindDeviceCallback
*/
typedef struct {
LPSTR szDevice;
GUID* lpGUID;
GUID GUID;
BOOL fFound;
} FindDeviceData;
BOOL CALLBACK FindDeviceCallback(GUID* lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam)
{
FindDeviceData *p = (FindDeviceData*)lParam;
if (lstrcmpiA(p->szDevice, szDevice) == 0) {
if (lpGUID) {
p->GUID = *lpGUID;
p->lpGUID = &p->GUID;
} else {
p->lpGUID = NULL;
}
p->fFound = TRUE;
return FALSE;
}
return TRUE;
}
BOOL CALLBACK FindDeviceCallbackEx(GUID* lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam, HMONITOR hMonitor)
{
FindDeviceData *p = (FindDeviceData*)lParam;
if (lstrcmpiA(p->szDevice, szDevice) == 0) {
if (lpGUID) {
p->GUID = *lpGUID;
p->lpGUID = &p->GUID;
} else {
p->lpGUID = NULL;
}
p->fFound = TRUE;
return FALSE;
}
return TRUE;
}
/*
* DirectDrawCreateFromDevice
*
* create a DirectDraw object for a particular device
*/
IDirectDraw * DirectDrawCreateFromDevice(LPSTR szDevice, PDRAWCREATE DirectDrawCreateP, PDRAWENUM DirectDrawEnumerateP)
{
IDirectDraw* pdd = NULL;
FindDeviceData find;
if (szDevice == NULL) {
DirectDrawCreateP(NULL, &pdd, NULL);
return pdd;
}
find.szDevice = szDevice;
find.fFound = FALSE;
DirectDrawEnumerateP(FindDeviceCallback, (LPVOID)&find);
if (find.fFound)
{
//
// In 4bpp mode the following DDraw call causes a message box to be popped
// up by DDraw (!?!). It's DDraw's fault, but we don't like it. So we
// make sure it doesn't happen.
//
UINT ErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
DirectDrawCreateP(find.lpGUID, &pdd, NULL);
SetErrorMode(ErrorMode);
}
return pdd;
}
/*
* DirectDrawCreateFromDeviceEx
*
* create a DirectDraw object for a particular device
*/
IDirectDraw * DirectDrawCreateFromDeviceEx(LPSTR szDevice, PDRAWCREATE DirectDrawCreateP, LPDIRECTDRAWENUMERATEEXA DirectDrawEnumerateExP)
{
IDirectDraw* pdd = NULL;
FindDeviceData find;
if (szDevice == NULL) {
DirectDrawCreateP(NULL, &pdd, NULL);
return pdd;
}
find.szDevice = szDevice;
find.fFound = FALSE;
DirectDrawEnumerateExP(FindDeviceCallbackEx, (LPVOID)&find,
DDENUM_ATTACHEDSECONDARYDEVICES);
if (find.fFound)
{
//
// In 4bpp mode the following DDraw call causes a message box to be popped
// up by DDraw (!?!). It's DDraw's fault, but we don't like it. So we
// make sure it doesn't happen.
//
UINT ErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
DirectDrawCreateP(find.lpGUID, &pdd, NULL);
SetErrorMode(ErrorMode);
}
return pdd;
}

View File

@ -1,28 +0,0 @@
//------------------------------------------------------------------------------
// File: DDMM.h
//
// Desc: DirectShow base classes - efines routines for using DirectDraw
// on a multimonitor system.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
// DDRAW.H might not include these
#ifndef DDENUM_ATTACHEDSECONDARYDEVICES
#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001L
#endif
typedef HRESULT (*PDRAWCREATE)(IID *,LPDIRECTDRAW *,LPUNKNOWN);
typedef HRESULT (*PDRAWENUM)(LPDDENUMCALLBACKA, LPVOID);
IDirectDraw * DirectDrawCreateFromDevice(LPSTR, PDRAWCREATE, PDRAWENUM);
IDirectDraw * DirectDrawCreateFromDeviceEx(LPSTR, PDRAWCREATE, LPDIRECTDRAWENUMERATEEXA);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -1,333 +0,0 @@
//------------------------------------------------------------------------------
// File: DllEntry.cpp
//
// Desc: DirectShow base classes - implements classes used to support dll
// entry points for COM objects.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <initguid.h>
#ifdef DEBUG
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif // _UNICODE
#endif // UNICODE
#endif // DEBUG
extern CFactoryTemplate g_Templates[];
extern int g_cTemplates;
HINSTANCE g_hInst;
DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx)
OSVERSIONINFO g_osInfo;
//
// an instance of this is created by the DLLGetClassObject entrypoint
// it uses the CFactoryTemplate object it is given to support the
// IClassFactory interface
class CClassFactory : public IClassFactory, public CBaseObject
{
private:
const CFactoryTemplate *const m_pTemplate;
ULONG m_cRef;
static int m_cLocked;
public:
CClassFactory(const CFactoryTemplate *);
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
STDMETHODIMP_(ULONG)AddRef();
STDMETHODIMP_(ULONG)Release();
// IClassFactory
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **pv);
STDMETHODIMP LockServer(BOOL fLock);
// allow DLLGetClassObject to know about global server lock status
static BOOL IsLocked() {
return (m_cLocked > 0);
};
};
// process-wide dll locked state
int CClassFactory::m_cLocked = 0;
CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate)
: CBaseObject(NAME("Class Factory"))
, m_cRef(0)
, m_pTemplate(pTemplate)
{
}
STDMETHODIMP
CClassFactory::QueryInterface(REFIID riid,void **ppv)
{
CheckPointer(ppv,E_POINTER)
ValidateReadWritePtr(ppv,sizeof(PVOID));
*ppv = NULL;
// any interface on this object is the object pointer.
if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) {
*ppv = (LPVOID) this;
// AddRef returned interface pointer
((LPUNKNOWN) *ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG)
CClassFactory::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG)
CClassFactory::Release()
{
if (--m_cRef == 0) {
delete this;
return 0;
} else {
return m_cRef;
}
}
STDMETHODIMP
CClassFactory::CreateInstance(
LPUNKNOWN pUnkOuter,
REFIID riid,
void **pv)
{
CheckPointer(pv,E_POINTER)
ValidateReadWritePtr(pv,sizeof(void *));
/* Enforce the normal OLE rules regarding interfaces and delegation */
if (pUnkOuter != NULL) {
if (IsEqualIID(riid,IID_IUnknown) == FALSE) {
return ResultFromScode(E_NOINTERFACE);
}
}
/* Create the new object through the derived class's create function */
HRESULT hr = NOERROR;
CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr);
if (pObj == NULL) {
if (SUCCEEDED(hr)) {
hr = E_OUTOFMEMORY;
}
return hr;
}
/* Delete the object if we got a construction error */
if (FAILED(hr)) {
delete pObj;
return hr;
}
/* Get a reference counted interface on the object */
/* We wrap the non-delegating QI with NDAddRef & NDRelease. */
/* This protects any outer object from being prematurely */
/* released by an inner object that may have to be created */
/* in order to supply the requested interface. */
pObj->NonDelegatingAddRef();
hr = pObj->NonDelegatingQueryInterface(riid, pv);
pObj->NonDelegatingRelease();
/* Note that if NonDelegatingQueryInterface fails, it will */
/* not increment the ref count, so the NonDelegatingRelease */
/* will drop the ref back to zero and the object will "self-*/
/* destruct". Hence we don't need additional tidy-up code */
/* to cope with NonDelegatingQueryInterface failing. */
if (SUCCEEDED(hr)) {
ASSERT(*pv);
}
return hr;
}
STDMETHODIMP
CClassFactory::LockServer(BOOL fLock)
{
if (fLock) {
m_cLocked++;
} else {
m_cLocked--;
}
return NOERROR;
}
// --- COM entrypoints -----------------------------------------
//called by COM to get the class factory object for a given class
STDAPI
DllGetClassObject(
REFCLSID rClsID,
REFIID riid,
void **pv)
{
if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) {
return E_NOINTERFACE;
}
// traverse the array of templates looking for one with this
// class id
for (int i = 0; i < g_cTemplates; i++) {
const CFactoryTemplate * pT = &g_Templates[i];
if (pT->IsClassID(rClsID)) {
// found a template - make a class factory based on this
// template
*pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT);
if (*pv == NULL) {
return E_OUTOFMEMORY;
}
((LPUNKNOWN)*pv)->AddRef();
return NOERROR;
}
}
return CLASS_E_CLASSNOTAVAILABLE;
}
//
// Call any initialization routines
//
void
DllInitClasses(BOOL bLoading)
{
int i;
// traverse the array of templates calling the init routine
// if they have one
for (i = 0; i < g_cTemplates; i++) {
const CFactoryTemplate * pT = &g_Templates[i];
if (pT->m_lpfnInit != NULL) {
(*pT->m_lpfnInit)(bLoading, pT->m_ClsID);
}
}
}
// called by COM to determine if this dll can be unloaded
// return ok unless there are outstanding objects or a lock requested
// by IClassFactory::LockServer
//
// CClassFactory has a static function that can tell us about the locks,
// and CCOMObject has a static function that can tell us about the active
// object count
STDAPI
DllCanUnloadNow()
{
DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"),
CClassFactory::IsLocked(),
CBaseObject::ObjectsActive()));
if (CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) {
return S_FALSE;
} else {
return S_OK;
}
}
// --- standard WIN32 entrypoints --------------------------------------
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL WINAPI
DllEntryPoint(HINSTANCE hInstance, ULONG ulReason, LPVOID pv)
{
#ifdef DEBUG
extern bool g_fDbgInDllEntryPoint;
g_fDbgInDllEntryPoint = true;
#endif
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInstance);
DbgInitialise(hInstance);
{
// The platform identifier is used to work out whether
// full unicode support is available or not. Hence the
// default will be the lowest common denominator - i.e. N/A
g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails
g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo);
if (GetVersionEx(&g_osInfo)) {
g_amPlatform = g_osInfo.dwPlatformId;
} else {
DbgLog((LOG_ERROR, 1, TEXT("Failed to get the OS platform, assuming Win95")));
}
}
g_hInst = hInstance;
DllInitClasses(TRUE);
break;
case DLL_PROCESS_DETACH:
DllInitClasses(FALSE);
#ifdef DEBUG
if (CBaseObject::ObjectsActive()) {
DbgSetModuleLevel(LOG_MEMORY, 2);
TCHAR szInfo[512];
extern TCHAR m_ModuleName[]; // Cut down module name
TCHAR FullName[_MAX_PATH]; // Load the full path and module name
TCHAR *pName; // Searches from the end for a backslash
GetModuleFileName(NULL,FullName,_MAX_PATH);
pName = _tcsrchr(FullName,'\\');
if (pName == NULL) {
pName = FullName;
} else {
pName++;
}
(void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("Executable: %s Pid %x Tid %x. "),
pName, GetCurrentProcessId(), GetCurrentThreadId());
DWORD cch = lstrlen(szInfo);
(void)StringCchPrintf(szInfo+cch, NUMELMS(szInfo) - cch, TEXT("Module %s, %d objects left active!"),
m_ModuleName, CBaseObject::ObjectsActive());
DbgAssert(szInfo, TEXT(__FILE__),__LINE__);
// If running remotely wait for the Assert to be acknowledged
// before dumping out the object register
DbgDumpObjectRegister();
}
DbgTerminate();
#endif
break;
}
#ifdef DEBUG
g_fDbgInDllEntryPoint = false;
#endif
return TRUE;
}

View File

@ -1,727 +0,0 @@
//------------------------------------------------------------------------------
// File: DllSetup.cpp
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
//---------------------------------------------------------------------------
// defines and constants
#define MAX_KEY_LEN 260
#ifdef UNICODE
static LPCTSTR CLSID_KEY_FORMAT_STRING = TEXT("CLSID\\%s");
#else
static LPCTSTR CLSID_KEY_FORMAT_STRING = TEXT("CLSID\\%S");
#endif
//---------------------------------------------------------------------------
// externally defined functions/variable
extern int g_cTemplates;
extern CFactoryTemplate g_Templates[];
//---------------------------------------------------------------------------
// internally defined functions
static HRESULT
ConvertUnicodeStringToTCHARString( LPTSTR szDest, size_t cchDest, LPCWSTR szSource );
//---------------------------------------------------------------------------
//
// EliminateSubKey
//
// Try to enumerate all keys under this one.
// if we find anything, delete it completely.
// Otherwise just delete it.
//
// note - this was pinched/duplicated from
// Filgraph\Mapper.cpp - so should it be in
// a lib somewhere?
//
//---------------------------------------------------------------------------
STDAPI
EliminateSubKey( HKEY hkey, LPTSTR strSubKey )
{
HKEY hk;
if (0 == lstrlen(strSubKey) ) {
// defensive approach
return E_FAIL;
}
LONG lreturn = RegOpenKeyEx( hkey
, strSubKey
, 0
, MAXIMUM_ALLOWED
, &hk );
ASSERT( lreturn == ERROR_SUCCESS
|| lreturn == ERROR_FILE_NOT_FOUND
|| lreturn == ERROR_INVALID_HANDLE );
if( ERROR_SUCCESS == lreturn )
{
// Keep on enumerating the first (zero-th)
// key and deleting that
for( ; ; )
{
TCHAR Buffer[MAX_KEY_LEN];
DWORD dw = MAX_KEY_LEN;
FILETIME ft;
lreturn = RegEnumKeyEx( hk
, 0
, Buffer
, &dw
, NULL
, NULL
, NULL
, &ft);
ASSERT( lreturn == ERROR_SUCCESS
|| lreturn == ERROR_NO_MORE_ITEMS );
if( ERROR_SUCCESS == lreturn )
{
EliminateSubKey(hk, Buffer);
}
else
{
break;
}
}
RegCloseKey(hk);
RegDeleteKey(hkey, strSubKey);
}
return NOERROR;
}
//---------------------------------------------------------------------------
//
// AMovieSetupRegisterServer()
//
// registers specfied file "szFileName" as server for
// CLSID "clsServer". A description is also required.
// The ThreadingModel and ServerType are optional, as
// they default to InprocServer32 (i.e. dll) and Both.
//
//---------------------------------------------------------------------------
STDAPI
AMovieSetupRegisterServer( CLSID clsServer
, LPCWSTR szDescription
, LPCWSTR szFileName
, LPCWSTR szThreadingModel = L"Both"
, LPCWSTR szServerType = L"InprocServer32" )
{
// temp buffer
//
TCHAR achTemp[MAX_PATH];
// convert CLSID uuid to string and write
// out subkey as string - CLSID\{}
//
OLECHAR szCLSID[CHARS_IN_GUID];
HRESULT hr = StringFromGUID2( clsServer
, szCLSID
, CHARS_IN_GUID );
ASSERT( SUCCEEDED(hr) );
// create key
//
HKEY hkey;
(void)StringCchPrintf( achTemp, NUMELMS(achTemp), CLSID_KEY_FORMAT_STRING, szCLSID );
LONG lreturn = RegCreateKey( HKEY_CLASSES_ROOT
, (LPCTSTR)achTemp
, &hkey );
if( ERROR_SUCCESS != lreturn )
{
return AmHresultFromWin32(lreturn);
}
// set description string
//
(void)ConvertUnicodeStringToTCHARString( achTemp, NUMELMS(achTemp), szDescription );
lreturn = RegSetValue( hkey
, (LPCTSTR)NULL
, REG_SZ
, achTemp
, sizeof(achTemp) );
if( ERROR_SUCCESS != lreturn )
{
RegCloseKey( hkey );
return AmHresultFromWin32(lreturn);
}
// create CLSID\\{"CLSID"}\\"ServerType" key,
// using key to CLSID\\{"CLSID"} passed back by
// last call to RegCreateKey().
//
HKEY hsubkey;
(void)ConvertUnicodeStringToTCHARString( achTemp, NUMELMS(achTemp), szServerType );
lreturn = RegCreateKey( hkey
, achTemp
, &hsubkey );
if( ERROR_SUCCESS != lreturn )
{
RegCloseKey( hkey );
return AmHresultFromWin32(lreturn);
}
// set Server string
//
(void)ConvertUnicodeStringToTCHARString( achTemp, NUMELMS(achTemp), szFileName );
lreturn = RegSetValue( hsubkey
, (LPCTSTR)NULL
, REG_SZ
, (LPCTSTR)achTemp
, sizeof(TCHAR) * (lstrlen(achTemp)+1) );
if( ERROR_SUCCESS != lreturn )
{
RegCloseKey( hkey );
RegCloseKey( hsubkey );
return AmHresultFromWin32(lreturn);
}
(void)ConvertUnicodeStringToTCHARString( achTemp, NUMELMS(achTemp), szThreadingModel );
lreturn = RegSetValueEx( hsubkey
, TEXT("ThreadingModel")
, 0L
, REG_SZ
, (CONST BYTE *)achTemp
, sizeof(TCHAR) * (lstrlen(achTemp)+1) );
// close hkeys
//
RegCloseKey( hkey );
RegCloseKey( hsubkey );
// and return
//
return HRESULT_FROM_WIN32(lreturn);
}
//---------------------------------------------------------------------------
//
// AMovieSetupUnregisterServer()
//
// default ActiveMovie dll setup function
// - to use must be called from an exported
// function named DllRegisterServer()
//
//---------------------------------------------------------------------------
STDAPI
AMovieSetupUnregisterServer( CLSID clsServer )
{
// convert CLSID uuid to string and write
// out subkey CLSID\{}
//
OLECHAR szCLSID[CHARS_IN_GUID];
HRESULT hr = StringFromGUID2( clsServer
, szCLSID
, CHARS_IN_GUID );
ASSERT( SUCCEEDED(hr) );
TCHAR achBuffer[MAX_KEY_LEN];
(void)StringCchPrintf( achBuffer, NUMELMS(achBuffer), CLSID_KEY_FORMAT_STRING, szCLSID );
// delete subkey
//
hr = EliminateSubKey( HKEY_CLASSES_ROOT, achBuffer );
ASSERT( SUCCEEDED(hr) );
// return
//
return NOERROR;
}
//---------------------------------------------------------------------------
//
// AMovieSetupRegisterFilter through IFilterMapper2
//
//---------------------------------------------------------------------------
STDAPI
AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata
, IFilterMapper2 * pIFM2
, BOOL bRegister )
{
DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter")));
// check we've got data
//
if( NULL == psetupdata ) return S_FALSE;
// unregister filter
// (as pins are subkeys of filter's CLSID key
// they do not need to be removed separately).
//
DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter")));
HRESULT hr = pIFM2->UnregisterFilter(
0, // default category
0, // default instance name
*psetupdata->clsID );
if( bRegister )
{
REGFILTER2 rf2;
rf2.dwVersion = 1;
rf2.dwMerit = psetupdata->dwMerit;
rf2.cPins = psetupdata->nPins;
rf2.rgPins = psetupdata->lpPin;
// register filter
//
DbgLog((LOG_TRACE, 3, TEXT("= = register filter")));
hr = pIFM2->RegisterFilter(*psetupdata->clsID
, psetupdata->strName
, 0 // moniker
, 0 // category
, NULL // instance
, &rf2);
}
// handle one acceptable "error" - that
// of filter not being registered!
// (couldn't find a suitable #define'd
// name for the error!)
//
if( 0x80070002 == hr)
return NOERROR;
else
return hr;
}
//---------------------------------------------------------------------------
//
// RegisterAllServers()
//
//---------------------------------------------------------------------------
STDAPI
RegisterAllServers( LPCWSTR szFileName, BOOL bRegister )
{
HRESULT hr = NOERROR;
for( int i = 0; i < g_cTemplates; i++ )
{
// get i'th template
//
const CFactoryTemplate *pT = &g_Templates[i];
DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"),
(LPCWSTR)pT->m_Name ));
// register CLSID and InprocServer32
//
if( bRegister )
{
hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
, (LPCWSTR)pT->m_Name
, szFileName );
}
else
{
hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
}
// check final error for this pass
// and break loop if we failed
//
if( FAILED(hr) )
break;
}
return hr;
}
//---------------------------------------------------------------------------
//
// AMovieDllRegisterServer2()
//
// default ActiveMovie dll setup function
// - to use must be called from an exported
// function named DllRegisterServer()
//
// this function is table driven using the
// static members of the CFactoryTemplate
// class defined in the dll.
//
// it registers the Dll as the InprocServer32
// and then calls the IAMovieSetup.Register
// method.
//
//---------------------------------------------------------------------------
STDAPI
AMovieDllRegisterServer2( BOOL bRegister )
{
HRESULT hr = NOERROR;
DbgLog((LOG_TRACE, 2, TEXT("AMovieDllRegisterServer2()")));
// get file name (where g_hInst is the
// instance handle of the filter dll)
//
WCHAR achFileName[MAX_PATH];
// WIN95 doesn't support GetModuleFileNameW
//
{
char achTemp[MAX_PATH];
DbgLog((LOG_TRACE, 2, TEXT("- get module file name")));
// g_hInst handle is set in our dll entry point. Make sure
// DllEntryPoint in dllentry.cpp is called
ASSERT(g_hInst != 0);
if( 0 == GetModuleFileNameA( g_hInst
, achTemp
, sizeof(achTemp) ) )
{
// we've failed!
DWORD dwerr = GetLastError();
return AmHresultFromWin32(dwerr);
}
MultiByteToWideChar( CP_ACP
, 0L
, achTemp
, lstrlenA(achTemp) + 1
, achFileName
, NUMELMS(achFileName) );
}
//
// first registering, register all OLE servers
//
if( bRegister )
{
DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
hr = RegisterAllServers( achFileName, TRUE );
}
//
// next, register/unregister all filters
//
if( SUCCEEDED(hr) )
{
// init is ref counted so call just in case
// we're being called cold.
//
DbgLog((LOG_TRACE, 2, TEXT("- CoInitialize")));
hr = CoInitialize( (LPVOID)NULL );
ASSERT( SUCCEEDED(hr) );
// get hold of IFilterMapper2
//
DbgLog((LOG_TRACE, 2, TEXT("- obtain IFilterMapper2")));
IFilterMapper2 *pIFM2 = 0;
IFilterMapper *pIFM = 0;
hr = CoCreateInstance( CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, IID_IFilterMapper2
, (void **)&pIFM2 );
if(FAILED(hr))
{
DbgLog((LOG_TRACE, 2, TEXT("- trying IFilterMapper instead")));
hr = CoCreateInstance(
CLSID_FilterMapper,
NULL,
CLSCTX_INPROC_SERVER,
IID_IFilterMapper,
(void **)&pIFM);
}
if( SUCCEEDED(hr) )
{
// scan through array of CFactoryTemplates
// registering servers and filters.
//
DbgLog((LOG_TRACE, 2, TEXT("- register Filters")));
for( int i = 0; i < g_cTemplates; i++ )
{
// get i'th template
//
const CFactoryTemplate *pT = &g_Templates[i];
if( NULL != pT->m_pAMovieSetup_Filter )
{
DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), (LPCWSTR)pT->m_Name ));
if(pIFM2)
{
hr = AMovieSetupRegisterFilter2( pT->m_pAMovieSetup_Filter, pIFM2, bRegister );
}
else
{
hr = AMovieSetupRegisterFilter( pT->m_pAMovieSetup_Filter, pIFM, bRegister );
}
}
// check final error for this pass
// and break loop if we failed
//
if( FAILED(hr) )
break;
}
// release interface
//
if(pIFM2)
pIFM2->Release();
else
pIFM->Release();
}
// and clear up
//
CoFreeUnusedLibraries();
CoUninitialize();
}
//
// if unregistering, unregister all OLE servers
//
if( SUCCEEDED(hr) && !bRegister )
{
DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
hr = RegisterAllServers( achFileName, FALSE );
}
DbgLog((LOG_TRACE, 2, TEXT("- return %0x"), hr));
return hr;
}
//---------------------------------------------------------------------------
//
// AMovieDllRegisterServer()
//
// default ActiveMovie dll setup function
// - to use must be called from an exported
// function named DllRegisterServer()
//
// this function is table driven using the
// static members of the CFactoryTemplate
// class defined in the dll.
//
// it registers the Dll as the InprocServer32
// and then calls the IAMovieSetup.Register
// method.
//
//---------------------------------------------------------------------------
STDAPI
AMovieDllRegisterServer( void )
{
HRESULT hr = NOERROR;
// get file name (where g_hInst is the
// instance handle of the filter dll)
//
WCHAR achFileName[MAX_PATH];
{
// WIN95 doesn't support GetModuleFileNameW
//
char achTemp[MAX_PATH];
if( 0 == GetModuleFileNameA( g_hInst
, achTemp
, sizeof(achTemp) ) )
{
// we've failed!
DWORD dwerr = GetLastError();
return AmHresultFromWin32(dwerr);
}
MultiByteToWideChar( CP_ACP
, 0L
, achTemp
, lstrlenA(achTemp) + 1
, achFileName
, NUMELMS(achFileName) );
}
// scan through array of CFactoryTemplates
// registering servers and filters.
//
for( int i = 0; i < g_cTemplates; i++ )
{
// get i'th template
//
const CFactoryTemplate *pT = &g_Templates[i];
// register CLSID and InprocServer32
//
hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
, (LPCWSTR)pT->m_Name
, achFileName );
// instantiate all servers and get hold of
// IAMovieSetup, if implemented, and call
// IAMovieSetup.Register() method
//
if( SUCCEEDED(hr) && (NULL != pT->m_lpfnNew) )
{
// instantiate object
//
PAMOVIESETUP psetup;
hr = CoCreateInstance( *(pT->m_ClsID)
, 0
, CLSCTX_INPROC_SERVER
, IID_IAMovieSetup
, reinterpret_cast<void**>(&psetup) );
if( SUCCEEDED(hr) )
{
hr = psetup->Unregister();
if( SUCCEEDED(hr) )
hr = psetup->Register();
psetup->Release();
}
else
{
if( (E_NOINTERFACE == hr )
|| (VFW_E_NEED_OWNER == hr ) )
hr = NOERROR;
}
}
// check final error for this pass
// and break loop if we failed
//
if( FAILED(hr) )
break;
} // end-for
return hr;
}
//---------------------------------------------------------------------------
//
// AMovieDllUnregisterServer()
//
// default ActiveMovie dll uninstall function
// - to use must be called from an exported
// function named DllRegisterServer()
//
// this function is table driven using the
// static members of the CFactoryTemplate
// class defined in the dll.
//
// it calls the IAMovieSetup.Unregister
// method and then unregisters the Dll
// as the InprocServer32
//
//---------------------------------------------------------------------------
STDAPI
AMovieDllUnregisterServer()
{
// initialize return code
//
HRESULT hr = NOERROR;
// scan through CFactory template and unregister
// all OLE servers and filters.
//
for( int i = g_cTemplates; i--; )
{
// get i'th template
//
const CFactoryTemplate *pT = &g_Templates[i];
// check method exists
//
if( NULL != pT->m_lpfnNew )
{
// instantiate object
//
PAMOVIESETUP psetup;
hr = CoCreateInstance( *(pT->m_ClsID)
, 0
, CLSCTX_INPROC_SERVER
, IID_IAMovieSetup
, reinterpret_cast<void**>(&psetup) );
if( SUCCEEDED(hr) )
{
hr = psetup->Unregister();
psetup->Release();
}
else
{
if( (E_NOINTERFACE == hr )
|| (VFW_E_NEED_OWNER == hr ) )
hr = NOERROR;
}
}
// unregister CLSID and InprocServer32
//
if( SUCCEEDED(hr) )
{
hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
}
// check final error for this pass
// and break loop if we failed
//
if( FAILED(hr) )
break;
}
return hr;
}
static HRESULT
ConvertUnicodeStringToTCHARString( LPTSTR szDest, size_t cchDest, LPCWSTR szSource )
{
HRESULT hr = NOERROR;
#ifdef UNICODE
LPCTSTR FORMAT_STRING = TEXT("%s");
#else
LPCTSTR FORMAT_STRING = TEXT("%S");
#endif
hr = StringCchPrintf( szDest, cchDest, FORMAT_STRING, szSource );
if( FAILED( hr ) )
{
return hr;
}
return S_OK;
}

View File

@ -1,46 +0,0 @@
//------------------------------------------------------------------------------
// File: DllSetup.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// To be self registering, OLE servers must
// export functions named DllRegisterServer
// and DllUnregisterServer. To allow use of
// custom and default implementations the
// defaults are named AMovieDllRegisterServer
// and AMovieDllUnregisterServer.
//
// To the use the default implementation you
// must provide stub functions.
//
// i.e. STDAPI DllRegisterServer()
// {
// return AMovieDllRegisterServer();
// }
//
// STDAPI DllUnregisterServer()
// {
// return AMovieDllUnregisterServer();
// }
//
//
// AMovieDllRegisterServer calls IAMovieSetup.Register(), and
// AMovieDllUnregisterServer calls IAMovieSetup.Unregister().
STDAPI AMovieDllRegisterServer2( BOOL );
STDAPI AMovieDllRegisterServer();
STDAPI AMovieDllUnregisterServer();
// helper functions
STDAPI EliminateSubKey( HKEY, LPTSTR );
STDAPI
AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata
, IFilterMapper2 * pIFM2
, BOOL bRegister );

View File

@ -1,83 +0,0 @@
//------------------------------------------------------------------------------
// File: DShow.h
//
// Desc: DirectShow top-level include file
//
// Copyright (c) 2000-2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __DSHOW_INCLUDED__
#define __DSHOW_INCLUDED__
///////////////////////////////////////////////////////////////////////////
// Set up constants & pragmas for the compiler
///////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// disable some level-4 warnings, use #pragma warning(default:###) to re-enable
#pragma warning(disable:4100) // warning C4100: unreferenced formal parameter
#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
#pragma warning(disable:4511) // warning C4511: copy constructor could not be generated
#pragma warning(disable:4512) // warning C4512: assignment operator could not be generated
#pragma warning(disable:4514) // warning C4514: "unreferenced inline function has been removed"
#if _MSC_VER>=1100
#define AM_NOVTABLE __declspec(novtable)
#else
#define AM_NOVTABLE
#endif
#endif // MSC_VER
///////////////////////////////////////////////////////////////////////////
// Include standard Windows files
///////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <windowsx.h>
#include <olectl.h>
#include <ddraw.h>
#include <mmsystem.h>
#ifndef NO_DSHOW_STRSAFE
#define NO_SHLWAPI_STRFCNS
#include <strsafe.h>
#endif
#ifndef NUMELMS
#define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0]))
#endif
///////////////////////////////////////////////////////////////////////////
// Include DirectShow include files
///////////////////////////////////////////////////////////////////////////
#include <strmif.h> // Generated IDL header file for streams interfaces
#include <amvideo.h> // ActiveMovie video interfaces and definitions
#include <amaudio.h> // ActiveMovie audio interfaces and definitions
#include <control.h> // generated from control.odl
#include <evcode.h> // event code definitions
#include <uuids.h> // declaration of type GUIDs and well-known clsids
#include <errors.h> // HRESULT status and error definitions
#include <edevdefs.h> // External device control interface defines
#include <audevcod.h> // audio filter device error event codes
#include <dvdevcod.h> // DVD error event codes
///////////////////////////////////////////////////////////////////////////
// Define OLE Automation constants
///////////////////////////////////////////////////////////////////////////
#ifndef OATRUE
#define OATRUE (-1)
#endif // OATRUE
#ifndef OAFALSE
#define OAFALSE (0)
#endif // OAFALSE
///////////////////////////////////////////////////////////////////////////
// Define Win64 interfaces if not already defined
///////////////////////////////////////////////////////////////////////////
// InterlockedExchangePointer
#ifndef InterlockedExchangePointer
#define InterlockedExchangePointer(Target, Value) \
(PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value))
#endif
#endif // __DSHOW_INCLUDED__

View File

@ -1,128 +0,0 @@
//------------------------------------------------------------------------------
// File: DSSchedule.h (replaces DirectX 8's schedule.h)
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __CAMSchedule__
#define __CAMSchedule__
class CAMSchedule : private CBaseObject
{
public:
virtual ~CAMSchedule();
// ev is the event we should fire if the advise time needs re-evaluating
CAMSchedule( HANDLE ev );
DWORD GetAdviseCount();
REFERENCE_TIME GetNextAdviseTime();
// We need a method for derived classes to add advise packets, we return the cookie
DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic );
// And a way to cancel
HRESULT Unadvise(DWORD_PTR dwAdviseCookie);
// Tell us the time please, and we'll dispatch the expired events. We return the time of the next event.
// NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of
// whoever is using this helper class (typically a clock).
REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime );
// Get the event handle which will be set if advise time requires re-evaluation.
HANDLE GetEvent() const { return m_ev; }
private:
// We define the nodes that will be used in our singly linked list
// of advise packets. The list is ordered by time, with the
// elements that will expire first at the front.
class CAdvisePacket
{
public:
CAdvisePacket()
{}
CAdvisePacket * m_next;
DWORD_PTR m_dwAdviseCookie;
REFERENCE_TIME m_rtEventTime; // Time at which event should be set
REFERENCE_TIME m_rtPeriod; // Periodic time
HANDLE m_hNotify; // Handle to event or semephore
BOOL m_bPeriodic; // TRUE => Periodic event
CAdvisePacket( CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time)
{}
void InsertAfter( CAdvisePacket * p )
{
p->m_next = m_next;
m_next = p;
}
int IsZ() const // That is, is it the node that represents the end of the list
{ return m_next == 0; }
CAdvisePacket * RemoveNext()
{
CAdvisePacket *const next = m_next;
CAdvisePacket *const new_next = next->m_next;
m_next = new_next;
return next;
}
void DeleteNext()
{
delete RemoveNext();
}
CAdvisePacket * Next() const
{
CAdvisePacket * result = m_next;
if (result->IsZ()) result = 0;
return result;
}
DWORD_PTR Cookie() const
{ return m_dwAdviseCookie; }
};
// Structure is:
// head -> elmt1 -> elmt2 -> z -> null
// So an empty list is: head -> z -> null
// Having head & z as links makes insertaion,
// deletion and shunting much easier.
CAdvisePacket head, z; // z is both a tail and a sentry
volatile DWORD_PTR m_dwNextCookie; // Strictly increasing
volatile DWORD m_dwAdviseCount; // Number of elements on list
CCritSec m_Serialize;
// AddAdvisePacket: adds the packet, returns the cookie (0 if failed)
DWORD_PTR AddAdvisePacket( CAdvisePacket * pPacket );
// Event that we should set if the packed added above will be the next to fire.
const HANDLE m_ev;
// A Shunt is where we have changed the first element in the
// list and want it re-evaluating (i.e. repositioned) in
// the list.
void ShuntHead();
// Rather than delete advise packets, we cache them for future use
CAdvisePacket * m_pAdviseCache;
DWORD m_dwCacheCount;
enum { dwCacheMax = 5 }; // Don't bother caching more than five
void Delete( CAdvisePacket * pLink );// This "Delete" will cache the Link
// Attributes and methods for debugging
public:
#ifdef DEBUG
void DumpLinkedList();
#else
void DumpLinkedList() {}
#endif
};
#endif // __CAMSchedule__

View File

@ -1,363 +0,0 @@
//------------------------------------------------------------------------------
// File: DVDevCod.h
//
// Desc: List of standard DVD-Video event codes and the expected params.
//
// Copyright (c) 1992 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __DVDEVCOD__
#define __DVDEVCOD__
#define EC_DVDBASE 0x0100
#ifndef EXCLUDE_DVDEVCODE_ENUMS
typedef enum _tagDVD_ERROR {
DVD_ERROR_Unexpected=1, // Something unexpected happened, perhaps content
// is incorrectly authored. Playback is stopped.
DVD_ERROR_CopyProtectFail=2, // Key exchange for DVD copy protection failed.
// Playback is stopped.
DVD_ERROR_InvalidDVD1_0Disc=3, // DVD-Video disc is incorrectly authored for v1.0
// of spec. Playback is stopped.
DVD_ERROR_InvalidDiscRegion=4, // The Disc cannot be played because the disc is not
// authored to play in system region.
// The region mismatch may be fixable by
// changing the system region with dvdrgn.exe
DVD_ERROR_LowParentalLevel=5, // Player parental level is lower than the lowest parental
// level available in the DVD content. Playback is stopped.
DVD_ERROR_MacrovisionFail=6, // Macrovision Distribution Failed.
// Playback is stopped.
DVD_ERROR_IncompatibleSystemAndDecoderRegions=7,
// No discs can be played because the system region
// does not match the decoder region.
DVD_ERROR_IncompatibleDiscAndDecoderRegions=8
// The disc cannot be played because the disc is
// not authored to be played in the decoder's region
} DVD_ERROR;
typedef enum _tagDVD_WARNING {
DVD_WARNING_InvalidDVD1_0Disc=1,// DVD-Video disc is incorrectly authored. Playback
// can continue, but unexpected behavior may occur.
DVD_WARNING_FormatNotSupported=2,// A decoder would not support the current format. Playback
// of a stream (audio, video of SP) may not function.
// lParam2 contains the stream type (see AM_DVD_STREAM_FLAGS)
DVD_WARNING_IllegalNavCommand=3,// The internal DVD navigation command processor attempted to
// process an illegal command.
DVD_WARNING_Open = 4, // File Open Failed
DVD_WARNING_Seek = 5, // File Seek Failed
DVD_WARNING_Read = 6 // File Read Failed
} DVD_WARNING;
typedef enum _tagDVD_PB_STOPPED {
DVD_PB_STOPPED_Other=0, // The navigator stopped the playback (no reason available).
DVD_PB_STOPPED_NoBranch=1, // The nav completed the current pgc and there was no more video and
// did not find any other branching instruction for subsequent playback.
DVD_PB_STOPPED_NoFirstPlayDomain =2, // The disc does not contain an initial startup program.
DVD_PB_STOPPED_StopCommand = 3, // The app issued a stop() command or a stop command was authored on the disc.
DVD_PB_STOPPED_Reset=4, // The navigator was reset to the start of the disc (using ResetOnStop).
DVD_PB_STOPPED_DiscEjected=5, // The disc was ejected.
DVD_PB_STOPPED_IllegalNavCommand = 6, // An illegal nav command prevented playback from continuing.
DVD_PB_STOPPED_PlayPeriodAutoStop = 7, // PlayPeriod completed
DVD_PB_STOPPED_PlayChapterAutoStop = 8, // PlayChapter completed
DVD_PB_STOPPED_ParentalFailure = 9, // A parental level failure prevented playback
DVD_PB_STOPPED_RegionFailure = 10, // A region failure prevented playback
DVD_PB_STOPPED_MacrovisionFailure = 11, // A Macrovision failure prevented playback.
DVD_PB_STOPPED_DiscReadError = 12, // A read error prevented playback.
DVD_PB_STOPPED_CopyProtectFailure = 13 // Copy protection failure.
} DVD_PB_STOPPED;
#endif
// DVD-Video event codes
// ======================
//
// All DVD-Video event are always passed on to the application, and are
// never processed by the filter graph
#define EC_DVD_DOMAIN_CHANGE (EC_DVDBASE + 0x01)
// Parameters: ( DWORD, void )
// lParam1 is enum DVD_DOMAIN, and indicates the player's new domain
//
// Raised from following domains: all
//
// Signaled when ever the DVD player changes domains.
#define EC_DVD_TITLE_CHANGE (EC_DVDBASE + 0x02)
// Parameters: ( DWORD, void )
// lParam1 is the new title number.
//
// Raised from following domains: DVD_DOMAIN_Title
//
// Indicates when the current title number changes. Title numbers
// range 1 to 99. This indicates the TTN, which is the title number
// with respect to the whole disc, not the VTS_TTN which is the title
// number with respect to just a current VTS.
#define EC_DVD_CHAPTER_START (EC_DVDBASE + 0x03)
// Parameters: ( DWORD, void )
// lParam1 is the new chapter number (which is the program number for
// One_Sequential_PGC_Titles).
//
// Raised from following domains: DVD_DOMAIN_Title
//
// Signales that DVD player started playback of a new program in the Title
// domain. This is only signaled for One_Sequential_PGC_Titles.
#define EC_DVD_AUDIO_STREAM_CHANGE (EC_DVDBASE + 0x04)
// Parameters: ( DWORD, void )
// lParam1 is the new user audio stream number.
//
// Raised from following domains: all
//
// Signaled when ever the current user audio stream number changes for the main
// title. This can be changed automatically with a navigation command on disc
// as well as through IDVDAnnexJ.
// Audio stream numbers range from 0 to 7. Stream 0xffffffff
// indicates that no stream is selected.
#define EC_DVD_SUBPICTURE_STREAM_CHANGE (EC_DVDBASE + 0x05)
// Parameters: ( DWORD, BOOL )
// lParam1 is the new user subpicture stream number.
// lParam2 is the subpicture's on/off state (TRUE if on)
//
// Raised from following domains: all
//
// Signaled when ever the current user subpicture stream number changes for the main
// title. This can be changed automatically with a navigation command on disc
// as well as through IDVDAnnexJ.
// Subpicture stream numbers range from 0 to 31. Stream 0xffffffff
// indicates that no stream is selected.
#define EC_DVD_ANGLE_CHANGE (EC_DVDBASE + 0x06)
// Parameters: ( DWORD, DWORD )
// lParam1 is the number of available angles.
// lParam2 is the current user angle number.
//
// Raised from following domains: all
//
// Signaled when ever either
// a) the number of available angles changes, or
// b) the current user angle number changes.
// Current angle number can be changed automatically with navigation command
// on disc as well as through IDVDAnnexJ.
// When the number of available angles is 1, the current video is not multiangle.
// Angle numbers range from 1 to 9.
#define EC_DVD_BUTTON_CHANGE (EC_DVDBASE + 0x07)
// Parameters: ( DWORD, DWORD )
// lParam1 is the number of available buttons.
// lParam2 is the current selected button number.
//
// Raised from following domains: all
//
// Signaled when ever either
// a) the number of available buttons changes, or
// b) the current selected button number changes.
// The current selected button can be changed automatically with navigation
// commands on disc as well as through IDVDAnnexJ.
// Button numbers range from 1 to 36. Selected button number 0 implies that
// no button is selected. Note that these button numbers enumerate all
// available button numbers, and do not always correspond to button numbers
// used for IDVDAnnexJ::ButtonSelectAndActivate since only a subset of buttons
// may be activated with ButtonSelectAndActivate.
#define EC_DVD_VALID_UOPS_CHANGE (EC_DVDBASE + 0x08)
// Parameters: ( DWORD, void )
// lParam1 is a VALID_UOP_SOMTHING_OR_OTHER bit-field stuct which indicates
// which IDVDAnnexJ commands are explicitly disable by the DVD disc.
//
// Raised from following domains: all
//
// Signaled when ever the available set of IDVDAnnexJ methods changes. This
// only indicates which operations are explicited disabled by the content on
// the DVD disc, and does not guarentee that it is valid to call methods
// which are not disabled. For example, if no buttons are currently present,
// IDVDAnnexJ::ButtonActivate() won't work, even though the buttons are not
// explicitly disabled.
#define EC_DVD_STILL_ON (EC_DVDBASE + 0x09)
// Parameters: ( BOOL, DWORD )
// lParam1 == 0 --> buttons are available, so StillOff won't work
// lParam1 == 1 --> no buttons available, so StillOff will work
// lParam2 indicates the number of seconds the still will last, with 0xffffffff
// indicating an infinite still (wait till button or StillOff selected).
//
// Raised from following domains: all
//
// Signaled at the beginning of any still: PGC still, Cell Still, or VOBU Still.
// Note that all combinations of buttons and still are possible (buttons on with
// still on, buttons on with still off, button off with still on, button off
// with still off).
#define EC_DVD_STILL_OFF (EC_DVDBASE + 0x0a)
// Parameters: ( void, void )
//
// Indicating that any still that is currently active
// has been released.
//
// Raised from following domains: all
//
// Signaled at the end of any still: PGC still, Cell Still, or VOBU Still.
//
#define EC_DVD_CURRENT_TIME (EC_DVDBASE + 0x0b)
// Parameters: ( DWORD, BOOL )
// lParam1 is a DVD_TIMECODE which indicates the current
// playback time code in a BCD HH:MM:SS:FF format.
// lParam2 == 0 --> time code is 25 frames/sec
// lParam2 == 1 --> time code is 30 frames/sec (non-drop).
// lParam2 == 2 --> time code is invalid (current playback time
// cannot be determined for current title)
//
// Raised from following domains: DVD_DOMAIN_Title
//
// Signaled at the beginning of every VOBU, which occurs every .4 to 1.0 sec.
// This is only signaled for One_Sequential_PGC_Titles.
#define EC_DVD_ERROR (EC_DVDBASE + 0x0c)
// Parameters: ( DWORD, void)
// lParam1 is an enum DVD_ERROR which notifies the app of some error condition.
//
// Raised from following domains: all
//
#define EC_DVD_WARNING (EC_DVDBASE + 0x0d)
// Parameters: ( DWORD, DWORD)
// lParam1 is an enum DVD_WARNING which notifies the app of some warning condition.
// lParam2 contains more specific information about the warning (warning dependent)
//
// Raised from following domains: all
//
#define EC_DVD_CHAPTER_AUTOSTOP (EC_DVDBASE + 0x0e)
// Parameters: (BOOL, void)
// lParam1 is a BOOL which indicates the reason for the cancellation of ChapterPlayAutoStop
// lParam1 == 0 indicates successful completion of ChapterPlayAutoStop
// lParam1 == 1 indicates that ChapterPlayAutoStop is being cancelled as a result of another
// IDVDControl call or the end of content has been reached & no more chapters
// can be played.
// Indicating that playback is stopped as a result of a call
// to IDVDControl::ChapterPlayAutoStop()
//
// Raised from following domains : DVD_DOMAIN_TITLE
//
#define EC_DVD_NO_FP_PGC (EC_DVDBASE + 0x0f)
// Parameters : (void, void)
//
// Raised from the following domains : FP_DOM
//
// Indicates that the DVD disc does not have a FP_PGC (First Play Program Chain)
// and the DVD Navigator will not automatically load any PGC and start playback.
//
#define EC_DVD_PLAYBACK_RATE_CHANGE (EC_DVDBASE + 0x10)
// Parameters : (LONG, void)
// lParam1 is a LONG indicating the new playback rate.
// lParam1 < 0 indicates reverse playback mode.
// lParam1 > 0 indicates forward playback mode
// Value of lParam1 is the actual playback rate multiplied by 10000.
// i.e. lParam1 = rate * 10000
//
// Raised from the following domains : TT_DOM
//
// Indicates that a rate change in playback has been initiated and the parameter
// lParam1 indicates the new playback rate that is being used.
//
#define EC_DVD_PARENTAL_LEVEL_CHANGE (EC_DVDBASE + 0x11)
// Parameters : (LONG, void)
// lParam1 is a LONG indicating the new parental level.
//
// Raised from the following domains : VMGM_DOM
//
// Indicates that an authored Nav command has changed the parental level
// setting in the player.
//
#define EC_DVD_PLAYBACK_STOPPED (EC_DVDBASE + 0x12)
// Parameters : (DWORD, void)
//
// Raised from the following domains : All Domains
//
// Indicates that playback has been stopped as the Navigator has completed
// playback of the pgc and did not find any other branching instruction for
// subsequent playback.
//
// The DWORD returns the reason for the completion of the playback. See
// The DVD_PB_STOPPED enumeration for details.
//
#define EC_DVD_ANGLES_AVAILABLE (EC_DVDBASE + 0x13)
// Parameters : (BOOL, void)
// lParam1 == 0 indicates that playback is not in an angle block and angles are
// not available
// lParam1 == 1 indicates that an angle block is being played back and angle changes
// can be performed.
//
// Indicates whether an angle block is being played and if angle changes can be
// performed. However, angle changes are not restricted to angle blocks and the
// manifestation of the angle change can be seen only in an angle block.
#define EC_DVD_PLAYPERIOD_AUTOSTOP (EC_DVDBASE + 0x14)
// Parameters: (void, void)
// Sent when the PlayPeriodInTitle completes or is cancelled
//
// Raised from following domains : DVD_DOMAIN_TITLE
//
#define EC_DVD_BUTTON_AUTO_ACTIVATED (EC_DVDBASE + 0x15)
// Parameters: (DWORD button, void)
// Sent when a button is automatically activated
//
// Raised from following domains : DVD_DOMAIN_MENU
//
#define EC_DVD_CMD_START (EC_DVDBASE + 0x16)
// Parameters: (CmdID, HRESULT)
// Sent when a command begins
//
#define EC_DVD_CMD_END (EC_DVDBASE + 0x17)
// Parameters: (CmdID, HRESULT)
// Sent when a command completes
//
#define EC_DVD_DISC_EJECTED (EC_DVDBASE + 0x18)
// Parameters: none
// Sent when the nav detects that a disc was ejected and stops the playback
// The app does not need to take any action to stop the playback.
//
#define EC_DVD_DISC_INSERTED (EC_DVDBASE + 0x19)
// Parameters: none
// Sent when the nav detects that a disc was inserted and the nav begins playback
// The app does not need to take any action to start the playback.
//
#define EC_DVD_CURRENT_HMSF_TIME (EC_DVDBASE + 0x1a)
// Parameters: ( ULONG, ULONG )
// lParam2 contains a union of the DVD_TIMECODE_FLAGS
// lParam1 contains a DVD_HMSF_TIMECODE. Assign lParam1 to a ULONG then cast the
// ULONG as a DVD_HMSF_TIMECODE to use its values.
//
// Raised from following domains: DVD_DOMAIN_Title
//
// Signaled at the beginning of every VOBU, which occurs every .4 to 1.0 sec.
#define EC_DVD_KARAOKE_MODE (EC_DVDBASE + 0x1b)
// Parameters: ( BOOL, reserved )
// lParam1 is either TRUE (a karaoke track is being played) or FALSE (no karaoke data is being played).
//
#endif // __DVDEVCOD__

View File

@ -1,427 +0,0 @@
//------------------------------------------------------------------------------
// File: DVDMedia.h
//
// Desc: Contains typedefs and defines necessary for user mode (ring 3) DVD
// filters and applications.
//
// This should be included in the DirectShow SDK for user mode filters.
// The types defined here should be kept in synch with ksmedia.h WDM
// DDK for kernel mode filters.
//
// Copyright (c) 1997 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __DVDMEDIA_H__
#define __DVDMEDIA_H__
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// -----------------------------------------------------------------------
// AC-3 definition for the AM_KSPROPSETID_AC3 property set
// -----------------------------------------------------------------------
typedef enum {
AM_PROPERTY_AC3_ERROR_CONCEALMENT = 1,
AM_PROPERTY_AC3_ALTERNATE_AUDIO = 2,
AM_PROPERTY_AC3_DOWNMIX = 3,
AM_PROPERTY_AC3_BIT_STREAM_MODE = 4,
AM_PROPERTY_AC3_DIALOGUE_LEVEL = 5,
AM_PROPERTY_AC3_LANGUAGE_CODE = 6,
AM_PROPERTY_AC3_ROOM_TYPE = 7
} AM_PROPERTY_AC3;
typedef struct {
BOOL fRepeatPreviousBlock;
BOOL fErrorInCurrentBlock;
} AM_AC3_ERROR_CONCEALMENT, *PAM_AC3_ERROR_CONCEALMENT;
typedef struct {
BOOL fStereo;
ULONG DualMode;
} AM_AC3_ALTERNATE_AUDIO, *PAM_AC3_ALTERNATE_AUDIO;
#define AM_AC3_ALTERNATE_AUDIO_1 1
#define AM_AC3_ALTERNATE_AUDIO_2 2
#define AM_AC3_ALTERNATE_AUDIO_BOTH 3
typedef struct {
BOOL fDownMix;
BOOL fDolbySurround;
} AM_AC3_DOWNMIX, *PAM_AC3_DOWNMIX;
typedef struct {
LONG BitStreamMode;
} AM_AC3_BIT_STREAM_MODE, *PAM_AC3_BIT_STREAM_MODE;
#define AM_AC3_SERVICE_MAIN_AUDIO 0
#define AM_AC3_SERVICE_NO_DIALOG 1
#define AM_AC3_SERVICE_VISUALLY_IMPAIRED 2
#define AM_AC3_SERVICE_HEARING_IMPAIRED 3
#define AM_AC3_SERVICE_DIALOG_ONLY 4
#define AM_AC3_SERVICE_COMMENTARY 5
#define AM_AC3_SERVICE_EMERGENCY_FLASH 6
#define AM_AC3_SERVICE_VOICE_OVER 7
typedef struct {
ULONG DialogueLevel;
} AM_AC3_DIALOGUE_LEVEL, *PAM_AC3_DIALOGUE_LEVEL;
typedef struct {
BOOL fLargeRoom;
} AM_AC3_ROOM_TYPE, *PAM_AC3_ROOM_TYPE;
// -----------------------------------------------------------------------
// subpicture definition for the AM_KSPROPSETID_DvdSubPic property set
// -----------------------------------------------------------------------
typedef enum {
AM_PROPERTY_DVDSUBPIC_PALETTE = 0,
AM_PROPERTY_DVDSUBPIC_HLI = 1,
AM_PROPERTY_DVDSUBPIC_COMPOSIT_ON = 2 // TRUE for subpicture is displayed
} AM_PROPERTY_DVDSUBPIC;
typedef struct _AM_DVD_YUV {
UCHAR Reserved;
UCHAR Y;
UCHAR U;
UCHAR V;
} AM_DVD_YUV, *PAM_DVD_YUV;
typedef struct _AM_PROPERTY_SPPAL {
AM_DVD_YUV sppal[16];
} AM_PROPERTY_SPPAL, *PAM_PROPERTY_SPPAL;
typedef struct _AM_COLCON {
UCHAR emph1col:4;
UCHAR emph2col:4;
UCHAR backcol:4;
UCHAR patcol:4;
UCHAR emph1con:4;
UCHAR emph2con:4;
UCHAR backcon:4;
UCHAR patcon:4;
} AM_COLCON, *PAM_COLCON;
typedef struct _AM_PROPERTY_SPHLI {
USHORT HLISS; //
USHORT Reserved;
ULONG StartPTM; // start presentation time in x/90000
ULONG EndPTM; // end PTM in x/90000
USHORT StartX;
USHORT StartY;
USHORT StopX;
USHORT StopY;
AM_COLCON ColCon; // color contrast description (4 bytes as given in HLI)
} AM_PROPERTY_SPHLI, *PAM_PROPERTY_SPHLI;
typedef BOOL AM_PROPERTY_COMPOSIT_ON, *PAM_PROPERTY_COMPOSIT_ON;
// -----------------------------------------------------------------------
// copy protection definitions
// -----------------------------------------------------------------------
// AM_UseNewCSSKey for the dwTypeSpecificFlags in IMediaSample2 to indicate
// the exact point in a stream after which to start applying a new CSS key.
// This is typically sent on an empty media sample just before attempting
// to renegotiate a CSS key.
#define AM_UseNewCSSKey 0x1
//
// AM_KSPROPSETID_CopyProt property set definitions
//
typedef enum {
AM_PROPERTY_DVDCOPY_CHLG_KEY = 0x01,
AM_PROPERTY_DVDCOPY_DVD_KEY1 = 0x02,
AM_PROPERTY_DVDCOPY_DEC_KEY2 = 0x03,
AM_PROPERTY_DVDCOPY_TITLE_KEY = 0x04,
AM_PROPERTY_COPY_MACROVISION = 0x05,
AM_PROPERTY_DVDCOPY_REGION = 0x06,
AM_PROPERTY_DVDCOPY_SET_COPY_STATE = 0x07,
AM_PROPERTY_DVDCOPY_DISC_KEY = 0x80
} AM_PROPERTY_DVDCOPYPROT;
typedef struct _AM_DVDCOPY_CHLGKEY {
BYTE ChlgKey[10];
BYTE Reserved[2];
} AM_DVDCOPY_CHLGKEY, *PAM_DVDCOPY_CHLGKEY;
typedef struct _AM_DVDCOPY_BUSKEY {
BYTE BusKey[5];
BYTE Reserved[1];
} AM_DVDCOPY_BUSKEY, *PAM_DVDCOPY_BUSKEY;
typedef struct _AM_DVDCOPY_DISCKEY {
BYTE DiscKey[2048];
} AM_DVDCOPY_DISCKEY, *PAM_DVDCOPY_DISCKEY;
typedef struct AM_DVDCOPY_TITLEKEY {
ULONG KeyFlags;
ULONG Reserved1[2];
UCHAR TitleKey[6];
UCHAR Reserved2[2];
} AM_DVDCOPY_TITLEKEY, *PAM_DVDCOPY_TITLEKEY;
typedef struct _AM_COPY_MACROVISION {
ULONG MACROVISIONLevel;
} AM_COPY_MACROVISION, *PAM_COPY_MACROVISION;
typedef struct AM_DVDCOPY_SET_COPY_STATE {
ULONG DVDCopyState;
} AM_DVDCOPY_SET_COPY_STATE, *PAM_DVDCOPY_SET_COPY_STATE;
typedef enum {
AM_DVDCOPYSTATE_INITIALIZE = 0,
AM_DVDCOPYSTATE_INITIALIZE_TITLE = 1, // indicates we are starting a title
// key copy protection sequence
AM_DVDCOPYSTATE_AUTHENTICATION_NOT_REQUIRED = 2,
AM_DVDCOPYSTATE_AUTHENTICATION_REQUIRED = 3,
AM_DVDCOPYSTATE_DONE = 4
} AM_DVDCOPYSTATE;
typedef enum {
AM_MACROVISION_DISABLED = 0,
AM_MACROVISION_LEVEL1 = 1,
AM_MACROVISION_LEVEL2 = 2,
AM_MACROVISION_LEVEL3 = 3
} AM_COPY_MACROVISION_LEVEL, *PAM_COPY_MACROVISION_LEVEL;
// CSS region stucture
typedef struct _DVD_REGION {
UCHAR CopySystem;
UCHAR RegionData;
UCHAR SystemRegion;
UCHAR Reserved;
} DVD_REGION, *PDVD_REGION;
//
// CGMS Copy Protection Flags
//
#define AM_DVD_CGMS_RESERVED_MASK 0x00000078
#define AM_DVD_CGMS_COPY_PROTECT_MASK 0x00000018
#define AM_DVD_CGMS_COPY_PERMITTED 0x00000000
#define AM_DVD_CGMS_COPY_ONCE 0x00000010
#define AM_DVD_CGMS_NO_COPY 0x00000018
#define AM_DVD_COPYRIGHT_MASK 0x00000040
#define AM_DVD_NOT_COPYRIGHTED 0x00000000
#define AM_DVD_COPYRIGHTED 0x00000040
#define AM_DVD_SECTOR_PROTECT_MASK 0x00000020
#define AM_DVD_SECTOR_NOT_PROTECTED 0x00000000
#define AM_DVD_SECTOR_PROTECTED 0x00000020
// -----------------------------------------------------------------------
// video format blocks
// -----------------------------------------------------------------------
enum AM_MPEG2Level {
AM_MPEG2Level_Low = 1,
AM_MPEG2Level_Main = 2,
AM_MPEG2Level_High1440 = 3,
AM_MPEG2Level_High = 4
};
enum AM_MPEG2Profile {
AM_MPEG2Profile_Simple = 1,
AM_MPEG2Profile_Main = 2,
AM_MPEG2Profile_SNRScalable = 3,
AM_MPEG2Profile_SpatiallyScalable = 4,
AM_MPEG2Profile_High = 5
};
#define AMINTERLACE_IsInterlaced 0x00000001 // if 0, other interlace bits are irrelevent
#define AMINTERLACE_1FieldPerSample 0x00000002 // else 2 fields per media sample
#define AMINTERLACE_Field1First 0x00000004 // else Field 2 is first; top field in PAL is field 1, top field in NTSC is field 2?
#define AMINTERLACE_UNUSED 0x00000008 //
#define AMINTERLACE_FieldPatternMask 0x00000030 // use this mask with AMINTERLACE_FieldPat*
#define AMINTERLACE_FieldPatField1Only 0x00000000 // stream never contains a Field2
#define AMINTERLACE_FieldPatField2Only 0x00000010 // stream never contains a Field1
#define AMINTERLACE_FieldPatBothRegular 0x00000020 // There will be a Field2 for every Field1 (required for Weave?)
#define AMINTERLACE_FieldPatBothIrregular 0x00000030 // Random pattern of Field1s and Field2s
#define AMINTERLACE_DisplayModeMask 0x000000c0
#define AMINTERLACE_DisplayModeBobOnly 0x00000000
#define AMINTERLACE_DisplayModeWeaveOnly 0x00000040
#define AMINTERLACE_DisplayModeBobOrWeave 0x00000080
#define AMCOPYPROTECT_RestrictDuplication 0x00000001 // duplication of this stream should be restricted
#define AMMPEG2_DoPanScan 0x00000001 //if set, the MPEG-2 video decoder should crop output image
// based on pan-scan vectors in picture_display_extension
// and change the picture aspect ratio accordingly.
#define AMMPEG2_DVDLine21Field1 0x00000002 //if set, the MPEG-2 decoder must be able to produce an output
// pin for DVD style closed caption data found in GOP layer of field 1
#define AMMPEG2_DVDLine21Field2 0x00000004 //if set, the MPEG-2 decoder must be able to produce an output
// pin for DVD style closed caption data found in GOP layer of field 2
#define AMMPEG2_SourceIsLetterboxed 0x00000008 //if set, indicates that black bars have been encoded in the top
// and bottom of the video.
#define AMMPEG2_FilmCameraMode 0x00000010 //if set, indicates "film mode" used for 625/50 content. If cleared,
// indicates that "camera mode" was used.
#define AMMPEG2_LetterboxAnalogOut 0x00000020 //if set and this stream is sent to an analog output, it should
// be letterboxed. Streams sent to VGA should be letterboxed only by renderers.
#define AMMPEG2_DSS_UserData 0x00000040 //if set, the MPEG-2 decoder must process DSS style user data
#define AMMPEG2_DVB_UserData 0x00000080 //if set, the MPEG-2 decoder must process DVB style user data
#define AMMPEG2_27MhzTimebase 0x00000100 //if set, the PTS,DTS timestamps advance at 27MHz rather than 90KHz
#define AMMPEG2_WidescreenAnalogOut 0x00000200 //if set and this stream is sent to an analog output, it should
// be in widescreen format (4x3 content should be centered on a 16x9 output).
// Streams sent to VGA should be widescreened only by renderers.
// PRESENT in dwReserved1 field in VIDEOINFOHEADER2
#define AMCONTROL_USED 0x00000001 // Used to test if these flags are supported. Set and test for AcceptMediaType.
// If rejected, then you cannot use the AMCONTROL flags (send 0 for dwReserved1)
#define AMCONTROL_PAD_TO_4x3 0x00000002 // if set means display the image in a 4x3 area
#define AMCONTROL_PAD_TO_16x9 0x00000004 // if set means display the image in a 16x9 area
typedef struct tagVIDEOINFOHEADER2 {
RECT rcSource;
RECT rcTarget;
DWORD dwBitRate;
DWORD dwBitErrorRate;
REFERENCE_TIME AvgTimePerFrame;
DWORD dwInterlaceFlags; // use AMINTERLACE_* defines. Reject connection if undefined bits are not 0
DWORD dwCopyProtectFlags; // use AMCOPYPROTECT_* defines. Reject connection if undefined bits are not 0
DWORD dwPictAspectRatioX; // X dimension of picture aspect ratio, e.g. 16 for 16x9 display
DWORD dwPictAspectRatioY; // Y dimension of picture aspect ratio, e.g. 9 for 16x9 display
union {
DWORD dwControlFlags; // use AMCONTROL_* defines, use this from now on
DWORD dwReserved1; // for backward compatiblity (was "must be 0"; connection rejected otherwise)
};
DWORD dwReserved2; // must be 0; reject connection otherwise
BITMAPINFOHEADER bmiHeader;
} VIDEOINFOHEADER2;
typedef struct tagMPEG2VIDEOINFO {
VIDEOINFOHEADER2 hdr;
DWORD dwStartTimeCode; // ?? not used for DVD ??
DWORD cbSequenceHeader; // is 0 for DVD (no sequence header)
DWORD dwProfile; // use enum MPEG2Profile
DWORD dwLevel; // use enum MPEG2Level
DWORD dwFlags; // use AMMPEG2_* defines. Reject connection if undefined bits are not 0
DWORD dwSequenceHeader[1]; // DWORD instead of Byte for alignment purposes
// For MPEG-2, if a sequence_header is included, the sequence_extension
// should also be included
} MPEG2VIDEOINFO;
#define SIZE_MPEG2VIDEOINFO(pv) (FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader[0]) + (pv)->cbSequenceHeader)
// do not use
#define MPEG1_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->bSequenceHeader)
// use this macro instead, the previous only works for MPEG1VIDEOINFO structures
#define MPEG2_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->dwSequenceHeader)
//===================================================================================
// flags for dwTypeSpecificFlags in AM_SAMPLE2_PROPERTIES which define type specific
// data in IMediaSample2
//===================================================================================
#define AM_VIDEO_FLAG_FIELD_MASK 0x0003L // use this mask to check whether the sample is field1 or field2 or frame
#define AM_VIDEO_FLAG_INTERLEAVED_FRAME 0x0000L // the sample is a frame (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this)
#define AM_VIDEO_FLAG_FIELD1 0x0001L // the sample is field1 (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this)
#define AM_VIDEO_FLAG_FIELD2 0x0002L // the sample is the field2 (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this)
#define AM_VIDEO_FLAG_FIELD1FIRST 0x0004L // if set means display field1 first, else display field2 first.
// this bit is irrelavant for 1FieldPerSample mode
#define AM_VIDEO_FLAG_WEAVE 0x0008L // if set use bob display mode else weave
#define AM_VIDEO_FLAG_IPB_MASK 0x0030L // use this mask to check whether the sample is I, P or B
#define AM_VIDEO_FLAG_I_SAMPLE 0x0000L // I Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this)
#define AM_VIDEO_FLAG_P_SAMPLE 0x0010L // P Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this)
#define AM_VIDEO_FLAG_B_SAMPLE 0x0020L // B Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this)
#define AM_VIDEO_FLAG_REPEAT_FIELD 0x0040L // if set means display the field which has been displayed first again after displaying
// both fields first. This bit is irrelavant for 1FieldPerSample mode
// -----------------------------------------------------------------------
// AM_KSPROPSETID_DvdKaraoke property set definitions
// -----------------------------------------------------------------------
typedef struct tagAM_DvdKaraokeData
{
DWORD dwDownmix; // bitwise OR of AM_DvdKaraoke_Downmix flags
DWORD dwSpeakerAssignment; // AM_DvdKaraoke_SpeakerAssignment
} AM_DvdKaraokeData;
typedef enum {
AM_PROPERTY_DVDKARAOKE_ENABLE = 0, // BOOL
AM_PROPERTY_DVDKARAOKE_DATA = 1,
} AM_PROPERTY_DVDKARAOKE;
// -----------------------------------------------------------------------
// AM_KSPROPSETID_TSRateChange property set definitions for time stamp
// rate changes.
// -----------------------------------------------------------------------
typedef enum {
AM_RATE_SimpleRateChange = 1, // rw, use AM_SimpleRateChange
AM_RATE_ExactRateChange = 2, // rw, use AM_ExactRateChange
AM_RATE_MaxFullDataRate = 3, // r, use AM_MaxFullDataRate
AM_RATE_Step = 4, // w, use AM_Step
AM_RATE_UseRateVersion = 5, // w, use WORD
AM_RATE_QueryFullFrameRate =6, // r, use AM_QueryRate
AM_RATE_QueryLastRateSegPTS =7, // r, use REFERENCE_TIME
AM_RATE_CorrectTS = 8 // w, use LONG
} AM_PROPERTY_TS_RATE_CHANGE;
// -------------------------------------------------------------------
// AM_KSPROPSETID_DVD_RateChange property set definitions for new DVD
// rate change scheme.
// -------------------------------------------------------------------
typedef enum {
AM_RATE_ChangeRate = 1, // w, use AM_DVD_ChangeRate
AM_RATE_FullDataRateMax = 2, // r, use AM_MaxFullDataRate
AM_RATE_ReverseDecode = 3, // r, use LONG
AM_RATE_DecoderPosition = 4, // r, use AM_DVD_DecoderPosition
AM_RATE_DecoderVersion = 5 // r, use LONG
} AM_PROPERTY_DVD_RATE_CHANGE;
typedef struct {
// this is the simplest mechanism to set a time stamp rate change on
// a filter (simplest for the person setting the rate change, harder
// for the filter doing the rate change).
REFERENCE_TIME StartTime; //stream time at which to start this rate
LONG Rate; //new rate * 10000 (decimal)
} AM_SimpleRateChange;
typedef struct {
LONG lMaxForwardFullFrame ; // rate * 10000
LONG lMaxReverseFullFrame ; // rate * 10000
} AM_QueryRate ;
typedef struct {
REFERENCE_TIME OutputZeroTime; //input TS that maps to zero output TS
LONG Rate; //new rate * 10000 (decimal)
} AM_ExactRateChange;
typedef LONG AM_MaxFullDataRate; //rate * 10000 (decimal)
typedef DWORD AM_Step; // number of frame to step
// New rate change property set, structs. enums etc.
typedef struct {
REFERENCE_TIME StartInTime; // stream time (input) at which to start decoding at this rate
REFERENCE_TIME StartOutTime; // reference time (output) at which to start showing at this rate
LONG Rate; // new rate * 10000 (decimal)
} AM_DVD_ChangeRate ;
typedef LONGLONG AM_DVD_DecoderPosition ;
typedef enum {
DVD_DIR_FORWARD = 0,
DVD_DIR_BACKWARD = 1
} DVD_PLAY_DIRECTION ;
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __DVDMEDIA_H__

View File

@ -1,531 +0,0 @@
//------------------------------------------------------------------------------
// File: EDevDefs.h
//
// Desc: External Device (such as a VCR) control interface parameter and
// value definitions.
//
// Note: new constants added: ED_BASE+800L -> ED_BASE+811L
//
// Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __EDEVDEFS__
#define __EDEVDEFS__
#define ED_BASE 0x1000L
// this is used to tell the device communications object which
// physical communications port to use.
#define DEV_PORT_SIM 1
#define DEV_PORT_COM1 2 // standard serial ports
#define DEV_PORT_COM2 3
#define DEV_PORT_COM3 4
#define DEV_PORT_COM4 5
#define DEV_PORT_DIAQ 6 // Diaquest driver
#define DEV_PORT_ARTI 7 // ARTI driver
#define DEV_PORT_1394 8 // IEEE 1394 Bus
#define DEV_PORT_USB 9 // Universal Serial Bus
#define DEV_PORT_MIN DEV_PORT_SIM
#define DEV_PORT_MAX DEV_PORT_USB
// IAMExtDevice Capability Items: unless otherwise specified, these items return
// OATRUE or OAFALSE. All return values are in pdwValue unless otherwise specified:
#define ED_DEVCAP_CAN_RECORD ED_BASE+1L
#define ED_DEVCAP_CAN_RECORD_STROBE ED_BASE+2L // for multitrack devices:
// switches currently recording tracks off
// and selected non-recording tracks into record
#define ED_DEVCAP_HAS_AUDIO ED_BASE+3L
#define ED_DEVCAP_HAS_VIDEO ED_BASE+4L
#define ED_DEVCAP_USES_FILES ED_BASE+5L
#define ED_DEVCAP_CAN_SAVE ED_BASE+6L
#define ED_DEVCAP_DEVICE_TYPE ED_BASE+7L // returns one of the following:
#define ED_DEVTYPE_VCR ED_BASE+8L
#define ED_DEVTYPE_LASERDISK ED_BASE+9L
#define ED_DEVTYPE_ATR ED_BASE+10L
#define ED_DEVTYPE_DDR ED_BASE+11L
#define ED_DEVTYPE_ROUTER ED_BASE+12L
#define ED_DEVTYPE_KEYER ED_BASE+13L
#define ED_DEVTYPE_MIXER_VIDEO ED_BASE+14L
#define ED_DEVTYPE_DVE ED_BASE+15L
#define ED_DEVTYPE_WIPEGEN ED_BASE+16L
#define ED_DEVTYPE_MIXER_AUDIO ED_BASE+17L
#define ED_DEVTYPE_CG ED_BASE+18L
#define ED_DEVTYPE_TBC ED_BASE+19L
#define ED_DEVTYPE_TCG ED_BASE+20L
#define ED_DEVTYPE_GPI ED_BASE+21L
#define ED_DEVTYPE_JOYSTICK ED_BASE+22L
#define ED_DEVTYPE_KEYBOARD ED_BASE+23L
// returns mfr-specific ID from external device.
#define ED_DEVCAP_EXTERNAL_DEVICE_ID ED_BASE+24L
#define ED_DEVCAP_TIMECODE_READ ED_BASE+25L
#define ED_DEVCAP_TIMECODE_WRITE ED_BASE+26L
// used for seekable non-timecode enabled devices
#define ED_DEVCAP_CTLTRK_READ ED_BASE+27L
// used for seekable non-timecode enabled devices
#define ED_DEVCAP_INDEX_READ ED_BASE+28L
// returns device preroll time in current time format
#define ED_DEVCAP_PREROLL ED_BASE+29L
// returns device postroll time in current time format
#define ED_DEVCAP_POSTROLL ED_BASE+30L
// returns indication of devices synchronization accuracy.
#define ED_DEVCAP_SYNC_ACCURACY ED_BASE+31L // returns one of the following:
#define ED_SYNCACC_PRECISE ED_BASE+32L
#define ED_SYNCACC_FRAME ED_BASE+33L
#define ED_SYNCACC_ROUGH ED_BASE+34L
// returns devices normal framerate.
#define ED_DEVCAP_NORMAL_RATE ED_BASE+35L // returns one of the following:
#define ED_RATE_24 ED_BASE+36L
#define ED_RATE_25 ED_BASE+37L
#define ED_RATE_2997 ED_BASE+38L
#define ED_RATE_30 ED_BASE+39L
#define ED_DEVCAP_CAN_PREVIEW ED_BASE+40L
#define ED_DEVCAP_CAN_MONITOR_SOURCES ED_BASE+41L
// indicates implementation allows testing of methods/parameters by
// setting the hi bit of a parm that makes sense - see individual methods
// for details.
#define ED_DEVCAP_CAN_TEST ED_BASE+42L
// indicates device accepts video as an input.
#define ED_DEVCAP_VIDEO_INPUTS ED_BASE+43L
// indicates device accepts audio as an input.
#define ED_DEVCAP_AUDIO_INPUTS ED_BASE+44L
#define ED_DEVCAP_NEEDS_CALIBRATING ED_BASE+45L
#define ED_DEVCAP_SEEK_TYPE ED_BASE+46L // returns one of the following:
#define ED_SEEK_PERFECT ED_BASE+47L // indicates device can execute seek
// within 1 video frames without signal
// break (like a DDR)
#define ED_SEEK_FAST ED_BASE+48L // indicates device can move pretty quick
// with short break in signal
#define ED_SEEK_SLOW ED_BASE+49L // seeks like a tape transport
#define ED_POWER_ON ED_BASE+50L
#define ED_POWER_OFF ED_BASE+51L
#define ED_POWER_STANDBY ED_BASE+52L
#define ED_ACTIVE ED_BASE+53L
#define ED_INACTIVE ED_BASE+54L
#define ED_ALL ED_BASE+55L
#define ED_TEST ED_BASE+56L
// IAMExtTransport Capability Items: unless otherwise specified, these items return
// OATRUE or OAFALSE. All return values are in pdwValue unless otherwise specified:
#define ED_TRANSCAP_CAN_EJECT ED_BASE+100L
#define ED_TRANSCAP_CAN_BUMP_PLAY ED_BASE+101L // variable speed for synchronizing
#define ED_TRANSCAP_CAN_PLAY_BACKWARDS ED_BASE+102L // servo locked for use during an edit
#define ED_TRANSCAP_CAN_SET_EE ED_BASE+103L // show devices input on its output
#define ED_TRANSCAP_CAN_SET_PB ED_BASE+104L // show media playback on devices output
#define ED_TRANSCAP_CAN_DELAY_VIDEO_IN ED_BASE+105L // transport can do delayed-in video edits
#define ED_TRANSCAP_CAN_DELAY_VIDEO_OUT ED_BASE+106L // transport can do delayed-out video edits
#define ED_TRANSCAP_CAN_DELAY_AUDIO_IN ED_BASE+107L // transport can do delayed-in audio edits
#define ED_TRANSCAP_CAN_DELAY_AUDIO_OUT ED_BASE+108L // transport can do delayed-out audio edits
#define ED_TRANSCAP_FWD_VARIABLE_MAX ED_BASE+109L // max forward speed (multiple of play speed)
// in pdblValue
#define ED_TRANSCAP_FWD_VARIABLE_MIN ED_BASE+800L // min forward speed (multiple of play speed)
// in pdblValue
#define ED_TRANSCAP_REV_VARIABLE_MAX ED_BASE+110L // max reverse speed (multiple of play speed) in
// pdblValue
#define ED_TRANSCAP_REV_VARIABLE_MIN ED_BASE+801L // min reverse speed (multiple of play speed)
// in pdblValue
#define ED_TRANSCAP_FWD_SHUTTLE_MAX ED_BASE+802L // max forward speed in Shuttle mode (multiple
// of play speed) in pdblValue
#define ED_TRANSCAP_FWD_SHUTTLE_MIN ED_BASE+803L // min forward speed in Shuttle mode (multiple
// of play speed) in pdblValue
#define ED_TRANSCAP_REV_SHUTTLE_MAX ED_BASE+804L // max reverse speed in Shuttle mode (multiple
// of play speed) in pdblValue
#define ED_TRANSCAP_REV_SHUTTLE_MIN ED_BASE+805L // min reverse speed in Shuttle mode (multiple
// of play speed) in pdblValue
#define ED_TRANSCAP_NUM_AUDIO_TRACKS ED_BASE+111L // returns number of audio tracks
#define ED_TRANSCAP_LTC_TRACK ED_BASE+112L // returns track number of LTC timecode track.
// ED_ALL means no dedicated timecode track
#define ED_TRANSCAP_NEEDS_TBC ED_BASE+113L // devices output not stable
#define ED_TRANSCAP_NEEDS_CUEING ED_BASE+114L // device must be cued prior to performing edit
#define ED_TRANSCAP_CAN_INSERT ED_BASE+115L
#define ED_TRANSCAP_CAN_ASSEMBLE ED_BASE+116L
#define ED_TRANSCAP_FIELD_STEP ED_BASE+117L // device responds to Frame Advance command by
// advancing one field
#define ED_TRANSCAP_CLOCK_INC_RATE ED_BASE+118L // VISCA command - keep for compatibility
#define ED_TRANSCAP_CAN_DETECT_LENGTH ED_BASE+119L
#define ED_TRANSCAP_CAN_FREEZE ED_BASE+120L
#define ED_TRANSCAP_HAS_TUNER ED_BASE+121L
#define ED_TRANSCAP_HAS_TIMER ED_BASE+122L
#define ED_TRANSCAP_HAS_CLOCK ED_BASE+123L
#define ED_TRANSCAP_MULTIPLE_EDITS ED_BASE+806L // OATRUE means device/filter can support
// multiple edit events
#define ED_TRANSCAP_IS_MASTER ED_BASE+807L // OATRUE means device is the master clock
// for synchronizing (this sets timecode-to-
// reference clock offset for editing)
#define ED_TRANSCAP_HAS_DT ED_BASE+814L // OATRUE means device has Dynamic Tracking
// IAMExtTransport Media States
#define ED_MEDIA_SPIN_UP ED_BASE+130L
#define ED_MEDIA_SPIN_DOWN ED_BASE+131L
#define ED_MEDIA_UNLOAD ED_BASE+132L
// IAMExtTransport Modes
#define ED_MODE_PLAY ED_BASE+200L
#define ED_MODE_STOP ED_BASE+201L
#define ED_MODE_FREEZE ED_BASE+202L // really "pause"
#define ED_MODE_THAW ED_BASE+203L
#define ED_MODE_FF ED_BASE+204L
#define ED_MODE_REW ED_BASE+205L
#define ED_MODE_RECORD ED_BASE+206L
#define ED_MODE_RECORD_STROBE ED_BASE+207L
#define ED_MODE_RECORD_FREEZE ED_BASE+808L // never "put", only "get"
#define ED_MODE_STEP ED_BASE+208L // same as "jog"
#define ED_MODE_STEP_FWD ED_BASE+208L // same as ED_MODE_STEP
#define ED_MODE_STEP_REV ED_BASE+809L
#define ED_MODE_SHUTTLE ED_BASE+209L
#define ED_MODE_EDIT_CUE ED_BASE+210L
#define ED_MODE_VAR_SPEED ED_BASE+211L
#define ED_MODE_PERFORM ED_BASE+212L // returned status only
#define ED_MODE_LINK_ON ED_BASE+280L
#define ED_MODE_LINK_OFF ED_BASE+281L
#define ED_MODE_NOTIFY_ENABLE ED_BASE+810L
#define ED_MODE_NOTIFY_DISABLE ED_BASE+811L
#define ED_MODE_SHOT_SEARCH ED_BASE+812L
// IAMTimecodeReader/Generator/Display defines
//
// Timecode Generator Mode params and values:
//
#define ED_TCG_TIMECODE_TYPE ED_BASE+400L // can be one of the following:
#define ED_TCG_SMPTE_LTC ED_BASE+401L
#define ED_TCG_SMPTE_VITC ED_BASE+402L
#define ED_TCG_MIDI_QF ED_BASE+403L
#define ED_TCG_MIDI_FULL ED_BASE+404L
#define ED_TCG_FRAMERATE ED_BASE+405L // can be one of the following:
#define ED_FORMAT_SMPTE_30 ED_BASE+406L
#define ED_FORMAT_SMPTE_30DROP ED_BASE+407L
#define ED_FORMAT_SMPTE_25 ED_BASE+408L
#define ED_FORMAT_SMPTE_24 ED_BASE+409L
#define ED_TCG_SYNC_SOURCE ED_BASE+410L // can be one of the following:
#define ED_TCG_VIDEO ED_BASE+411L
#define ED_TCG_READER ED_BASE+412L
#define ED_TCG_FREE ED_BASE+413L
#define ED_TCG_REFERENCE_SOURCE ED_BASE+414L // can have one these values:
// ED_TCG_FREE || ED_TCG_READER
// (for regen/jamsync)
// TimeCodeReader Mode params and values:
#define ED_TCR_SOURCE ED_BASE+416L // can be one of the following:
// ED_TCG (already defined)
#define ED_TCR_LTC ED_BASE+417L
#define ED_TCR_VITC ED_BASE+418L
#define ED_TCR_CT ED_BASE+419L // Control Track
#define ED_TCR_FTC ED_BASE+420L // File TimeCode - for file-based devices
// that wish they were transports
// ED_MODE_NOTIFY_ENABLE can be OATRUE or OAFALSE (defined in transport mode
// section of this file).
#define ED_TCR_LAST_VALUE ED_BASE+421L // for notification mode -
// successive calls to GetTimecode
// return the last read value
// TimeCode Display Mode params and values:
//
#define ED_TCD_SOURCE ED_BASE+422L // can be one of the following:
#define ED_TCR ED_BASE+423L
#define ED_TCG ED_BASE+424L
#define ED_TCD_SIZE ED_BASE+425L // can be one of the following:
#define ED_SMALL ED_BASE+426L
#define ED_MED ED_BASE+427L
#define ED_LARGE ED_BASE+428L
#define ED_TCD_POSITION ED_BASE+429L // can be one of the following:
#define ED_TOP 0x0001
#define ED_MIDDLE 0x0002
#define ED_BOTTOM 0x0004 // OR'd with
#define ED_LEFT 0x0100
#define ED_CENTER 0x0200
#define ED_RIGHT 0x0400
#define ED_TCD_INTENSITY ED_BASE+436L // can be one of the following:
#define ED_HIGH ED_BASE+437L
#define ED_LOW ED_BASE+438L
#define ED_TCD_TRANSPARENCY ED_BASE+439L // 0-4, 0 is opaque
#define ED_TCD_INVERT ED_BASE+440L // OATRUE=black on white
// OAFALSE=white on black
// IAMExtTransport defines
//
// Transport status, params and values
//
// IAMExtTransport Status items and and values:
#define ED_MODE ED_BASE+500L // see ED_MODE_xxx values above
#define ED_ERROR ED_BASE+501L
#define ED_LOCAL ED_BASE+502L
#define ED_RECORD_INHIBIT ED_BASE+503L
#define ED_SERVO_LOCK ED_BASE+504L
#define ED_MEDIA_PRESENT ED_BASE+505L
#define ED_MEDIA_LENGTH ED_BASE+506L
#define ED_MEDIA_SIZE ED_BASE+507L
#define ED_MEDIA_TRACK_COUNT ED_BASE+508L
#define ED_MEDIA_TRACK_LENGTH ED_BASE+509L
#define ED_MEDIA_SIDE ED_BASE+510L
#define ED_MEDIA_TYPE ED_BASE+511L // can be one of the following:
#define ED_MEDIA_VHS ED_BASE+512L
#define ED_MEDIA_SVHS ED_BASE+513L
#define ED_MEDIA_HI8 ED_BASE+514L
#define ED_MEDIA_UMATIC ED_BASE+515L
#define ED_MEDIA_DVC ED_BASE+516L
#define ED_MEDIA_1_INCH ED_BASE+517L
#define ED_MEDIA_D1 ED_BASE+518L
#define ED_MEDIA_D2 ED_BASE+519L
#define ED_MEDIA_D3 ED_BASE+520L
#define ED_MEDIA_D5 ED_BASE+521L
#define ED_MEDIA_DBETA ED_BASE+522L
#define ED_MEDIA_BETA ED_BASE+523L
#define ED_MEDIA_8MM ED_BASE+524L
#define ED_MEDIA_DDR ED_BASE+525L
#define ED_MEDIA_SX ED_BASE+813L
#define ED_MEDIA_OTHER ED_BASE+526L
#define ED_MEDIA_CLV ED_BASE+527L
#define ED_MEDIA_CAV ED_BASE+528L
#define ED_MEDIA_POSITION ED_BASE+529L
#define ED_LINK_MODE ED_BASE+530L // OATRUE if transport controls
// are linked to graph's RUN,
// STOP, and PAUSE methods
// IAMExtTransport Basic Parms
#define ED_TRANSBASIC_TIME_FORMAT ED_BASE+540L // can be one of the following:
#define ED_FORMAT_MILLISECONDS ED_BASE+541L
#define ED_FORMAT_FRAMES ED_BASE+542L
#define ED_FORMAT_REFERENCE_TIME ED_BASE+543L
#define ED_FORMAT_HMSF ED_BASE+547L
#define ED_FORMAT_TMSF ED_BASE+548L
#define ED_TRANSBASIC_TIME_REFERENCE ED_BASE+549L // can be one of the following:
#define ED_TIMEREF_TIMECODE ED_BASE+550L
#define ED_TIMEREF_CONTROL_TRACK ED_BASE+551L
#define ED_TIMEREF_INDEX ED_BASE+552L
#define ED_TRANSBASIC_SUPERIMPOSE ED_BASE+553L // enable/disable onscreen display
#define ED_TRANSBASIC_END_STOP_ACTION ED_BASE+554L // can be one of: ED_MODE_STOP |
// ED_MODE_REWIND | ED_MODE_FREEZE
#define ED_TRANSBASIC_RECORD_FORMAT ED_BASE+555L // can be one of the following:
#define ED_RECORD_FORMAT_SP ED_BASE+556L
#define ED_RECORD_FORMAT_LP ED_BASE+557L
#define ED_RECORD_FORMAT_EP ED_BASE+558L
#define ED_TRANSBASIC_STEP_COUNT ED_BASE+559L
#define ED_TRANSBASIC_STEP_UNIT ED_BASE+560L // can be one of the following:
#define ED_STEP_FIELD ED_BASE+561L
#define ED_STEP_FRAME ED_BASE+562L
#define ED_STEP_3_2 ED_BASE+563L
#define ED_TRANSBASIC_PREROLL ED_BASE+564L
#define ED_TRANSBASIC_RECPREROLL ED_BASE+565L
#define ED_TRANSBASIC_POSTROLL ED_BASE+566L
#define ED_TRANSBASIC_EDIT_DELAY ED_BASE+567L
#define ED_TRANSBASIC_PLAYTC_DELAY ED_BASE+568L
#define ED_TRANSBASIC_RECTC_DELAY ED_BASE+569L
#define ED_TRANSBASIC_EDIT_FIELD ED_BASE+570L
#define ED_TRANSBASIC_FRAME_SERVO ED_BASE+571L
#define ED_TRANSBASIC_CF_SERVO ED_BASE+572L
#define ED_TRANSBASIC_SERVO_REF ED_BASE+573L // can be one of the following:
#define ED_REF_EXTERNAL ED_BASE+574L
#define ED_REF_INPUT ED_BASE+575L
#define ED_REF_INTERNAL ED_BASE+576L
#define ED_REF_AUTO ED_BASE+577L
#define ED_TRANSBASIC_WARN_GL ED_BASE+578L
#define ED_TRANSBASIC_SET_TRACKING ED_BASE+579L // can be one of the following:
#define ED_TRACKING_PLUS ED_BASE+580L
#define ED_TRACKING_MINUS ED_BASE+581L
#define ED_TRACKING_RESET ED_BASE+582L
#define ED_TRANSBASIC_SET_FREEZE_TIMEOUT ED_BASE+583L
#define ED_TRANSBASIC_VOLUME_NAME ED_BASE+584L
#define ED_TRANSBASIC_BALLISTIC_1 ED_BASE+585L // space for proprietary data
#define ED_TRANSBASIC_BALLISTIC_2 ED_BASE+586L
#define ED_TRANSBASIC_BALLISTIC_3 ED_BASE+587L
#define ED_TRANSBASIC_BALLISTIC_4 ED_BASE+588L
#define ED_TRANSBASIC_BALLISTIC_5 ED_BASE+589L
#define ED_TRANSBASIC_BALLISTIC_6 ED_BASE+590L
#define ED_TRANSBASIC_BALLISTIC_7 ED_BASE+591L
#define ED_TRANSBASIC_BALLISTIC_8 ED_BASE+592L
#define ED_TRANSBASIC_BALLISTIC_9 ED_BASE+593L
#define ED_TRANSBASIC_BALLISTIC_10 ED_BASE+594L
#define ED_TRANSBASIC_BALLISTIC_11 ED_BASE+595L
#define ED_TRANSBASIC_BALLISTIC_12 ED_BASE+596L
#define ED_TRANSBASIC_BALLISTIC_13 ED_BASE+597L
#define ED_TRANSBASIC_BALLISTIC_14 ED_BASE+598L
#define ED_TRANSBASIC_BALLISTIC_15 ED_BASE+599L
#define ED_TRANSBASIC_BALLISTIC_16 ED_BASE+600L
#define ED_TRANSBASIC_BALLISTIC_17 ED_BASE+601L
#define ED_TRANSBASIC_BALLISTIC_18 ED_BASE+602L
#define ED_TRANSBASIC_BALLISTIC_19 ED_BASE+603L
#define ED_TRANSBASIC_BALLISTIC_20 ED_BASE+604L
// consumer VCR items
#define ED_TRANSBASIC_SETCLOCK ED_BASE+605L
#define ED_TRANSBASIC_SET_COUNTER_FORMAT ED_BASE+606L // uses time format flags
#define ED_TRANSBASIC_SET_COUNTER_VALUE ED_BASE+607L
#define ED_TRANSBASIC_SETTUNER_CH_UP ED_BASE+608L
#define ED_TRANSBASIC_SETTUNER_CH_DN ED_BASE+609L
#define ED_TRANSBASIC_SETTUNER_SK_UP ED_BASE+610L
#define ED_TRANSBASIC_SETTUNER_SK_DN ED_BASE+611L
#define ED_TRANSBASIC_SETTUNER_CH ED_BASE+612L
#define ED_TRANSBASIC_SETTUNER_NUM ED_BASE+613L
#define ED_TRANSBASIC_SETTIMER_EVENT ED_BASE+614L
#define ED_TRANSBASIC_SETTIMER_STARTDAY ED_BASE+615L
#define ED_TRANSBASIC_SETTIMER_STARTTIME ED_BASE+616L
#define ED_TRANSBASIC_SETTIMER_STOPDAY ED_BASE+617L
#define ED_TRANSBASIC_SETTIMER_STOPTIME ED_BASE+618L
// IAMExtTransport video parameters
#define ED_TRANSVIDEO_SET_OUTPUT ED_BASE+630L // can be one of the following:
#define ED_E2E ED_BASE+631L
#define ED_PLAYBACK ED_BASE+632L
#define ED_OFF ED_BASE+633L
#define ED_TRANSVIDEO_SET_SOURCE ED_BASE+634L
// IAMExtTransport audio parameters
#define ED_TRANSAUDIO_ENABLE_OUTPUT ED_BASE+640L // can be the following:
#define ED_AUDIO_ALL 0x10000000 // or any of the following OR'd together
#define ED_AUDIO_1 0x0000001L
#define ED_AUDIO_2 0x0000002L
#define ED_AUDIO_3 0x0000004L
#define ED_AUDIO_4 0x0000008L
#define ED_AUDIO_5 0x0000010L
#define ED_AUDIO_6 0x0000020L
#define ED_AUDIO_7 0x0000040L
#define ED_AUDIO_8 0x0000080L
#define ED_AUDIO_9 0x0000100L
#define ED_AUDIO_10 0x0000200L
#define ED_AUDIO_11 0x0000400L
#define ED_AUDIO_12 0x0000800L
#define ED_AUDIO_13 0x0001000L
#define ED_AUDIO_14 0x0002000L
#define ED_AUDIO_15 0x0004000L
#define ED_AUDIO_16 0x0008000L
#define ED_AUDIO_17 0x0010000L
#define ED_AUDIO_18 0x0020000L
#define ED_AUDIO_19 0x0040000L
#define ED_AUDIO_20 0x0080000L
#define ED_AUDIO_21 0x0100000L
#define ED_AUDIO_22 0x0200000L
#define ED_AUDIO_23 0x0400000L
#define ED_AUDIO_24 0x0800000L
#define ED_VIDEO 0x2000000L // for Edit props below
#define ED_TRANSAUDIO_ENABLE_RECORD ED_BASE+642L
#define ED_TRANSAUDIO_ENABLE_SELSYNC ED_BASE+643L
#define ED_TRANSAUDIO_SET_SOURCE ED_BASE+644L
#define ED_TRANSAUDIO_SET_MONITOR ED_BASE+645L
// Edit Property Set-related defs
// The following values reflect (and control) the state of an
// edit property set
#define ED_INVALID ED_BASE+652L
#define ED_EXECUTING ED_BASE+653L
#define ED_REGISTER ED_BASE+654L
#define ED_DELETE ED_BASE+655L
// Edit property set parameters and values
#define ED_EDIT_HEVENT ED_BASE+656L // event handle to signal event
// completion
#define ED_EDIT_TEST ED_BASE+657L // returns OAFALSE if filter thinks
// edit can be done, OATRUE if not
#define ED_EDIT_IMMEDIATE ED_BASE+658L // OATRUE means start put the
// device into edit mode (editing
// "on the fly") immediately upon
// execution of Mode(ED_MODE_EDIT_CUE)
#define ED_EDIT_MODE ED_BASE+659L
// can be one of the following values:
#define ED_EDIT_MODE_ASSEMBLE ED_BASE+660L
#define ED_EDIT_MODE_INSERT ED_BASE+661L
#define ED_EDIT_MODE_CRASH_RECORD ED_BASE+662L
#define ED_EDIT_MODE_BOOKMARK_TIME ED_BASE+663L // these two are for
#define ED_EDIT_MODE_BOOKMARK_CHAPTER ED_BASE+664L // laserdisks
#define ED_EDIT_MASTER ED_BASE+666L // OATRUE causes device
// not to synchronize
#define ED_EDIT_TRACK ED_BASE+667L
// can be one of the following possible OR'd values:
// ED_VIDEO, ED_AUDIO_1 thru ED_AUDIO_24 (or ED_AUDIO_ALL)
#define ED_EDIT_SRC_INPOINT ED_BASE+668L // in current time format
#define ED_EDIT_SRC_OUTPOINT ED_BASE+669L // in current time format
#define ED_EDIT_REC_INPOINT ED_BASE+670L // in current time format
#define ED_EDIT_REC_OUTPOINT ED_BASE+671L // in current time format
#define ED_EDIT_REHEARSE_MODE ED_BASE+672L
// can be one of the following possible values:
#define ED_EDIT_BVB ED_BASE+673L // means rehearse the edit with
// "black-video-black"
#define ED_EDIT_VBV ED_BASE+674L
#define ED_EDIT_VVV ED_BASE+675L
#define ED_EDIT_PERFORM ED_BASE+676L // means perform the edit with no
// rehearsal.
// Set this property to OATRUE to kill the edit if in progress
#define ED_EDIT_ABORT ED_BASE+677L
// how long to wait for edit to complete
#define ED_EDIT_TIMEOUT ED_BASE+678L // in current time format
// This property causes the device to seek to a point specified by
// ED_EDIT_SEEK_MODE (see below). NOTE: Only one event at a time can seek.
#define ED_EDIT_SEEK ED_BASE+679L // OATRUE means do it now.
#define ED_EDIT_SEEK_MODE ED_BASE+680L
//possible values:
#define ED_EDIT_SEEK_EDIT_IN ED_BASE+681L // seek to edit's inpoint
#define ED_EDIT_SEEK_EDIT_OUT ED_BASE+682L // seek to edit's outpoint
#define ED_EDIT_SEEK_PREROLL ED_BASE+683L // seek to edit's
// inpoint-preroll
#define ED_EDIT_SEEK_PREROLL_CT ED_BASE+684L // seek to preroll point
// using control track (used for tapes with
// discontinuoustimecode before edit point: seek
// to inpoint using timecode, then backup to
// preroll point using control track)
#define ED_EDIT_SEEK_BOOKMARK ED_BASE+685L // seek to bookmark (just like
// timecode search)
// This property is used for multiple-VCR systems where each machine must
// cue to a different location relative to the graph's reference clock. The
// basic idea is that an edit event is setup with an ED_EDIT_OFFSET property
// that tells the VCR what offset to maintain between it's timecode (converted
// to reference clock units) and the reference clock.
#define ED_EDIT_OFFSET ED_BASE+686L // in current time format
#define ED_EDIT_PREREAD ED_BASE+815L // OATRUE means device supports
// pre-read (recorder can also be
// player
//
// Some error codes:
//
// device could be in local mode
#define ED_ERR_DEVICE_NOT_READY ED_BASE+700L
#endif // __EDEVDEFS__
// eof edevdefs.h

View File

@ -1,47 +0,0 @@
//------------------------------------------------------------------------------
// File: Errors.h
//
// Desc: ActiveMovie error defines.
//
// Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __ERRORS__
#define __ERRORS__
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#ifndef _AMOVIE_
#define AMOVIEAPI DECLSPEC_IMPORT
#else
#define AMOVIEAPI
#endif
// codes 0-01ff are reserved for OLE
#define VFW_FIRST_CODE 0x200
#define MAX_ERROR_TEXT_LEN 160
#include <VFWMSGS.H> // includes all message definitions
typedef BOOL (WINAPI* AMGETERRORTEXTPROCA)(HRESULT, char *, DWORD);
typedef BOOL (WINAPI* AMGETERRORTEXTPROCW)(HRESULT, WCHAR *, DWORD);
AMOVIEAPI DWORD WINAPI AMGetErrorTextA( HRESULT hr , char *pbuffer , DWORD MaxLen);
AMOVIEAPI DWORD WINAPI AMGetErrorTextW( HRESULT hr , WCHAR *pbuffer , DWORD MaxLen);
#ifdef UNICODE
#define AMGetErrorText AMGetErrorTextW
typedef AMGETERRORTEXTPROCW AMGETERRORTEXTPROC;
#else
#define AMGetErrorText AMGetErrorTextA
typedef AMGETERRORTEXTPROCA AMGETERRORTEXTPROC;
#endif
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __ERRORS__

View File

@ -1,428 +0,0 @@
//------------------------------------------------------------------------------
// File: EvCode.h
//
// Desc: List of standard Quartz event codes and the expected params.
//
// Copyright (c) 1992 - 2001, Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// Event codes are broken into two groups
// -- system event codes
// -- extension event codes
// All system event codes are below EC_USER
#define EC_SYSTEMBASE 0x00
#define EC_USER 0x8000
// System-defined event codes
// ==========================
//
// There are three types of system-defined event codes:
//
// 1. Those which are always passed through to the application
// (To be collected by calls to GetEvent or within WaitForCompletion.)
// (e.g. EC_ERRORABORT, EC_USERABORT.)
//
// 2. Those which are pure internal and will never be passed to
// the application. (e.g. EC_SHUTDOWN)
//
// 3. Those which have default handling. Default handing implies that
// the event is not passed to the application. However, default
// handling may be canceled by calling
// IMediaEvent::CancelDefaultHandling. If the default handling is
// cancelled in this way, then the message will be delivered to the
// application and the application must action it appropriately.
// Default handling can be restored by calling RestoreDefaultHandling.
//
// We will refer to these events as application, internal and defaulted
// events respectively.
//
// System-defined events may have interface pointers, BSTR's, etc passed
// as parameters. It is therefore essential that, for any message
// retrieved using GetEvent, a matching call to FreeEventParams is made
// to ensure that relevant interfaces are released and storage freed.
// Failure to call FreeEventParams will result in memory leaks, if not
// worse.
//
// Filters sending these messages to the filter graph should not AddRef()
// any interfaces that they may pass as parameters. The filter graph
// manager will AddRef them if required. E.g. if the event is to be queued
// for the application or queued to a worker thread.
// Each event listed below is immediately followed by a parameter list
// detailing the types of the parameters associated with the message,
// and an indication of whether the message is an application, internal
// or defaulted message. This is then followed by a short description.
// The use of "void" in the parameter list implies that the parameter is not
// used. Such parameters should be zero.
// Other defined EC_ regions:
// DVD event codes 0x0100 - 0x0150 (dvdevcod.h)
// audio device event codes 0x0200 - 0x0250 (audevcod.h)
// WindowsMedia SDK-originated events 0x0251 - 0x0300 (see below)
// MSVIDCTL 0x0301 - 0x0325 (msvidctl.idl)
// stream buffer engine (PVR) 0x0326 - 0x0350 (sbe.idl)
#define EC_COMPLETE 0x01
// ( HRESULT, void ) : defaulted (special)
// Signals the completed playback of a stream within the graph. This message
// is sent by renderers when they receive end-of-stream. The default handling
// of this message results in a _SINGLE_ EC_COMPLETE being sent to the
// application when ALL of the individual renderers have signaled EC_COMPLETE
// to the filter graph. If the default handing is canceled, the application
// will see all of the individual EC_COMPLETEs.
#define EC_USERABORT 0x02
// ( void, void ) : application
// In some sense, the user has requested that playback be terminated.
// This message is typically sent by renderers that render into a
// window if the user closes the window into which it was rendering.
// It is up to the application to decide if playback should actually
// be stopped.
#define EC_ERRORABORT 0x03
// ( HRESULT, void ) : application
// Operation aborted because of error
#define EC_TIME 0x04
// ( DWORD, DWORD ) : application
// The requested reference time occurred. (This event is currently not used).
// lParam1 is low dword of ref time, lParam2 is high dword of reftime.
#define EC_REPAINT 0x05
// ( IPin * (could be NULL), void ) : defaulted
// A repaint is required - lParam1 contains the (IPin *) that needs the data
// to be sent again. Default handling is: if the output pin which the IPin is
// attached to supports the IMediaEventSink interface then it will be called
// with the EC_REPAINT first. If that fails then normal repaint processing is
// done by the filter graph.
// Stream error notifications
#define EC_STREAM_ERROR_STOPPED 0x06
#define EC_STREAM_ERROR_STILLPLAYING 0x07
// ( HRESULT, DWORD ) : application
// lParam 1 is major code, lParam2 is minor code, either may be zero.
#define EC_ERROR_STILLPLAYING 0x08
// ( HRESULT, void ) : application
// The filter graph manager may issue Run's to the graph asynchronously.
// If such a Run fails, EC_ERROR_STILLPLAYING is issued to notify the
// application of the failure. The state of the underlying filters
// at such a time will be indeterminate - they will all have been asked
// to run, but some are almost certainly not.
#define EC_PALETTE_CHANGED 0x09
// ( void, void ) : application
// notify application that the video palette has changed
#define EC_VIDEO_SIZE_CHANGED 0x0A
// ( DWORD, void ) : application
// Sent by video renderers.
// Notifies the application that the native video size has changed.
// LOWORD of the DWORD is the new width, HIWORD is the new height.
#define EC_QUALITY_CHANGE 0x0B
// ( void, void ) : application
// Notify application that playback degradation has occurred
#define EC_SHUTTING_DOWN 0x0C
// ( void, void ) : internal
// This message is sent by the filter graph manager to any plug-in
// distributors which support IMediaEventSink to notify them that
// the filter graph is starting to shutdown.
#define EC_CLOCK_CHANGED 0x0D
// ( void, void ) : application
// Notify application that the clock has changed.
// (i.e. SetSyncSource has been called on the filter graph and has been
// distributed successfully to the filters in the graph.)
#define EC_PAUSED 0x0E
// ( HRESULT, void ) : application
// Notify application the previous pause request has completed
#define EC_OPENING_FILE 0x10
#define EC_BUFFERING_DATA 0x11
// ( BOOL, void ) : application
// lParam1 == 1 --> starting to open file or buffer data
// lParam1 == 0 --> not opening or buffering any more
// (This event does not appear to be used by ActiveMovie.)
#define EC_FULLSCREEN_LOST 0x12
// ( void, IBaseFilter * ) : application
// Sent by full screen renderers when switched away from full screen.
// IBaseFilter may be NULL.
#define EC_ACTIVATE 0x13
// ( BOOL, IBaseFilter * ) : internal
// Sent by video renderers when they lose or gain activation.
// lParam1 is set to 1 if gained or 0 if lost
// lParam2 is the IBaseFilter* for the filter that is sending the message
// Used for sound follows focus and full-screen switching
#define EC_NEED_RESTART 0x14
// ( void, void ) : defaulted
// Sent by renderers when they regain a resource (e.g. audio renderer).
// Causes a restart by Pause/put_Current/Run (if running).
#define EC_WINDOW_DESTROYED 0x15
// ( IBaseFilter *, void ) : internal
// Sent by video renderers when the window has been destroyed. Handled
// by the filter graph / distributor telling the resource manager.
// lParam1 is the IBaseFilter* of the filter whose window is being destroyed
#define EC_DISPLAY_CHANGED 0x16
// ( IPin *, void ) : internal
// Sent by renderers when they detect a display change. the filter graph
// will arrange for the graph to be stopped and the pin send in lParam1
// to be reconnected. by being reconnected it allows a renderer to reset
// and connect with a more appropriate format for the new display mode
// lParam1 contains an (IPin *) that should be reconnected by the graph
#define EC_STARVATION 0x17
// ( void, void ) : defaulted
// Sent by a filter when it detects starvation. Default handling (only when
// running) is for the graph to be paused until all filters enter the
// paused state and then run. Normally this would be sent by a parser or source
// filter when too little data is arriving.
#define EC_OLE_EVENT 0x18
// ( BSTR, BSTR ) : application
// Sent by a filter to pass a text string to the application.
// Conventionally, the first string is a type, and the second a parameter.
#define EC_NOTIFY_WINDOW 0x19
// ( HWND, void ) : internal
// Pass the window handle around during pin connection.
#define EC_STREAM_CONTROL_STOPPED 0x1A
// ( IPin * pSender, DWORD dwCookie )
// Notification that an earlier call to IAMStreamControl::StopAt
// has now take effect. Calls to the method can be marked
// with a cookie which is passed back in the second parameter,
// allowing applications to easily tie together request
// and completion notifications.
//
// NB: IPin will point to the pin that actioned the Stop. This
// may not be the pin that the StopAt was sent to.
#define EC_STREAM_CONTROL_STARTED 0x1B
// ( IPin * pSender, DWORD dwCookie )
// Notification that an earlier call to IAMStreamControl::StartAt
// has now take effect. Calls to the method can be marked
// with a cookie which is passed back in the second parameter,
// allowing applications to easily tie together request
// and completion notifications.
//
// NB: IPin will point to the pin that actioned the Start. This
// may not be the pin that the StartAt was sent to.
#define EC_END_OF_SEGMENT 0x1C
//
// ( const REFERENCE_TIME *pStreamTimeAtEndOfSegment, DWORD dwSegmentNumber )
//
// pStreamTimeAtEndOfSegment
// pointer to the accumulated stream clock
// time since the start of the segment - this is directly computable
// as the sum of the previous and current segment durations (Stop - Start)
// and the rate applied to each segment
// The source add this time to the time within each segment to get
// a total elapsed time
//
// dwSegmentNumber
// Segment number - starts at 0
//
// Notifies that a segment end has been reached when the
// AM_SEEKING_Segment flags was set for IMediaSeeking::SetPositions
// Passes in an IMediaSeeking interface to allow the next segment
// to be defined by the application
#define EC_SEGMENT_STARTED 0x1D
//
// ( const REFERENCE_TIME *pStreamTimeAtStartOfSegment, DWORD dwSegmentNumber)
//
// pStreamTimeAtStartOfSegment
// pointer to the accumulated stream clock
// time since the start of the segment - this is directly computable
// as the sum of the previous segment durations (Stop - Start)
// and the rate applied to each segment
//
// dwSegmentNumber
// Segment number - starts at 0
//
// Notifies that a new segment has been started.
// This is sent synchronously by any entity that will issue
// EC_END_OF_SEGMENT when a new segment is started
// (See IMediaSeeking::SetPositions - AM_SEEKING_Segment flag)
// It is used to compute how many EC_END_OF_SEGMENT notifications
// to expect at the end of a segment and as a consitency check
#define EC_LENGTH_CHANGED 0x1E
// (void, void)
// sent to indicate that the length of the "file" has changed
#define EC_DEVICE_LOST 0x1f
// (IUnknown, 0)
//
// request window notification when the device is available again
// (through WM_DEVICECHANGED messages registered with
// RegisterDeviceNotification; see IAMDeviceRemoval interface)
#define EC_STEP_COMPLETE 0x24
// (BOOL bCacelled, void)
// Step request complete
// if bCancelled is TRUE the step was cancelled. This can happen
// if the application issued some control request or because there
// was a mode change etc etc
// Event code 25 is reserved for future use.
#define EC_TIMECODE_AVAILABLE 0x30
// Sent by filter supporting timecode
// Param1 has a pointer to the sending object
// Param2 has the device ID of the sending object
#define EC_EXTDEVICE_MODE_CHANGE 0x31
// Sent by filter supporting IAMExtDevice
// Param1 has the new mode
// Param2 has the device ID of the sending object
#define EC_STATE_CHANGE 0x32
// ( FILTER_STATE, BOOL bInternal)
// Used to notify the application of any state changes in the filter graph.
// lParam1 is of type enum FILTER_STATE (defined in strmif.h) and indicates
// the state of the filter graph.
//
// lParam2 == 0 indicates that the previous state change request has completed
// & a change in application state.
// lParam2 == 1 reserved for future use to indicate internal state changes.
#define EC_GRAPH_CHANGED 0x50
// Sent by filter to notify interesting graph changes
#define EC_CLOCK_UNSET 0x51
// ( void, void ) : application
// Used to notify the filter graph to unset the current graph clock.
// Has the affect of forcing the filter graph to reestablish the graph clock
// on the next Pause/Run (note that this is only used by ksproxy, when the pin
// of a clock providing filter is disconnected)
#define EC_VMR_RENDERDEVICE_SET 0x53
// (Render_Device type, void)
// Identifies the type of rendering mechanism the VMR
// is using to display video. Types used include:
#define VMR_RENDER_DEVICE_OVERLAY 0x01
#define VMR_RENDER_DEVICE_VIDMEM 0x02
#define VMR_RENDER_DEVICE_SYSMEM 0x04
#define EC_VMR_SURFACE_FLIPPED 0x54
// (hr - Flip return code, void)
// Identifies the VMR's allocator-presenter has called the DDraw flip api on
// the surface being presented. This allows the VMR to keep its DX-VA table
// of DDraw surfaces in sync with DDraws flipping chain.
#define EC_VMR_RECONNECTION_FAILED 0x55
// (hr - ReceiveConnection return code, void)
// Identifies that an upstream decoder tried to perform a dynamic format
// change and the VMR was unable to accept the new format.
#define EC_PREPROCESS_COMPLETE 0x56
// Sent by the WM ASF writer filter (WMSDK V9 version) to signal the completion
// of a pre-process run when running in multipass encode mode.
// Param1 = 0, Param2 = IBaseFilter ptr of sending filter
#define EC_CODECAPI_EVENT 0x57
// Sent by the Codec API when an event is encountered. Both the Data
// must be freed by the recipient using CoTaskMemFree
// Param1 = UserDataPointer, Param2 = VOID* Data
//------------------------------------------
//
// BDA events:
//
// Event code 0x80 through 0x8f are reserved for BDA
//
//------------------------------------------
//
// WindowsMedia SDK filter-specific events:
//
//
// Note that for EC_WMT_EVENT events the wmsdk-based filters use the following structure for
// passing event parameters to the app:
#ifndef AM_WMT_EVENT_DATA_DEFINED
#define AM_WMT_EVENT_DATA_DEFINED
typedef struct {
HRESULT hrStatus; // status code
void * pData; // event data
} AM_WMT_EVENT_DATA;
#endif
//
#define EC_WMT_EVENT_BASE 0x0251
//
#define EC_WMT_INDEX_EVENT EC_WMT_EVENT_BASE
// WindowsMedia SDK-originated file indexing status, sent by WMSDK-based filters
//
// lParam1 is one of the enum WMT_STATUS messages listed below, sent by the WindowsMedia SDK
// lParam2 is specific to the lParam event
//
// the following WMT_STATUS messages are sent for this event:
// WMT_STARTED - lParam2 is 0
// WMT_CLOSED - lParam2 is 0
// WMT_INDEX_PROGRESS - lParam2 is a DWORD containing the progress percent complete
//
#define EC_WMT_EVENT EC_WMT_EVENT_BASE+1
// WindowsMedia SDK-originated event, sent by WMSDK-based filters
//
// lParam1 is one of the enum WMT_STATUS messages listed below, sent by the WindowsMedia SDK
// lParam2 is a pointer an AM_WMT_EVENT_DATA structure where,
// hrStatus is the status code sent by the wmsdk
// pData is specific to the lParam1 event
//
// the following WMT_STATUS messages are sent by the WMSDK Reader filter for this event:
// WMT_NO_RIGHTS - pData is a pointer to a WCHAR string containing a challenge URL
// WMT_ACQUIRE_LICENSE - lParam2 is a pointer to a WM_GET_LICENSE_DATA struct
// WMT_NO_RIGHTS_EX - lParam2 is a pointer to a WM_GET_LICENSE_DATA struct
// WMT_NEEDS_INDIVIDUALIZATION - lParam2 is NULL
// WMT_INDIVIDUALIZE - lParam2 is a pointer to a WM_INDIVIDUALIZE_STATUS struct
// the WMSDK (V9) ASF Writer filter will send this event in response to a wmsdk-signaled error during file
// writing, along with the wmsdk WMT_STATUS error as the lParam1 and hrStatus embedded in the
// AM_WMT_EVENT_DATA struct pointed to by the lParam2 pointer.
//
// end WMSDK-originated events
//-----------------------------------------
#define EC_BUILT 0x300
// Sent to notify transition from unbuilt to built state
#define EC_UNBUILT 0x301
// Sent to notify transtion from built to unbuilt state

View File

@ -1,101 +0,0 @@
//------------------------------------------------------------------------------
// File: FourCC.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// FOURCCMap
//
// provides a mapping between old-style multimedia format DWORDs
// and new-style GUIDs.
//
// A range of 4 billion GUIDs has been allocated to ensure that this
// mapping can be done straightforwardly one-to-one in both directions.
//
// January 95
#ifndef __FOURCC__
#define __FOURCC__
// Multimedia format types are marked with DWORDs built from four 8-bit
// chars and known as FOURCCs. New multimedia AM_MEDIA_TYPE definitions include
// a subtype GUID. In order to simplify the mapping, GUIDs in the range:
// XXXXXXXX-0000-0010-8000-00AA00389B71
// are reserved for FOURCCs.
class FOURCCMap : public GUID
{
public:
FOURCCMap();
FOURCCMap(DWORD Fourcc);
FOURCCMap(const GUID *);
DWORD GetFOURCC(void);
void SetFOURCC(DWORD fourcc);
void SetFOURCC(const GUID *);
private:
void InitGUID();
};
#define GUID_Data2 0
#define GUID_Data3 0x10
#define GUID_Data4_1 0xaa000080
#define GUID_Data4_2 0x719b3800
inline void
FOURCCMap::InitGUID() {
Data2 = GUID_Data2;
Data3 = GUID_Data3;
((DWORD *)Data4)[0] = GUID_Data4_1;
((DWORD *)Data4)[1] = GUID_Data4_2;
}
inline
FOURCCMap::FOURCCMap() {
InitGUID();
SetFOURCC( DWORD(0));
}
inline
FOURCCMap::FOURCCMap(DWORD fourcc)
{
InitGUID();
SetFOURCC(fourcc);
}
inline
FOURCCMap::FOURCCMap(const GUID * pGuid)
{
InitGUID();
SetFOURCC(pGuid);
}
inline void
FOURCCMap::SetFOURCC(const GUID * pGuid)
{
FOURCCMap * p = (FOURCCMap*) pGuid;
SetFOURCC(p->GetFOURCC());
}
inline void
FOURCCMap::SetFOURCC(DWORD fourcc)
{
Data1 = fourcc;
}
inline DWORD
FOURCCMap::GetFOURCC(void)
{
return Data1;
}
#endif /* __FOURCC__ */

View File

@ -1,222 +0,0 @@
//------------------------------------------------------------------------------
// File: Measure.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
/*
The idea is to pepper the source code with interesting measurements and
have the last few thousand of these recorded in a circular buffer that
can be post-processed to give interesting numbers.
WHAT THE LOG LOOKS LIKE:
Time (sec) Type Delta Incident_Name
0.055,41 NOTE -. Incident Nine - Another note
0.055,42 NOTE 0.000,01 Incident Nine - Another note
0.055,44 NOTE 0.000,02 Incident Nine - Another note
0.055,45 STOP -. Incident Eight - Also random
0.055,47 START -. Incident Seven - Random
0.055,49 NOTE 0.000,05 Incident Nine - Another note
------- <etc. there is a lot of this> ----------------
0.125,60 STOP 0.000,03 Msr_Stop
0.125,62 START -. Msr_Start
0.125,63 START -. Incident Two - Start/Stop
0.125,65 STOP 0.000,03 Msr_Start
0.125,66 START -. Msr_Stop
0.125,68 STOP 0.000,05 Incident Two - Start/Stop
0.125,70 STOP 0.000,04 Msr_Stop
0.125,72 START -. Msr_Start
0.125,73 START -. Incident Two - Start/Stop
0.125,75 STOP 0.000,03 Msr_Start
0.125,77 START -. Msr_Stop
0.125,78 STOP 0.000,05 Incident Two - Start/Stop
0.125,80 STOP 0.000,03 Msr_Stop
0.125,81 NOTE -. Incident Three - single Note
0.125,83 START -. Incident Four - Start, no stop
0.125,85 START -. Incident Five - Single Start/Stop
0.125,87 STOP 0.000,02 Incident Five - Single Start/Stop
Number Average StdDev Smallest Largest Incident_Name
10 0.000,58 0.000,10 0.000,55 0.000,85 Incident One - Note
50 0.000,05 0.000,00 0.000,05 0.000,05 Incident Two - Start/Stop
1 -. -. -. -. Incident Three - single Note
0 -. -. -. -. Incident Four - Start, no stop
1 0.000,02 -. 0.000,02 0.000,02 Incident Five - Single Start/Stop
0 -. -. -. -. Incident Six - zero occurrences
100 0.000,25 0.000,12 0.000,02 0.000,62 Incident Seven - Random
100 0.000,79 0.000,48 0.000,02 0.001,92 Incident Eight - Also random
5895 0.000,01 0.000,01 0.000,01 0.000,56 Incident Nine - Another note
10 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Note
50 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Start
50 0.000,04 0.000,03 0.000,03 0.000,31 Msr_Stop
WHAT IT MEANS:
The log shows what happened and when. Each line shows the time at which
something happened (see WHAT YOU CODE below) what it was that happened
and (if approporate) the time since the corresponding previous event
(that's the delta column).
The statistics show how many times each event occurred, what the average
delta time was, also the standard deviation, largest and smalles delta.
WHAT YOU CODE:
Before anything else executes: - register your ids
int id1 = Msr_Register("Incident One - Note");
int id2 = Msr_Register("Incident Two - Start/Stop");
int id3 = Msr_Register("Incident Three - single Note");
etc.
At interesting moments:
// To measure a repetitive event - e.g. end of bitblt to screen
Msr_Note(Id9); // e.g. "video frame hiting the screen NOW!"
or
// To measure an elapsed time e.g. time taken to decode an MPEG B-frame
Msr_Start(Id2); // e.g. "Starting to decode MPEG B-frame"
. . .
MsrStop(Id2); // "Finished MPEG decode"
At the end:
HANDLE hFile;
hFile = CreateFile("Perf.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
Msr_Dump(hFile); // This writes the log out to the file
CloseHandle(hFile);
or
Msr_Dump(NULL); // This writes it to DbgLog((LOG_TRACE,0, ... ));
// but if you are writing it out to the debugger
// then the times are probably all garbage because
// the debugger can make things run awfully slow.
A given id should be used either for start / stop or Note calls. If Notes
are mixed in with Starts and Stops their statistics will be gibberish.
If you code the calls in upper case i.e. MSR_START(idMunge); then you get
macros which will turn into nothing unless PERF is defined.
You can reset the statistical counts for a given id by calling Reset(Id).
They are reset by default at the start.
It logs Reset as a special incident, so you can see it in the log.
The log is a circular buffer in storage (to try to minimise disk I/O).
It overwrites the oldest entries once full. The statistics include ALL
incidents since the last Reset, whether still visible in the log or not.
*/
#ifndef __MEASURE__
#define __MEASURE__
#ifdef PERF
#define MSR_INIT() Msr_Init()
#define MSR_TERMINATE() Msr_Terminate()
#define MSR_REGISTER(a) Msr_Register(a)
#define MSR_RESET(a) Msr_Reset(a)
#define MSR_CONTROL(a) Msr_Control(a)
#define MSR_START(a) Msr_Start(a)
#define MSR_STOP(a) Msr_Stop(a)
#define MSR_NOTE(a) Msr_Note(a)
#define MSR_INTEGER(a,b) Msr_Integer(a,b)
#define MSR_DUMP(a) Msr_Dump(a)
#define MSR_DUMPSTATS(a) Msr_DumpStats(a)
#else
#define MSR_INIT() ((void)0)
#define MSR_TERMINATE() ((void)0)
#define MSR_REGISTER(a) 0
#define MSR_RESET(a) ((void)0)
#define MSR_CONTROL(a) ((void)0)
#define MSR_START(a) ((void)0)
#define MSR_STOP(a) ((void)0)
#define MSR_NOTE(a) ((void)0)
#define MSR_INTEGER(a,b) ((void)0)
#define MSR_DUMP(a) ((void)0)
#define MSR_DUMPSTATS(a) ((void)0)
#endif
#ifdef __cplusplus
extern "C" {
#endif
// This must be called first - (called by the DllEntry)
void WINAPI Msr_Init(void);
// Call this last to clean up (or just let it fall off the end - who cares?)
void WINAPI Msr_Terminate(void);
// Call this to get an Id for an "incident" that you can pass to Start, Stop or Note
// everything that's logged is called an "incident".
int WINAPI Msr_Register(LPTSTR Incident);
// Reset the statistical counts for an incident
void WINAPI Msr_Reset(int Id);
// Reset all the counts for all incidents
#define MSR_RESET_ALL 0
#define MSR_PAUSE 1
#define MSR_RUN 2
void WINAPI Msr_Control(int iAction);
// log the start of an operation
void WINAPI Msr_Start(int Id);
// log the end of an operation
void WINAPI Msr_Stop(int Id);
// log a one-off or repetitive operation
void WINAPI Msr_Note(int Id);
// log an integer (on which we can see statistics later)
void WINAPI Msr_Integer(int Id, int n);
// print out all the vaialable log (it may have wrapped) and then the statistics.
// When the log wraps you lose log but the statistics are still complete.
// hFIle==NULL => use DbgLog
// otherwise hFile must have come from CreateFile or OpenFile.
void WINAPI Msr_Dump(HANDLE hFile);
// just dump the statistics - never mind the log
void WINAPI Msr_DumpStats(HANDLE hFile);
// Type definitions in case you want to declare a pointer to the dump functions
// (makes it a trifle easier to do dynamic linking
// i.e. LoadModule, GetProcAddress and call that)
// Typedefs so can declare MSR_DUMPPROC *MsrDumpStats; or whatever
typedef void WINAPI MSR_DUMPPROC(HANDLE hFile);
typedef void WINAPI MSR_CONTROLPROC(int iAction);
#ifdef __cplusplus
}
#endif
#endif // __MEASURE__

View File

@ -1,120 +0,0 @@
//------------------------------------------------------------------------------
// File: MsgThrd.h
//
// Desc: DirectShow base classes - provides support for a worker thread
// class to which one can asynchronously post messages.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// Message class - really just a structure.
//
class CMsg {
public:
UINT uMsg;
DWORD dwFlags;
LPVOID lpParam;
CAMEvent *pEvent;
CMsg(UINT u, DWORD dw, LPVOID lp, CAMEvent *pEvnt)
: uMsg(u), dwFlags(dw), lpParam(lp), pEvent(pEvnt) {}
CMsg()
: uMsg(0), dwFlags(0L), lpParam(NULL), pEvent(NULL) {}
};
// This is the actual thread class. It exports all the usual thread control
// functions. The created thread is different from a normal WIN32 thread in
// that it is prompted to perform particaular tasks by responding to messages
// posted to its message queue.
//
class AM_NOVTABLE CMsgThread {
private:
static DWORD WINAPI DefaultThreadProc(LPVOID lpParam);
DWORD m_ThreadId;
HANDLE m_hThread;
protected:
// if you want to override GetThreadMsg to block on other things
// as well as this queue, you need access to this
CGenericList<CMsg> m_ThreadQueue;
CCritSec m_Lock;
HANDLE m_hSem;
LONG m_lWaiting;
public:
CMsgThread()
: m_ThreadId(0),
m_hThread(NULL),
m_lWaiting(0),
m_hSem(NULL),
// make a list with a cache of 5 items
m_ThreadQueue(NAME("MsgThread list"), 5)
{
}
~CMsgThread();
// override this if you want to block on other things as well
// as the message loop
void virtual GetThreadMsg(CMsg *msg);
// override this if you want to do something on thread startup
virtual void OnThreadInit() {
};
BOOL CreateThread();
BOOL WaitForThreadExit(LPDWORD lpdwExitCode) {
if (m_hThread != NULL) {
WaitForSingleObject(m_hThread, INFINITE);
return GetExitCodeThread(m_hThread, lpdwExitCode);
}
return FALSE;
}
DWORD ResumeThread() {
return ::ResumeThread(m_hThread);
}
DWORD SuspendThread() {
return ::SuspendThread(m_hThread);
}
int GetThreadPriority() {
return ::GetThreadPriority(m_hThread);
}
BOOL SetThreadPriority(int nPriority) {
return ::SetThreadPriority(m_hThread, nPriority);
}
HANDLE GetThreadHandle() {
return m_hThread;
}
DWORD GetThreadId() {
return m_ThreadId;
}
void PutThreadMsg(UINT uMsg, DWORD dwMsgFlags,
LPVOID lpMsgParam, CAMEvent *pEvent = NULL) {
CAutoLock lck(&m_Lock);
CMsg* pMsg = new CMsg(uMsg, dwMsgFlags, lpMsgParam, pEvent);
m_ThreadQueue.AddTail(pMsg);
if (m_lWaiting != 0) {
ReleaseSemaphore(m_hSem, m_lWaiting, 0);
m_lWaiting = 0;
}
}
// This is the function prototype of the function that the client
// supplies. It is always called on the created thread, never on
// the creator thread.
//
virtual LRESULT ThreadMessageProc(
UINT uMsg, DWORD dwFlags, LPVOID lpParam, CAMEvent *pEvent) = 0;
};

View File

@ -1,477 +0,0 @@
//------------------------------------------------------------------------------
// File: MType.cpp
//
// Desc: DirectShow base classes - implements a class that holds and
// manages media type information.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// helper class that derived pin objects can use to compare media
// types etc. Has same data members as the struct AM_MEDIA_TYPE defined
// in the streams IDL file, but also has (non-virtual) functions
#include <streams.h>
#include <mmreg.h>
CMediaType::~CMediaType(){
FreeMediaType(*this);
}
CMediaType::CMediaType()
{
InitMediaType();
}
CMediaType::CMediaType(const GUID * type)
{
InitMediaType();
majortype = *type;
}
// copy constructor does a deep copy of the format block
CMediaType::CMediaType(const AM_MEDIA_TYPE& rt, HRESULT* phr)
{
HRESULT hr = CopyMediaType(this, &rt);
if (FAILED(hr) && (NULL != phr)) {
*phr = hr;
}
}
CMediaType::CMediaType(const CMediaType& rt, HRESULT* phr)
{
HRESULT hr = CopyMediaType(this, &rt);
if (FAILED(hr) && (NULL != phr)) {
*phr = hr;
}
}
// this class inherits publicly from AM_MEDIA_TYPE so the compiler could generate
// the following assignment operator itself, however it could introduce some
// memory conflicts and leaks in the process because the structure contains
// a dynamically allocated block (pbFormat) which it will not copy correctly
CMediaType&
CMediaType::operator=(const AM_MEDIA_TYPE& rt)
{
Set(rt);
return *this;
}
CMediaType&
CMediaType::operator=(const CMediaType& rt)
{
*this = (AM_MEDIA_TYPE &) rt;
return *this;
}
BOOL
CMediaType::operator == (const CMediaType& rt) const
{
// I don't believe we need to check sample size or
// temporal compression flags, since I think these must
// be represented in the type, subtype and format somehow. They
// are pulled out as separate flags so that people who don't understand
// the particular format representation can still see them, but
// they should duplicate information in the format block.
return ((IsEqualGUID(majortype,rt.majortype) == TRUE) &&
(IsEqualGUID(subtype,rt.subtype) == TRUE) &&
(IsEqualGUID(formattype,rt.formattype) == TRUE) &&
(cbFormat == rt.cbFormat) &&
( (cbFormat == 0) ||
(memcmp(pbFormat, rt.pbFormat, cbFormat) == 0)));
}
BOOL
CMediaType::operator != (const CMediaType& rt) const
{
/* Check to see if they are equal */
if (*this == rt) {
return FALSE;
}
return TRUE;
}
HRESULT
CMediaType::Set(const CMediaType& rt)
{
return Set((AM_MEDIA_TYPE &) rt);
}
HRESULT
CMediaType::Set(const AM_MEDIA_TYPE& rt)
{
if (&rt != this) {
FreeMediaType(*this);
HRESULT hr = CopyMediaType(this, &rt);
if (FAILED(hr)) {
return E_OUTOFMEMORY;
}
}
return S_OK;
}
BOOL
CMediaType::IsValid() const
{
return (!IsEqualGUID(majortype,GUID_NULL));
}
void
CMediaType::SetType(const GUID* ptype)
{
majortype = *ptype;
}
void
CMediaType::SetSubtype(const GUID* ptype)
{
subtype = *ptype;
}
ULONG
CMediaType::GetSampleSize() const {
if (IsFixedSize()) {
return lSampleSize;
} else {
return 0;
}
}
void
CMediaType::SetSampleSize(ULONG sz) {
if (sz == 0) {
SetVariableSize();
} else {
bFixedSizeSamples = TRUE;
lSampleSize = sz;
}
}
void
CMediaType::SetVariableSize() {
bFixedSizeSamples = FALSE;
}
void
CMediaType::SetTemporalCompression(BOOL bCompressed) {
bTemporalCompression = bCompressed;
}
BOOL
CMediaType::SetFormat(BYTE * pformat, ULONG cb)
{
if (NULL == AllocFormatBuffer(cb))
return(FALSE);
ASSERT(pbFormat);
memcpy(pbFormat, pformat, cb);
return(TRUE);
}
// set the type of the media type format block, this type defines what you
// will actually find in the format pointer. For example FORMAT_VideoInfo or
// FORMAT_WaveFormatEx. In the future this may be an interface pointer to a
// property set. Before sending out media types this should be filled in.
void
CMediaType::SetFormatType(const GUID *pformattype)
{
formattype = *pformattype;
}
// reset the format buffer
void CMediaType::ResetFormatBuffer()
{
if (cbFormat) {
CoTaskMemFree((PVOID)pbFormat);
}
cbFormat = 0;
pbFormat = NULL;
}
// allocate length bytes for the format and return a read/write pointer
// If we cannot allocate the new block of memory we return NULL leaving
// the original block of memory untouched (as does ReallocFormatBuffer)
BYTE*
CMediaType::AllocFormatBuffer(ULONG length)
{
ASSERT(length);
// do the types have the same buffer size
if (cbFormat == length) {
return pbFormat;
}
// allocate the new format buffer
BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length);
if (pNewFormat == NULL) {
if (length <= cbFormat) return pbFormat; //reuse the old block anyway.
return NULL;
}
// delete the old format
if (cbFormat != 0) {
ASSERT(pbFormat);
CoTaskMemFree((PVOID)pbFormat);
}
cbFormat = length;
pbFormat = pNewFormat;
return pbFormat;
}
// reallocate length bytes for the format and return a read/write pointer
// to it. We keep as much information as we can given the new buffer size
// if this fails the original format buffer is left untouched. The caller
// is responsible for ensuring the size of memory required is non zero
BYTE*
CMediaType::ReallocFormatBuffer(ULONG length)
{
ASSERT(length);
// do the types have the same buffer size
if (cbFormat == length) {
return pbFormat;
}
// allocate the new format buffer
BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length);
if (pNewFormat == NULL) {
if (length <= cbFormat) return pbFormat; //reuse the old block anyway.
return NULL;
}
// copy any previous format (or part of if new is smaller)
// delete the old format and replace with the new one
if (cbFormat != 0) {
ASSERT(pbFormat);
memcpy(pNewFormat,pbFormat,min(length,cbFormat));
CoTaskMemFree((PVOID)pbFormat);
}
cbFormat = length;
pbFormat = pNewFormat;
return pNewFormat;
}
// initialise a media type structure
void CMediaType::InitMediaType()
{
ZeroMemory((PVOID)this, sizeof(*this));
lSampleSize = 1;
bFixedSizeSamples = TRUE;
}
// a partially specified media type can be passed to IPin::Connect
// as a constraint on the media type used in the connection.
// the type, subtype or format type can be null.
BOOL
CMediaType::IsPartiallySpecified(void) const
{
if ((majortype == GUID_NULL) ||
(formattype == GUID_NULL)) {
return TRUE;
} else {
return FALSE;
}
}
BOOL
CMediaType::MatchesPartial(const CMediaType* ppartial) const
{
if ((ppartial->majortype != GUID_NULL) &&
(majortype != ppartial->majortype)) {
return FALSE;
}
if ((ppartial->subtype != GUID_NULL) &&
(subtype != ppartial->subtype)) {
return FALSE;
}
if (ppartial->formattype != GUID_NULL) {
// if the format block is specified then it must match exactly
if (formattype != ppartial->formattype) {
return FALSE;
}
if (cbFormat != ppartial->cbFormat) {
return FALSE;
}
if ((cbFormat != 0) &&
(memcmp(pbFormat, ppartial->pbFormat, cbFormat) != 0)) {
return FALSE;
}
}
return TRUE;
}
// general purpose function to delete a heap allocated AM_MEDIA_TYPE structure
// which is useful when calling IEnumMediaTypes::Next as the interface
// implementation allocates the structures which you must later delete
// the format block may also be a pointer to an interface to release
void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt)
{
// allow NULL pointers for coding simplicity
if (pmt == NULL) {
return;
}
FreeMediaType(*pmt);
CoTaskMemFree((PVOID)pmt);
}
// this also comes in useful when using the IEnumMediaTypes interface so
// that you can copy a media type, you can do nearly the same by creating
// a CMediaType object but as soon as it goes out of scope the destructor
// will delete the memory it allocated (this takes a copy of the memory)
AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc)
{
ASSERT(pSrc);
// Allocate a block of memory for the media type
AM_MEDIA_TYPE *pMediaType =
(AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
if (pMediaType == NULL) {
return NULL;
}
// Copy the variable length format block
HRESULT hr = CopyMediaType(pMediaType,pSrc);
if (FAILED(hr)) {
CoTaskMemFree((PVOID)pMediaType);
return NULL;
}
return pMediaType;
}
// Copy 1 media type to another
HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource)
{
// We'll leak if we copy onto one that already exists - there's one
// case we can check like that - copying to itself.
ASSERT(pmtSource != pmtTarget);
*pmtTarget = *pmtSource;
if (pmtSource->cbFormat != 0) {
ASSERT(pmtSource->pbFormat != NULL);
pmtTarget->pbFormat = (PBYTE)CoTaskMemAlloc(pmtSource->cbFormat);
if (pmtTarget->pbFormat == NULL) {
pmtTarget->cbFormat = 0;
return E_OUTOFMEMORY;
} else {
CopyMemory((PVOID)pmtTarget->pbFormat, (PVOID)pmtSource->pbFormat,
pmtTarget->cbFormat);
}
}
if (pmtTarget->pUnk != NULL) {
pmtTarget->pUnk->AddRef();
}
return S_OK;
}
// Free an existing media type (ie free resources it holds)
void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt)
{
if (mt.cbFormat != 0) {
CoTaskMemFree((PVOID)mt.pbFormat);
// Strictly unnecessary but tidier
mt.cbFormat = 0;
mt.pbFormat = NULL;
}
if (mt.pUnk != NULL) {
mt.pUnk->Release();
mt.pUnk = NULL;
}
}
// Initialize a media type from a WAVEFORMATEX
STDAPI CreateAudioMediaType(
const WAVEFORMATEX *pwfx,
AM_MEDIA_TYPE *pmt,
BOOL bSetFormat
)
{
pmt->majortype = MEDIATYPE_Audio;
if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
pmt->subtype = ((PWAVEFORMATEXTENSIBLE)pwfx)->SubFormat;
} else {
pmt->subtype = FOURCCMap(pwfx->wFormatTag);
}
pmt->formattype = FORMAT_WaveFormatEx;
pmt->bFixedSizeSamples = TRUE;
pmt->bTemporalCompression = FALSE;
pmt->lSampleSize = pwfx->nBlockAlign;
pmt->pUnk = NULL;
if (bSetFormat) {
if (pwfx->wFormatTag == WAVE_FORMAT_PCM) {
pmt->cbFormat = sizeof(WAVEFORMATEX);
} else {
pmt->cbFormat = sizeof(WAVEFORMATEX) + pwfx->cbSize;
}
pmt->pbFormat = (PBYTE)CoTaskMemAlloc(pmt->cbFormat);
if (pmt->pbFormat == NULL) {
return E_OUTOFMEMORY;
}
if (pwfx->wFormatTag == WAVE_FORMAT_PCM) {
CopyMemory(pmt->pbFormat, pwfx, sizeof(PCMWAVEFORMAT));
((WAVEFORMATEX *)pmt->pbFormat)->cbSize = 0;
} else {
CopyMemory(pmt->pbFormat, pwfx, pmt->cbFormat);
}
}
return S_OK;
}
// eliminate very many spurious warnings from MS compiler
#pragma warning(disable:4514)

View File

@ -1,89 +0,0 @@
//------------------------------------------------------------------------------
// File: MtType.h
//
// Desc: DirectShow base classes - defines a class that holds and manages
// media type information.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __MTYPE__
#define __MTYPE__
/* Helper class that derived pin objects can use to compare media
types etc. Has same data members as the struct AM_MEDIA_TYPE defined
in the streams IDL file, but also has (non-virtual) functions */
class CMediaType : public _AMMediaType {
public:
~CMediaType();
CMediaType();
CMediaType(const GUID * majortype);
CMediaType(const AM_MEDIA_TYPE&, HRESULT* phr = NULL);
CMediaType(const CMediaType&, HRESULT* phr = NULL);
CMediaType& operator=(const CMediaType&);
CMediaType& operator=(const AM_MEDIA_TYPE&);
BOOL operator == (const CMediaType&) const;
BOOL operator != (const CMediaType&) const;
HRESULT Set(const CMediaType& rt);
HRESULT Set(const AM_MEDIA_TYPE& rt);
BOOL IsValid() const;
const GUID *Type() const { return &majortype;} ;
void SetType(const GUID *);
const GUID *Subtype() const { return &subtype;} ;
void SetSubtype(const GUID *);
BOOL IsFixedSize() const {return bFixedSizeSamples; };
BOOL IsTemporalCompressed() const {return bTemporalCompression; };
ULONG GetSampleSize() const;
void SetSampleSize(ULONG sz);
void SetVariableSize();
void SetTemporalCompression(BOOL bCompressed);
// read/write pointer to format - can't change length without
// calling SetFormat, AllocFormatBuffer or ReallocFormatBuffer
BYTE* Format() const {return pbFormat; };
ULONG FormatLength() const { return cbFormat; };
void SetFormatType(const GUID *);
const GUID *FormatType() const {return &formattype; };
BOOL SetFormat(BYTE *pFormat, ULONG length);
void ResetFormatBuffer();
BYTE* AllocFormatBuffer(ULONG length);
BYTE* ReallocFormatBuffer(ULONG length);
void InitMediaType();
BOOL MatchesPartial(const CMediaType* ppartial) const;
BOOL IsPartiallySpecified(void) const;
};
/* General purpose functions to copy and delete a task allocated AM_MEDIA_TYPE
structure which is useful when using the IEnumMediaFormats interface as
the implementation allocates the structures which you must later delete */
void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt);
AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc);
HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource);
void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt);
// Initialize a media type from a WAVEFORMATEX
STDAPI CreateAudioMediaType(
const WAVEFORMATEX *pwfx,
AM_MEDIA_TYPE *pmt,
BOOL bSetFormat);
#endif /* __MTYPE__ */

View File

@ -1,794 +0,0 @@
//------------------------------------------------------------------------------
// File: OutputQ.cpp
//
// Desc: DirectShow base classes - implements COutputQueue class used by an
// output pin which may sometimes want to queue output samples on a
// separate thread and sometimes call Receive() directly on the input
// pin.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
//
// COutputQueue Constructor :
//
// Determines if a thread is to be created and creates resources
//
// pInputPin - the downstream input pin we're queueing samples to
//
// phr - changed to a failure code if this function fails
// (otherwise unchanges)
//
// bAuto - Ask pInputPin if it can block in Receive by calling
// its ReceiveCanBlock method and create a thread if
// it can block, otherwise not.
//
// bQueue - if bAuto == FALSE then we create a thread if and only
// if bQueue == TRUE
//
// lBatchSize - work in batches of lBatchSize
//
// bBatchEact - Use exact batch sizes so don't send until the
// batch is full or SendAnyway() is called
//
// lListSize - If we create a thread make the list of samples queued
// to the thread have this size cache
//
// dwPriority - If we create a thread set its priority to this
//
COutputQueue::COutputQueue(
IPin *pInputPin, // Pin to send stuff to
HRESULT *phr, // 'Return code'
BOOL bAuto, // Ask pin if queue or not
BOOL bQueue, // Send through queue
LONG lBatchSize, // Batch
BOOL bBatchExact, // Batch exactly to BatchSize
LONG lListSize,
DWORD dwPriority,
bool bFlushingOpt // flushing optimization
) : m_lBatchSize(lBatchSize),
m_bBatchExact(bBatchExact && (lBatchSize > 1)),
m_hThread(NULL),
m_hSem(NULL),
m_List(NULL),
m_pPin(pInputPin),
m_ppSamples(NULL),
m_lWaiting(0),
m_pInputPin(NULL),
m_bSendAnyway(FALSE),
m_nBatched(0),
m_bFlushing(FALSE),
m_bFlushed(TRUE),
m_bFlushingOpt(bFlushingOpt),
m_bTerminate(FALSE),
m_hEventPop(NULL),
m_hr(S_OK)
{
ASSERT(m_lBatchSize > 0);
if (FAILED(*phr)) {
return;
}
// Check the input pin is OK and cache its IMemInputPin interface
*phr = pInputPin->QueryInterface(IID_IMemInputPin, (void **)&m_pInputPin);
if (FAILED(*phr)) {
return;
}
// See if we should ask the downstream pin
if (bAuto) {
HRESULT hr = m_pInputPin->ReceiveCanBlock();
if (SUCCEEDED(hr)) {
bQueue = hr == S_OK;
}
}
// Create our sample batch
m_ppSamples = new PMEDIASAMPLE[m_lBatchSize];
if (m_ppSamples == NULL) {
*phr = E_OUTOFMEMORY;
return;
}
// If we're queueing allocate resources
if (bQueue) {
DbgLog((LOG_TRACE, 2, TEXT("Creating thread for output pin")));
m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
if (m_hSem == NULL) {
DWORD dwError = GetLastError();
*phr = AmHresultFromWin32(dwError);
return;
}
m_List = new CSampleList(NAME("Sample Queue List"),
lListSize,
FALSE // No lock
);
if (m_List == NULL) {
*phr = E_OUTOFMEMORY;
return;
}
DWORD dwThreadId;
m_hThread = CreateThread(NULL,
0,
InitialThreadProc,
(LPVOID)this,
0,
&dwThreadId);
if (m_hThread == NULL) {
DWORD dwError = GetLastError();
*phr = AmHresultFromWin32(dwError);
return;
}
SetThreadPriority(m_hThread, dwPriority);
} else {
DbgLog((LOG_TRACE, 2, TEXT("Calling input pin directly - no thread")));
}
}
//
// COutputQueuee Destructor :
//
// Free all resources -
//
// Thread,
// Batched samples
//
COutputQueue::~COutputQueue()
{
DbgLog((LOG_TRACE, 3, TEXT("COutputQueue::~COutputQueue")));
/* Free our pointer */
if (m_pInputPin != NULL) {
m_pInputPin->Release();
}
if (m_hThread != NULL) {
{
CAutoLock lck(this);
m_bTerminate = TRUE;
m_hr = S_FALSE;
NotifyThread();
}
DbgWaitForSingleObject(m_hThread);
EXECUTE_ASSERT(CloseHandle(m_hThread));
// The thread frees the samples when asked to terminate
ASSERT(m_List->GetCount() == 0);
delete m_List;
} else {
FreeSamples();
}
if (m_hSem != NULL) {
EXECUTE_ASSERT(CloseHandle(m_hSem));
}
delete [] m_ppSamples;
}
//
// Call the real thread proc as a member function
//
DWORD WINAPI COutputQueue::InitialThreadProc(LPVOID pv)
{
HRESULT hrCoInit = CAMThread::CoInitializeHelper();
COutputQueue *pSampleQueue = (COutputQueue *)pv;
DWORD dwReturn = pSampleQueue->ThreadProc();
if(hrCoInit == S_OK) {
CoUninitialize();
}
return dwReturn;
}
//
// Thread sending the samples downstream :
//
// When there is nothing to do the thread sets m_lWaiting (while
// holding the critical section) and then waits for m_hSem to be
// set (not holding the critical section)
//
DWORD COutputQueue::ThreadProc()
{
while (TRUE) {
BOOL bWait = FALSE;
IMediaSample *pSample;
LONG lNumberToSend; // Local copy
NewSegmentPacket* ppacket;
//
// Get a batch of samples and send it if possible
// In any case exit the loop if there is a control action
// requested
//
{
CAutoLock lck(this);
while (TRUE) {
if (m_bTerminate) {
FreeSamples();
return 0;
}
if (m_bFlushing) {
FreeSamples();
SetEvent(m_evFlushComplete);
}
// Get a sample off the list
pSample = m_List->RemoveHead();
// inform derived class we took something off the queue
if (m_hEventPop) {
//DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT")));
SetEvent(m_hEventPop);
}
if (pSample != NULL &&
!IsSpecialSample(pSample)) {
// If its just a regular sample just add it to the batch
// and exit the loop if the batch is full
m_ppSamples[m_nBatched++] = pSample;
if (m_nBatched == m_lBatchSize) {
break;
}
} else {
// If there was nothing in the queue and there's nothing
// to send (either because there's nothing or the batch
// isn't full) then prepare to wait
if (pSample == NULL &&
(m_bBatchExact || m_nBatched == 0)) {
// Tell other thread to set the event when there's
// something do to
ASSERT(m_lWaiting == 0);
m_lWaiting++;
bWait = TRUE;
} else {
// We break out of the loop on SEND_PACKET unless
// there's nothing to send
if (pSample == SEND_PACKET && m_nBatched == 0) {
continue;
}
if (pSample == NEW_SEGMENT) {
// now we need the parameters - we are
// guaranteed that the next packet contains them
ppacket = (NewSegmentPacket *) m_List->RemoveHead();
// we took something off the queue
if (m_hEventPop) {
//DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT")));
SetEvent(m_hEventPop);
}
ASSERT(ppacket);
}
// EOS_PACKET falls through here and we exit the loop
// In this way it acts like SEND_PACKET
}
break;
}
}
if (!bWait) {
// We look at m_nBatched from the client side so keep
// it up to date inside the critical section
lNumberToSend = m_nBatched; // Local copy
m_nBatched = 0;
}
}
// Wait for some more data
if (bWait) {
DbgWaitForSingleObject(m_hSem);
continue;
}
// OK - send it if there's anything to send
// We DON'T check m_bBatchExact here because either we've got
// a full batch or we dropped through because we got
// SEND_PACKET or EOS_PACKET - both of which imply we should
// flush our batch
if (lNumberToSend != 0) {
long nProcessed;
if (m_hr == S_OK) {
ASSERT(!m_bFlushed);
HRESULT hr = m_pInputPin->ReceiveMultiple(m_ppSamples,
lNumberToSend,
&nProcessed);
/* Don't overwrite a flushing state HRESULT */
CAutoLock lck(this);
if (m_hr == S_OK) {
m_hr = hr;
}
ASSERT(!m_bFlushed);
}
while (lNumberToSend != 0) {
m_ppSamples[--lNumberToSend]->Release();
}
if (m_hr != S_OK) {
// In any case wait for more data - S_OK just
// means there wasn't an error
DbgLog((LOG_ERROR, 2, TEXT("ReceiveMultiple returned %8.8X"),
m_hr));
}
}
// Check for end of stream
if (pSample == EOS_PACKET) {
// We don't send even end of stream on if we've previously
// returned something other than S_OK
// This is because in that case the pin which returned
// something other than S_OK should have either sent
// EndOfStream() or notified the filter graph
if (m_hr == S_OK) {
DbgLog((LOG_TRACE, 2, TEXT("COutputQueue sending EndOfStream()")));
HRESULT hr = m_pPin->EndOfStream();
if (FAILED(hr)) {
DbgLog((LOG_ERROR, 2, TEXT("COutputQueue got code 0x%8.8X from EndOfStream()")));
}
}
}
// Data from a new source
if (pSample == RESET_PACKET) {
m_hr = S_OK;
SetEvent(m_evFlushComplete);
}
if (pSample == NEW_SEGMENT) {
m_pPin->NewSegment(ppacket->tStart, ppacket->tStop, ppacket->dRate);
delete ppacket;
}
}
}
// Send batched stuff anyway
void COutputQueue::SendAnyway()
{
if (!IsQueued()) {
// m_bSendAnyway is a private parameter checked in ReceiveMultiple
m_bSendAnyway = TRUE;
LONG nProcessed;
ReceiveMultiple(NULL, 0, &nProcessed);
m_bSendAnyway = FALSE;
} else {
CAutoLock lck(this);
QueueSample(SEND_PACKET);
NotifyThread();
}
}
void
COutputQueue::NewSegment(
REFERENCE_TIME tStart,
REFERENCE_TIME tStop,
double dRate)
{
if (!IsQueued()) {
if (S_OK == m_hr) {
if (m_bBatchExact) {
SendAnyway();
}
m_pPin->NewSegment(tStart, tStop, dRate);
}
} else {
if (m_hr == S_OK) {
//
// we need to queue the new segment to appear in order in the
// data, but we need to pass parameters to it. Rather than
// take the hit of wrapping every single sample so we can tell
// special ones apart, we queue special pointers to indicate
// special packets, and we guarantee (by holding the
// critical section) that the packet immediately following a
// NEW_SEGMENT value is a NewSegmentPacket containing the
// parameters.
NewSegmentPacket * ppack = new NewSegmentPacket;
if (ppack == NULL) {
return;
}
ppack->tStart = tStart;
ppack->tStop = tStop;
ppack->dRate = dRate;
CAutoLock lck(this);
QueueSample(NEW_SEGMENT);
QueueSample( (IMediaSample*) ppack);
NotifyThread();
}
}
}
//
// End of Stream is queued to output device
//
void COutputQueue::EOS()
{
CAutoLock lck(this);
if (!IsQueued()) {
if (m_bBatchExact) {
SendAnyway();
}
if (m_hr == S_OK) {
DbgLog((LOG_TRACE, 2, TEXT("COutputQueue sending EndOfStream()")));
m_bFlushed = FALSE;
HRESULT hr = m_pPin->EndOfStream();
if (FAILED(hr)) {
DbgLog((LOG_ERROR, 2, TEXT("COutputQueue got code 0x%8.8X from EndOfStream()")));
}
}
} else {
if (m_hr == S_OK) {
m_bFlushed = FALSE;
QueueSample(EOS_PACKET);
NotifyThread();
}
}
}
//
// Flush all the samples in the queue
//
void COutputQueue::BeginFlush()
{
if (IsQueued()) {
{
CAutoLock lck(this);
// block receives -- we assume this is done by the
// filter in which we are a component
// discard all queued data
m_bFlushing = TRUE;
// Make sure we discard all samples from now on
if (m_hr == S_OK) {
m_hr = S_FALSE;
}
// Optimize so we don't keep calling downstream all the time
if (m_bFlushed && m_bFlushingOpt) {
return;
}
// Make sure we really wait for the flush to complete
m_evFlushComplete.Reset();
NotifyThread();
}
// pass this downstream
m_pPin->BeginFlush();
} else {
// pass downstream first to avoid deadlocks
m_pPin->BeginFlush();
CAutoLock lck(this);
// discard all queued data
m_bFlushing = TRUE;
// Make sure we discard all samples from now on
if (m_hr == S_OK) {
m_hr = S_FALSE;
}
}
}
//
// leave flush mode - pass this downstream
void COutputQueue::EndFlush()
{
{
CAutoLock lck(this);
ASSERT(m_bFlushing);
if (m_bFlushingOpt && m_bFlushed && IsQueued()) {
m_bFlushing = FALSE;
m_hr = S_OK;
return;
}
}
// sync with pushing thread -- done in BeginFlush
// ensure no more data to go downstream -- done in BeginFlush
//
// Because we are synching here there is no need to hold the critical
// section (in fact we'd deadlock if we did!)
if (IsQueued()) {
m_evFlushComplete.Wait();
} else {
FreeSamples();
}
// Be daring - the caller has guaranteed no samples will arrive
// before EndFlush() returns
m_bFlushing = FALSE;
m_bFlushed = TRUE;
// call EndFlush on downstream pins
m_pPin->EndFlush();
m_hr = S_OK;
}
// COutputQueue::QueueSample
//
// private method to Send a sample to the output queue
// The critical section MUST be held when this is called
void COutputQueue::QueueSample(IMediaSample *pSample)
{
if (NULL == m_List->AddTail(pSample)) {
if (!IsSpecialSample(pSample)) {
pSample->Release();
}
}
}
//
// COutputQueue::Receive()
//
// Send a single sample by the multiple sample route
// (NOTE - this could be optimized if necessary)
//
// On return the sample will have been Release()'d
//
HRESULT COutputQueue::Receive(IMediaSample *pSample)
{
LONG nProcessed;
return ReceiveMultiple(&pSample, 1, &nProcessed);
}
//
// COutputQueue::ReceiveMultiple()
//
// Send a set of samples to the downstream pin
//
// ppSamples - array of samples
// nSamples - how many
// nSamplesProcessed - How many were processed
//
// On return all samples will have been Release()'d
//
HRESULT COutputQueue::ReceiveMultiple (
IMediaSample **ppSamples,
long nSamples,
long *nSamplesProcessed)
{
CAutoLock lck(this);
// Either call directly or queue up the samples
if (!IsQueued()) {
// If we already had a bad return code then just return
if (S_OK != m_hr) {
// If we've never received anything since the last Flush()
// and the sticky return code is not S_OK we must be
// flushing
// ((!A || B) is equivalent to A implies B)
ASSERT(!m_bFlushed || m_bFlushing);
// We're supposed to Release() them anyway!
*nSamplesProcessed = 0;
for (int i = 0; i < nSamples; i++) {
DbgLog((LOG_TRACE, 3, TEXT("COutputQueue (direct) : Discarding %d samples code 0x%8.8X"),
nSamples, m_hr));
ppSamples[i]->Release();
}
return m_hr;
}
//
// If we're flushing the sticky return code should be S_FALSE
//
ASSERT(!m_bFlushing);
m_bFlushed = FALSE;
ASSERT(m_nBatched < m_lBatchSize);
ASSERT(m_nBatched == 0 || m_bBatchExact);
// Loop processing the samples in batches
LONG iLost = 0;
long iDone;
for (iDone = 0;
iDone < nSamples || (m_nBatched != 0 && m_bSendAnyway);
) {
//pragma message (REMIND("Implement threshold scheme"))
ASSERT(m_nBatched < m_lBatchSize);
if (iDone < nSamples) {
m_ppSamples[m_nBatched++] = ppSamples[iDone++];
}
if (m_nBatched == m_lBatchSize ||
nSamples == 0 && (m_bSendAnyway || !m_bBatchExact)) {
LONG nDone;
DbgLog((LOG_TRACE, 4, TEXT("Batching %d samples"),
m_nBatched));
if (m_hr == S_OK) {
m_hr = m_pInputPin->ReceiveMultiple(m_ppSamples,
m_nBatched,
&nDone);
} else {
nDone = 0;
}
iLost += m_nBatched - nDone;
for (LONG i = 0; i < m_nBatched; i++) {
m_ppSamples[i]->Release();
}
m_nBatched = 0;
}
}
*nSamplesProcessed = iDone - iLost;
if (*nSamplesProcessed < 0) {
*nSamplesProcessed = 0;
}
return m_hr;
} else {
/* We're sending to our thread */
if (m_hr != S_OK) {
*nSamplesProcessed = 0;
DbgLog((LOG_TRACE, 3, TEXT("COutputQueue (queued) : Discarding %d samples code 0x%8.8X"),
nSamples, m_hr));
for (int i = 0; i < nSamples; i++) {
ppSamples[i]->Release();
}
return m_hr;
}
m_bFlushed = FALSE;
for (long i = 0; i < nSamples; i++) {
QueueSample(ppSamples[i]);
}
*nSamplesProcessed = nSamples;
if (!m_bBatchExact ||
m_nBatched + m_List->GetCount() >= m_lBatchSize) {
NotifyThread();
}
return S_OK;
}
}
// Get ready for new data - cancels sticky m_hr
void COutputQueue::Reset()
{
if (!IsQueued()) {
m_hr = S_OK;
} else {
CAutoLock lck(this);
QueueSample(RESET_PACKET);
NotifyThread();
m_evFlushComplete.Wait();
}
}
// Remove and Release() all queued and Batched samples
void COutputQueue::FreeSamples()
{
CAutoLock lck(this);
if (IsQueued()) {
while (TRUE) {
IMediaSample *pSample = m_List->RemoveHead();
// inform derived class we took something off the queue
if (m_hEventPop) {
//DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT")));
SetEvent(m_hEventPop);
}
if (pSample == NULL) {
break;
}
if (!IsSpecialSample(pSample)) {
pSample->Release();
} else {
if (pSample == NEW_SEGMENT) {
// Free NEW_SEGMENT packet
NewSegmentPacket *ppacket =
(NewSegmentPacket *) m_List->RemoveHead();
// inform derived class we took something off the queue
if (m_hEventPop) {
//DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT")));
SetEvent(m_hEventPop);
}
ASSERT(ppacket != NULL);
delete ppacket;
}
}
}
}
for (int i = 0; i < m_nBatched; i++) {
m_ppSamples[i]->Release();
}
m_nBatched = 0;
}
// Notify the thread if there is something to do
//
// The critical section MUST be held when this is called
void COutputQueue::NotifyThread()
{
// Optimize - no need to signal if it's not waiting
ASSERT(IsQueued());
if (m_lWaiting) {
ReleaseSemaphore(m_hSem, m_lWaiting, NULL);
m_lWaiting = 0;
}
}
// See if there's any work to do
// Returns
// TRUE if there is nothing on the queue and nothing in the batch
// and all data has been sent
// FALSE otherwise
//
BOOL COutputQueue::IsIdle()
{
CAutoLock lck(this);
// We're idle if
// there is no thread (!IsQueued()) OR
// the thread is waiting for more work (m_lWaiting != 0)
// AND
// there's nothing in the current batch (m_nBatched == 0)
if (IsQueued() && m_lWaiting == 0 || m_nBatched != 0) {
return FALSE;
} else {
// If we're idle it shouldn't be possible for there
// to be anything on the work queue
ASSERT(!IsQueued() || m_List->GetCount() == 0);
return TRUE;
}
}
void COutputQueue::SetPopEvent(HANDLE hEvent)
{
m_hEventPop = hEvent;
}

View File

@ -1,137 +0,0 @@
//------------------------------------------------------------------------------
// File: OutputQ.h
//
// Desc: DirectShow base classes - defines the COutputQueue class, which
// makes a queue of samples and sends them to an output pin. The
// class will optionally send the samples to the pin directly.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
typedef CGenericList<IMediaSample> CSampleList;
class COutputQueue : public CCritSec
{
public:
// Constructor
COutputQueue(IPin *pInputPin, // Pin to send stuff to
HRESULT *phr, // 'Return code'
BOOL bAuto = TRUE, // Ask pin if blocks
BOOL bQueue = TRUE, // Send through queue (ignored if
// bAuto set)
LONG lBatchSize = 1, // Batch
BOOL bBatchExact = FALSE,// Batch exactly to BatchSize
LONG lListSize = // Likely number in the list
DEFAULTCACHE,
DWORD dwPriority = // Priority of thread to create
THREAD_PRIORITY_NORMAL,
bool bFlushingOpt = false // flushing optimization
);
~COutputQueue();
// enter flush state - discard all data
void BeginFlush(); // Begin flushing samples
// re-enable receives (pass this downstream)
void EndFlush(); // Complete flush of samples - downstream
// pin guaranteed not to block at this stage
void EOS(); // Call this on End of stream
void SendAnyway(); // Send batched samples anyway (if bBatchExact set)
void NewSegment(
REFERENCE_TIME tStart,
REFERENCE_TIME tStop,
double dRate);
HRESULT Receive(IMediaSample *pSample);
// do something with these media samples
HRESULT ReceiveMultiple (
IMediaSample **pSamples,
long nSamples,
long *nSamplesProcessed);
void Reset(); // Reset m_hr ready for more data
// See if its idle or not
BOOL IsIdle();
// give the class an event to fire after everything removed from the queue
void SetPopEvent(HANDLE hEvent);
protected:
static DWORD WINAPI InitialThreadProc(LPVOID pv);
DWORD ThreadProc();
BOOL IsQueued()
{
return m_List != NULL;
}
// The critical section MUST be held when this is called
void QueueSample(IMediaSample *pSample);
BOOL IsSpecialSample(IMediaSample *pSample)
{
return (DWORD_PTR)pSample > (DWORD_PTR)(LONG_PTR)(-16);
}
// Remove and Release() batched and queued samples
void FreeSamples();
// Notify the thread there is something to do
void NotifyThread();
protected:
// Queue 'messages'
#define SEND_PACKET ((IMediaSample *)(LONG_PTR)(-2)) // Send batch
#define EOS_PACKET ((IMediaSample *)(LONG_PTR)(-3)) // End of stream
#define RESET_PACKET ((IMediaSample *)(LONG_PTR)(-4)) // Reset m_hr
#define NEW_SEGMENT ((IMediaSample *)(LONG_PTR)(-5)) // send NewSegment
// new segment packet is always followed by one of these
struct NewSegmentPacket {
REFERENCE_TIME tStart;
REFERENCE_TIME tStop;
double dRate;
};
// Remember input stuff
IPin * const m_pPin;
IMemInputPin * m_pInputPin;
BOOL const m_bBatchExact;
LONG const m_lBatchSize;
CSampleList * m_List;
HANDLE m_hSem;
CAMEvent m_evFlushComplete;
HANDLE m_hThread;
IMediaSample ** m_ppSamples;
LONG m_nBatched;
// Wait optimization
LONG m_lWaiting;
// Flush synchronization
BOOL m_bFlushing;
// flushing optimization. some downstream filters have trouble
// with the queue's flushing optimization. other rely on it
BOOL m_bFlushed;
bool m_bFlushingOpt;
// Terminate now
BOOL m_bTerminate;
// Send anyway flag for batching
BOOL m_bSendAnyway;
// Deferred 'return code'
BOOL volatile m_hr;
// an event that can be fired after every deliver
HANDLE m_hEventPop;
};

View File

@ -1,196 +0,0 @@
//------------------------------------------------------------------------------
// File: PStream.cpp
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#ifdef PERF
#include <measure.h>
#endif
//
// Constructor
//
CPersistStream::CPersistStream(IUnknown *punk, HRESULT *phr)
: mPS_fDirty(FALSE)
{
mPS_dwFileVersion = GetSoftwareVersion();
}
//
// Destructor
//
CPersistStream::~CPersistStream() {
// Nothing to do
}
#if 0
SAMPLE CODE TO COPY - not active at the moment
//
// NonDelegatingQueryInterface
//
// This object supports IPersist & IPersistStream
STDMETHODIMP CPersistStream::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if (riid == IID_IPersist) {
return GetInterface((IPersist *) this, ppv);
}
else if (riid == IID_IPersistStream) {
return GetInterface((IPersistStream *) this, ppv);
}
else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}
#endif
//
// WriteToStream
//
// Writes to the stream (default action is to write nothing)
HRESULT CPersistStream::WriteToStream(IStream *pStream)
{
// You can override this to do things like
// hr = pStream->Write(MyStructure, sizeof(MyStructure), NULL);
return NOERROR;
}
HRESULT CPersistStream::ReadFromStream(IStream * pStream)
{
// You can override this to do things like
// hr = pStream->Read(MyStructure, sizeof(MyStructure), NULL);
return NOERROR;
}
//
// Load
//
// Load all the data from the given stream
STDMETHODIMP CPersistStream::Load(LPSTREAM pStm)
{
HRESULT hr;
// Load the version number then the data
mPS_dwFileVersion = ReadInt(pStm, hr);
if (FAILED(hr)) {
return hr;
}
return ReadFromStream(pStm);
} // Load
//
// Save
//
// Save the contents of this Stream.
STDMETHODIMP CPersistStream::Save(LPSTREAM pStm, BOOL fClearDirty)
{
HRESULT hr = WriteInt(pStm, GetSoftwareVersion());
if (FAILED(hr)) {
return hr;
}
hr = WriteToStream(pStm);
if (FAILED(hr)) {
return hr;
}
mPS_fDirty = !fClearDirty;
return hr;
} // Save
// WriteInt
//
// Writes an integer to an IStream as 11 UNICODE characters followed by one space.
// You could use this for shorts or unsigneds or anything (up to 32 bits)
// where the value isn't actually truncated by squeezing it into 32 bits.
// Values such as (unsigned) 0x80000000 would come out as -2147483648
// but would then load as 0x80000000 through ReadInt. Cast as you please.
STDAPI WriteInt(IStream *pIStream, int n)
{
WCHAR Buff[13]; // Allows for trailing null that we don't write
(void)StringCchPrintfW(Buff, NUMELMS(Buff), L"%011d ",n);
return pIStream->Write(&(Buff[0]), 12*sizeof(WCHAR), NULL);
} // WriteInt
// ReadInt
//
// Reads an integer from an IStream.
// Read as 4 bytes. You could use this for shorts or unsigneds or anything
// where the value isn't actually truncated by squeezing it into 32 bits
// Striped down subset of what sscanf can do (without dragging in the C runtime)
STDAPI_(int) ReadInt(IStream *pIStream, HRESULT &hr)
{
int Sign = 1;
unsigned int n = 0; // result wil be n*Sign
WCHAR wch;
hr = pIStream->Read( &wch, sizeof(wch), NULL);
if (FAILED(hr)) {
return 0;
}
if (wch==L'-'){
Sign = -1;
hr = pIStream->Read( &wch, sizeof(wch), NULL);
if (FAILED(hr)) {
return 0;
}
}
for( ; ; ) {
if (wch>=L'0' && wch<=L'9') {
n = 10*n+(int)(wch-L'0');
} else if ( wch == L' '
|| wch == L'\t'
|| wch == L'\r'
|| wch == L'\n'
|| wch == L'\0'
) {
break;
} else {
hr = VFW_E_INVALID_FILE_FORMAT;
return 0;
}
hr = pIStream->Read( &wch, sizeof(wch), NULL);
if (FAILED(hr)) {
return 0;
}
}
if (n==0x80000000 && Sign==-1) {
// This is the negative number that has no positive version!
return (int)n;
}
else return (int)n * Sign;
} // ReadInt
// The microsoft C/C++ compile generates level 4 warnings to the effect that
// a particular inline function (from some base class) was not needed.
// This line gets rid of hundreds of such unwanted messages and makes
// -W4 compilation feasible:
#pragma warning(disable: 4514)

View File

@ -1,114 +0,0 @@
//------------------------------------------------------------------------------
// File: PStream.h
//
// Desc: DirectShow base classes - defines a class for persistent properties
// of filters.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __PSTREAM__
#define __PSTREAM__
// Base class for persistent properties of filters
// (i.e. filter properties in saved graphs)
// The simplest way to use this is:
// 1. Arrange for your filter to inherit this class
// 2. Implement in your class WriteToStream and ReadFromStream
// These will override the "do nothing" functions here.
// 3. Change your NonDelegatingQueryInterface to handle IPersistStream
// 4. Implement SizeMax to return the number of bytes of data you save.
// If you save UNICODE data, don't forget a char is 2 bytes.
// 5. Whenever your data changes, call SetDirty()
//
// At some point you may decide to alter, or extend the format of your data.
// At that point you will wish that you had a version number in all the old
// saved graphs, so that you can tell, when you read them, whether they
// represent the old or new form. To assist you in this, this class
// writes and reads a version number.
// When it writes, it calls GetSoftwareVersion() to enquire what version
// of the software we have at the moment. (In effect this is a version number
// of the data layout in the file). It writes this as the first thing in the data.
// If you want to change the version, implement (override) GetSoftwareVersion().
// It reads this from the file into mPS_dwFileVersion before calling ReadFromStream,
// so in ReadFromStream you can check mPS_dwFileVersion to see if you are reading
// an old version file.
// Normally you should accept files whose version is no newer than the software
// version that's reading them.
// CPersistStream
//
// Implements IPersistStream.
// See 'OLE Programmers Reference (Vol 1):Structured Storage Overview' for
// more implementation information.
class CPersistStream : public IPersistStream {
private:
// Internal state:
protected:
DWORD mPS_dwFileVersion; // version number of file (being read)
BOOL mPS_fDirty;
public:
// IPersistStream methods
STDMETHODIMP IsDirty()
{return (mPS_fDirty ? S_OK : S_FALSE);} // note FALSE means clean
STDMETHODIMP Load(LPSTREAM pStm);
STDMETHODIMP Save(LPSTREAM pStm, BOOL fClearDirty);
STDMETHODIMP GetSizeMax(ULARGE_INTEGER * pcbSize)
// Allow 24 bytes for version.
{ pcbSize->QuadPart = 12*sizeof(WCHAR)+SizeMax(); return NOERROR; }
// implementation
CPersistStream(IUnknown *punk, HRESULT *phr);
~CPersistStream();
HRESULT SetDirty(BOOL fDirty)
{ mPS_fDirty = fDirty; return NOERROR;}
// override to reveal IPersist & IPersistStream
// STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
// --- IPersist ---
// You must override this to provide your own class id
STDMETHODIMP GetClassID(CLSID *pClsid) PURE;
// overrideable if you want
// file version number. Override it if you ever change format
virtual DWORD GetSoftwareVersion(void) { return 0; }
//=========================================================================
// OVERRIDE THESE to read and write your data
// OVERRIDE THESE to read and write your data
// OVERRIDE THESE to read and write your data
virtual int SizeMax() {return 0;}
virtual HRESULT WriteToStream(IStream *pStream);
virtual HRESULT ReadFromStream(IStream *pStream);
//=========================================================================
private:
};
// --- Useful helpers ---
// Writes an int to an IStream as UNICODE.
STDAPI WriteInt(IStream *pIStream, int n);
// inverse of WriteInt
STDAPI_(int) ReadInt(IStream *pIStream, HRESULT &hr);
#endif // __PSTREAM__

View File

@ -1,527 +0,0 @@
//------------------------------------------------------------------------------
// File: PullPin.cpp
//
// Desc: DirectShow base classes - implements CPullPin class that pulls data
// from IAsyncReader.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include "pullpin.h"
CPullPin::CPullPin()
: m_pReader(NULL),
m_pAlloc(NULL),
m_State(TM_Exit)
{
}
CPullPin::~CPullPin()
{
Disconnect();
}
// returns S_OK if successfully connected to an IAsyncReader interface
// from this object
// Optional allocator should be proposed as a preferred allocator if
// necessary
HRESULT
CPullPin::Connect(IUnknown* pUnk, IMemAllocator* pAlloc, BOOL bSync)
{
CAutoLock lock(&m_AccessLock);
if (m_pReader) {
return VFW_E_ALREADY_CONNECTED;
}
HRESULT hr = pUnk->QueryInterface(IID_IAsyncReader, (void**)&m_pReader);
if (FAILED(hr)) {
return(hr);
}
hr = DecideAllocator(pAlloc, NULL);
if (FAILED(hr)) {
Disconnect();
return hr;
}
LONGLONG llTotal, llAvail;
hr = m_pReader->Length(&llTotal, &llAvail);
if (FAILED(hr)) {
Disconnect();
return hr;
}
// convert from file position to reference time
m_tDuration = llTotal * UNITS;
m_tStop = m_tDuration;
m_tStart = 0;
m_bSync = bSync;
return S_OK;
}
// disconnect any connection made in Connect
HRESULT
CPullPin::Disconnect()
{
CAutoLock lock(&m_AccessLock);
StopThread();
if (m_pReader) {
m_pReader->Release();
m_pReader = NULL;
}
if (m_pAlloc) {
m_pAlloc->Release();
m_pAlloc = NULL;
}
return S_OK;
}
// agree an allocator using RequestAllocator - optional
// props param specifies your requirements (non-zero fields).
// returns an error code if fail to match requirements.
// optional IMemAllocator interface is offered as a preferred allocator
// but no error occurs if it can't be met.
HRESULT
CPullPin::DecideAllocator(
IMemAllocator * pAlloc,
ALLOCATOR_PROPERTIES * pProps)
{
ALLOCATOR_PROPERTIES *pRequest;
ALLOCATOR_PROPERTIES Request;
if (pProps == NULL) {
Request.cBuffers = 3;
Request.cbBuffer = 64*1024;
Request.cbAlign = 0;
Request.cbPrefix = 0;
pRequest = &Request;
} else {
pRequest = pProps;
}
HRESULT hr = m_pReader->RequestAllocator(
pAlloc,
pRequest,
&m_pAlloc);
return hr;
}
// start pulling data
HRESULT
CPullPin::Active(void)
{
ASSERT(!ThreadExists());
return StartThread();
}
// stop pulling data
HRESULT
CPullPin::Inactive(void)
{
StopThread();
return S_OK;
}
HRESULT
CPullPin::Seek(REFERENCE_TIME tStart, REFERENCE_TIME tStop)
{
CAutoLock lock(&m_AccessLock);
ThreadMsg AtStart = m_State;
if (AtStart == TM_Start) {
BeginFlush();
PauseThread();
EndFlush();
}
m_tStart = tStart;
m_tStop = tStop;
HRESULT hr = S_OK;
if (AtStart == TM_Start) {
hr = StartThread();
}
return hr;
}
HRESULT
CPullPin::Duration(REFERENCE_TIME* ptDuration)
{
*ptDuration = m_tDuration;
return S_OK;
}
HRESULT
CPullPin::StartThread()
{
CAutoLock lock(&m_AccessLock);
if (!m_pAlloc || !m_pReader) {
return E_UNEXPECTED;
}
HRESULT hr;
if (!ThreadExists()) {
// commit allocator
hr = m_pAlloc->Commit();
if (FAILED(hr)) {
return hr;
}
// start thread
if (!Create()) {
return E_FAIL;
}
}
m_State = TM_Start;
hr = (HRESULT) CallWorker(m_State);
return hr;
}
HRESULT
CPullPin::PauseThread()
{
CAutoLock lock(&m_AccessLock);
if (!ThreadExists()) {
return E_UNEXPECTED;
}
// need to flush to ensure the thread is not blocked
// in WaitForNext
HRESULT hr = m_pReader->BeginFlush();
if (FAILED(hr)) {
return hr;
}
m_State = TM_Pause;
hr = CallWorker(TM_Pause);
m_pReader->EndFlush();
return hr;
}
HRESULT
CPullPin::StopThread()
{
CAutoLock lock(&m_AccessLock);
if (!ThreadExists()) {
return S_FALSE;
}
// need to flush to ensure the thread is not blocked
// in WaitForNext
HRESULT hr = m_pReader->BeginFlush();
if (FAILED(hr)) {
return hr;
}
m_State = TM_Exit;
hr = CallWorker(TM_Exit);
m_pReader->EndFlush();
// wait for thread to completely exit
Close();
// decommit allocator
if (m_pAlloc) {
m_pAlloc->Decommit();
}
return S_OK;
}
DWORD
CPullPin::ThreadProc(void)
{
while(1) {
DWORD cmd = GetRequest();
switch(cmd) {
case TM_Exit:
Reply(S_OK);
return 0;
case TM_Pause:
// we are paused already
Reply(S_OK);
break;
case TM_Start:
Reply(S_OK);
Process();
break;
}
// at this point, there should be no outstanding requests on the
// upstream filter.
// We should force begin/endflush to ensure that this is true.
// !!!Note that we may currently be inside a BeginFlush/EndFlush pair
// on another thread, but the premature EndFlush will do no harm now
// that we are idle.
m_pReader->BeginFlush();
CleanupCancelled();
m_pReader->EndFlush();
}
}
HRESULT
CPullPin::QueueSample(
REFERENCE_TIME& tCurrent,
REFERENCE_TIME tAlignStop,
BOOL bDiscontinuity
)
{
IMediaSample* pSample;
HRESULT hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0);
if (FAILED(hr)) {
return hr;
}
LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS);
if (tStopThis > tAlignStop) {
tStopThis = tAlignStop;
}
pSample->SetTime(&tCurrent, &tStopThis);
tCurrent = tStopThis;
pSample->SetDiscontinuity(bDiscontinuity);
hr = m_pReader->Request(
pSample,
0);
if (FAILED(hr)) {
pSample->Release();
CleanupCancelled();
OnError(hr);
}
return hr;
}
HRESULT
CPullPin::CollectAndDeliver(
REFERENCE_TIME tStart,
REFERENCE_TIME tStop)
{
IMediaSample* pSample = NULL; // better be sure pSample is set
DWORD_PTR dwUnused;
HRESULT hr = m_pReader->WaitForNext(
INFINITE,
&pSample,
&dwUnused);
if (FAILED(hr)) {
if (pSample) {
pSample->Release();
}
} else {
hr = DeliverSample(pSample, tStart, tStop);
}
if (FAILED(hr)) {
CleanupCancelled();
OnError(hr);
}
return hr;
}
HRESULT
CPullPin::DeliverSample(
IMediaSample* pSample,
REFERENCE_TIME tStart,
REFERENCE_TIME tStop
)
{
// fix up sample if past actual stop (for sector alignment)
REFERENCE_TIME t1, t2;
pSample->GetTime(&t1, &t2);
if (t2 > tStop) {
t2 = tStop;
}
// adjust times to be relative to (aligned) start time
t1 -= tStart;
t2 -= tStart;
pSample->SetTime(&t1, &t2);
HRESULT hr = Receive(pSample);
pSample->Release();
return hr;
}
void
CPullPin::Process(void)
{
// is there anything to do?
if (m_tStop <= m_tStart) {
EndOfStream();
return;
}
BOOL bDiscontinuity = TRUE;
// if there is more than one sample at the allocator,
// then try to queue 2 at once in order to overlap.
// -- get buffer count and required alignment
ALLOCATOR_PROPERTIES Actual;
HRESULT hr = m_pAlloc->GetProperties(&Actual);
// align the start position downwards
REFERENCE_TIME tStart = AlignDown(m_tStart / UNITS, Actual.cbAlign) * UNITS;
REFERENCE_TIME tCurrent = tStart;
REFERENCE_TIME tStop = m_tStop;
if (tStop > m_tDuration) {
tStop = m_tDuration;
}
// align the stop position - may be past stop, but that
// doesn't matter
REFERENCE_TIME tAlignStop = AlignUp(tStop / UNITS, Actual.cbAlign) * UNITS;
DWORD dwRequest;
if (!m_bSync) {
// Break out of the loop either if we get to the end or we're asked
// to do something else
while (tCurrent < tAlignStop) {
// Break out without calling EndOfStream if we're asked to
// do something different
if (CheckRequest(&dwRequest)) {
return;
}
// queue a first sample
if (Actual.cBuffers > 1) {
hr = QueueSample(tCurrent, tAlignStop, TRUE);
bDiscontinuity = FALSE;
if (FAILED(hr)) {
return;
}
}
// loop queueing second and waiting for first..
while (tCurrent < tAlignStop) {
hr = QueueSample(tCurrent, tAlignStop, bDiscontinuity);
bDiscontinuity = FALSE;
if (FAILED(hr)) {
return;
}
hr = CollectAndDeliver(tStart, tStop);
if (S_OK != hr) {
// stop if error, or if downstream filter said
// to stop.
return;
}
}
if (Actual.cBuffers > 1) {
hr = CollectAndDeliver(tStart, tStop);
if (FAILED(hr)) {
return;
}
}
}
} else {
// sync version of above loop
while (tCurrent < tAlignStop) {
// Break out without calling EndOfStream if we're asked to
// do something different
if (CheckRequest(&dwRequest)) {
return;
}
IMediaSample* pSample;
hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0);
if (FAILED(hr)) {
OnError(hr);
return;
}
LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS);
if (tStopThis > tAlignStop) {
tStopThis = tAlignStop;
}
pSample->SetTime(&tCurrent, &tStopThis);
tCurrent = tStopThis;
if (bDiscontinuity) {
pSample->SetDiscontinuity(TRUE);
bDiscontinuity = FALSE;
}
hr = m_pReader->SyncReadAligned(pSample);
if (FAILED(hr)) {
pSample->Release();
OnError(hr);
return;
}
hr = DeliverSample(pSample, tStart, tStop);
if (hr != S_OK) {
if (FAILED(hr)) {
OnError(hr);
}
return;
}
}
}
EndOfStream();
}
// after a flush, cancelled i/o will be waiting for collection
// and release
void
CPullPin::CleanupCancelled(void)
{
while (1) {
IMediaSample * pSample;
DWORD_PTR dwUnused;
HRESULT hr = m_pReader->WaitForNext(
0, // no wait
&pSample,
&dwUnused);
if(pSample) {
pSample->Release();
} else {
// no more samples
return;
}
}
}

View File

@ -1,152 +0,0 @@
//------------------------------------------------------------------------------
// File: PullPin.h
//
// Desc: DirectShow base classes - defines CPullPin class.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __PULLPIN_H__
#define __PULLPIN_H__
//
// CPullPin
//
// object supporting pulling data from an IAsyncReader interface.
// Given a start/stop position, calls a pure Receive method with each
// IMediaSample received.
//
// This is essentially for use in a MemInputPin when it finds itself
// connected to an IAsyncReader pin instead of a pushing pin.
//
class CPullPin : public CAMThread
{
IAsyncReader* m_pReader;
REFERENCE_TIME m_tStart;
REFERENCE_TIME m_tStop;
REFERENCE_TIME m_tDuration;
BOOL m_bSync;
enum ThreadMsg {
TM_Pause, // stop pulling and wait for next message
TM_Start, // start pulling
TM_Exit, // stop and exit
};
ThreadMsg m_State;
// override pure thread proc from CAMThread
DWORD ThreadProc(void);
// running pull method (check m_bSync)
void Process(void);
// clean up any cancelled i/o after a flush
void CleanupCancelled(void);
// suspend thread from pulling, eg during seek
HRESULT PauseThread();
// start thread pulling - create thread if necy
HRESULT StartThread();
// stop and close thread
HRESULT StopThread();
// called from ProcessAsync to queue and collect requests
HRESULT QueueSample(
REFERENCE_TIME& tCurrent,
REFERENCE_TIME tAlignStop,
BOOL bDiscontinuity);
HRESULT CollectAndDeliver(
REFERENCE_TIME tStart,
REFERENCE_TIME tStop);
HRESULT DeliverSample(
IMediaSample* pSample,
REFERENCE_TIME tStart,
REFERENCE_TIME tStop);
protected:
IMemAllocator * m_pAlloc;
public:
CPullPin();
virtual ~CPullPin();
// returns S_OK if successfully connected to an IAsyncReader interface
// from this object
// Optional allocator should be proposed as a preferred allocator if
// necessary
// bSync is TRUE if we are to use sync reads instead of the
// async methods.
HRESULT Connect(IUnknown* pUnk, IMemAllocator* pAlloc, BOOL bSync);
// disconnect any connection made in Connect
HRESULT Disconnect();
// agree an allocator using RequestAllocator - optional
// props param specifies your requirements (non-zero fields).
// returns an error code if fail to match requirements.
// optional IMemAllocator interface is offered as a preferred allocator
// but no error occurs if it can't be met.
virtual HRESULT DecideAllocator(
IMemAllocator* pAlloc,
ALLOCATOR_PROPERTIES * pProps);
// set start and stop position. if active, will start immediately at
// the new position. Default is 0 to duration
HRESULT Seek(REFERENCE_TIME tStart, REFERENCE_TIME tStop);
// return the total duration
HRESULT Duration(REFERENCE_TIME* ptDuration);
// start pulling data
HRESULT Active(void);
// stop pulling data
HRESULT Inactive(void);
// helper functions
LONGLONG AlignDown(LONGLONG ll, LONG lAlign) {
// aligning downwards is just truncation
return ll & ~(lAlign-1);
};
LONGLONG AlignUp(LONGLONG ll, LONG lAlign) {
// align up: round up to next boundary
return (ll + (lAlign -1)) & ~(lAlign -1);
};
// GetReader returns the (addrefed) IAsyncReader interface
// for SyncRead etc
IAsyncReader* GetReader() {
m_pReader->AddRef();
return m_pReader;
};
// -- pure --
// override this to handle data arrival
// return value other than S_OK will stop data
virtual HRESULT Receive(IMediaSample*) PURE;
// override this to handle end-of-stream
virtual HRESULT EndOfStream(void) PURE;
// called on runtime errors that will have caused pulling
// to stop
// these errors are all returned from the upstream filter, who
// will have already reported any errors to the filtergraph.
virtual void OnError(HRESULT hr) PURE;
// flush this pin and all downstream
virtual HRESULT BeginFlush() PURE;
virtual HRESULT EndFlush() PURE;
};
#endif //__PULLPIN_H__

View File

@ -1,340 +0,0 @@
//------------------------------------------------------------------------------
// File: RefClock.cpp
//
// Desc: DirectShow base classes - implements the IReferenceClock interface.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <limits.h>
// 'this' used in constructor list
#pragma warning(disable:4355)
STDMETHODIMP CBaseReferenceClock::NonDelegatingQueryInterface(
REFIID riid,
void ** ppv)
{
HRESULT hr;
if (riid == IID_IReferenceClock)
{
hr = GetInterface((IReferenceClock *) this, ppv);
}
else
{
hr = CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
return hr;
}
CBaseReferenceClock::~CBaseReferenceClock()
{
if (m_TimerResolution) timeEndPeriod(m_TimerResolution);
m_pSchedule->DumpLinkedList();
if (m_hThread)
{
m_bAbort = TRUE;
TriggerThread();
WaitForSingleObject( m_hThread, INFINITE );
EXECUTE_ASSERT( CloseHandle(m_hThread) );
m_hThread = 0;
EXECUTE_ASSERT( CloseHandle(m_pSchedule->GetEvent()) );
delete m_pSchedule;
}
}
// A derived class may supply a hThreadEvent if it has its own thread that will take care
// of calling the schedulers Advise method. (Refere to CBaseReferenceClock::AdviseThread()
// to see what such a thread has to do.)
CBaseReferenceClock::CBaseReferenceClock( TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule * pShed )
: CUnknown( pName, pUnk )
, m_rtLastGotTime(0)
, m_TimerResolution(0)
, m_bAbort( FALSE )
, m_pSchedule( pShed ? pShed : new CAMSchedule(CreateEvent(NULL, FALSE, FALSE, NULL)) )
, m_hThread(0)
{
ASSERT(m_pSchedule);
if (!m_pSchedule)
{
*phr = E_OUTOFMEMORY;
}
else
{
// Set up the highest resolution timer we can manage
TIMECAPS tc;
m_TimerResolution = (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(tc)))
? tc.wPeriodMin
: 1;
timeBeginPeriod(m_TimerResolution);
/* Initialise our system times - the derived clock should set the right values */
m_dwPrevSystemTime = timeGetTime();
m_rtPrivateTime = (UNITS / MILLISECONDS) * m_dwPrevSystemTime;
#ifdef PERF
m_idGetSystemTime = MSR_REGISTER(TEXT("CBaseReferenceClock::GetTime"));
#endif
if ( !pShed )
{
DWORD ThreadID;
m_hThread = ::CreateThread(NULL, // Security attributes
(DWORD) 0, // Initial stack size
AdviseThreadFunction, // Thread start address
(LPVOID) this, // Thread parameter
(DWORD) 0, // Creation flags
&ThreadID); // Thread identifier
if (m_hThread)
{
SetThreadPriority( m_hThread, THREAD_PRIORITY_TIME_CRITICAL );
}
else
{
*phr = E_FAIL;
EXECUTE_ASSERT( CloseHandle(m_pSchedule->GetEvent()) );
delete m_pSchedule;
}
}
}
}
void CBaseReferenceClock::Restart (IN REFERENCE_TIME rtMinTime)
{
Lock();
m_rtLastGotTime = rtMinTime ;
Unlock();
}
STDMETHODIMP CBaseReferenceClock::GetTime(REFERENCE_TIME *pTime)
{
HRESULT hr;
if (pTime)
{
REFERENCE_TIME rtNow;
Lock();
rtNow = GetPrivateTime();
if (rtNow > m_rtLastGotTime)
{
m_rtLastGotTime = rtNow;
hr = S_OK;
}
else
{
hr = S_FALSE;
}
*pTime = m_rtLastGotTime;
Unlock();
MSR_INTEGER(m_idGetSystemTime, LONG((*pTime) / (UNITS/MILLISECONDS)) );
}
else hr = E_POINTER;
return hr;
}
/* Ask for an async notification that a time has elapsed */
STDMETHODIMP CBaseReferenceClock::AdviseTime(
REFERENCE_TIME baseTime, // base reference time
REFERENCE_TIME streamTime, // stream offset time
HEVENT hEvent, // advise via this event
DWORD_PTR *pdwAdviseCookie) // where your cookie goes
{
CheckPointer(pdwAdviseCookie, E_POINTER);
*pdwAdviseCookie = 0;
// Check that the event is not already set
ASSERT(WAIT_TIMEOUT == WaitForSingleObject(HANDLE(hEvent),0));
HRESULT hr;
const REFERENCE_TIME lRefTime = baseTime + streamTime;
if ( lRefTime <= 0 || lRefTime == MAX_TIME )
{
hr = E_INVALIDARG;
}
else
{
*pdwAdviseCookie = m_pSchedule->AddAdvisePacket( lRefTime, 0, HANDLE(hEvent), FALSE );
hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY;
}
return hr;
}
/* Ask for an asynchronous periodic notification that a time has elapsed */
STDMETHODIMP CBaseReferenceClock::AdvisePeriodic(
REFERENCE_TIME StartTime, // starting at this time
REFERENCE_TIME PeriodTime, // time between notifications
HSEMAPHORE hSemaphore, // advise via a semaphore
DWORD_PTR *pdwAdviseCookie) // where your cookie goes
{
CheckPointer(pdwAdviseCookie, E_POINTER);
*pdwAdviseCookie = 0;
HRESULT hr;
if (StartTime > 0 && PeriodTime > 0 && StartTime != MAX_TIME )
{
*pdwAdviseCookie = m_pSchedule->AddAdvisePacket( StartTime, PeriodTime, HANDLE(hSemaphore), TRUE );
hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY;
}
else hr = E_INVALIDARG;
return hr;
}
STDMETHODIMP CBaseReferenceClock::Unadvise(DWORD_PTR dwAdviseCookie)
{
return m_pSchedule->Unadvise(dwAdviseCookie);
}
REFERENCE_TIME CBaseReferenceClock::GetPrivateTime()
{
CAutoLock cObjectLock(this);
/* If the clock has wrapped then the current time will be less than
* the last time we were notified so add on the extra milliseconds
*
* The time period is long enough so that the likelihood of
* successive calls spanning the clock cycle is not considered.
*/
DWORD dwTime = timeGetTime();
{
m_rtPrivateTime += Int32x32To64(UNITS / MILLISECONDS, (DWORD)(dwTime - m_dwPrevSystemTime));
m_dwPrevSystemTime = dwTime;
}
return m_rtPrivateTime;
}
/* Adjust the current time by the input value. This allows an
external time source to work out some of the latency of the clock
system and adjust the "current" time accordingly. The intent is
that the time returned to the user is synchronised to a clock
source and allows drift to be catered for.
For example: if the clock source detects a drift it can pass a delta
to the current time rather than having to set an explicit time.
*/
STDMETHODIMP CBaseReferenceClock::SetTimeDelta(const REFERENCE_TIME & TimeDelta)
{
#ifdef DEBUG
// Just break if passed an improper time delta value
LONGLONG llDelta = TimeDelta > 0 ? TimeDelta : -TimeDelta;
if (llDelta > UNITS * 1000) {
DbgLog((LOG_TRACE, 0, TEXT("Bad Time Delta")));
//DebugBreak();
}
// We're going to calculate a "severity" for the time change. Max -1
// min 8. We'll then use this as the debug logging level for a
// debug log message.
const LONG usDelta = LONG(TimeDelta/10); // Delta in micro-secs
DWORD delta = abs(usDelta); // varying delta
// Severity == 8 - ceil(log<base 8>(abs( micro-secs delta)))
int Severity = 8;
while ( delta > 0 )
{
delta >>= 3; // div 8
Severity--;
}
// Sev == 0 => > 2 second delta!
DbgLog((LOG_TIMING, Severity < 0 ? 0 : Severity,
TEXT("Sev %2i: CSystemClock::SetTimeDelta(%8ld us) %lu -> %lu ms."),
Severity, usDelta, DWORD(ConvertToMilliseconds(m_rtPrivateTime)),
DWORD(ConvertToMilliseconds(TimeDelta+m_rtPrivateTime)) ));
// Don't want the DbgBreak to fire when running stress on debug-builds.
#ifdef BREAK_ON_SEVERE_TIME_DELTA
if (Severity < 0)
DbgBreakPoint(TEXT("SetTimeDelta > 16 seconds!"),
TEXT(__FILE__),__LINE__);
#endif
#endif
CAutoLock cObjectLock(this);
m_rtPrivateTime += TimeDelta;
// If time goes forwards, and we have advises, then we need to
// trigger the thread so that it can re-evaluate its wait time.
// Since we don't want the cost of the thread switches if the change
// is really small, only do it if clock goes forward by more than
// 0.5 millisecond. If the time goes backwards, the thread will
// wake up "early" (relativly speaking) and will re-evaluate at
// that time.
if ( TimeDelta > 5000 && m_pSchedule->GetAdviseCount() > 0 ) TriggerThread();
return NOERROR;
}
// Thread stuff
DWORD __stdcall CBaseReferenceClock::AdviseThreadFunction(LPVOID p)
{
return DWORD(reinterpret_cast<CBaseReferenceClock*>(p)->AdviseThread());
}
HRESULT CBaseReferenceClock::AdviseThread()
{
DWORD dwWait = INFINITE;
// The first thing we do is wait until something interesting happens
// (meaning a first advise or shutdown). This prevents us calling
// GetPrivateTime immediately which is goodness as that is a virtual
// routine and the derived class may not yet be constructed. (This
// thread is created in the base class constructor.)
while ( !m_bAbort )
{
// Wait for an interesting event to happen
DbgLog((LOG_TIMING, 3, TEXT("CBaseRefClock::AdviseThread() Delay: %lu ms"), dwWait ));
WaitForSingleObject(m_pSchedule->GetEvent(), dwWait);
if (m_bAbort) break;
// There are several reasons why we need to work from the internal
// time, mainly to do with what happens when time goes backwards.
// Mainly, it stop us looping madly if an event is just about to
// expire when the clock goes backward (i.e. GetTime stop for a
// while).
const REFERENCE_TIME rtNow = GetPrivateTime();
DbgLog((LOG_TIMING, 3,
TEXT("CBaseRefClock::AdviseThread() Woke at = %lu ms"),
ConvertToMilliseconds(rtNow) ));
// We must add in a millisecond, since this is the resolution of our
// WaitForSingleObject timer. Failure to do so will cause us to loop
// franticly for (approx) 1 a millisecond.
m_rtNextAdvise = m_pSchedule->Advise( 10000 + rtNow );
LONGLONG llWait = m_rtNextAdvise - rtNow;
ASSERT( llWait > 0 );
llWait = ConvertToMilliseconds(llWait);
// DON'T replace this with a max!! (The type's of these things is VERY important)
dwWait = (llWait > REFERENCE_TIME(UINT_MAX)) ? UINT_MAX : DWORD(llWait);
};
return NOERROR;
}

View File

@ -1,171 +0,0 @@
//------------------------------------------------------------------------------
// File: RefClock.h
//
// Desc: DirectShow base classes - defines the IReferenceClock interface.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __BASEREFCLOCK__
#define __BASEREFCLOCK__
#include "dsschedule.h"
const UINT RESOLUTION = 1; /* High resolution timer */
const INT ADVISE_CACHE = 4; /* Default cache size */
const LONGLONG MAX_TIME = 0x7FFFFFFFFFFFFFFF; /* Maximum LONGLONG value */
inline LONGLONG WINAPI ConvertToMilliseconds(const REFERENCE_TIME& RT)
{
/* This converts an arbitrary value representing a reference time
into a MILLISECONDS value for use in subsequent system calls */
return (RT / (UNITS / MILLISECONDS));
}
/* This class hierarchy will support an IReferenceClock interface so
that an audio card (or other externally driven clock) can update the
system wide clock that everyone uses.
The interface will be pretty thin with probably just one update method
This interface has not yet been defined.
*/
/* This abstract base class implements the IReferenceClock
* interface. Classes that actually provide clock signals (from
* whatever source) have to be derived from this class.
*
* The abstract class provides implementations for:
* CUnknown support
* locking support (CCritSec)
* client advise code (creates a thread)
*
* Question: what can we do about quality? Change the timer
* resolution to lower the system load? Up the priority of the
* timer thread to force more responsive signals?
*
* During class construction we create a worker thread that is destroyed during
* destuction. This thread executes a series of WaitForSingleObject calls,
* waking up when a command is given to the thread or the next wake up point
* is reached. The wakeup points are determined by clients making Advise
* calls.
*
* Each advise call defines a point in time when they wish to be notified. A
* periodic advise is a series of these such events. We maintain a list of
* advise links and calculate when the nearest event notification is due for.
* We then call WaitForSingleObject with a timeout equal to this time. The
* handle we wait on is used by the class to signal that something has changed
* and that we must reschedule the next event. This typically happens when
* someone comes in and asks for an advise link while we are waiting for an
* event to timeout.
*
* While we are modifying the list of advise requests we
* are protected from interference through a critical section. Clients are NOT
* advised through callbacks. One shot clients have an event set, while
* periodic clients have a semaphore released for each event notification. A
* semaphore allows a client to be kept up to date with the number of events
* actually triggered and be assured that they can't miss multiple events being
* set.
*
* Keeping track of advises is taken care of by the CAMSchedule class.
*/
class CBaseReferenceClock
: public CUnknown, public IReferenceClock, public CCritSec
{
protected:
virtual ~CBaseReferenceClock(); // Don't let me be created on the stack!
public:
CBaseReferenceClock(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule * pSched = 0 );
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void ** ppv);
DECLARE_IUNKNOWN
/* IReferenceClock methods */
// Derived classes must implement GetPrivateTime(). All our GetTime
// does is call GetPrivateTime and then check so that time does not
// go backwards. A return code of S_FALSE implies that the internal
// clock has gone backwards and GetTime time has halted until internal
// time has caught up. (Don't know if this will be much use to folk,
// but it seems odd not to use the return code for something useful.)
STDMETHODIMP GetTime(REFERENCE_TIME *pTime);
// When this is called, it sets m_rtLastGotTime to the time it returns.
/* Provide standard mechanisms for scheduling events */
/* Ask for an async notification that a time has elapsed */
STDMETHODIMP AdviseTime(
REFERENCE_TIME baseTime, // base reference time
REFERENCE_TIME streamTime, // stream offset time
HEVENT hEvent, // advise via this event
DWORD_PTR *pdwAdviseCookie // where your cookie goes
);
/* Ask for an asynchronous periodic notification that a time has elapsed */
STDMETHODIMP AdvisePeriodic(
REFERENCE_TIME StartTime, // starting at this time
REFERENCE_TIME PeriodTime, // time between notifications
HSEMAPHORE hSemaphore, // advise via a semaphore
DWORD_PTR *pdwAdviseCookie // where your cookie goes
);
/* Cancel a request for notification(s) - if the notification was
* a one shot timer then this function doesn't need to be called
* as the advise is automatically cancelled, however it does no
* harm to explicitly cancel a one-shot advise. It is REQUIRED that
* clients call Unadvise to clear a Periodic advise setting.
*/
STDMETHODIMP Unadvise(DWORD_PTR dwAdviseCookie);
/* Methods for the benefit of derived classes or outer objects */
// GetPrivateTime() is the REAL clock. GetTime is just a cover for
// it. Derived classes will probably override this method but not
// GetTime() itself.
// The important point about GetPrivateTime() is it's allowed to go
// backwards. Our GetTime() will keep returning the LastGotTime
// until GetPrivateTime() catches up.
virtual REFERENCE_TIME GetPrivateTime();
/* Provide a method for correcting drift */
STDMETHODIMP SetTimeDelta( const REFERENCE_TIME& TimeDelta );
CAMSchedule * GetSchedule() const { return m_pSchedule; }
private:
REFERENCE_TIME m_rtPrivateTime; // Current best estimate of time
DWORD m_dwPrevSystemTime; // Last vaule we got from timeGetTime
REFERENCE_TIME m_rtLastGotTime; // Last time returned by GetTime
REFERENCE_TIME m_rtNextAdvise; // Time of next advise
UINT m_TimerResolution;
#ifdef PERF
int m_idGetSystemTime;
#endif
// Thread stuff
public:
void TriggerThread() // Wakes thread up. Need to do this if
{ // time to next advise needs reevaluating.
EXECUTE_ASSERT(SetEvent(m_pSchedule->GetEvent()));
}
private:
BOOL m_bAbort; // Flag used for thread shutdown
HANDLE m_hThread; // Thread handle
HRESULT AdviseThread(); // Method in which the advise thread runs
static DWORD __stdcall AdviseThreadFunction(LPVOID); // Function used to get there
protected:
CAMSchedule * const m_pSchedule;
void Restart (IN REFERENCE_TIME rtMinTime = 0I64) ;
};
#endif

View File

@ -1,116 +0,0 @@
//------------------------------------------------------------------------------
// File: RefTime.h
//
// Desc: DirectShow base classes - defines CRefTime, a class that manages
// reference times.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
//
// CRefTime
//
// Manage reference times.
// Shares same data layout as REFERENCE_TIME, but adds some (nonvirtual)
// functions providing simple comparison, conversion and arithmetic.
//
// A reference time (at the moment) is a unit of seconds represented in
// 100ns units as is used in the Win32 FILETIME structure. BUT the time
// a REFERENCE_TIME represents is NOT the time elapsed since 1/1/1601 it
// will either be stream time or reference time depending upon context
//
// This class provides simple arithmetic operations on reference times
//
// keep non-virtual otherwise the data layout will not be the same as
// REFERENCE_TIME
// -----
// note that you are safe to cast a CRefTime* to a REFERENCE_TIME*, but
// you will need to do so explicitly
// -----
#ifndef __REFTIME__
#define __REFTIME__
const LONGLONG MILLISECONDS = (1000); // 10 ^ 3
const LONGLONG NANOSECONDS = (1000000000); // 10 ^ 9
const LONGLONG UNITS = (NANOSECONDS / 100); // 10 ^ 7
/* Unfortunately an inline function here generates a call to __allmul
- even for constants!
*/
#define MILLISECONDS_TO_100NS_UNITS(lMs) \
Int32x32To64((lMs), (UNITS / MILLISECONDS))
class CRefTime
{
public:
// *MUST* be the only data member so that this class is exactly
// equivalent to a REFERENCE_TIME.
// Also, must be *no virtual functions*
REFERENCE_TIME m_time;
inline CRefTime()
{
// default to 0 time
m_time = 0;
};
inline CRefTime(LONG msecs)
{
m_time = MILLISECONDS_TO_100NS_UNITS(msecs);
};
inline CRefTime(REFERENCE_TIME rt)
{
m_time = rt;
};
inline operator REFERENCE_TIME() const
{
return m_time;
};
inline CRefTime& operator=(const CRefTime& rt)
{
m_time = rt.m_time;
return *this;
};
inline CRefTime& operator=(const LONGLONG ll)
{
m_time = ll;
return *this;
};
inline CRefTime& operator+=(const CRefTime& rt)
{
return (*this = *this + rt);
};
inline CRefTime& operator-=(const CRefTime& rt)
{
return (*this = *this - rt);
};
inline LONG Millisecs(void)
{
return (LONG)(m_time / (UNITS / MILLISECONDS));
};
inline LONGLONG GetUnits(void)
{
return m_time;
};
};
const LONGLONG TimeZero = 0;
#endif /* __REFTIME__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,478 +0,0 @@
//------------------------------------------------------------------------------
// File: RenBase.h
//
// Desc: DirectShow base classes - defines a generic ActiveX base renderer
// class.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __RENBASE__
#define __RENBASE__
// Forward class declarations
class CBaseRenderer;
class CBaseVideoRenderer;
class CRendererInputPin;
// This is our input pin class that channels calls to the renderer
class CRendererInputPin : public CBaseInputPin
{
protected:
CBaseRenderer *m_pRenderer;
public:
CRendererInputPin(CBaseRenderer *pRenderer,
HRESULT *phr,
LPCWSTR Name);
// Overriden from the base pin classes
HRESULT BreakConnect();
HRESULT CompleteConnect(IPin *pReceivePin);
HRESULT SetMediaType(const CMediaType *pmt);
HRESULT CheckMediaType(const CMediaType *pmt);
HRESULT Active();
HRESULT Inactive();
// Add rendering behaviour to interface functions
STDMETHODIMP QueryId(LPWSTR *Id);
STDMETHODIMP EndOfStream();
STDMETHODIMP BeginFlush();
STDMETHODIMP EndFlush();
STDMETHODIMP Receive(IMediaSample *pMediaSample);
// Helper
IMemAllocator inline *Allocator() const
{
return m_pAllocator;
}
};
// Main renderer class that handles synchronisation and state changes
class CBaseRenderer : public CBaseFilter
{
protected:
friend class CRendererInputPin;
friend void CALLBACK EndOfStreamTimer(UINT uID, // Timer identifier
UINT uMsg, // Not currently used
DWORD_PTR dwUser, // User information
DWORD_PTR dw1, // Windows reserved
DWORD_PTR dw2); // Is also reserved
CRendererPosPassThru *m_pPosition; // Media seeking pass by object
CAMEvent m_RenderEvent; // Used to signal timer events
CAMEvent m_ThreadSignal; // Signalled to release worker thread
CAMEvent m_evComplete; // Signalled when state complete
BOOL m_bAbort; // Stop us from rendering more data
BOOL m_bStreaming; // Are we currently streaming
DWORD_PTR m_dwAdvise; // Timer advise cookie
IMediaSample *m_pMediaSample; // Current image media sample
BOOL m_bEOS; // Any more samples in the stream
BOOL m_bEOSDelivered; // Have we delivered an EC_COMPLETE
CRendererInputPin *m_pInputPin; // Our renderer input pin object
CCritSec m_InterfaceLock; // Critical section for interfaces
CCritSec m_RendererLock; // Controls access to internals
IQualityControl * m_pQSink; // QualityControl sink
BOOL m_bRepaintStatus; // Can we signal an EC_REPAINT
// Avoid some deadlocks by tracking filter during stop
volatile BOOL m_bInReceive; // Inside Receive between PrepareReceive
// And actually processing the sample
REFERENCE_TIME m_SignalTime; // Time when we signal EC_COMPLETE
UINT m_EndOfStreamTimer; // Used to signal end of stream
CCritSec m_ObjectCreationLock; // This lock protects the creation and
// of m_pPosition and m_pInputPin. It
// ensures that two threads cannot create
// either object simultaneously.
public:
CBaseRenderer(REFCLSID RenderClass, // CLSID for this renderer
TCHAR *pName, // Debug ONLY description
LPUNKNOWN pUnk, // Aggregated owner object
HRESULT *phr); // General OLE return code
~CBaseRenderer();
// Overriden to say what interfaces we support and where
virtual HRESULT GetMediaPositionInterface(REFIID riid,void **ppv);
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void **);
virtual HRESULT SourceThreadCanWait(BOOL bCanWait);
#ifdef DEBUG
// Debug only dump of the renderer state
void DisplayRendererState();
#endif
virtual HRESULT WaitForRenderTime();
virtual HRESULT CompleteStateChange(FILTER_STATE OldState);
// Return internal information about this filter
BOOL IsEndOfStream() { return m_bEOS; };
BOOL IsEndOfStreamDelivered() { return m_bEOSDelivered; };
BOOL IsStreaming() { return m_bStreaming; };
void SetAbortSignal(BOOL bAbort) { m_bAbort = bAbort; };
virtual void OnReceiveFirstSample(IMediaSample *pMediaSample) { };
CAMEvent *GetRenderEvent() { return &m_RenderEvent; };
// Permit access to the transition state
void Ready() { m_evComplete.Set(); };
void NotReady() { m_evComplete.Reset(); };
BOOL CheckReady() { return m_evComplete.Check(); };
virtual int GetPinCount();
virtual CBasePin *GetPin(int n);
FILTER_STATE GetRealState();
void SendRepaint();
void SendNotifyWindow(IPin *pPin,HWND hwnd);
BOOL OnDisplayChange();
void SetRepaintStatus(BOOL bRepaint);
// Override the filter and pin interface functions
STDMETHODIMP Stop();
STDMETHODIMP Pause();
STDMETHODIMP Run(REFERENCE_TIME StartTime);
STDMETHODIMP GetState(DWORD dwMSecs,FILTER_STATE *State);
STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin);
// These are available for a quality management implementation
virtual void OnRenderStart(IMediaSample *pMediaSample);
virtual void OnRenderEnd(IMediaSample *pMediaSample);
virtual HRESULT OnStartStreaming() { return NOERROR; };
virtual HRESULT OnStopStreaming() { return NOERROR; };
virtual void OnWaitStart() { };
virtual void OnWaitEnd() { };
virtual void PrepareRender() { };
#ifdef PERF
REFERENCE_TIME m_trRenderStart; // Just before we started drawing
// Set in OnRenderStart, Used in OnRenderEnd
int m_idBaseStamp; // MSR_id for frame time stamp
int m_idBaseRenderTime; // MSR_id for true wait time
int m_idBaseAccuracy; // MSR_id for time frame is late (int)
#endif
// Quality management implementation for scheduling rendering
virtual BOOL ScheduleSample(IMediaSample *pMediaSample);
virtual HRESULT GetSampleTimes(IMediaSample *pMediaSample,
REFERENCE_TIME *pStartTime,
REFERENCE_TIME *pEndTime);
virtual HRESULT ShouldDrawSampleNow(IMediaSample *pMediaSample,
REFERENCE_TIME *ptrStart,
REFERENCE_TIME *ptrEnd);
// Lots of end of stream complexities
void TimerCallback();
void ResetEndOfStreamTimer();
HRESULT NotifyEndOfStream();
virtual HRESULT SendEndOfStream();
virtual HRESULT ResetEndOfStream();
virtual HRESULT EndOfStream();
// Rendering is based around the clock
void SignalTimerFired();
virtual HRESULT CancelNotification();
virtual HRESULT ClearPendingSample();
// Called when the filter changes state
virtual HRESULT Active();
virtual HRESULT Inactive();
virtual HRESULT StartStreaming();
virtual HRESULT StopStreaming();
virtual HRESULT BeginFlush();
virtual HRESULT EndFlush();
// Deal with connections and type changes
virtual HRESULT BreakConnect();
virtual HRESULT SetMediaType(const CMediaType *pmt);
virtual HRESULT CompleteConnect(IPin *pReceivePin);
// These look after the handling of data samples
virtual HRESULT PrepareReceive(IMediaSample *pMediaSample);
virtual HRESULT Receive(IMediaSample *pMediaSample);
virtual BOOL HaveCurrentSample();
virtual IMediaSample *GetCurrentSample();
virtual HRESULT Render(IMediaSample *pMediaSample);
// Derived classes MUST override these
virtual HRESULT DoRenderSample(IMediaSample *pMediaSample) PURE;
virtual HRESULT CheckMediaType(const CMediaType *) PURE;
// Helper
void WaitForReceiveToComplete();
};
// CBaseVideoRenderer is a renderer class (see its ancestor class) and
// it handles scheduling of media samples so that they are drawn at the
// correct time by the reference clock. It implements a degradation
// strategy. Possible degradation modes are:
// Drop frames here (only useful if the drawing takes significant time)
// Signal supplier (upstream) to drop some frame(s) - i.e. one-off skip.
// Signal supplier to change the frame rate - i.e. ongoing skipping.
// Or any combination of the above.
// In order to determine what's useful to try we need to know what's going
// on. This is done by timing various operations (including the supplier).
// This timing is done by using timeGetTime as it is accurate enough and
// usually cheaper than calling the reference clock. It also tells the
// truth if there is an audio break and the reference clock stops.
// We provide a number of public entry points (named OnXxxStart, OnXxxEnd)
// which the rest of the renderer calls at significant moments. These do
// the timing.
// the number of frames that the sliding averages are averaged over.
// the rule is (1024*NewObservation + (AVGPERIOD-1) * PreviousAverage)/AVGPERIOD
#define AVGPERIOD 4
#define DO_MOVING_AVG(avg,obs) (avg = (1024*obs + (AVGPERIOD-1)*avg)/AVGPERIOD)
// Spot the bug in this macro - I can't. but it doesn't work!
class CBaseVideoRenderer : public CBaseRenderer, // Base renderer class
public IQualProp, // Property page guff
public IQualityControl // Allow throttling
{
protected:
// Hungarian:
// tFoo is the time Foo in mSec (beware m_tStart from filter.h)
// trBar is the time Bar by the reference clock
//******************************************************************
// State variables to control synchronisation
//******************************************************************
// Control of sending Quality messages. We need to know whether
// we are in trouble (e.g. frames being dropped) and where the time
// is being spent.
// When we drop a frame we play the next one early.
// The frame after that is likely to wait before drawing and counting this
// wait as spare time is unfair, so we count it as a zero wait.
// We therefore need to know whether we are playing frames early or not.
int m_nNormal; // The number of consecutive frames
// drawn at their normal time (not early)
// -1 means we just dropped a frame.
#ifdef PERF
BOOL m_bDrawLateFrames; // Don't drop any frames (debug and I'm
// not keen on people using it!)
#endif
BOOL m_bSupplierHandlingQuality;// The response to Quality messages says
// our supplier is handling things.
// We will allow things to go extra late
// before dropping frames. We will play
// very early after he has dropped one.
// Control of scheduling, frame dropping etc.
// We need to know where the time is being spent so as to tell whether
// we should be taking action here, signalling supplier or what.
// The variables are initialised to a mode of NOT dropping frames.
// They will tell the truth after a few frames.
// We typically record a start time for an event, later we get the time
// again and subtract to get the elapsed time, and we average this over
// a few frames. The average is used to tell what mode we are in.
// Although these are reference times (64 bit) they are all DIFFERENCES
// between times which are small. An int will go up to 214 secs before
// overflow. Avoiding 64 bit multiplications and divisions seems
// worth while.
// Audio-video throttling. If the user has turned up audio quality
// very high (in principle it could be any other stream, not just audio)
// then we can receive cries for help via the graph manager. In this case
// we put in a wait for some time after rendering each frame.
int m_trThrottle;
// The time taken to render (i.e. BitBlt) frames controls which component
// needs to degrade. If the blt is expensive, the renderer degrades.
// If the blt is cheap it's done anyway and the supplier degrades.
int m_trRenderAvg; // Time frames are taking to blt
int m_trRenderLast; // Time for last frame blt
int m_tRenderStart; // Just before we started drawing (mSec)
// derived from timeGetTime.
// When frames are dropped we will play the next frame as early as we can.
// If it was a false alarm and the machine is fast we slide gently back to
// normal timing. To do this, we record the offset showing just how early
// we really are. This will normally be negative meaning early or zero.
int m_trEarliness;
// Target provides slow long-term feedback to try to reduce the
// average sync offset to zero. Whenever a frame is actually rendered
// early we add a msec or two, whenever late we take off a few.
// We add or take off 1/32 of the error time.
// Eventually we should be hovering around zero. For a really bad case
// where we were (say) 300mSec off, it might take 100 odd frames to
// settle down. The rate of change of this is intended to be slower
// than any other mechanism in Quartz, thereby avoiding hunting.
int m_trTarget;
// The proportion of time spent waiting for the right moment to blt
// controls whether we bother to drop a frame or whether we reckon that
// we're doing well enough that we can stand a one-frame glitch.
int m_trWaitAvg; // Average of last few wait times
// (actually we just average how early
// we were). Negative here means LATE.
// The average inter-frame time.
// This is used to calculate the proportion of the time used by the
// three operations (supplying us, waiting, rendering)
int m_trFrameAvg; // Average inter-frame time
int m_trDuration; // duration of last frame.
#ifdef PERF
// Performance logging identifiers
int m_idTimeStamp; // MSR_id for frame time stamp
int m_idEarliness; // MSR_id for earliness fudge
int m_idTarget; // MSR_id for Target fudge
int m_idWaitReal; // MSR_id for true wait time
int m_idWait; // MSR_id for wait time recorded
int m_idFrameAccuracy; // MSR_id for time frame is late (int)
int m_idRenderAvg; // MSR_id for Render time recorded (int)
int m_idSchLateTime; // MSR_id for lateness at scheduler
int m_idQualityRate; // MSR_id for Quality rate requested
int m_idQualityTime; // MSR_id for Quality time requested
int m_idDecision; // MSR_id for decision code
int m_idDuration; // MSR_id for duration of a frame
int m_idThrottle; // MSR_id for audio-video throttling
//int m_idDebug; // MSR_id for trace style debugging
//int m_idSendQuality; // MSR_id for timing the notifications per se
#endif // PERF
REFERENCE_TIME m_trRememberStampForPerf; // original time stamp of frame
// with no earliness fudges etc.
#ifdef PERF
REFERENCE_TIME m_trRememberFrameForPerf; // time when previous frame rendered
// debug...
int m_idFrameAvg;
int m_idWaitAvg;
#endif
// PROPERTY PAGE
// This has edit fields that show the user what's happening
// These member variables hold these counts.
int m_cFramesDropped; // cumulative frames dropped IN THE RENDERER
int m_cFramesDrawn; // Frames since streaming started seen BY THE
// RENDERER (some may be dropped upstream)
// Next two support average sync offset and standard deviation of sync offset.
LONGLONG m_iTotAcc; // Sum of accuracies in mSec
LONGLONG m_iSumSqAcc; // Sum of squares of (accuracies in mSec)
// Next two allow jitter calculation. Jitter is std deviation of frame time.
REFERENCE_TIME m_trLastDraw; // Time of prev frame (for inter-frame times)
LONGLONG m_iSumSqFrameTime; // Sum of squares of (inter-frame time in mSec)
LONGLONG m_iSumFrameTime; // Sum of inter-frame times in mSec
// To get performance statistics on frame rate, jitter etc, we need
// to record the lateness and inter-frame time. What we actually need are the
// data above (sum, sum of squares and number of entries for each) but the data
// is generated just ahead of time and only later do we discover whether the
// frame was actually drawn or not. So we have to hang on to the data
int m_trLate; // hold onto frame lateness
int m_trFrame; // hold onto inter-frame time
int m_tStreamingStart; // if streaming then time streaming started
// else time of last streaming session
// used for property page statistics
#ifdef PERF
LONGLONG m_llTimeOffset; // timeGetTime()*10000+m_llTimeOffset==ref time
#endif
public:
CBaseVideoRenderer(REFCLSID RenderClass, // CLSID for this renderer
TCHAR *pName, // Debug ONLY description
LPUNKNOWN pUnk, // Aggregated owner object
HRESULT *phr); // General OLE return code
~CBaseVideoRenderer();
// IQualityControl methods - Notify allows audio-video throttling
STDMETHODIMP SetSink( IQualityControl * piqc);
STDMETHODIMP Notify( IBaseFilter * pSelf, Quality q);
// These provide a full video quality management implementation
void OnRenderStart(IMediaSample *pMediaSample);
void OnRenderEnd(IMediaSample *pMediaSample);
void OnWaitStart();
void OnWaitEnd();
HRESULT OnStartStreaming();
HRESULT OnStopStreaming();
void ThrottleWait();
// Handle the statistics gathering for our quality management
void PreparePerformanceData(int trLate, int trFrame);
virtual void RecordFrameLateness(int trLate, int trFrame);
virtual void OnDirectRender(IMediaSample *pMediaSample);
virtual HRESULT ResetStreamingTimes();
BOOL ScheduleSample(IMediaSample *pMediaSample);
HRESULT ShouldDrawSampleNow(IMediaSample *pMediaSample,
REFERENCE_TIME *ptrStart,
REFERENCE_TIME *ptrEnd);
virtual HRESULT SendQuality(REFERENCE_TIME trLate, REFERENCE_TIME trRealStream);
STDMETHODIMP JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName);
//
// Do estimates for standard deviations for per-frame
// statistics
//
// *piResult = (llSumSq - iTot * iTot / m_cFramesDrawn - 1) /
// (m_cFramesDrawn - 2)
// or 0 if m_cFramesDrawn <= 3
//
HRESULT GetStdDev(
int nSamples,
int *piResult,
LONGLONG llSumSq,
LONGLONG iTot
);
public:
// IQualProp property page support
STDMETHODIMP get_FramesDroppedInRenderer(int *cFramesDropped);
STDMETHODIMP get_FramesDrawn(int *pcFramesDrawn);
STDMETHODIMP get_AvgFrameRate(int *piAvgFrameRate);
STDMETHODIMP get_Jitter(int *piJitter);
STDMETHODIMP get_AvgSyncOffset(int *piAvg);
STDMETHODIMP get_DevSyncOffset(int *piDev);
// Implement an IUnknown interface and expose IQualProp
DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,VOID **ppv);
};
#endif // __RENBASE__

View File

@ -1,284 +0,0 @@
//------------------------------------------------------------------------------
// File: Schedule.cpp
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
// DbgLog values (all on LOG_TIMING):
//
// 2 for schedulting, firing and shunting of events
// 3 for wait delays and wake-up times of event thread
// 4 for details of whats on the list when the thread awakes
/* Construct & destructors */
CAMSchedule::CAMSchedule( HANDLE ev )
: CBaseObject(TEXT("CAMSchedule"))
, head(&z, 0), z(0, MAX_TIME)
, m_dwNextCookie(0), m_dwAdviseCount(0)
, m_pAdviseCache(0), m_dwCacheCount(0)
, m_ev( ev )
{
head.m_dwAdviseCookie = z.m_dwAdviseCookie = 0;
}
CAMSchedule::~CAMSchedule()
{
m_Serialize.Lock();
// Delete cache
CAdvisePacket * p = m_pAdviseCache;
while (p)
{
CAdvisePacket *const p_next = p->m_next;
delete p;
p = p_next;
}
ASSERT( m_dwAdviseCount == 0 );
// Better to be safe than sorry
if ( m_dwAdviseCount > 0 )
{
DumpLinkedList();
while ( !head.m_next->IsZ() )
{
head.DeleteNext();
--m_dwAdviseCount;
}
}
// If, in the debug version, we assert twice, it means, not only
// did we have left over advises, but we have also let m_dwAdviseCount
// get out of sync. with the number of advises actually on the list.
ASSERT( m_dwAdviseCount == 0 );
m_Serialize.Unlock();
}
/* Public methods */
DWORD CAMSchedule::GetAdviseCount()
{
// No need to lock, m_dwAdviseCount is 32bits & declared volatile
return m_dwAdviseCount;
}
REFERENCE_TIME CAMSchedule::GetNextAdviseTime()
{
CAutoLock lck(&m_Serialize); // Need to stop the linked list from changing
return head.m_next->m_rtEventTime;
}
DWORD_PTR CAMSchedule::AddAdvisePacket
( const REFERENCE_TIME & time1
, const REFERENCE_TIME & time2
, HANDLE h, BOOL periodic
)
{
// Since we use MAX_TIME as a sentry, we can't afford to
// schedule a notification at MAX_TIME
ASSERT( time1 < MAX_TIME );
DWORD_PTR Result;
CAdvisePacket * p;
m_Serialize.Lock();
if (m_pAdviseCache)
{
p = m_pAdviseCache;
m_pAdviseCache = p->m_next;
--m_dwCacheCount;
}
else
{
p = new CAdvisePacket();
}
if (p)
{
p->m_rtEventTime = time1; p->m_rtPeriod = time2;
p->m_hNotify = h; p->m_bPeriodic = periodic;
Result = AddAdvisePacket( p );
}
else Result = 0;
m_Serialize.Unlock();
return Result;
}
HRESULT CAMSchedule::Unadvise(DWORD_PTR dwAdviseCookie)
{
HRESULT hr = S_FALSE;
CAdvisePacket * p_prev = &head;
CAdvisePacket * p_n;
m_Serialize.Lock();
while ( p_n = p_prev->Next() ) // The Next() method returns NULL when it hits z
{
if ( p_n->m_dwAdviseCookie == dwAdviseCookie )
{
Delete( p_prev->RemoveNext() );
--m_dwAdviseCount;
hr = S_OK;
// Having found one cookie that matches, there should be no more
#ifdef DEBUG
while (p_n = p_prev->Next())
{
ASSERT(p_n->m_dwAdviseCookie != dwAdviseCookie);
p_prev = p_n;
}
#endif
break;
}
p_prev = p_n;
};
m_Serialize.Unlock();
return hr;
}
REFERENCE_TIME CAMSchedule::Advise( const REFERENCE_TIME & rtTime )
{
REFERENCE_TIME rtNextTime;
CAdvisePacket * pAdvise;
DbgLog((LOG_TIMING, 2,
TEXT("CAMSchedule::Advise( %lu ms )"), ULONG(rtTime / (UNITS / MILLISECONDS))));
CAutoLock lck(&m_Serialize);
#ifdef DEBUG
if (DbgCheckModuleLevel(LOG_TIMING, 4)) DumpLinkedList();
#endif
// Note - DON'T cache the difference, it might overflow
while ( rtTime >= (rtNextTime = (pAdvise=head.m_next)->m_rtEventTime) &&
!pAdvise->IsZ() )
{
ASSERT(pAdvise->m_dwAdviseCookie); // If this is zero, its the head or the tail!!
ASSERT(pAdvise->m_hNotify != INVALID_HANDLE_VALUE);
if (pAdvise->m_bPeriodic == TRUE)
{
ReleaseSemaphore(pAdvise->m_hNotify,1,NULL);
pAdvise->m_rtEventTime += pAdvise->m_rtPeriod;
ShuntHead();
}
else
{
ASSERT( pAdvise->m_bPeriodic == FALSE );
EXECUTE_ASSERT(SetEvent(pAdvise->m_hNotify));
--m_dwAdviseCount;
Delete( head.RemoveNext() );
}
}
DbgLog((LOG_TIMING, 3,
TEXT("CAMSchedule::Advise() Next time stamp: %lu ms, for advise %lu."),
DWORD(rtNextTime / (UNITS / MILLISECONDS)), pAdvise->m_dwAdviseCookie ));
return rtNextTime;
}
/* Private methods */
DWORD_PTR CAMSchedule::AddAdvisePacket( CAdvisePacket * pPacket )
{
ASSERT(pPacket->m_rtEventTime >= 0 && pPacket->m_rtEventTime < MAX_TIME);
ASSERT(CritCheckIn(&m_Serialize));
CAdvisePacket * p_prev = &head;
CAdvisePacket * p_n;
const DWORD_PTR Result = pPacket->m_dwAdviseCookie = ++m_dwNextCookie;
// This relies on the fact that z is a sentry with a maximal m_rtEventTime
for(;;p_prev = p_n)
{
p_n = p_prev->m_next;
if ( p_n->m_rtEventTime >= pPacket->m_rtEventTime ) break;
}
p_prev->InsertAfter( pPacket );
++m_dwAdviseCount;
DbgLog((LOG_TIMING, 2, TEXT("Added advise %lu, for thread 0x%02X, scheduled at %lu"),
pPacket->m_dwAdviseCookie, GetCurrentThreadId(), (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) ));
// If packet added at the head, then clock needs to re-evaluate wait time.
if ( p_prev == &head ) SetEvent( m_ev );
return Result;
}
void CAMSchedule::Delete( CAdvisePacket * pPacket )
{
if ( m_dwCacheCount >= dwCacheMax ) delete pPacket;
else
{
m_Serialize.Lock();
pPacket->m_next = m_pAdviseCache;
m_pAdviseCache = pPacket;
++m_dwCacheCount;
m_Serialize.Unlock();
}
}
// Takes the head of the list & repositions it
void CAMSchedule::ShuntHead()
{
CAdvisePacket * p_prev = &head;
CAdvisePacket * p_n;
m_Serialize.Lock();
CAdvisePacket *const pPacket = head.m_next;
// This will catch both an empty list,
// and if somehow a MAX_TIME time gets into the list
// (which would also break this method).
ASSERT( pPacket->m_rtEventTime < MAX_TIME );
// This relies on the fact that z is a sentry with a maximal m_rtEventTime
for(;;p_prev = p_n)
{
p_n = p_prev->m_next;
if ( p_n->m_rtEventTime > pPacket->m_rtEventTime ) break;
}
// If p_prev == pPacket then we're already in the right place
if (p_prev != pPacket)
{
head.m_next = pPacket->m_next;
(p_prev->m_next = pPacket)->m_next = p_n;
}
#ifdef DEBUG
DbgLog((LOG_TIMING, 2, TEXT("Periodic advise %lu, shunted to %lu"),
pPacket->m_dwAdviseCookie, (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) ));
#endif
m_Serialize.Unlock();
}
#ifdef DEBUG
void CAMSchedule::DumpLinkedList()
{
m_Serialize.Lock();
int i=0;
DbgLog((LOG_TIMING, 1, TEXT("CAMSchedule::DumpLinkedList() this = 0x%p"), this));
for ( CAdvisePacket * p = &head
; p
; p = p->m_next , i++
)
{
DbgLog((LOG_TIMING, 1, TEXT("Advise List # %lu, Cookie %d, RefTime %lu"),
i,
p->m_dwAdviseCookie,
p->m_rtEventTime / (UNITS / MILLISECONDS)
));
}
m_Serialize.Unlock();
}
#endif

View File

@ -1,128 +0,0 @@
//------------------------------------------------------------------------------
// File: Schedule.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __CAMSchedule__
#define __CAMSchedule__
class CAMSchedule : private CBaseObject
{
public:
virtual ~CAMSchedule();
// ev is the event we should fire if the advise time needs re-evaluating
CAMSchedule( HANDLE ev );
DWORD GetAdviseCount();
REFERENCE_TIME GetNextAdviseTime();
// We need a method for derived classes to add advise packets, we return the cookie
DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic );
// And a way to cancel
HRESULT Unadvise(DWORD_PTR dwAdviseCookie);
// Tell us the time please, and we'll dispatch the expired events. We return the time of the next event.
// NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of
// whoever is using this helper class (typically a clock).
REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime );
// Get the event handle which will be set if advise time requires re-evaluation.
HANDLE GetEvent() const { return m_ev; }
private:
// We define the nodes that will be used in our singly linked list
// of advise packets. The list is ordered by time, with the
// elements that will expire first at the front.
class CAdvisePacket
{
public:
CAdvisePacket()
{}
CAdvisePacket * m_next;
DWORD_PTR m_dwAdviseCookie;
REFERENCE_TIME m_rtEventTime; // Time at which event should be set
REFERENCE_TIME m_rtPeriod; // Periodic time
HANDLE m_hNotify; // Handle to event or semephore
BOOL m_bPeriodic; // TRUE => Periodic event
CAdvisePacket( CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time)
{}
void InsertAfter( CAdvisePacket * p )
{
p->m_next = m_next;
m_next = p;
}
int IsZ() const // That is, is it the node that represents the end of the list
{ return m_next == 0; }
CAdvisePacket * RemoveNext()
{
CAdvisePacket *const next = m_next;
CAdvisePacket *const new_next = next->m_next;
m_next = new_next;
return next;
}
void DeleteNext()
{
delete RemoveNext();
}
CAdvisePacket * Next() const
{
CAdvisePacket * result = m_next;
if (result->IsZ()) result = 0;
return result;
}
DWORD_PTR Cookie() const
{ return m_dwAdviseCookie; }
};
// Structure is:
// head -> elmt1 -> elmt2 -> z -> null
// So an empty list is: head -> z -> null
// Having head & z as links makes insertaion,
// deletion and shunting much easier.
CAdvisePacket head, z; // z is both a tail and a sentry
volatile DWORD_PTR m_dwNextCookie; // Strictly increasing
volatile DWORD m_dwAdviseCount; // Number of elements on list
CCritSec m_Serialize;
// AddAdvisePacket: adds the packet, returns the cookie (0 if failed)
DWORD_PTR AddAdvisePacket( CAdvisePacket * pPacket );
// Event that we should set if the packed added above will be the next to fire.
const HANDLE m_ev;
// A Shunt is where we have changed the first element in the
// list and want it re-evaluating (i.e. repositioned) in
// the list.
void ShuntHead();
// Rather than delete advise packets, we cache them for future use
CAdvisePacket * m_pAdviseCache;
DWORD m_dwCacheCount;
enum { dwCacheMax = 5 }; // Don't bother caching more than five
void Delete( CAdvisePacket * pLink );// This "Delete" will cache the Link
// Attributes and methods for debugging
public:
#ifdef DEBUG
void DumpLinkedList();
#else
void DumpLinkedList() {}
#endif
};
#endif // __CAMSchedule__

View File

@ -1,83 +0,0 @@
//------------------------------------------------------------------------------
// File: SeekPT.cpp
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include "seekpt.h"
//==================================================================
// CreateInstance
// This goes in the factory template table to create new instances
// If there is already a mapper instance - return that, else make one
// and save it in a static variable so that forever after we can return that.
//==================================================================
CUnknown * CSeekingPassThru::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
{
return new CSeekingPassThru(NAME("Seeking PassThru"),pUnk, phr);
}
STDMETHODIMP CSeekingPassThru::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
{
if (riid == IID_ISeekingPassThru) {
return GetInterface((ISeekingPassThru *) this, ppv);
} else {
if (m_pPosPassThru &&
(riid == IID_IMediaSeeking ||
riid == IID_IMediaPosition)) {
return m_pPosPassThru->NonDelegatingQueryInterface(riid,ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}
}
CSeekingPassThru::CSeekingPassThru( TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr )
: CUnknown(pName, pUnk, phr),
m_pPosPassThru(NULL)
{
}
CSeekingPassThru::~CSeekingPassThru()
{
delete m_pPosPassThru;
}
STDMETHODIMP CSeekingPassThru::Init(BOOL bRendererSeeking, IPin *pPin)
{
HRESULT hr = NOERROR;
if (m_pPosPassThru) {
hr = E_FAIL;
} else {
m_pPosPassThru =
bRendererSeeking ?
new CRendererPosPassThru(
NAME("Render Seeking COM object"),
(IUnknown *)this,
&hr,
pPin) :
new CPosPassThru(
NAME("Render Seeking COM object"),
(IUnknown *)this,
&hr,
pPin);
if (!m_pPosPassThru) {
hr = E_OUTOFMEMORY;
} else {
if (FAILED(hr)) {
delete m_pPosPassThru;
m_pPosPassThru = NULL;
}
}
}
return hr;
}

View File

@ -1,30 +0,0 @@
//------------------------------------------------------------------------------
// File: SeekPT.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __seekpt_h__
#define __seekpt_h__
class CSeekingPassThru : public ISeekingPassThru, public CUnknown
{
public:
static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
CSeekingPassThru(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr);
~CSeekingPassThru();
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
STDMETHODIMP Init(BOOL bSupportRendering, IPin *pPin);
private:
CPosPassThru *m_pPosPassThru;
};
#endif

View File

@ -1,522 +0,0 @@
//------------------------------------------------------------------------------
// File: Source.cpp
//
// Desc: DirectShow base classes - implements CSource, which is a Quartz
// source filter 'template.'
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// Locking Strategy.
//
// Hold the filter critical section (m_pFilter->pStateLock()) to serialise
// access to functions. Note that, in general, this lock may be held
// by a function when the worker thread may want to hold it. Therefore
// if you wish to access shared state from the worker thread you will
// need to add another critical section object. The execption is during
// the threads processing loop, when it is safe to get the filter critical
// section from within FillBuffer().
#include <streams.h>
//
// CSource::Constructor
//
// Initialise the pin count for the filter. The user will create the pins in
// the derived class.
CSource::CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid)
: CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
m_iPins(0),
m_paStreams(NULL)
{
}
CSource::CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr)
: CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
m_iPins(0),
m_paStreams(NULL)
{
UNREFERENCED_PARAMETER(phr);
}
#ifdef UNICODE
CSource::CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid)
: CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
m_iPins(0),
m_paStreams(NULL)
{
}
CSource::CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr)
: CBaseFilter(pName, lpunk, &m_cStateLock, clsid),
m_iPins(0),
m_paStreams(NULL)
{
UNREFERENCED_PARAMETER(phr);
}
#endif
//
// CSource::Destructor
//
CSource::~CSource()
{
/* Free our pins and pin array */
while (m_iPins != 0) {
// deleting the pins causes them to be removed from the array...
delete m_paStreams[m_iPins - 1];
}
ASSERT(m_paStreams == NULL);
}
//
// Add a new pin
//
HRESULT CSource::AddPin(CSourceStream *pStream)
{
CAutoLock lock(&m_cStateLock);
/* Allocate space for this pin and the old ones */
CSourceStream **paStreams = new CSourceStream *[m_iPins + 1];
if (paStreams == NULL) {
return E_OUTOFMEMORY;
}
if (m_paStreams != NULL) {
CopyMemory((PVOID)paStreams, (PVOID)m_paStreams,
m_iPins * sizeof(m_paStreams[0]));
paStreams[m_iPins] = pStream;
delete [] m_paStreams;
}
m_paStreams = paStreams;
m_paStreams[m_iPins] = pStream;
m_iPins++;
return S_OK;
}
//
// Remove a pin - pStream is NOT deleted
//
HRESULT CSource::RemovePin(CSourceStream *pStream)
{
int i;
for (i = 0; i < m_iPins; i++) {
if (m_paStreams[i] == pStream) {
if (m_iPins == 1) {
delete [] m_paStreams;
m_paStreams = NULL;
} else {
/* no need to reallocate */
while (++i < m_iPins)
m_paStreams[i - 1] = m_paStreams[i];
}
m_iPins--;
return S_OK;
}
}
return S_FALSE;
}
//
// FindPin
//
// Set *ppPin to the IPin* that has the id Id.
// or to NULL if the Id cannot be matched.
STDMETHODIMP CSource::FindPin(LPCWSTR Id, IPin **ppPin)
{
CheckPointer(ppPin,E_POINTER);
ValidateReadWritePtr(ppPin,sizeof(IPin *));
// The -1 undoes the +1 in QueryId and ensures that totally invalid
// strings (for which WstrToInt delivers 0) give a deliver a NULL pin.
int i = WstrToInt(Id) -1;
*ppPin = GetPin(i);
if (*ppPin!=NULL){
(*ppPin)->AddRef();
return NOERROR;
} else {
return VFW_E_NOT_FOUND;
}
}
//
// FindPinNumber
//
// return the number of the pin with this IPin* or -1 if none
int CSource::FindPinNumber(IPin *iPin) {
int i;
for (i=0; i<m_iPins; ++i) {
if ((IPin *)(m_paStreams[i])==iPin) {
return i;
}
}
return -1;
}
//
// GetPinCount
//
// Returns the number of pins this filter has
int CSource::GetPinCount(void) {
CAutoLock lock(&m_cStateLock);
return m_iPins;
}
//
// GetPin
//
// Return a non-addref'd pointer to pin n
// needed by CBaseFilter
CBasePin *CSource::GetPin(int n) {
CAutoLock lock(&m_cStateLock);
// n must be in the range 0..m_iPins-1
// if m_iPins>n && n>=0 it follows that m_iPins>0
// which is what used to be checked (i.e. checking that we have a pin)
if ((n >= 0) && (n < m_iPins)) {
ASSERT(m_paStreams[n]);
return m_paStreams[n];
}
return NULL;
}
//
// *
// * --- CSourceStream ----
// *
//
// Set Id to point to a CoTaskMemAlloc'd
STDMETHODIMP CSourceStream::QueryId(LPWSTR *Id) {
CheckPointer(Id,E_POINTER);
ValidateReadWritePtr(Id,sizeof(LPWSTR));
// We give the pins id's which are 1,2,...
// FindPinNumber returns -1 for an invalid pin
int i = 1+ m_pFilter->FindPinNumber(this);
if (i<1) return VFW_E_NOT_FOUND;
*Id = (LPWSTR)CoTaskMemAlloc(4*sizeof(WCHAR));
if (*Id==NULL) {
return E_OUTOFMEMORY;
}
IntToWstr(i, *Id, 4);
return NOERROR;
}
//
// CSourceStream::Constructor
//
// increments the number of pins present on the filter
CSourceStream::CSourceStream(
TCHAR *pObjectName,
HRESULT *phr,
CSource *ps,
LPCWSTR pPinName)
: CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),
m_pFilter(ps) {
*phr = m_pFilter->AddPin(this);
}
#ifdef UNICODE
CSourceStream::CSourceStream(
char *pObjectName,
HRESULT *phr,
CSource *ps,
LPCWSTR pPinName)
: CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName),
m_pFilter(ps) {
*phr = m_pFilter->AddPin(this);
}
#endif
//
// CSourceStream::Destructor
//
// Decrements the number of pins on this filter
CSourceStream::~CSourceStream(void) {
m_pFilter->RemovePin(this);
}
//
// CheckMediaType
//
// Do we support this type? Provides the default support for 1 type.
HRESULT CSourceStream::CheckMediaType(const CMediaType *pMediaType) {
CAutoLock lock(m_pFilter->pStateLock());
CMediaType mt;
GetMediaType(&mt);
if (mt == *pMediaType) {
return NOERROR;
}
return E_FAIL;
}
//
// GetMediaType/3
//
// By default we support only one type
// iPosition indexes are 0-n
HRESULT CSourceStream::GetMediaType(int iPosition, CMediaType *pMediaType) {
CAutoLock lock(m_pFilter->pStateLock());
if (iPosition<0) {
return E_INVALIDARG;
}
if (iPosition>0) {
return VFW_S_NO_MORE_ITEMS;
}
return GetMediaType(pMediaType);
}
//
// Active
//
// The pin is active - start up the worker thread
HRESULT CSourceStream::Active(void) {
CAutoLock lock(m_pFilter->pStateLock());
HRESULT hr;
if (m_pFilter->IsActive()) {
return S_FALSE; // succeeded, but did not allocate resources (they already exist...)
}
// do nothing if not connected - its ok not to connect to
// all pins of a source filter
if (!IsConnected()) {
return NOERROR;
}
hr = CBaseOutputPin::Active();
if (FAILED(hr)) {
return hr;
}
ASSERT(!ThreadExists());
// start the thread
if (!Create()) {
return E_FAIL;
}
// Tell thread to initialize. If OnThreadCreate Fails, so does this.
hr = Init();
if (FAILED(hr))
return hr;
return Pause();
}
//
// Inactive
//
// Pin is inactive - shut down the worker thread
// Waits for the worker to exit before returning.
HRESULT CSourceStream::Inactive(void) {
CAutoLock lock(m_pFilter->pStateLock());
HRESULT hr;
// do nothing if not connected - its ok not to connect to
// all pins of a source filter
if (!IsConnected()) {
return NOERROR;
}
// !!! need to do this before trying to stop the thread, because
// we may be stuck waiting for our own allocator!!!
hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator
if (FAILED(hr)) {
return hr;
}
if (ThreadExists()) {
hr = Stop();
if (FAILED(hr)) {
return hr;
}
hr = Exit();
if (FAILED(hr)) {
return hr;
}
Close(); // Wait for the thread to exit, then tidy up.
}
// hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator
//if (FAILED(hr)) {
// return hr;
//}
return NOERROR;
}
//
// ThreadProc
//
// When this returns the thread exits
// Return codes > 0 indicate an error occured
DWORD CSourceStream::ThreadProc(void) {
HRESULT hr; // the return code from calls
Command com;
do {
com = GetRequest();
if (com != CMD_INIT) {
DbgLog((LOG_ERROR, 1, TEXT("Thread expected init command")));
Reply((DWORD) E_UNEXPECTED);
}
} while (com != CMD_INIT);
DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread initializing")));
hr = OnThreadCreate(); // perform set up tasks
if (FAILED(hr)) {
DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadCreate failed. Aborting thread.")));
OnThreadDestroy();
Reply(hr); // send failed return code from OnThreadCreate
return 1;
}
// Initialisation suceeded
Reply(NOERROR);
Command cmd;
do {
cmd = GetRequest();
switch (cmd) {
case CMD_EXIT:
Reply(NOERROR);
break;
case CMD_RUN:
DbgLog((LOG_ERROR, 1, TEXT("CMD_RUN received before a CMD_PAUSE???")));
// !!! fall through???
case CMD_PAUSE:
Reply(NOERROR);
DoBufferProcessingLoop();
break;
case CMD_STOP:
Reply(NOERROR);
break;
default:
DbgLog((LOG_ERROR, 1, TEXT("Unknown command %d received!"), cmd));
Reply((DWORD) E_NOTIMPL);
break;
}
} while (cmd != CMD_EXIT);
hr = OnThreadDestroy(); // tidy up.
if (FAILED(hr)) {
DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadDestroy failed. Exiting thread.")));
return 1;
}
DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread exiting")));
return 0;
}
//
// DoBufferProcessingLoop
//
// Grabs a buffer and calls the users processing function.
// Overridable, so that different delivery styles can be catered for.
HRESULT CSourceStream::DoBufferProcessingLoop(void) {
Command com;
OnThreadStartPlay();
do {
while (!CheckRequest(&com)) {
IMediaSample *pSample;
HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
if (FAILED(hr)) {
Sleep(1);
continue; // go round again. Perhaps the error will go away
// or the allocator is decommited & we will be asked to
// exit soon.
}
// Virtual function user will override.
hr = FillBuffer(pSample);
if (hr == S_OK) {
hr = Deliver(pSample);
pSample->Release();
// downstream filter returns S_FALSE if it wants us to
// stop or an error if it's reporting an error.
if(hr != S_OK)
{
DbgLog((LOG_TRACE, 2, TEXT("Deliver() returned %08x; stopping"), hr));
return S_OK;
}
} else if (hr == S_FALSE) {
// derived class wants us to stop pushing data
pSample->Release();
DeliverEndOfStream();
return S_OK;
} else {
// derived class encountered an error
pSample->Release();
DbgLog((LOG_ERROR, 1, TEXT("Error %08lX from FillBuffer!!!"), hr));
DeliverEndOfStream();
m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
return hr;
}
// all paths release the sample
}
// For all commands sent to us there must be a Reply call!
if (com == CMD_RUN || com == CMD_PAUSE) {
Reply(NOERROR);
} else if (com != CMD_STOP) {
Reply((DWORD) E_UNEXPECTED);
DbgLog((LOG_ERROR, 1, TEXT("Unexpected command!!!")));
}
} while (com != CMD_STOP);
return S_FALSE;
}

Some files were not shown because too many files have changed in this diff Show More