Initial commit: ROW Client source code
Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
@@ -0,0 +1,147 @@
|
||||
# Microsoft Developer Studio Project File - Name="Cube" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=Cube - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Cube.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Cube.mak" CFG="Cube - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Cube - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "Cube - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Cube - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\DirectShow\BaseClasses" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 ..\..\..\DirectShow\BaseClasses\Release\strmbase.lib strmiids.lib quartz.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /OPT:NOREF /OPT:ICF
|
||||
|
||||
!ELSEIF "$(CFG)" == "Cube - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "..\..\..\DirectShow\BaseClasses" /D "_DEBUG" /D "DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 ..\..\..\DirectShow\BaseClasses\Debug\strmbasd.lib strmiids.lib quartz.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Cube - Win32 Release"
|
||||
# Name "Cube - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\commands.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\compositor.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\project.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Cube.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Cube.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\toolbar.bmp
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Cube"=".\Cube.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,992 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: app.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - VMR-based Cube video player
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlconv.cpp>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include <initguid.h>
|
||||
#include "project.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Global variables that are initialized at run time and then stay constant.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
HINSTANCE hInst;
|
||||
HICON hIconVideoCd;
|
||||
HWND hwndApp;
|
||||
HWND g_hwndToolbar;
|
||||
CMpegMovie *pMpegMovie;
|
||||
|
||||
BOOL m_bFullScreen = FALSE;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** True Globals - these may change during execution of the program.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
DWORD g_State = VCD_NO_CD;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
const TCHAR szClassName[] = TEXT("VMR_CubePlayer_CLASS");
|
||||
const TCHAR g_szNULL[] = TEXT("\0");
|
||||
const TCHAR g_szEmpty[] = TEXT("");
|
||||
|
||||
/*
|
||||
** User interface values
|
||||
*/
|
||||
int dyToolbar;
|
||||
const int dxBitmap = 16;
|
||||
const int dyBitmap = 15;
|
||||
const int dxButtonSep = 8;
|
||||
const TCHAR g_chNULL = TEXT('\0');
|
||||
const LONG g_Style = WS_THICKFRAME | WS_POPUP | WS_CAPTION |
|
||||
WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
|
||||
WS_CLIPCHILDREN;
|
||||
|
||||
|
||||
const TBBUTTON tbButtons[DEFAULT_TBAR_SIZE] = {
|
||||
{ IDX_SEPARATOR, 1, 0, TBSTYLE_SEP },
|
||||
{ IDX_1, IDM_MOVIE_PLAY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
|
||||
{ IDX_2, IDM_MOVIE_PAUSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
|
||||
{ IDX_3, IDM_MOVIE_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
|
||||
{ IDX_SEPARATOR, 1, 0, TBSTYLE_SEP },
|
||||
{ IDX_4, IDM_FULL_SCREEN, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0, 0, -1 }
|
||||
};
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Local function prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
void SetFullScreenMode(BOOL bMode);
|
||||
BOOL IsFullScreenMode();
|
||||
LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* WinMain
|
||||
*
|
||||
*
|
||||
* Windows recognizes this function by name as the initial entry point
|
||||
* for the program. This function calls the application initialization
|
||||
* routine, if no other instance of the program is running, and always
|
||||
* calls the instance initialization routine. It then executes a message
|
||||
* retrieval and dispatch loop that is the top-level control structure
|
||||
* for the remainder of execution. The loop is terminated when a WM_QUIT
|
||||
* message is received, at which time this function exits the application
|
||||
* instance by returning the value passed by PostQuitMessage().
|
||||
*
|
||||
* If this function must abort before entering the message loop, it
|
||||
* returns the conventional value NULL.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int PASCAL
|
||||
WinMain(
|
||||
HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLineOld,
|
||||
int nCmdShow
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
HRESULT hres = CoInitialize(NULL);
|
||||
if(hres == S_FALSE)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
if(!hPrevInstance)
|
||||
{
|
||||
if(!InitApplication(hInstance))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform initializations that apply to a specific instance
|
||||
*/
|
||||
if(!InitInstance(hInstance, nCmdShow))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Verify that the VMR is present on this system */
|
||||
if(!VerifyVMR())
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
** Acquire and dispatch messages until a WM_QUIT message is received.
|
||||
*/
|
||||
int iRet = DoMainLoop();
|
||||
QzUninitialize();
|
||||
return iRet;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DoMainLoop
|
||||
*
|
||||
* Process the main message loop
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
DoMainLoop(
|
||||
void
|
||||
)
|
||||
{
|
||||
MSG msg;
|
||||
HANDLE ahObjects[8];;
|
||||
int cObjects;
|
||||
HACCEL haccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
|
||||
|
||||
//
|
||||
// message loop lasts until we get a WM_QUIT message
|
||||
//
|
||||
for(;;)
|
||||
{
|
||||
if(pMpegMovie != NULL)
|
||||
{
|
||||
cObjects = 1;
|
||||
ahObjects[0] = pMpegMovie->GetMovieEventHandle();
|
||||
}
|
||||
else
|
||||
{
|
||||
ahObjects[0] = NULL;
|
||||
cObjects = 0;
|
||||
}
|
||||
|
||||
if(ahObjects[0] == NULL)
|
||||
{
|
||||
WaitMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// wait for any message sent or posted to this queue
|
||||
// or for a graph notification
|
||||
//
|
||||
DWORD result;
|
||||
|
||||
result = MsgWaitForMultipleObjects(cObjects, ahObjects, FALSE,
|
||||
INFINITE, QS_ALLINPUT);
|
||||
if(result != (WAIT_OBJECT_0 + cObjects))
|
||||
{
|
||||
VideoCd_OnGraphNotify(result - WAIT_OBJECT_0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// When here, we either have a message or no event handle
|
||||
// has been created yet.
|
||||
//
|
||||
// read all of the messages in this next loop
|
||||
// removing each message as we read it
|
||||
//
|
||||
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if(msg.message == WM_QUIT)
|
||||
{
|
||||
return (int) msg.wParam;
|
||||
}
|
||||
|
||||
if(!TranslateAccelerator(hwndApp, haccel, &msg))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // DoMainLoop
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitApplication(HANDLE)
|
||||
*
|
||||
* This function is called at initialization time only if no other
|
||||
* instances of the application are running. This function performs
|
||||
* initialization tasks that can be done once for any number of running
|
||||
* instances.
|
||||
*
|
||||
* In this case, we initialize a window class by filling out a data
|
||||
* structure of type WNDCLASS and calling the Windows RegisterClass()
|
||||
* function. Since all instances of this application use the same window
|
||||
* class, we only need to do this when the first instance is initialized.
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
InitApplication(
|
||||
HINSTANCE hInstance
|
||||
)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
|
||||
/*
|
||||
** Fill in window class structure with parameters that describe the
|
||||
** main window.
|
||||
*/
|
||||
hIconVideoCd = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_VIDEOCD_ICON));
|
||||
|
||||
wc.style = CS_VREDRAW | CS_HREDRAW;
|
||||
wc.lpfnWndProc = VideoCdWndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = hIconVideoCd;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)NULL;
|
||||
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN_MENU);
|
||||
wc.lpszClassName = szClassName;
|
||||
|
||||
/*
|
||||
** Register the window class and return success/failure code.
|
||||
*/
|
||||
return RegisterClass(&wc);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitInstance
|
||||
*
|
||||
* This function is called at initialization time for every instance of
|
||||
* this application. This function performs initialization tasks that
|
||||
* cannot be shared by multiple instances.
|
||||
*
|
||||
* In this case, we save the instance handle in a static variable and
|
||||
* create and display the main program window.
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
InitInstance(
|
||||
HINSTANCE hInstance,
|
||||
int nCmdShow
|
||||
)
|
||||
{
|
||||
HWND hwnd;
|
||||
RECT rc;
|
||||
|
||||
/*
|
||||
** Save the instance handle in static variable, which will be used
|
||||
** in many subsequent calls to Windows.
|
||||
*/
|
||||
hInst = hInstance;
|
||||
rc.left = rc.top = 100;
|
||||
rc.bottom = rc.right = 400;
|
||||
|
||||
/*
|
||||
** Create a main window for this application instance.
|
||||
*/
|
||||
hwnd = CreateWindow(szClassName, IdStr(STR_APP_TITLE), g_Style,
|
||||
rc.left, rc.top,
|
||||
rc.right, rc.bottom,
|
||||
NULL, NULL, hInstance, NULL);
|
||||
|
||||
/*
|
||||
** If window could not be created, return "failure"
|
||||
*/
|
||||
if(NULL == hwnd)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
hwndApp = hwnd;
|
||||
|
||||
/*
|
||||
** Make the window visible; update its client area; and return "success"
|
||||
*/
|
||||
SetPlayButtonsEnableState();
|
||||
ShowWindow(hwnd, nCmdShow);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetMoviePosition
|
||||
*
|
||||
* Place the movie in the centre of the client window.
|
||||
* We do not stretch the the movie yet.
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
GetMoviePosition(
|
||||
HWND hwnd,
|
||||
long* xPos,
|
||||
long* yPos,
|
||||
long* pcx,
|
||||
long* pcy
|
||||
)
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
GetAdjustedClientRect(&rc);
|
||||
|
||||
*xPos = rc.left;
|
||||
*yPos = rc.top;
|
||||
*pcx = rc.right - rc.left;
|
||||
*pcy = rc.bottom - rc.top;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RepositionMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
RepositionMovie(HWND hwnd)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
long xPos, yPos, cx, cy;
|
||||
|
||||
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
|
||||
|
||||
pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
|
||||
InvalidateRect(hwnd, NULL, false);
|
||||
UpdateWindow(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnMove
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnMove(
|
||||
HWND hwnd,
|
||||
int x,
|
||||
int y
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
if(pMpegMovie->GetStateMovie() != State_Running)
|
||||
{
|
||||
RepositionMovie(hwnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
long xPos, yPos, cx, cy;
|
||||
|
||||
// Reposition movie but don't invalidate the rect, since
|
||||
// the next video frame will handle the redraw.
|
||||
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
|
||||
pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCdWndProc
|
||||
*
|
||||
\**************************************************************************/
|
||||
LRESULT CALLBACK
|
||||
VideoCdWndProc(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch(message)
|
||||
{
|
||||
HANDLE_MSG(hwnd, WM_CREATE, VideoCd_OnCreate);
|
||||
HANDLE_MSG(hwnd, WM_PAINT, VideoCd_OnPaint);
|
||||
HANDLE_MSG(hwnd, WM_COMMAND, VideoCd_OnCommand);
|
||||
HANDLE_MSG(hwnd, WM_CLOSE, VideoCd_OnClose);
|
||||
HANDLE_MSG(hwnd, WM_DESTROY, VideoCd_OnDestroy);
|
||||
HANDLE_MSG(hwnd, WM_SIZE, VideoCd_OnSize);
|
||||
HANDLE_MSG(hwnd, WM_SYSCOLORCHANGE, VideoCd_OnSysColorChange);
|
||||
HANDLE_MSG(hwnd, WM_INITMENUPOPUP, VideoCd_OnInitMenuPopup);
|
||||
HANDLE_MSG(hwnd, WM_NOTIFY, VideoCd_OnNotify);
|
||||
HANDLE_MSG(hwnd, WM_KEYUP, VideoCd_OnKeyUp);
|
||||
HANDLE_MSG(hwnd, WM_MOVE, VideoCd_OnMove);
|
||||
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->DisplayModeChanged();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnCreate
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VideoCd_OnCreate(
|
||||
HWND hwnd,
|
||||
LPCREATESTRUCT lpCreateStruct
|
||||
)
|
||||
{
|
||||
InitCommonControls();
|
||||
|
||||
/*
|
||||
** Create the toolbar and statusbar.
|
||||
*/
|
||||
g_hwndToolbar = CreateToolbarEx(hwnd,
|
||||
WS_VISIBLE | WS_CHILD |
|
||||
TBSTYLE_TOOLTIPS | CCS_NODIVIDER,
|
||||
ID_TOOLBAR, NUMBER_OF_BITMAPS,
|
||||
hInst, IDR_TOOLBAR, tbButtons,
|
||||
DEFAULT_TBAR_SIZE, dxBitmap, dyBitmap,
|
||||
dxBitmap, dyBitmap, sizeof(TBBUTTON));
|
||||
|
||||
if(g_hwndToolbar == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnKeyUp
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnKeyUp(
|
||||
HWND hwnd,
|
||||
UINT vk,
|
||||
BOOL fDown,
|
||||
int cRepeat,
|
||||
UINT flags
|
||||
)
|
||||
{
|
||||
// Catch escape sequences to stop fullscreen mode
|
||||
if((vk == VK_ESCAPE) || (vk == VK_RETURN))
|
||||
{
|
||||
if(pMpegMovie && IsFullScreenMode())
|
||||
{
|
||||
SetFullScreenMode(FALSE);
|
||||
SetPlayButtonsEnableState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnPaint
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnPaint(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
RECT rc1;
|
||||
RECT rc2;
|
||||
|
||||
/*
|
||||
** Draw a frame around the movie playback area.
|
||||
*/
|
||||
GetClientRect(hwnd, &rc2);
|
||||
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
|
||||
if(pMpegMovie)
|
||||
{
|
||||
long xPos, yPos, cx, cy;
|
||||
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
|
||||
SetRect(&rc1, xPos, yPos, xPos + cx, yPos + cy);
|
||||
|
||||
HRGN rgnClient = CreateRectRgnIndirect(&rc2);
|
||||
HRGN rgnVideo = CreateRectRgnIndirect(&rc1);
|
||||
CombineRgn(rgnClient, rgnClient, rgnVideo, RGN_DIFF);
|
||||
|
||||
HBRUSH hbr = GetSysColorBrush(COLOR_BTNFACE);
|
||||
FillRgn(hdc, rgnClient, hbr);
|
||||
DeleteObject(hbr);
|
||||
DeleteObject(rgnClient);
|
||||
DeleteObject(rgnVideo);
|
||||
|
||||
pMpegMovie->RepaintVideo(hwnd, hdc);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1));
|
||||
}
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* AboutDlgProc
|
||||
*
|
||||
\**************************************************************************/
|
||||
LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
if(wParam == IDOK)
|
||||
{
|
||||
EndDialog(hWnd, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnCommand
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnCommand(
|
||||
HWND hwnd,
|
||||
int id,
|
||||
HWND hwndCtl,
|
||||
UINT codeNotify
|
||||
)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case IDM_FILE_OPEN:
|
||||
if(VcdPlayerOpenCmd())
|
||||
VcdPlayerPlayCmd();
|
||||
break;
|
||||
|
||||
case IDM_FILE_CLOSE:
|
||||
VcdPlayerCloseCmd();
|
||||
QzFreeUnusedLibraries();
|
||||
break;
|
||||
|
||||
case IDM_FILE_ABOUT:
|
||||
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX),
|
||||
hwnd, (DLGPROC) AboutDlgProc);
|
||||
break;
|
||||
|
||||
case IDM_FILE_EXIT:
|
||||
PostMessage(hwnd, WM_CLOSE, 0, 0L);
|
||||
break;
|
||||
|
||||
case IDM_MOVIE_PLAY:
|
||||
VcdPlayerPlayCmd();
|
||||
break;
|
||||
|
||||
case IDM_MOVIE_STOP:
|
||||
VcdPlayerStopCmd();
|
||||
VcdPlayerRewindCmd();
|
||||
break;
|
||||
|
||||
case IDM_MOVIE_PAUSE:
|
||||
VcdPlayerPauseCmd();
|
||||
break;
|
||||
|
||||
case IDM_FULL_SCREEN:
|
||||
if(pMpegMovie)
|
||||
{
|
||||
BOOL bFullScreen = (BOOL)SendMessage(g_hwndToolbar,
|
||||
TB_ISBUTTONCHECKED, IDM_FULL_SCREEN, 0);
|
||||
SetFullScreenMode(bFullScreen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SetPlayButtonsEnableState();
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnDestroy
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnDestroy(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnClose
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnClose(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
VcdPlayerCloseCmd();
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnSize
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnSize(
|
||||
HWND hwnd,
|
||||
UINT state,
|
||||
int dx,
|
||||
int dy
|
||||
)
|
||||
{
|
||||
if(IsWindow(g_hwndToolbar))
|
||||
SendMessage(g_hwndToolbar, WM_SIZE, 0, 0L);
|
||||
|
||||
RepositionMovie(hwnd);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnSysColorChange
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnSysColorChange(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
FORWARD_WM_SYSCOLORCHANGE(g_hwndToolbar, SendMessage);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnInitMenuPopup
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnInitMenuPopup(
|
||||
HWND hwnd,
|
||||
HMENU hMenu,
|
||||
UINT item,
|
||||
BOOL fSystemMenu
|
||||
)
|
||||
{
|
||||
UINT uFlags;
|
||||
|
||||
if(item == 0)
|
||||
{ // File menu
|
||||
|
||||
if(g_State & (VCD_IN_USE | VCD_NO_CD | VCD_DATA_CD_LOADED))
|
||||
{
|
||||
uFlags = (MF_BYCOMMAND | MF_GRAYED);
|
||||
}
|
||||
else
|
||||
{
|
||||
uFlags = (MF_BYCOMMAND | MF_ENABLED);
|
||||
}
|
||||
|
||||
// Disable menu items until a movie is opened
|
||||
EnableMenuItem(hMenu, IDM_FILE_CLOSE, uFlags);
|
||||
EnableMenuItem(hMenu, IDM_MOVIE_STOP, uFlags);
|
||||
EnableMenuItem(hMenu, IDM_MOVIE_PLAY, uFlags);
|
||||
EnableMenuItem(hMenu, IDM_MOVIE_PAUSE, uFlags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnGraphNotify
|
||||
*
|
||||
* This is where we get any notifications from the filter graph.
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnGraphNotify(
|
||||
int stream
|
||||
)
|
||||
{
|
||||
long lEventCode;
|
||||
|
||||
lEventCode = pMpegMovie->GetMovieEventCode();
|
||||
|
||||
switch(lEventCode)
|
||||
{
|
||||
case EC_FULLSCREEN_LOST:
|
||||
SetPlayButtonsEnableState();
|
||||
break;
|
||||
|
||||
case EC_USERABORT:
|
||||
case EC_ERRORABORT:
|
||||
VcdPlayerStopCmd();
|
||||
SetPlayButtonsEnableState();
|
||||
break;
|
||||
|
||||
case EC_COMPLETE:
|
||||
VcdPlayerRewindCmd();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnNotify
|
||||
*
|
||||
* This is where we get the text for tooltips
|
||||
*
|
||||
\**************************************************************************/
|
||||
LRESULT
|
||||
VideoCd_OnNotify(
|
||||
HWND hwnd,
|
||||
int idFrom,
|
||||
NMHDR FAR* pnmhdr
|
||||
)
|
||||
{
|
||||
switch(pnmhdr->code)
|
||||
{
|
||||
case TTN_NEEDTEXT:
|
||||
{
|
||||
LPTOOLTIPTEXT lpTt;
|
||||
lpTt = (LPTOOLTIPTEXT)pnmhdr;
|
||||
|
||||
LoadString(hInst, (UINT) lpTt->hdr.idFrom, lpTt->szText,
|
||||
sizeof(lpTt->szText));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetPlayButtonsEnableState
|
||||
*
|
||||
* Sets the play buttons enable state to match the state of the current
|
||||
* cdrom device. See below...
|
||||
*
|
||||
*
|
||||
* VCD Player buttons enable state table
|
||||
* --------------------------------------------------------------------
|
||||
* -E=Enabled D=Disabled - Play - Pause - Eject - Stop - Other -
|
||||
* --------------------------------------------------------------------
|
||||
* -Disk in use - D - D - D - D - D -
|
||||
* --------------------------------------------------------------------
|
||||
* -No video cd or data cdrom - D - D - E - D - D -
|
||||
* --------------------------------------------------------------------
|
||||
* -Video cd (playing) - D - E - E - E - E -
|
||||
* --------------------------------------------------------------------
|
||||
* -Video cd (paused) - E - D - E - E - E -
|
||||
* --------------------------------------------------------------------
|
||||
* -Video cd (stopped) - E - D - E - D - E -
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
SetPlayButtonsEnableState(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fEnable, fPress;
|
||||
BOOL fVideoCdLoaded;
|
||||
|
||||
/*
|
||||
** Do we have a video cd loaded.
|
||||
*/
|
||||
if(g_State & (VCD_NO_CD | VCD_DATA_CD_LOADED | VCD_IN_USE))
|
||||
{
|
||||
fVideoCdLoaded = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fVideoCdLoaded = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
** Do the play button
|
||||
*/
|
||||
if(fVideoCdLoaded
|
||||
&& ((g_State & VCD_STOPPED) || (g_State & VCD_PAUSED)))
|
||||
{
|
||||
fEnable = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fEnable = FALSE;
|
||||
}
|
||||
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PLAY, fEnable);
|
||||
|
||||
/*
|
||||
** Do the stop button
|
||||
*/
|
||||
if(fVideoCdLoaded
|
||||
&& ((g_State & VCD_PLAYING) || (g_State & VCD_PAUSED)))
|
||||
{
|
||||
fEnable = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fEnable = FALSE;
|
||||
}
|
||||
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_STOP, fEnable);
|
||||
|
||||
/*
|
||||
** Do the pause button
|
||||
*/
|
||||
if(fVideoCdLoaded && (g_State & VCD_PLAYING))
|
||||
{
|
||||
fEnable = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fEnable = FALSE;
|
||||
}
|
||||
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PAUSE, fEnable);
|
||||
|
||||
/*
|
||||
** Do the remaining buttons
|
||||
*/
|
||||
/*
|
||||
** Do the fullscreen button
|
||||
*/
|
||||
fPress = (fVideoCdLoaded && IsFullScreenMode());
|
||||
|
||||
SendMessage(g_hwndToolbar, TB_CHECKBUTTON, IDM_FULL_SCREEN, MAKELONG(fPress,0));
|
||||
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_FULL_SCREEN, fVideoCdLoaded && (g_State & VCD_PLAYING));
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetAdjustedClientRect
|
||||
*
|
||||
* Calculate the size of the client rect and then adjusts it to take into
|
||||
* account the space taken by the toolbar and status bar.
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
GetAdjustedClientRect(
|
||||
RECT *prc
|
||||
)
|
||||
{
|
||||
RECT rcTool;
|
||||
|
||||
GetClientRect(hwndApp, prc);
|
||||
|
||||
if(IsWindowVisible(g_hwndToolbar))
|
||||
{
|
||||
GetWindowRect(g_hwndToolbar, &rcTool);
|
||||
prc->top += (rcTool.bottom - rcTool.top);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* IdStr
|
||||
*
|
||||
* Loads the given string resource ID into the passed storage.
|
||||
*
|
||||
\**************************************************************************/
|
||||
LPCTSTR
|
||||
IdStr(
|
||||
int idResource
|
||||
)
|
||||
{
|
||||
static TCHAR chBuffer[ STR_MAX_STRING_LEN ];
|
||||
|
||||
if(LoadString(hInst, idResource, chBuffer, STR_MAX_STRING_LEN) == 0)
|
||||
{
|
||||
return g_szEmpty;
|
||||
}
|
||||
|
||||
return chBuffer;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetFullScreenMode
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
SetFullScreenMode(BOOL bMode)
|
||||
{
|
||||
m_bFullScreen = bMode;
|
||||
|
||||
// Defer until we activate the movie
|
||||
if(pMpegMovie->GetStateMovie() != State_Running)
|
||||
{
|
||||
if(bMode == TRUE)
|
||||
return;
|
||||
}
|
||||
|
||||
static HMENU hMenu;
|
||||
static LONG lStyle;
|
||||
static int xs, ys, cxs, cys;
|
||||
|
||||
HDC hdcScreen = GetDC(NULL);
|
||||
int cx = GetDeviceCaps(hdcScreen,HORZRES);
|
||||
int cy = GetDeviceCaps(hdcScreen,VERTRES);
|
||||
ReleaseDC(NULL, hdcScreen);
|
||||
|
||||
if(bMode)
|
||||
{
|
||||
hMenu = GetMenu(hwndApp);
|
||||
lStyle = GetWindowStyle(hwndApp);
|
||||
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(hwndApp, &wp);
|
||||
xs = wp.rcNormalPosition.left;
|
||||
ys = wp.rcNormalPosition.top;
|
||||
cxs = wp.rcNormalPosition.right - xs;
|
||||
cys = wp.rcNormalPosition.bottom - ys;
|
||||
ShowWindow(g_hwndToolbar, SW_HIDE);
|
||||
SetMenu(hwndApp, NULL);
|
||||
SetWindowLong(hwndApp, GWL_STYLE, WS_POPUP | WS_VISIBLE);
|
||||
SetWindowPos(hwndApp, HWND_TOP, 0, 0, cx, cy, SWP_NOACTIVATE);
|
||||
ShowCursor(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCursor(TRUE);
|
||||
ShowWindow(g_hwndToolbar, SW_SHOW);
|
||||
SetMenu(hwndApp, hMenu);
|
||||
SetWindowLong(hwndApp, GWL_STYLE, lStyle);
|
||||
SetWindowPos(hwndApp, HWND_TOP, xs, ys, cxs, cys, SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* IsFullScreenMode()
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
IsFullScreenMode()
|
||||
{
|
||||
return m_bFullScreen;
|
||||
}
|
||||
|
||||
301
Library/dxx8/samples/Multimedia/DirectShow_WinXP/VMR/Cube/app.h
Normal file
@@ -0,0 +1,301 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: app.h
|
||||
//
|
||||
// Desc: DirectShow sample code - prototypes for the Renderless player
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Function prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int DoMainLoop(void);
|
||||
BOOL InitApplication(HINSTANCE hInstance);
|
||||
BOOL InitInstance(HINSTANCE hInstance,int nCmdShow);
|
||||
|
||||
void UpdateMpegMovieRect(void);
|
||||
void GetAdjustedClientRect(RECT *prc);
|
||||
|
||||
BOOL DrawStats(HDC hdc);
|
||||
void CalcMovieRect(LPRECT lprc);
|
||||
|
||||
LPCTSTR IdStr(int idResource);
|
||||
void UpdateSystemColors(void);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Message crackers
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
/* void Cls_OnUser(HWND hwnd, WPARAM wParam, LPARAM lParam ) */
|
||||
#define HANDLE_WM_USER(hwnd, wParam, lParam, fn) \
|
||||
((fn)(hwnd, wParam, lParam), 0L)
|
||||
|
||||
#ifndef HANDLE_WM_NOTIFY
|
||||
/* LRESULT Cls_OnNotify(HWND hwnd, int idFrom, NMHDR FAR* pnmhdr); */
|
||||
#define HANDLE_WM_NOTIFY(hwnd, wParam, lParam, fn) \
|
||||
(fn)((hwnd), (int)(wParam), (NMHDR FAR*)(lParam))
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** VideoCd window class prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
extern "C" LRESULT CALLBACK
|
||||
VideoCdWndProc(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnClose(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnQueryEndSession(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDestroy(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnCommand(
|
||||
HWND hwnd,
|
||||
int id,
|
||||
HWND hwndCtl,
|
||||
UINT codeNotify
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnPaint(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnTimer(
|
||||
HWND hwnd,
|
||||
UINT id
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnCreate(
|
||||
HWND hwnd,
|
||||
LPCREATESTRUCT lpCreateStruct
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSize(
|
||||
HWND hwnd,
|
||||
UINT state,
|
||||
int cx,
|
||||
int cy
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnKeyUp(
|
||||
HWND hwnd,
|
||||
UINT vk,
|
||||
BOOL fDown,
|
||||
int cRepeat,
|
||||
UINT flags
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnHScroll(
|
||||
HWND hwnd,
|
||||
HWND hwndCtl,
|
||||
UINT code,
|
||||
int pos
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnUser(
|
||||
HWND hwnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSysColorChange(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnMenuSelect(
|
||||
HWND hwnd,
|
||||
HMENU hmenu,
|
||||
int item,
|
||||
HMENU hmenuPopup,
|
||||
UINT flags
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnInitMenuPopup(
|
||||
HWND hwnd,
|
||||
HMENU hMenu,
|
||||
UINT item,
|
||||
BOOL fSystemMenu
|
||||
);
|
||||
|
||||
#ifdef WM_NOTIFY
|
||||
LRESULT
|
||||
VideoCd_OnNotify(
|
||||
HWND hwnd,
|
||||
int idFrom,
|
||||
NMHDR FAR* pnmhdr
|
||||
);
|
||||
#endif
|
||||
|
||||
void
|
||||
VideoCd_OnGraphNotify(
|
||||
int stream
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDropFiles(
|
||||
HWND hwnd,
|
||||
HDROP hdrop);
|
||||
|
||||
void
|
||||
SetPlayButtonsEnableState(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Command processing functions
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
BOOL
|
||||
VcdPlayerSetLog(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerSetPerfLogFile(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
);
|
||||
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR achFileName[][MAX_PATH],
|
||||
DWORD dwNumFiles,
|
||||
BOOL bPlay = FALSE
|
||||
);
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Recent filename defines
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
typedef TCHAR RECENTFILES[MAX_PATH];
|
||||
#define MAX_RECENT_FILES 5
|
||||
#define ID_RECENT_FILE_BASE 500
|
||||
|
||||
int
|
||||
GetRecentFiles(
|
||||
int LastCount
|
||||
);
|
||||
|
||||
int
|
||||
SetRecentFiles(
|
||||
TCHAR *FileName,
|
||||
int iCount
|
||||
);
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Global Variables
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
extern int cxMovie;
|
||||
extern int cyMovie;
|
||||
extern HWND hwndApp;
|
||||
|
||||
extern int cx;
|
||||
extern int cy;
|
||||
extern int xOffset;
|
||||
extern int yOffset;
|
||||
extern DWORD g_State;
|
||||
extern TCHAR g_szPerfLog[];
|
||||
extern int g_TimeFormat;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
#define LEFT_MARGIN 0
|
||||
const DWORD MAXSTREAMS = 3;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Video CD Player states
|
||||
**
|
||||
** These are bit flags
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define VCD_PLAYING 0x0001
|
||||
#define VCD_STOPPED 0x0002
|
||||
#define VCD_PAUSED 0x0004
|
||||
#define VCD_SKIP_F 0x0008
|
||||
#define VCD_SKIP_B 0x0010
|
||||
#define VCD_FF 0x0020
|
||||
#define VCD_RW 0x0040
|
||||
#define VCD_SEEKING (VCD_FF | VCD_RW)
|
||||
#define VCD_LOADED 0x0080
|
||||
#define VCD_NO_CD 0x0100
|
||||
#define VCD_DATA_CD_LOADED 0x0200
|
||||
#define VCD_EDITING 0x0400
|
||||
#define VCD_PAUSED_AND_MOVED 0x0800
|
||||
#define VCD_PLAY_PENDING 0x1000
|
||||
#define VCD_WAS_PLAYING 0x2000
|
||||
#define VCD_IN_USE 0x4000
|
||||
|
||||
enum {PerformanceTimer = 32, StatusTimer = 33};
|
||||
@@ -0,0 +1,284 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: commands.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - Processes commands from the user
|
||||
//
|
||||
// Copyright (c) 1994-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "project.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern void RepositionMovie(HWND hwnd);
|
||||
|
||||
extern CMpegMovie *pMpegMovie;
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProcessOpen
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR achFileName[][MAX_PATH],
|
||||
DWORD dwNumFiles,
|
||||
BOOL bPlay
|
||||
)
|
||||
{
|
||||
/*
|
||||
** If we currently have a video loaded we need to discard it here.
|
||||
*/
|
||||
if(g_State & VCD_LOADED)
|
||||
{
|
||||
VcdPlayerCloseCmd();
|
||||
}
|
||||
|
||||
pMpegMovie = new CMpegMovie(hwndApp);
|
||||
if(pMpegMovie)
|
||||
{
|
||||
HRESULT hr = pMpegMovie->OpenMovie(achFileName, dwNumFiles);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
g_State = (VCD_LOADED | VCD_STOPPED);
|
||||
|
||||
RepositionMovie(hwndApp);
|
||||
InvalidateRect(hwndApp, NULL, TRUE);
|
||||
|
||||
if(bPlay)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp, TEXT("Failed to open the movie! "),
|
||||
IdStr(STR_APP_TITLE), MB_OK);
|
||||
|
||||
pMpegMovie->CloseMovie();
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerOpenCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
static OPENFILENAME ofn;
|
||||
static BOOL fFirstTime = TRUE;
|
||||
BOOL fRet = FALSE;
|
||||
TCHAR achFileName[MAXSTREAMS][MAX_PATH];
|
||||
TCHAR achFilter[MAX_PATH];
|
||||
LPTSTR lp;
|
||||
DWORD dwNumFiles = 0;
|
||||
|
||||
if(fFirstTime)
|
||||
{
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwndApp;
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST |
|
||||
OFN_SHAREAWARE | OFN_PATHMUSTEXIST;
|
||||
}
|
||||
|
||||
lstrcpy(achFilter, IdStr(STR_FILE_FILTER));
|
||||
ofn.lpstrFilter = achFilter;
|
||||
|
||||
/*
|
||||
** Convert the resource string into to something suitable for
|
||||
** GetOpenFileName ie. replace '#' characters with '\0' characters.
|
||||
*/
|
||||
for(lp = achFilter; *lp; lp++)
|
||||
{
|
||||
if(*lp == TEXT('#'))
|
||||
{
|
||||
*lp = TEXT('\0');
|
||||
}
|
||||
}
|
||||
|
||||
for (DWORD i = 0; i < MAXSTREAMS; i++)
|
||||
{
|
||||
ofn.lpstrFile = achFileName[i];
|
||||
ofn.nMaxFile = sizeof(achFileName[i]) / sizeof(TCHAR);
|
||||
ZeroMemory(achFileName[i], sizeof(achFileName[i]));
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
// load first file
|
||||
ofn.lpstrTitle = TEXT("Select First Media File");
|
||||
break;
|
||||
case 1:
|
||||
// load first file
|
||||
ofn.lpstrTitle = TEXT("Select Second Media File");
|
||||
break;
|
||||
case 2:
|
||||
// load first file
|
||||
ofn.lpstrTitle = TEXT("Select Third Media File");
|
||||
break;
|
||||
}
|
||||
|
||||
fRet = GetOpenFileName(&ofn);
|
||||
if(!fRet)
|
||||
{
|
||||
break;
|
||||
}
|
||||
dwNumFiles++;
|
||||
} // for i
|
||||
fFirstTime = FALSE;
|
||||
|
||||
if (0 == dwNumFiles)
|
||||
{
|
||||
return fRet;
|
||||
}
|
||||
|
||||
ProcessOpen(achFileName, dwNumFiles);
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerCloseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
g_State = VCD_NO_CD;
|
||||
pMpegMovie->StopMovie();
|
||||
pMpegMovie->CloseMovie();
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
|
||||
// Redraw main window
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPlayCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fStopped = (g_State & VCD_STOPPED);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fStopped || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
|
||||
g_State &= ~(fStopped ? VCD_STOPPED : VCD_PAUSED);
|
||||
g_State |= VCD_PLAYING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerStopCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fPlaying || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->StopMovie();
|
||||
}
|
||||
|
||||
g_State &= ~(fPlaying ? VCD_PLAYING : VCD_PAUSED);
|
||||
g_State |= VCD_STOPPED;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPauseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if(fPlaying)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PauseMovie();
|
||||
}
|
||||
|
||||
g_State &= ~VCD_PLAYING;
|
||||
g_State |= VCD_PAUSED;
|
||||
}
|
||||
else if(fPaused)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
|
||||
g_State &= ~VCD_PAUSED;
|
||||
g_State |= VCD_PLAYING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerRewindCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,626 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: compositor.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - VMR-based Cube video player
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <dvdmedia.h>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "project.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* MakeD3DVector
|
||||
*
|
||||
\**************************************************************************/
|
||||
D3DVECTOR
|
||||
MakeD3DVector( float x, float y, float z )
|
||||
{
|
||||
D3DVECTOR ret;
|
||||
ret.x = x;
|
||||
ret.y = y;
|
||||
ret.z = z;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* MakeD3DVertex
|
||||
*
|
||||
\**************************************************************************/
|
||||
D3DVERTEX
|
||||
MakeD3DVertex( const D3DVECTOR& p, const D3DVECTOR& n, float tu, float tv )
|
||||
{
|
||||
D3DVERTEX ret;
|
||||
ret.x = p.x; ret.y = p.y; ret.z = p.z;
|
||||
ret.nx = n.x; ret.ny = n.y; ret.nz = n.z;
|
||||
ret.tu = tu; ret.tv = tv;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* Name: MatrixMultiply()
|
||||
* Desc: Multiplies matrix B onto matrix A, as in: [Q] = [B] * [A].
|
||||
\**************************************************************************/
|
||||
VOID MatrixMultiply( D3DMATRIX& q, D3DMATRIX& a, D3DMATRIX& b )
|
||||
{
|
||||
FLOAT* pA = (FLOAT*)&a;
|
||||
FLOAT* pB = (FLOAT*)&b;
|
||||
FLOAT pM[16];
|
||||
|
||||
ZeroMemory( pM, sizeof(D3DMATRIX) );
|
||||
|
||||
for( DWORD i=0; i<4; i++ )
|
||||
for( DWORD j=0; j<4; j++ )
|
||||
for( DWORD k=0; k<4; k++ )
|
||||
pM[4*i+j] += pA[4*k+j] * pB[4*i+k];
|
||||
|
||||
memcpy( &q, pM, sizeof(D3DMATRIX) );
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* CreateCube()
|
||||
*
|
||||
* Sets up the vertices for a cube. Don't forget to set the texture
|
||||
* coordinates for each vertex.
|
||||
*
|
||||
\**************************************************************************/
|
||||
VOID
|
||||
CreateCube(
|
||||
D3DVERTEX* pVertices,
|
||||
StreamSize * pSize
|
||||
)
|
||||
{
|
||||
// Define the normals for the cube
|
||||
D3DVECTOR n0 = MakeD3DVector( 0.0f, 0.0f, 1.0f ); // Front face
|
||||
D3DVECTOR n4 = MakeD3DVector( 1.0f, 0.0f, 0.0f ); // Right face
|
||||
D3DVECTOR n1 = MakeD3DVector( 0.0f, 0.0f, 1.0f ); // Back face
|
||||
D3DVECTOR n5 = MakeD3DVector(-1.0f, 0.0f, 0.0f ); // Left face
|
||||
D3DVECTOR n2 = MakeD3DVector( 0.0f, 1.0f, 0.0f ); // Top face
|
||||
D3DVECTOR n3 = MakeD3DVector( 0.0f,-1.0f, 0.0f ); // Bottom face
|
||||
|
||||
// Front face
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f,-1.0f), n0, 0.0f, 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f,-1.0f), n0, pSize[0].cx , 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f,-1.0f), n0, 0.0f, pSize[0].cy );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f,-1.0f), n0, pSize[0].cx , pSize[0].cy );
|
||||
|
||||
// Right face
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f,-1.0f), n4, 0.0f, 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f, 1.0f), n4, pSize[1].cx , 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f,-1.0f), n4, 0.0f, pSize[1].cy );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f, 1.0f), n4, pSize[1].cx , pSize[1].cy );
|
||||
|
||||
// Top face
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f, 1.0f), n2, 0.0f, 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f, 1.0f), n2, pSize[2].cx , 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f,-1.0f), n2, 0.0f, pSize[2].cy );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f,-1.0f), n2, pSize[2].cx , pSize[2].cy );
|
||||
|
||||
// Back face
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f, 1.0f), n1, pSize[0].cx , 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f, 1.0f), n1, pSize[0].cx , pSize[0].cy );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f, 1.0f, 1.0f), n1, 0.0f, 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f, 1.0f), n1, 0.0f, pSize[0].cy );
|
||||
|
||||
// Left face
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f,-1.0f), n5, pSize[1].cx , 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f,-1.0f), n5, pSize[1].cx , pSize[1].cy );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f, 1.0f, 1.0f), n5, 0.0f, 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f, 1.0f), n5, 0.0f, pSize[1].cy );
|
||||
|
||||
// Bottom face
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f, 1.0f), n3, 0.0f, 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector(-1.0f,-1.0f,-1.0f), n3, 0.0f, pSize[2].cy );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f, 1.0f), n3, pSize[2].cx , 0.0f );
|
||||
*pVertices++ = MakeD3DVertex( MakeD3DVector( 1.0f,-1.0f,-1.0f), n3, pSize[2].cx , pSize[2].cy );
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* FrameMove
|
||||
*
|
||||
* Called once per frame, the call is used for animating the scene. The
|
||||
* device is used for changing various render states, and the timekey is
|
||||
* used for timing of the dynamics of the scene.
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::FrameMove(
|
||||
LPDIRECT3DDEVICE7 pd3dDevice,
|
||||
FLOAT fTimeKey
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
__try {
|
||||
|
||||
// Set the view matrix so that the camera is backed out along the z-axis,
|
||||
// and looks down on the cube (rotating along the x-axis by -0.5 radians).
|
||||
D3DMATRIX matView;
|
||||
ZeroMemory(&matView, sizeof(D3DMATRIX));
|
||||
|
||||
matView._11 = 1.0f;
|
||||
matView._22 = (FLOAT)cos(-0.5f);
|
||||
matView._23 = (FLOAT)sin(-0.5f);
|
||||
matView._32 = -(FLOAT)sin(-0.5f);
|
||||
matView._33 = (FLOAT)cos(-0.5f);
|
||||
matView._43 = 5.0f;
|
||||
matView._44 = 1.0f;
|
||||
CHECK_HR(hr = pd3dDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &matView));
|
||||
|
||||
// Set the world matrix to rotate along the y-axis, in sync with the timekey
|
||||
D3DMATRIX matRotate, matRotate2, matWorld;
|
||||
ZeroMemory(&matRotate, sizeof(D3DMATRIX));
|
||||
ZeroMemory(&matRotate2, sizeof(D3DMATRIX));
|
||||
ZeroMemory(&matWorld, sizeof(D3DMATRIX));
|
||||
|
||||
// rotate along y axis
|
||||
matRotate._11 = (FLOAT)cos(fTimeKey);
|
||||
matRotate._13 = (FLOAT)sin(fTimeKey);
|
||||
matRotate._22 = 1.0f;
|
||||
matRotate._31 = -(FLOAT)sin(fTimeKey);
|
||||
matRotate._33 = (FLOAT)cos(fTimeKey);
|
||||
matRotate._44 = 1.0f;
|
||||
|
||||
// rotate along z axis
|
||||
matRotate2._11 = (FLOAT)cos(fTimeKey);
|
||||
matRotate2._12 = (FLOAT)sin(fTimeKey);
|
||||
matRotate2._21 = -(FLOAT)sin(fTimeKey);
|
||||
matRotate2._22 = (FLOAT)cos(fTimeKey);
|
||||
matRotate2._33 = 1.0f;
|
||||
matRotate2._44 = 1.0f;
|
||||
|
||||
MatrixMultiply(matWorld, matRotate, matRotate2);
|
||||
CHECK_HR(hr = pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld));
|
||||
}
|
||||
__finally {}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetSourceRectFromMediaType
|
||||
*
|
||||
\**************************************************************************/
|
||||
RECT
|
||||
GetSourceRectFromMediaType(
|
||||
const AM_MEDIA_TYPE *pMediaType
|
||||
)
|
||||
{
|
||||
RECT rRect = {0,0,0,0};
|
||||
if (!pMediaType)
|
||||
{
|
||||
DbgLog((LOG_ERROR, 1, TEXT("pMediaType is NULL")));
|
||||
return rRect;
|
||||
}
|
||||
|
||||
if (!(pMediaType->pbFormat))
|
||||
{
|
||||
return rRect;
|
||||
}
|
||||
|
||||
if ((pMediaType->formattype == FORMAT_VideoInfo) &&
|
||||
(pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER)))
|
||||
{
|
||||
rRect = (((VIDEOINFOHEADER*)(pMediaType->pbFormat))->rcSource);
|
||||
}
|
||||
else if ((pMediaType->formattype == FORMAT_VideoInfo2) &&
|
||||
(pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER2)))
|
||||
{
|
||||
rRect = (((VIDEOINFOHEADER2*)(pMediaType->pbFormat))->rcSource);
|
||||
}
|
||||
|
||||
// DShow filters have the habit of sometimes not setting the src and dst
|
||||
// rectangles, in this case we should imply that the these rectangles
|
||||
// should be the same width and height as the bitmap in the media format.
|
||||
if (IsRectEmpty(&rRect))
|
||||
{
|
||||
LPBITMAPINFOHEADER lpbi = GetbmiHeader(pMediaType);
|
||||
|
||||
if (lpbi)
|
||||
{
|
||||
SetRect(&rRect, 0, 0, abs(lpbi->biWidth), abs(lpbi->biHeight));
|
||||
}
|
||||
}
|
||||
|
||||
return rRect;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetbmiHeader
|
||||
*
|
||||
* Returns the bitmap info header associated with the specified CMediaType.
|
||||
* Returns NULL if the CMediaType is not either of FORMAT_VideoInfo or
|
||||
* FORMAT_VideoInfo2.
|
||||
*
|
||||
\**************************************************************************/
|
||||
LPBITMAPINFOHEADER
|
||||
GetbmiHeader(
|
||||
const AM_MEDIA_TYPE *pMediaType
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("GetbmiHeader")));
|
||||
|
||||
if (!pMediaType)
|
||||
{
|
||||
DbgLog((LOG_ERROR, 1, TEXT("pMediaType is NULL")));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(pMediaType->pbFormat))
|
||||
{
|
||||
DbgLog((LOG_ERROR, 1, TEXT("pMediaType->pbFormat is NULL")));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LPBITMAPINFOHEADER lpHeader = NULL;
|
||||
if ((pMediaType->formattype == FORMAT_VideoInfo) &&
|
||||
(pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER)))
|
||||
{
|
||||
lpHeader = &(((VIDEOINFOHEADER*)(pMediaType->pbFormat))->bmiHeader);
|
||||
}
|
||||
else if ((pMediaType->formattype == FORMAT_VideoInfo2) &&
|
||||
(pMediaType->cbFormat >= sizeof(VIDEOINFOHEADER2)))
|
||||
{
|
||||
lpHeader = &(((VIDEOINFOHEADER2*)(pMediaType->pbFormat))->bmiHeader);
|
||||
}
|
||||
|
||||
return lpHeader;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* AllocateTextureMirror
|
||||
*
|
||||
\**************************************************************************/
|
||||
|
||||
// global data structures and static helper function for AllocateTextureMirror
|
||||
const DDPIXELFORMAT g_rgTextMirFormats[] = {
|
||||
{ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32, 0xff0000, 0xff00, 0xff, 0xff<<24ul},
|
||||
{ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24, 0xff0000, 0xff00, 0xff, 0 },
|
||||
{ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x1f<<11, 0x3f<<5, 0x1f, 0 },
|
||||
{ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x1f<<10, 0x1f<<5, 0x1f, 0 }
|
||||
};
|
||||
|
||||
const UINT g_cTextMirFormats = sizeof(g_rgTextMirFormats)/sizeof(DDPIXELFORMAT);
|
||||
|
||||
static UINT
|
||||
NextPow2( UINT i )
|
||||
{
|
||||
UINT ret = 1;
|
||||
while ( ret < i )
|
||||
{
|
||||
ret <<= 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* AllocateTextureMirror
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::AllocateTextureMirror(
|
||||
LPDIRECTDRAWSURFACE7 pddsVideo,
|
||||
DWORD* lpdwWidth,
|
||||
DWORD* lpdwHeight,
|
||||
bool bNonPow2Cond
|
||||
)
|
||||
{
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
DDSURFACEDESC2 ddsd = {sizeof(ddsd)};
|
||||
|
||||
__try {
|
||||
|
||||
LPDIRECTDRAW7 pDD;
|
||||
|
||||
CHECK_HR(pddsVideo->GetDDInterface((LPVOID*)&pDD));
|
||||
|
||||
if (m_pDDSTextureMirror) {
|
||||
|
||||
CHECK_HR(hr = m_pDDSTextureMirror->GetSurfaceDesc(&ddsd));
|
||||
|
||||
// early out if mirror already exists and is large enough to accommodate pDDS
|
||||
if (ddsd.dwWidth >= *lpdwWidth && ddsd.dwHeight >= *lpdwHeight) {
|
||||
*lpdwWidth = ddsd.dwWidth;
|
||||
*lpdwHeight = ddsd.dwHeight;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*lpdwWidth = max(ddsd.dwWidth, *lpdwWidth);
|
||||
*lpdwHeight = max(ddsd.dwHeight, *lpdwHeight);
|
||||
}
|
||||
|
||||
RELEASE(m_pDDSTextureMirror);
|
||||
|
||||
// bump dimensions out to next power of 2
|
||||
// if the 3D hardware needs it that way
|
||||
|
||||
if (!bNonPow2Cond) {
|
||||
*lpdwWidth = NextPow2(*lpdwWidth);
|
||||
*lpdwHeight = NextPow2(*lpdwHeight);
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 ddsd = {sizeof(ddsd)};
|
||||
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
||||
ddsd.dwWidth = *lpdwWidth;
|
||||
ddsd.dwHeight = *lpdwHeight;
|
||||
ddsd.ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||
|
||||
// loop over texture formats and return as soon as CreateSurface succeeds
|
||||
for (UINT i = 0; i < g_cTextMirFormats; i++) {
|
||||
|
||||
// create texture mirror
|
||||
ddsd.ddpfPixelFormat = g_rgTextMirFormats[i];
|
||||
hr = pDD->CreateSurface(&ddsd, &m_pDDSTextureMirror, NULL);
|
||||
if (SUCCEEDED(hr))
|
||||
break;
|
||||
}
|
||||
RELEASE(pDD);
|
||||
}
|
||||
__finally {}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitCompositionTarget
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::InitCompositionTarget(
|
||||
IUnknown* lpUnk,
|
||||
LPDIRECTDRAWSURFACE7 pddsRenderTarget
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
__try {
|
||||
|
||||
LPDIRECT3DDEVICE7 pd3dDevice = (LPDIRECT3DDEVICE7)lpUnk;
|
||||
DDSURFACEDESC2 ddsd = {sizeof(DDSURFACEDESC2)};
|
||||
|
||||
CHECK_HR(hr = pddsRenderTarget->GetSurfaceDesc(&ddsd));
|
||||
|
||||
D3DVIEWPORT7 vp = { 0, 0, ddsd.dwWidth, ddsd.dwHeight, 0.0f, 1.0f };
|
||||
CHECK_HR(hr = pd3dDevice->SetViewport(&vp));
|
||||
|
||||
//
|
||||
// Remind the CompositeImage (see below) to init the cube vertices.
|
||||
// We can't do it here because we don't know the size of the movie
|
||||
// being played yet.
|
||||
//
|
||||
m_bInitCube = true;
|
||||
|
||||
// For simplicity, just use ambient lighting and a white material
|
||||
D3DMATERIAL7 mtrl;
|
||||
ZeroMemory(&mtrl, sizeof(mtrl));
|
||||
mtrl.diffuse.r = mtrl.diffuse.g = mtrl.diffuse.b = 1.0f;
|
||||
mtrl.ambient.r = mtrl.ambient.g = mtrl.ambient.b = 1.0f;
|
||||
CHECK_HR(hr = pd3dDevice->SetMaterial(&mtrl));
|
||||
CHECK_HR(hr = pd3dDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff));
|
||||
|
||||
// Set the projection matrix. Note that the view and world matrices are
|
||||
// set in the App_FrameMove() function, so they can be animated each
|
||||
// frame.
|
||||
D3DMATRIX matProj;
|
||||
ZeroMemory(&matProj, sizeof(D3DMATRIX));
|
||||
matProj._11 = 2.0f;
|
||||
matProj._22 = 2.0f;
|
||||
matProj._33 = 1.0f;
|
||||
matProj._34 = 1.0f;
|
||||
matProj._43 = -1.0f;
|
||||
CHECK_HR(hr = pd3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &matProj));
|
||||
}
|
||||
__finally {
|
||||
};
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* CompositeImage
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::CompositeImage(
|
||||
IUnknown* lpUnk,
|
||||
LPDIRECTDRAWSURFACE7 pddsRenderTarget,
|
||||
AM_MEDIA_TYPE* pmtRenderTarget,
|
||||
REFERENCE_TIME rtStart,
|
||||
REFERENCE_TIME rtEnd,
|
||||
DWORD dwMapped,
|
||||
VMRVIDEOSTREAMINFO* pStrmInfo,
|
||||
UINT cStreams
|
||||
)
|
||||
{
|
||||
LPDIRECT3DDEVICE7 pd3dDevice = (LPDIRECT3DDEVICE7)lpUnk;
|
||||
HRESULT hr = S_OK;
|
||||
bool bInScene = false;
|
||||
|
||||
__try
|
||||
{
|
||||
LPDIRECTDRAWSURFACE7 pDDS;
|
||||
|
||||
//
|
||||
// First time thru init the Cube compositor
|
||||
//
|
||||
if (m_bInitCube)
|
||||
{
|
||||
// if the dimensions are not 0, one of the surfaces is not a texture and we need to create a texture mirror
|
||||
if (m_dwTexMirrorWidth && m_dwTexMirrorHeight)
|
||||
{
|
||||
hr = AllocateTextureMirror(pStrmInfo->pddsVideoSurface, &m_dwTexMirrorWidth, &m_dwTexMirrorHeight,
|
||||
DoesSupportNonPow2CondCap(pd3dDevice));
|
||||
}
|
||||
|
||||
m_bInitCube = false;
|
||||
}
|
||||
|
||||
// Rotate the Cube
|
||||
CHECK_HR(hr = FrameMove(pd3dDevice, ConvertToMilliseconds(rtStart) * 0.0005f));
|
||||
|
||||
// Clear the viewport to dark gray
|
||||
CHECK_HR(hr = pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00404040, 1.0f, 0L));
|
||||
|
||||
cStreams = min(MAXSTREAMS, cStreams);
|
||||
|
||||
StreamSize Sizes[MAXSTREAMS];
|
||||
for (DWORD j = 0; j < MAXSTREAMS; j++)
|
||||
{
|
||||
int iStream = j % cStreams;
|
||||
|
||||
if (m_StreamInfo[pStrmInfo[iStream].dwStrmID].bTexture)
|
||||
{
|
||||
Sizes[j].cx = (FLOAT)WIDTH(&m_StreamInfo[pStrmInfo[iStream].dwStrmID].SourceRect) / (FLOAT)pStrmInfo[iStream].dwWidth;
|
||||
Sizes[j].cy = (FLOAT)HEIGHT(&m_StreamInfo[pStrmInfo[iStream].dwStrmID].SourceRect) / (FLOAT)pStrmInfo[iStream].dwHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
Sizes[j].cx = (FLOAT)WIDTH(&m_StreamInfo[pStrmInfo[iStream].dwStrmID].SourceRect) / (FLOAT)m_dwTexMirrorWidth;
|
||||
Sizes[j].cy = (FLOAT)HEIGHT(&m_StreamInfo[pStrmInfo[iStream].dwStrmID].SourceRect) / (FLOAT)m_dwTexMirrorHeight;
|
||||
}
|
||||
}
|
||||
|
||||
CreateCube(m_pCubeVertices, Sizes);
|
||||
|
||||
// Begin the scene
|
||||
CHECK_HR(hr = pd3dDevice->BeginScene());
|
||||
bInScene = true;
|
||||
|
||||
for (unsigned int i = 0; i < MAXSTREAMS; i++)
|
||||
{
|
||||
int iStream = i % cStreams;
|
||||
//
|
||||
// Make sure we are dealing with a texture surface - if not
|
||||
// copy the stream to the mirror surface.
|
||||
//
|
||||
if (m_StreamInfo[pStrmInfo[iStream].dwStrmID].bTexture)
|
||||
{
|
||||
pDDS = pStrmInfo[iStream].pddsVideoSurface;
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT r = { 0, 0, pStrmInfo->dwWidth, pStrmInfo->dwHeight };
|
||||
|
||||
pDDS = m_pDDSTextureMirror;
|
||||
CHECK_HR(hr = pDDS->Blt(&r, pStrmInfo[iStream].pddsVideoSurface, &r, DDBLT_WAIT, NULL));
|
||||
}
|
||||
|
||||
// Prepare the texture stages
|
||||
CHECK_HR(hr = pd3dDevice->SetTexture(0, pDDS));
|
||||
if (DoesSupportAnisoCap(pd3dDevice))
|
||||
{
|
||||
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC));
|
||||
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC));
|
||||
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAXANISOTROPY, 4));
|
||||
}
|
||||
else if (DoesSupportLinearCap(pd3dDevice))
|
||||
{
|
||||
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR));
|
||||
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_POINT));
|
||||
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_POINT));
|
||||
}
|
||||
CHECK_HR(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP));
|
||||
|
||||
// Draw the faces of the cube
|
||||
CHECK_HR(hr = pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX,
|
||||
m_pCubeVertices+(4*i), 4, NULL));
|
||||
CHECK_HR(hr = pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX,
|
||||
m_pCubeVertices+(4*i)+12, 4, NULL));
|
||||
} // for i
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if (bInScene) {
|
||||
// End the scene.
|
||||
pd3dDevice->EndScene();
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SetStreamMediaType
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT CMpegMovie::SetStreamMediaType(DWORD dwStrmID, AM_MEDIA_TYPE *pmt, BOOL fTexture)
|
||||
{
|
||||
if (pmt)
|
||||
{
|
||||
m_StreamInfo[dwStrmID].bTexture = fTexture;
|
||||
m_StreamInfo[dwStrmID].SourceRect = GetSourceRectFromMediaType(pmt);
|
||||
|
||||
if (!fTexture)
|
||||
{
|
||||
// choose the largest measure in each dimension
|
||||
m_dwTexMirrorWidth = max(m_dwTexMirrorWidth, (DWORD)WIDTH(&m_StreamInfo[dwStrmID].SourceRect));
|
||||
m_dwTexMirrorHeight = max(m_dwTexMirrorHeight, (DWORD)HEIGHT(&m_StreamInfo[dwStrmID].SourceRect));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DoesSupportNonPow2CondCap
|
||||
*
|
||||
\**************************************************************************/
|
||||
bool CMpegMovie::DoesSupportNonPow2CondCap(LPDIRECT3DDEVICE7 pD3DDevice)
|
||||
{
|
||||
ASSERT(pD3DDevice);
|
||||
D3DDEVICEDESC7 ddDesc;
|
||||
if (!(DD_OK == pD3DDevice->GetCaps(&ddDesc)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) ? true : false;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DoesSupportAnisoCap
|
||||
*
|
||||
\**************************************************************************/
|
||||
bool CMpegMovie::DoesSupportAnisoCap(LPDIRECT3DDEVICE7 pD3DDevice)
|
||||
{
|
||||
ASSERT(pD3DDevice);
|
||||
D3DDEVICEDESC7 ddDesc;
|
||||
if (!(DD_OK == pD3DDevice->GetCaps(&ddDesc)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bMag = (ddDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) ? true : false;
|
||||
bool bMin = (ddDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) ? true : false;
|
||||
return (bMag && bMin);
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DoesSupportLinearCap
|
||||
*
|
||||
\**************************************************************************/
|
||||
bool CMpegMovie::DoesSupportLinearCap(LPDIRECT3DDEVICE7 pD3DDevice)
|
||||
{
|
||||
ASSERT(pD3DDevice);
|
||||
D3DDEVICEDESC7 ddDesc;
|
||||
if (!(DD_OK == pD3DDevice->GetCaps(&ddDesc)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bMag = (ddDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR) ? true : false;
|
||||
bool bMin = (ddDesc.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) ? true : false;
|
||||
return (bMag && bMin);
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,231 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resrc1.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
//
|
||||
|
||||
IDR_TOOLBAR BITMAP DISCARDABLE "toolbar.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_VIDEOCD_ICON ICON DISCARDABLE "cube.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_MAIN_MENU MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "&Open Video Files...\tCtrl+O", IDM_FILE_OPEN
|
||||
MENUITEM "&Close", IDM_FILE_CLOSE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Play\tCtrl+P", IDM_MOVIE_PLAY
|
||||
MENUITEM "Pa&use\tCtrl+U", IDM_MOVIE_PAUSE
|
||||
MENUITEM "&Stop\tCtrl+S", IDM_MOVIE_STOP
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Ex&it\tCtrl+X", IDM_FILE_EXIT
|
||||
END
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About Cube Player...", IDM_FILE_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About Cube Player"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
ICON IDR_VIDEOCD_ICON,-1,11,17,20,20
|
||||
LTEXT "DirectShow VMR Cube Player Sample",-1,40,10,131,8,
|
||||
SS_NOPREFIX
|
||||
LTEXT "Copyright (C) 1999-2001 Microsoft Corporation",-1,40,34,
|
||||
188,8
|
||||
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
|
||||
LTEXT "Version 8.1",-1,40,22,119,8,SS_NOPREFIX
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_ACCELERATOR ACCELERATORS DISCARDABLE
|
||||
BEGIN
|
||||
"F", IDM_MOVIE_FULLSCREEN, VIRTKEY, CONTROL, NOINVERT
|
||||
"O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
|
||||
"P", IDM_MOVIE_PLAY, VIRTKEY, CONTROL, NOINVERT
|
||||
"S", IDM_MOVIE_STOP, VIRTKEY, CONTROL, NOINVERT
|
||||
"T", ID_FILE_OPENSECONDVIDEO, VIRTKEY, CONTROL, NOINVERT
|
||||
"U", IDM_MOVIE_PAUSE, VIRTKEY, CONTROL, NOINVERT
|
||||
"X", IDM_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resrc1.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""resource.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,1,0,0
|
||||
PRODUCTVERSION 8,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "This sample requires Windows XP or greater.\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "Cube Application\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "VMR Cube\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "Cube.EXE\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "DirectX 8.1 SDK\0"
|
||||
VALUE "ProductVersion", "8.1\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_MOVIE_STOP "Stop"
|
||||
IDM_MOVIE_PLAY "Play"
|
||||
IDM_MOVIE_PAUSE "Pause"
|
||||
IDM_FULL_SCREEN "Full screen playback"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_OPEN "Open a new movie"
|
||||
STR_FILE_CLOSE "Close the movie"
|
||||
STR_FILE_EXIT "Quit Cube player"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_SYSMENU_RESTORE "Restore the window to normal size"
|
||||
STR_SYSMENU_MOVE "Changes the window position"
|
||||
STR_SYSMENU_MINIMIZE "Reduce the window to an icon"
|
||||
STR_SYSMENU_CLOSE "Closes the window"
|
||||
STR_SYSMENU_MAXIMIZE "Enlarges the window to its maximum size"
|
||||
STR_SYSMENU_TASK_LIST "Opens the task list"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_FILTER "All Movies#*.mpg;*.avi;*.dat;*.mov#Mpeg Files (*.mpg)#*.mpg#Video CD Files (*.dat)#*.dat#QuickTime Files (*.mov)#*.mov#All Files (*.*)#*.*#"
|
||||
STR_APP_TITLE "VMR Cube Player"
|
||||
STR_APP_TITLE_LOADED "VMR Cube Player - %s"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: project.h
|
||||
//
|
||||
// Desc: DirectShow sample code - main header file for Renderless player
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "app.h"
|
||||
#include "vcdplyer.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
#ifndef __RELEASE_DEFINED
|
||||
#define __RELEASE_DEFINED
|
||||
template<typename T>
|
||||
__inline void RELEASE( T* &p )
|
||||
{
|
||||
if( p ) {
|
||||
p->Release();
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_HR
|
||||
#define CHECK_HR(expr) { if (FAILED(expr)) __leave; };
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
Windows XP DirectShow Sample -- Cube
|
||||
------------------------------------
|
||||
|
||||
This sample demonstrates using the Video Mixing Renderer and
|
||||
a plug-in compositor to render video on a spinning cube.
|
||||
|
||||
NOTE: This sample requires Windows XP (or greater) functionality
|
||||
and will exit on other systems.
|
||||
@@ -0,0 +1,80 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: resource.h
|
||||
//
|
||||
// Desc: DirectShow sample code - resource header file for Cube player
|
||||
//
|
||||
// Copyright (c) 1995 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define IDC_STATIC -1
|
||||
|
||||
#define STR_MAX_STRING_LEN 256
|
||||
|
||||
#define IDX_SEPARATOR -1
|
||||
#define IDX_1 0
|
||||
#define IDX_2 1
|
||||
#define IDX_3 2
|
||||
#define IDX_4 3
|
||||
#define IDX_5 4
|
||||
#define IDX_6 5
|
||||
#define IDX_7 6
|
||||
#define IDX_8 7
|
||||
|
||||
#define IDX_10 9
|
||||
#define IDX_11 10
|
||||
#define DEFAULT_TBAR_SIZE 6
|
||||
#define NUMBER_OF_BITMAPS 11
|
||||
|
||||
#define ID_TOOLBAR 9
|
||||
#define IDD_ABOUTBOX 20
|
||||
|
||||
#define IDR_MAIN_MENU 101
|
||||
#define IDR_TOOLBAR 102
|
||||
#define IDR_VIDEOCD_ICON 103
|
||||
#define IDR_ACCELERATOR 104
|
||||
|
||||
#define IDM_FILE_OPEN 40001
|
||||
#define IDM_FILE_CLOSE 40002
|
||||
#define IDM_FILE_EXIT 40003
|
||||
#define IDM_FILE_ABOUT 40004
|
||||
|
||||
|
||||
// Toolbar commands
|
||||
#define IDM_MOVIE_STOP 40010
|
||||
#define IDM_MOVIE_PLAY 40011
|
||||
#define IDM_MOVIE_PAUSE 40012
|
||||
#define IDM_FULL_SCREEN 40013
|
||||
#define IDM_MOVIE_FULLSCREEN 40014
|
||||
|
||||
#define MENU_STRING_BASE 1000
|
||||
|
||||
// File
|
||||
#define STR_FILE_OPEN IDM_FILE_OPEN + MENU_STRING_BASE
|
||||
#define STR_FILE_CLOSE IDM_FILE_CLOSE + MENU_STRING_BASE
|
||||
#define STR_FILE_EXIT IDM_FILE_EXIT + MENU_STRING_BASE
|
||||
|
||||
|
||||
// System Menu
|
||||
#define STR_SYSMENU_RESTORE 1800
|
||||
#define STR_SYSMENU_MOVE 1801
|
||||
#define STR_SYSMENU_MINIMIZE 1802
|
||||
#define STR_SYSMENU_CLOSE 1803
|
||||
#define STR_SYSMENU_MAXIMIZE 1804
|
||||
#define STR_SYSMENU_TASK_LIST 1805
|
||||
|
||||
#define STR_FILE_FILTER 2000
|
||||
#define STR_APP_TITLE 2001
|
||||
#define STR_APP_TITLE_LOADED 2002
|
||||
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40002
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by Cube.rc
|
||||
//
|
||||
#define ID_FILE_OPENSECONDVIDEO 40005
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40007
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
After Width: | Height: | Size: 598 B |
@@ -0,0 +1,567 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - VMR-based Cube video player
|
||||
//
|
||||
// Copyright (c) 1994-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
#include <atlbase.h>
|
||||
|
||||
#include "project.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MY_USER_ID 0x1234ACDE
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CMpegMovie
|
||||
*
|
||||
* Constructors and destructors
|
||||
*
|
||||
\**************************************************************************/
|
||||
CMpegMovie::CMpegMovie(HWND hwndApplication)
|
||||
: CUnknown(NAME("Allocator Presenter"), NULL),
|
||||
m_hwndApp(hwndApplication),
|
||||
m_bInitCube(false),
|
||||
m_pDDSTextureMirror(NULL),
|
||||
m_MediaEvent(NULL),
|
||||
m_Mode(MOVIE_NOTOPENED),
|
||||
m_Fg(NULL),
|
||||
m_Gb(NULL),
|
||||
m_Mc(NULL),
|
||||
m_Me(NULL),
|
||||
m_Wc(NULL),
|
||||
m_Ms(NULL),
|
||||
m_dwRegister(0),
|
||||
m_dwTexMirrorWidth(0),
|
||||
m_dwTexMirrorHeight(0)
|
||||
{
|
||||
AddRef();
|
||||
}
|
||||
|
||||
CMpegMovie::~CMpegMovie() {
|
||||
;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* NonDelegatingQueryInterface
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NonDelegatingQueryInterface(
|
||||
REFIID riid,
|
||||
void** ppv
|
||||
)
|
||||
{
|
||||
if (riid == IID_IVMRImageCompositor) {
|
||||
return GetInterface((IVMRImageCompositor*)this, ppv);
|
||||
}
|
||||
|
||||
return CUnknown::NonDelegatingQueryInterface(riid,ppv);
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SetRenderingMode
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
SetRenderingMode(
|
||||
IBaseFilter* pBaseFilter,
|
||||
VMRMode mode,
|
||||
int iNumStreams,
|
||||
IVMRImageCompositor* lpCompositor
|
||||
)
|
||||
{
|
||||
IVMRFilterConfig* pConfig = NULL;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
__try {
|
||||
|
||||
CHECK_HR(hr = pBaseFilter->QueryInterface(IID_IVMRFilterConfig,
|
||||
(LPVOID *)&pConfig));
|
||||
|
||||
//
|
||||
// If you are pluging in a compositor you have to be in
|
||||
// mixing mode, that is, iNumStreams needs to be greater than 0.
|
||||
//
|
||||
if (lpCompositor && iNumStreams < 1) {
|
||||
iNumStreams = 1;
|
||||
}
|
||||
|
||||
if (iNumStreams) {
|
||||
CHECK_HR(hr = pConfig->SetNumberOfStreams(iNumStreams));
|
||||
}
|
||||
|
||||
if (lpCompositor) {
|
||||
CHECK_HR(hr = pConfig->SetImageCompositor(lpCompositor));
|
||||
}
|
||||
|
||||
CHECK_HR(hr = pConfig->SetRenderingMode(mode));
|
||||
}
|
||||
__finally {
|
||||
RELEASE(pConfig);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* AddVideoMixingRendererToFG()
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::AddVideoMixingRendererToFG(DWORD dwStreams)
|
||||
{
|
||||
IBaseFilter* pBF = NULL;
|
||||
HRESULT hRes = S_OK;
|
||||
|
||||
__try {
|
||||
CHECK_HR(hRes = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL, CLSCTX_INPROC,IID_IBaseFilter,
|
||||
(LPVOID *)&pBF));
|
||||
|
||||
CHECK_HR(hRes = m_Fg->AddFilter(pBF, L"Video Mixing Renderer"));
|
||||
CHECK_HR(hRes = SetRenderingMode(pBF, VMRMode_Windowless,
|
||||
dwStreams, (IVMRImageCompositor*)this));
|
||||
|
||||
CHECK_HR(hRes = pBF->QueryInterface(IID_IVMRWindowlessControl, (LPVOID *)&m_Wc));
|
||||
CHECK_HR(hRes = m_Wc->SetVideoClippingWindow(m_hwndApp));
|
||||
|
||||
CHECK_HR(hRes = m_Wc->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX));
|
||||
}
|
||||
__finally {
|
||||
RELEASE(pBF);
|
||||
}
|
||||
|
||||
return hRes;
|
||||
}
|
||||
|
||||
|
||||
HRESULT AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
|
||||
{
|
||||
IMoniker * pMoniker;
|
||||
IRunningObjectTable *pROT;
|
||||
if (FAILED(GetRunningObjectTable(0, &pROT))) {
|
||||
return E_FAIL;
|
||||
}
|
||||
WCHAR wsz[256];
|
||||
wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
|
||||
HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
|
||||
pMoniker->Release();
|
||||
}
|
||||
pROT->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* OpenMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::OpenMovie(
|
||||
TCHAR achFileName[][MAX_PATH],
|
||||
DWORD dwNumFiles
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
IUnknown *pUnk = NULL;
|
||||
HRESULT hres = S_OK;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
__try {
|
||||
CHECK_HR(hres = CoCreateInstance(CLSID_FilterGraph,
|
||||
NULL, CLSCTX_INPROC,
|
||||
IID_IUnknown, (LPVOID *)&pUnk));
|
||||
m_Mode = MOVIE_OPENED;
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IFilterGraph, (LPVOID *)&m_Fg));
|
||||
CHECK_HR(hres = AddVideoMixingRendererToFG(4));
|
||||
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IGraphBuilder, (LPVOID *)&m_Gb));
|
||||
|
||||
AddToRot(m_Gb, &m_dwRegister);
|
||||
|
||||
for (DWORD i = 0; i < dwNumFiles; i++)
|
||||
{
|
||||
wcscpy(FileName, T2W(achFileName[i]));
|
||||
CHECK_HR(hres = m_Gb->RenderFile(FileName, NULL));
|
||||
}
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IMediaControl, (LPVOID *)&m_Mc));
|
||||
|
||||
//
|
||||
// Not being able to get the IMediaEvent interface does
|
||||
// necessarly mean that we can't play the graph.
|
||||
//
|
||||
pUnk->QueryInterface(IID_IMediaEvent, (LPVOID *)&m_Me);
|
||||
GetMovieEventHandle();
|
||||
pUnk->QueryInterface(IID_IMediaSeeking, (LPVOID *)&m_Ms);
|
||||
}
|
||||
__finally {
|
||||
|
||||
if (FAILED(hres)) {
|
||||
RELEASE(m_Ms);
|
||||
RELEASE(m_Me);
|
||||
RELEASE(m_Mc);
|
||||
RELEASE(m_Gb);
|
||||
RELEASE(m_Fg);
|
||||
}
|
||||
|
||||
RELEASE(pUnk);
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
void RemoveFromRot(DWORD pdwRegister)
|
||||
{
|
||||
IRunningObjectTable *pROT;
|
||||
if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
|
||||
pROT->Revoke(pdwRegister);
|
||||
pROT->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CloseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
DWORD
|
||||
CMpegMovie::CloseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_NOTOPENED;
|
||||
|
||||
RELEASE(m_Ms);
|
||||
RELEASE(m_Mc);
|
||||
RELEASE(m_Me);
|
||||
RELEASE(m_Gb);
|
||||
RELEASE(m_Fg);
|
||||
RELEASE(m_Wc);
|
||||
RELEASE(m_pDDSTextureMirror);
|
||||
|
||||
if (m_dwRegister)
|
||||
{
|
||||
RemoveFromRot(m_dwRegister);
|
||||
m_dwRegister = 0;
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RepaintVideo
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::RepaintVideo(
|
||||
HWND hwnd,
|
||||
HDC hdc
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
if (m_Wc) {
|
||||
bRet = (m_Wc->RepaintVideo(hwnd, hdc) == S_OK);
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PutMoviePosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PutMoviePosition(
|
||||
LONG x,
|
||||
LONG y,
|
||||
LONG cx,
|
||||
LONG cy
|
||||
)
|
||||
{
|
||||
RECT rc;
|
||||
SetRect(&rc, x, y, x + cx, y + cy);
|
||||
BOOL bRet = (m_Wc->SetVideoPosition(NULL, &rc) == S_OK);
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PlayMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PlayMovie(
|
||||
)
|
||||
{
|
||||
REFTIME rt;
|
||||
REFTIME rtAbs;
|
||||
REFTIME rtDur;
|
||||
|
||||
rt = GetCurrentPosition();
|
||||
rtDur = GetDuration();
|
||||
|
||||
//
|
||||
// If we are near the end of the movie seek to the start, otherwise
|
||||
// stay where we are.
|
||||
//
|
||||
rtAbs = rt - rtDur;
|
||||
if (rtAbs < (REFTIME)0) {
|
||||
rtAbs = -rtAbs;
|
||||
}
|
||||
|
||||
if (rtAbs <= (REFTIME)1) {
|
||||
SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// Change mode after setting m_Mode but before starting the graph
|
||||
//
|
||||
m_Mode = MOVIE_PLAYING;
|
||||
HRESULT hr = m_Mc->Run();
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PauseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PauseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
HRESULT hr = m_Mc->Pause();
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetStateMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
|
||||
OAFilterState
|
||||
CMpegMovie::GetStateMovie(
|
||||
)
|
||||
{
|
||||
OAFilterState State;
|
||||
HRESULT hr = m_Mc->GetState(INFINITE,&State);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
return State;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StopMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::StopMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
HRESULT hr = m_Mc->Stop();
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMediaEventHandle
|
||||
*
|
||||
* Returns the IMediaEvent event hamdle for the filter graph iff the
|
||||
* filter graph exists.
|
||||
*
|
||||
\**************************************************************************/
|
||||
HANDLE
|
||||
CMpegMovie::GetMovieEventHandle(
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (m_Me != NULL) {
|
||||
|
||||
if ( m_MediaEvent == NULL) {
|
||||
hr = m_Me->GetEventHandle((OAEVENT *)&m_MediaEvent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_MediaEvent = NULL;
|
||||
}
|
||||
|
||||
return m_MediaEvent;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMovieEventCode
|
||||
*
|
||||
\**************************************************************************/
|
||||
long
|
||||
CMpegMovie::GetMovieEventCode()
|
||||
{
|
||||
HRESULT hr;
|
||||
long lEventCode;
|
||||
LONG_PTR lParam1, lParam2;
|
||||
|
||||
if (m_Me != NULL) {
|
||||
hr = m_Me->GetEvent(&lEventCode, &lParam1, &lParam2, 0);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = m_Me->FreeEventParams(lEventCode, lParam1, lParam2);
|
||||
return lEventCode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetDuration
|
||||
*
|
||||
* Returns the duration of the current movie
|
||||
*
|
||||
\**************************************************************************/
|
||||
REFTIME
|
||||
CMpegMovie::GetDuration()
|
||||
{
|
||||
HRESULT hr;
|
||||
LONGLONG Duration;
|
||||
|
||||
// Should we seek using IMediaSelection
|
||||
|
||||
if (m_Ms != NULL && m_TimeFormat != TIME_FORMAT_MEDIA_TIME) {
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return double(Duration);
|
||||
}
|
||||
} else if (m_Ms != NULL) {
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return double(Duration) / UNITS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetCurrentPosition
|
||||
*
|
||||
* Returns the duration of the current movie
|
||||
*
|
||||
\**************************************************************************/
|
||||
REFTIME
|
||||
CMpegMovie::GetCurrentPosition()
|
||||
{
|
||||
REFTIME rt = (REFTIME)0;
|
||||
HRESULT hr;
|
||||
LONGLONG Position;
|
||||
|
||||
// Should we return a media position
|
||||
|
||||
if (m_Ms != NULL && m_TimeFormat != TIME_FORMAT_MEDIA_TIME) {
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return double(Position);
|
||||
}
|
||||
} else if (m_Ms != NULL) {
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if (SUCCEEDED(hr)) {
|
||||
return double(Position) / UNITS;
|
||||
}
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SeekToPosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SeekToPosition(
|
||||
REFTIME rt,
|
||||
BOOL bFlushData
|
||||
)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
LONGLONG llTime =
|
||||
LONGLONG(m_TimeFormat == TIME_FORMAT_MEDIA_TIME ? rt * double(UNITS) : rt);
|
||||
|
||||
if (m_Ms != NULL) {
|
||||
|
||||
FILTER_STATE fs;
|
||||
hr = m_Mc->GetState(100, (OAFilterState *)&fs);
|
||||
|
||||
hr = m_Ms->SetPositions(&llTime, AM_SEEKING_AbsolutePositioning, NULL, 0);
|
||||
|
||||
// This gets new data through to the renderers
|
||||
if (fs == State_Stopped && bFlushData){
|
||||
hr = m_Mc->Pause();
|
||||
hr = m_Mc->GetState(INFINITE, (OAFilterState *)&fs);
|
||||
hr = m_Mc->Stop();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VerifyVMR
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL VerifyVMR(void)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
// Verify that the VMR exists on this system
|
||||
IBaseFilter* pBF = NULL;
|
||||
hres = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
pBF->Release();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp,
|
||||
TEXT("This application requires the Video Mixing Renderer, which is present\r\n")
|
||||
TEXT("only on Windows XP.\r\n\r\n")
|
||||
TEXT("The Video Mixing Renderer (VMR) is also not enabled when viewing a \r\n")
|
||||
TEXT("remote Windows XP machine through a Remote Desktop session.\r\n")
|
||||
TEXT("You can run VMR-enabled applications only on your local machine.")
|
||||
TEXT("\r\n\r\nThis sample will now exit."),
|
||||
TEXT("Video Mixing Renderer capabilities are required"), MB_OK);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for CMpegMovie class
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <ddraw.h>
|
||||
#define D3D_OVERLOADS
|
||||
#include <d3d.h>
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** CMpegMovie - an Mpeg movie playback class.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
enum EMpegMovieMode { MOVIE_NOTOPENED = 0x00,
|
||||
MOVIE_OPENED = 0x01,
|
||||
MOVIE_PLAYING = 0x02,
|
||||
MOVIE_STOPPED = 0x03,
|
||||
MOVIE_PAUSED = 0x04 };
|
||||
|
||||
|
||||
|
||||
#define NUM_CUBE_VERTICES (4*6)
|
||||
|
||||
BOOL VerifyVMR(void);
|
||||
|
||||
struct StreamInfo
|
||||
{
|
||||
RECT SourceRect;
|
||||
BOOL bTexture;
|
||||
};
|
||||
|
||||
struct StreamSize
|
||||
{
|
||||
float cx;
|
||||
float cy;
|
||||
};
|
||||
|
||||
|
||||
class CMpegMovie :
|
||||
public CUnknown,
|
||||
public IVMRImageCompositor
|
||||
{
|
||||
|
||||
private:
|
||||
bool DoesSupportNonPow2CondCap(LPDIRECT3DDEVICE7 pD3DDevice);
|
||||
bool DoesSupportLinearCap(LPDIRECT3DDEVICE7 pD3DDevice);
|
||||
bool DoesSupportAnisoCap(LPDIRECT3DDEVICE7 pD3DDevice);
|
||||
DWORD m_dwTexMirrorWidth;
|
||||
DWORD m_dwTexMirrorHeight;
|
||||
DWORD m_dwRegister;
|
||||
// Our state variable - records whether we are opened, playing etc.
|
||||
EMpegMovieMode m_Mode;
|
||||
HANDLE m_MediaEvent;
|
||||
HWND m_hwndApp;
|
||||
int m_iDuration;
|
||||
GUID m_TimeFormat;
|
||||
bool m_bInitCube;
|
||||
|
||||
StreamInfo m_StreamInfo[16];
|
||||
|
||||
HRESULT FrameMove(LPDIRECT3DDEVICE7 pd3dDevice, FLOAT fTimeKey);
|
||||
D3DVERTEX m_pCubeVertices[NUM_CUBE_VERTICES];
|
||||
|
||||
HRESULT AllocateTextureMirror(LPDIRECTDRAWSURFACE7 pddsVideo,
|
||||
DWORD* dwWidth, DWORD* dwHeight,
|
||||
bool bNonPow2Cond);
|
||||
LPDIRECTDRAWSURFACE7 m_pDDSTextureMirror;
|
||||
|
||||
IFilterGraph* m_Fg;
|
||||
IGraphBuilder* m_Gb;
|
||||
IMediaControl* m_Mc;
|
||||
IMediaSeeking* m_Ms;
|
||||
IMediaEvent* m_Me;
|
||||
IVMRWindowlessControl* m_Wc;
|
||||
|
||||
|
||||
HRESULT AddVideoMixingRendererToFG(DWORD dwStreams);
|
||||
|
||||
public:
|
||||
STDMETHODIMP SetStreamMediaType(DWORD dwStrmID, AM_MEDIA_TYPE* pmt, BOOL fTexture);
|
||||
CMpegMovie(HWND hwndApplication);
|
||||
~CMpegMovie();
|
||||
|
||||
DECLARE_IUNKNOWN
|
||||
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void**);
|
||||
|
||||
STDMETHODIMP InitCompositionTarget(
|
||||
IUnknown* pD3DDevice,
|
||||
LPDIRECTDRAWSURFACE7 pddsRenderTarget
|
||||
);
|
||||
|
||||
STDMETHODIMP TermCompositionTarget(
|
||||
IUnknown* pD3DDevice,
|
||||
LPDIRECTDRAWSURFACE7 pddsRenderTarget
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CompositeImage(
|
||||
IUnknown* pD3DDevice,
|
||||
LPDIRECTDRAWSURFACE7 pddsRenderTarget,
|
||||
AM_MEDIA_TYPE* pmtRenderTarget,
|
||||
REFERENCE_TIME rtStart,
|
||||
REFERENCE_TIME rtEnd,
|
||||
DWORD dwMappedClrBkgnd,
|
||||
VMRVIDEOSTREAMINFO* pVideoStreamInfo,
|
||||
UINT cStreams
|
||||
);
|
||||
|
||||
|
||||
HRESULT OpenMovie(TCHAR achFileName[][MAX_PATH], DWORD dwNumFiles);
|
||||
DWORD CloseMovie();
|
||||
|
||||
BOOL PlayMovie();
|
||||
BOOL PauseMovie();
|
||||
BOOL StopMovie();
|
||||
|
||||
OAFilterState GetStateMovie();
|
||||
|
||||
HANDLE GetMovieEventHandle();
|
||||
long GetMovieEventCode();
|
||||
|
||||
BOOL PutMoviePosition(LONG x, LONG y, LONG cx, LONG cy);
|
||||
BOOL RepaintVideo(HWND hwnd, HDC hdc);
|
||||
|
||||
REFTIME GetDuration();
|
||||
REFTIME GetCurrentPosition();
|
||||
BOOL SeekToPosition(REFTIME rt,BOOL bFlushData);
|
||||
|
||||
void SetFullScreenMode(BOOL bMode);
|
||||
|
||||
void DisplayModeChanged() {
|
||||
if (m_Wc) {
|
||||
m_Wc->DisplayModeChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RECT GetSourceRectFromMediaType(const AM_MEDIA_TYPE *pMediaType);
|
||||
LPBITMAPINFOHEADER GetbmiHeader(const AM_MEDIA_TYPE *pMediaType);
|
||||
|
||||
@@ -0,0 +1,464 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: allocpresenter.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - Custom allocator-presenter
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include "project.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <initguid.h>
|
||||
|
||||
|
||||
// {99d54f63-1a69-41ae-aa4d-c976eb3f0713}
|
||||
//DEFINE_GUID(CLSID_AllocPresenter, 0x99d54f63, 0x1a69, 0x41ae, 0xaa, 0x4d, 0xc9, 0x76, 0xeb, 0x3f, 0x07, 0x13);
|
||||
|
||||
template <typename T>
|
||||
__inline void INITDDSTRUCT(T& dd)
|
||||
{
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
dd.dwSize = sizeof(dd);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* CreateDefaultAllocatorPresenter
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::CreateDefaultAllocatorPresenter()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
__try {
|
||||
CHECK_HR(hr = CoCreateInstance(CLSID_AllocPresenter, NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_IVMRSurfaceAllocator,
|
||||
(LPVOID*)&m_lpDefSA));
|
||||
|
||||
CHECK_HR(hr = m_lpDefSA->QueryInterface(IID_IVMRImagePresenter,
|
||||
(LPVOID*)&m_lpDefIP));
|
||||
|
||||
CHECK_HR(hr = m_lpDefSA->QueryInterface(IID_IVMRWindowlessControl,
|
||||
(LPVOID*)&m_lpDefWC));
|
||||
|
||||
CHECK_HR(hr = m_lpDefWC->SetVideoClippingWindow(m_hwndApp));
|
||||
CHECK_HR(hr = m_lpDefSA->AdviseNotify(this));
|
||||
}
|
||||
__finally {
|
||||
|
||||
if(FAILED(hr)) {
|
||||
RELEASE(m_lpDefWC);
|
||||
RELEASE(m_lpDefIP);
|
||||
RELEASE(m_lpDefSA);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* NonDelegatingQueryInterface
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NonDelegatingQueryInterface(
|
||||
REFIID riid,
|
||||
void** ppv
|
||||
)
|
||||
{
|
||||
if(riid == IID_IVMRSurfaceAllocator)
|
||||
{
|
||||
return GetInterface((IVMRSurfaceAllocator*)this, ppv);
|
||||
}
|
||||
else if(riid == IID_IVMRImagePresenter)
|
||||
{
|
||||
return GetInterface((IVMRImagePresenter*)this, ppv);
|
||||
}
|
||||
|
||||
return CUnknown::NonDelegatingQueryInterface(riid,ppv);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRSurfaceAllocator
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AllocateSurfaces
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AllocateSurface(
|
||||
DWORD_PTR dwUserID,
|
||||
VMRALLOCATIONINFO* lpAllocInfo,
|
||||
DWORD* lpdwBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface
|
||||
)
|
||||
{
|
||||
return m_lpDefSA->AllocateSurface(dwUserID, lpAllocInfo,
|
||||
lpdwBuffer, lplpSurface);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* FreeSurfaces()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::FreeSurface(
|
||||
DWORD_PTR dwUserID
|
||||
)
|
||||
{
|
||||
return m_lpDefSA->FreeSurface(dwUserID);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PrepareSurface
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PrepareSurface(
|
||||
DWORD_PTR dwUserID,
|
||||
LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags
|
||||
)
|
||||
{
|
||||
return m_lpDefSA->PrepareSurface(dwUserID, lplpSurface, dwSurfaceFlags);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AdviseNotify
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AdviseNotify(
|
||||
IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify
|
||||
)
|
||||
{
|
||||
return m_lpDefSA->AdviseNotify(lpIVMRSurfAllocNotify);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRSurfaceAllocatorNotify
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AdviseSurfaceAllocator
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AdviseSurfaceAllocator(
|
||||
DWORD_PTR dwUserID,
|
||||
IVMRSurfaceAllocator* lpIVRMSurfaceAllocator
|
||||
)
|
||||
{
|
||||
return m_lpDefSAN->AdviseSurfaceAllocator(dwUserID, lpIVRMSurfaceAllocator);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetDDrawDevice
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::SetDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor)
|
||||
{
|
||||
return m_lpDefSAN->SetDDrawDevice(lpDDrawDevice, hMonitor);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ChangeDDrawDevice
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::ChangeDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor)
|
||||
{
|
||||
return m_lpDefSAN->ChangeDDrawDevice(lpDDrawDevice, hMonitor);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DDSurfEnumFunc
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT WINAPI
|
||||
DDSurfEnumFunc(
|
||||
LPDIRECTDRAWSURFACE7 pdds,
|
||||
DDSURFACEDESC2* pddsd,
|
||||
void* lpContext
|
||||
)
|
||||
{
|
||||
LPDIRECTDRAWSURFACE7* ppdds = (LPDIRECTDRAWSURFACE7*)lpContext;
|
||||
|
||||
DDSURFACEDESC2 ddsd;
|
||||
INITDDSTRUCT(ddsd);
|
||||
|
||||
HRESULT hr = pdds->GetSurfaceDesc(&ddsd);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
if(ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
|
||||
{
|
||||
*ppdds = pdds;
|
||||
return DDENUMRET_CANCEL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pdds->Release();
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* OnSetDDrawDevice
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::OnSetDDrawDevice(
|
||||
LPDIRECTDRAW7 pDD,
|
||||
HMONITOR hMon
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
RELEASE(m_pddsRenderT);
|
||||
RELEASE(m_pddsPriText);
|
||||
RELEASE(m_pddsPrimary);
|
||||
|
||||
__try
|
||||
{
|
||||
|
||||
DDSURFACEDESC2 ddsd; // A surface description structure
|
||||
INITDDSTRUCT(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
|
||||
CHECK_HR(hr = pDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST |
|
||||
DDENUMSURFACES_ALL,
|
||||
&ddsd,
|
||||
&m_pddsPrimary,
|
||||
DDSurfEnumFunc));
|
||||
if(!m_pddsPrimary)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
__leave;
|
||||
}
|
||||
|
||||
MONITORINFOEX miInfoEx;
|
||||
miInfoEx.cbSize = sizeof(miInfoEx);
|
||||
GetMonitorInfo(hMon, &miInfoEx);
|
||||
|
||||
INITDDSTRUCT(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||
ddsd.dwWidth = (miInfoEx.rcMonitor.right - miInfoEx.rcMonitor.left);
|
||||
ddsd.dwHeight = (miInfoEx.rcMonitor.bottom - miInfoEx.rcMonitor.top);
|
||||
|
||||
CHECK_HR(hr = pDD->CreateSurface(&ddsd, &m_pddsPriText, NULL));
|
||||
CHECK_HR(hr = pDD->CreateSurface(&ddsd, &m_pddsRenderT, NULL));
|
||||
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RELEASE(m_pddsRenderT);
|
||||
RELEASE(m_pddsPriText);
|
||||
RELEASE(m_pddsPrimary);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RestoreDDrawSurfaces
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP CMpegMovie::RestoreDDrawSurfaces()
|
||||
{
|
||||
return m_lpDefSAN->RestoreDDrawSurfaces();
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RestoreDDrawSurfaces
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NotifyEvent(LONG EventCode, LONG_PTR lp1, LONG_PTR lp2)
|
||||
{
|
||||
return m_lpDefSAN->NotifyEvent(EventCode, lp1, lp2);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetBorderColor
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::SetBorderColor(
|
||||
COLORREF clr
|
||||
)
|
||||
{
|
||||
return m_lpDefSAN->SetBorderColor(clr);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRImagePresenter
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StartPresenting()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StartPresenting(DWORD_PTR dwUserID)
|
||||
{
|
||||
return m_lpDefIP->StartPresenting(dwUserID);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StopPresenting()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StopPresenting(DWORD_PTR dwUserID)
|
||||
{
|
||||
return m_lpDefIP->StopPresenting(dwUserID);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PresentImage
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PresentImage(
|
||||
DWORD_PTR dwUserID,
|
||||
VMRPRESENTATIONINFO* lpPresInfo
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
LPDIRECTDRAWSURFACE7 lpSurface = lpPresInfo->lpSurf;
|
||||
const REFERENCE_TIME rtNow = lpPresInfo->rtStart;
|
||||
const DWORD dwSurfaceFlags = lpPresInfo->dwFlags;
|
||||
|
||||
if(m_iDuration > 0)
|
||||
{
|
||||
HRESULT hr;
|
||||
RECT rs, rd;
|
||||
DDSURFACEDESC2 ddsdV;
|
||||
|
||||
INITDDSTRUCT(ddsdV);
|
||||
hr = lpSurface->GetSurfaceDesc(&ddsdV);
|
||||
|
||||
DDSURFACEDESC2 ddsdP;
|
||||
INITDDSTRUCT(ddsdP);
|
||||
hr = m_pddsPriText->GetSurfaceDesc(&ddsdP);
|
||||
|
||||
FLOAT fPos = (FLOAT)m_iDuration / 30.0F;
|
||||
FLOAT fPosInv = 1.0F - fPos;
|
||||
|
||||
SetRect(&rs, 0, 0,
|
||||
MulDiv((int)ddsdV.dwWidth, 30 - m_iDuration, 30),
|
||||
ddsdV.dwHeight);
|
||||
|
||||
SetRect(&rd, 0, 0,
|
||||
MulDiv((int)ddsdP.dwWidth, 30 - m_iDuration, 30),
|
||||
ddsdP.dwHeight);
|
||||
|
||||
hr = m_pddsRenderT->Blt(&rd, lpSurface,
|
||||
&rs, DDBLT_WAIT, NULL);
|
||||
|
||||
SetRect(&rs, 0, 0,
|
||||
MulDiv((int)ddsdP.dwWidth, m_iDuration, 30),
|
||||
ddsdP.dwHeight);
|
||||
|
||||
SetRect(&rd,
|
||||
(int)ddsdP.dwWidth - MulDiv((int)ddsdP.dwWidth, m_iDuration, 30),
|
||||
0,
|
||||
ddsdP.dwWidth,
|
||||
ddsdP.dwHeight);
|
||||
|
||||
hr = m_pddsRenderT->Blt(&rd, m_pddsPriText,
|
||||
&rs, DDBLT_WAIT, NULL);
|
||||
|
||||
//
|
||||
// need to wait for VBlank before blt-ing
|
||||
//
|
||||
{
|
||||
LPDIRECTDRAW lpdd;
|
||||
hr = m_pddsPrimary->GetDDInterface((LPVOID*)&lpdd);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
DWORD dwScanLine;
|
||||
for(; ;)
|
||||
{
|
||||
hr = lpdd->GetScanLine(&dwScanLine);
|
||||
|
||||
if(hr == DDERR_VERTICALBLANKINPROGRESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if((LONG)dwScanLine>= rd.top)
|
||||
{
|
||||
if((LONG)dwScanLine <= rd.bottom)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
RELEASE(lpdd);
|
||||
}
|
||||
}
|
||||
|
||||
hr = m_pddsPrimary->Blt(NULL, m_pddsRenderT,
|
||||
NULL, DDBLT_WAIT, NULL);
|
||||
|
||||
m_iDuration--;
|
||||
if(m_iDuration == 0 && (ddsdV.ddsCaps.dwCaps & DDSCAPS_OVERLAY))
|
||||
{
|
||||
// need to get the color key visible again.
|
||||
InvalidateRect(m_hwndApp, NULL, FALSE);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_lpDefIP->PresentImage(dwUserID, lpPresInfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_lpDefIP->PresentImage(dwUserID, lpPresInfo);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
# Microsoft Developer Studio Project File - Name="RenderLess" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=RenderLess - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "RenderLess.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "RenderLess.mak" CFG="RenderLess - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "RenderLess - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "RenderLess - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "RenderLess - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\DirectShow\BaseClasses" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 ..\..\..\DirectShow\BaseClasses\Release\strmbase.lib strmiids.lib quartz.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /pdb:none /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "RenderLess - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "..\..\..\DirectShow\BaseClasses" /D "_DEBUG" /D "DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 ..\..\..\DirectShow\BaseClasses\Debug\strmbasd.lib strmiids.lib quartz.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "RenderLess - Win32 Release"
|
||||
# Name "RenderLess - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AllocPresenter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\commands.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\project.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\renderless.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\renderless.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\toolbar.bmp
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,995 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: app.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - VMR-based Renderless video player
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlconv.cpp>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include <initguid.h>
|
||||
#include "project.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Global variables that are initialized at run time and then stay constant.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
HINSTANCE hInst;
|
||||
HICON hIconVideoCd;
|
||||
HWND hwndApp;
|
||||
HWND g_hwndToolbar;
|
||||
CMpegMovie *pMpegMovie;
|
||||
|
||||
BOOL m_bFullScreen = FALSE;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** True Globals - these may change during execution of the program.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
TCHAR g_achFileName[MAX_PATH];
|
||||
DWORD g_State = VCD_NO_CD;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
const TCHAR szClassName[] = TEXT("VMR_RenderlessPlayer_CLASS");
|
||||
const TCHAR g_szNULL[] = TEXT("\0");
|
||||
const TCHAR g_szEmpty[] = TEXT("");
|
||||
|
||||
/*
|
||||
** User interface values
|
||||
*/
|
||||
int dyToolbar;
|
||||
const int dxBitmap = 16;
|
||||
const int dyBitmap = 15;
|
||||
const int dxButtonSep = 8;
|
||||
const TCHAR g_chNULL = TEXT('\0');
|
||||
const LONG g_Style = WS_THICKFRAME | WS_POPUP | WS_CAPTION |
|
||||
WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
|
||||
WS_CLIPCHILDREN;
|
||||
|
||||
|
||||
const TBBUTTON tbButtons[DEFAULT_TBAR_SIZE] = {
|
||||
{ IDX_SEPARATOR, 1, 0, TBSTYLE_SEP },
|
||||
{ IDX_1, IDM_MOVIE_PLAY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
|
||||
{ IDX_2, IDM_MOVIE_PAUSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
|
||||
{ IDX_3, IDM_MOVIE_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
|
||||
{ IDX_SEPARATOR, 1, 0, TBSTYLE_SEP },
|
||||
{ IDX_4, IDM_FULL_SCREEN, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0, 0, -1 }
|
||||
};
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Local function prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
void SetFullScreenMode(BOOL bMode);
|
||||
BOOL IsFullScreenMode();
|
||||
LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* WinMain
|
||||
*
|
||||
*
|
||||
* Windows recognizes this function by name as the initial entry point
|
||||
* for the program. This function calls the application initialization
|
||||
* routine, if no other instance of the program is running, and always
|
||||
* calls the instance initialization routine. It then executes a message
|
||||
* retrieval and dispatch loop that is the top-level control structure
|
||||
* for the remainder of execution. The loop is terminated when a WM_QUIT
|
||||
* message is received, at which time this function exits the application
|
||||
* instance by returning the value passed by PostQuitMessage().
|
||||
*
|
||||
* If this function must abort before entering the message loop, it
|
||||
* returns the conventional value NULL.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int PASCAL
|
||||
WinMain(
|
||||
HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLineOld,
|
||||
int nCmdShow
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
LPTSTR lpCmdLine = A2T(lpCmdLineOld);
|
||||
|
||||
HRESULT hres = CoInitialize(NULL);
|
||||
if(hres == S_FALSE)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
if(!hPrevInstance)
|
||||
{
|
||||
if(!InitApplication(hInstance))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform initializations that apply to a specific instance
|
||||
*/
|
||||
if(!InitInstance(hInstance, nCmdShow))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Verify that the VMR is present on this system */
|
||||
if(!VerifyVMR())
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
** Acquire and dispatch messages until a WM_QUIT message is received.
|
||||
*/
|
||||
int iRet = DoMainLoop();
|
||||
QzUninitialize();
|
||||
return iRet;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DoMainLoop
|
||||
*
|
||||
* Process the main message loop
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
DoMainLoop(
|
||||
void
|
||||
)
|
||||
{
|
||||
MSG msg;
|
||||
HANDLE ahObjects[8];;
|
||||
int cObjects;
|
||||
HACCEL haccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
|
||||
|
||||
//
|
||||
// message loop lasts until we get a WM_QUIT message
|
||||
//
|
||||
for(;;)
|
||||
{
|
||||
if(pMpegMovie != NULL)
|
||||
{
|
||||
cObjects = 1;
|
||||
ahObjects[0] = pMpegMovie->GetMovieEventHandle();
|
||||
}
|
||||
else
|
||||
{
|
||||
ahObjects[0] = NULL;
|
||||
cObjects = 0;
|
||||
}
|
||||
|
||||
if(ahObjects[0] == NULL)
|
||||
{
|
||||
WaitMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// wait for any message sent or posted to this queue
|
||||
// or for a graph notification
|
||||
//
|
||||
DWORD result;
|
||||
|
||||
result = MsgWaitForMultipleObjects(cObjects, ahObjects, FALSE,
|
||||
INFINITE, QS_ALLINPUT);
|
||||
if(result != (WAIT_OBJECT_0 + cObjects))
|
||||
{
|
||||
|
||||
VideoCd_OnGraphNotify(result - WAIT_OBJECT_0);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// When here, we either have a message or no event handle
|
||||
// has been created yet.
|
||||
//
|
||||
// read all of the messages in this next loop
|
||||
// removing each message as we read it
|
||||
//
|
||||
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if(msg.message == WM_QUIT)
|
||||
{
|
||||
return (int) msg.wParam;
|
||||
}
|
||||
|
||||
if(!TranslateAccelerator(hwndApp, haccel, &msg))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // DoMainLoop
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitApplication(HANDLE)
|
||||
*
|
||||
* This function is called at initialization time only if no other
|
||||
* instances of the application are running. This function performs
|
||||
* initialization tasks that can be done once for any number of running
|
||||
* instances.
|
||||
*
|
||||
* In this case, we initialize a window class by filling out a data
|
||||
* structure of type WNDCLASS and calling the Windows RegisterClass()
|
||||
* function. Since all instances of this application use the same window
|
||||
* class, we only need to do this when the first instance is initialized.
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
InitApplication(
|
||||
HINSTANCE hInstance
|
||||
)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
|
||||
/*
|
||||
** Fill in window class structure with parameters that describe the
|
||||
** main window.
|
||||
*/
|
||||
hIconVideoCd = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_VIDEOCD_ICON));
|
||||
|
||||
wc.style = CS_VREDRAW | CS_HREDRAW;
|
||||
wc.lpfnWndProc = VideoCdWndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = hIconVideoCd;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)NULL;
|
||||
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN_MENU);
|
||||
wc.lpszClassName = szClassName;
|
||||
|
||||
/*
|
||||
** Register the window class and return success/failure code.
|
||||
*/
|
||||
return RegisterClass(&wc);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitInstance
|
||||
*
|
||||
* This function is called at initialization time for every instance of
|
||||
* this application. This function performs initialization tasks that
|
||||
* cannot be shared by multiple instances.
|
||||
*
|
||||
* In this case, we save the instance handle in a static variable and
|
||||
* create and display the main program window.
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
InitInstance(
|
||||
HINSTANCE hInstance,
|
||||
int nCmdShow
|
||||
)
|
||||
{
|
||||
HWND hwnd;
|
||||
RECT rc;
|
||||
|
||||
/*
|
||||
** Save the instance handle in static variable, which will be used
|
||||
** in many subsequent calls to Windows.
|
||||
*/
|
||||
hInst = hInstance;
|
||||
rc.left = rc.top = 100;
|
||||
rc.bottom = rc.right = 400;
|
||||
|
||||
/*
|
||||
** Create a main window for this application instance.
|
||||
*/
|
||||
hwnd = CreateWindow(szClassName, IdStr(STR_APP_TITLE), g_Style,
|
||||
rc.left, rc.top,
|
||||
rc.right, rc.bottom,
|
||||
NULL, NULL, hInstance, NULL);
|
||||
|
||||
/*
|
||||
** If window could not be created, return "failure"
|
||||
*/
|
||||
if(NULL == hwnd)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
hwndApp = hwnd;
|
||||
|
||||
/*
|
||||
** Make the window visible; update its client area; and return "success"
|
||||
*/
|
||||
SetPlayButtonsEnableState();
|
||||
ShowWindow(hwnd, nCmdShow);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetMoviePosition
|
||||
*
|
||||
* Place the movie in the centre of the client window.
|
||||
* We do not stretch the the movie yet.
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
GetMoviePosition(
|
||||
HWND hwnd,
|
||||
long* xPos,
|
||||
long* yPos,
|
||||
long* pcx,
|
||||
long* pcy
|
||||
)
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
GetAdjustedClientRect(&rc);
|
||||
|
||||
*xPos = rc.left;
|
||||
*yPos = rc.top;
|
||||
*pcx = rc.right - rc.left;
|
||||
*pcy = rc.bottom - rc.top;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RepositionMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
RepositionMovie(HWND hwnd)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
long xPos, yPos, cx, cy;
|
||||
|
||||
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
|
||||
|
||||
pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
|
||||
InvalidateRect(hwnd, NULL, false);
|
||||
UpdateWindow(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnMove
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnMove(
|
||||
HWND hwnd,
|
||||
int x,
|
||||
int y
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
if(pMpegMovie->GetStateMovie() != State_Running)
|
||||
{
|
||||
RepositionMovie(hwnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
long xPos, yPos, cx, cy;
|
||||
|
||||
// Reposition movie but don't invalidate the rect, since
|
||||
// the next video frame will handle the redraw.
|
||||
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
|
||||
pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCdWndProc
|
||||
*
|
||||
\**************************************************************************/
|
||||
LRESULT CALLBACK
|
||||
VideoCdWndProc(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
switch(message)
|
||||
{
|
||||
HANDLE_MSG(hwnd, WM_CREATE, VideoCd_OnCreate);
|
||||
HANDLE_MSG(hwnd, WM_PAINT, VideoCd_OnPaint);
|
||||
HANDLE_MSG(hwnd, WM_COMMAND, VideoCd_OnCommand);
|
||||
HANDLE_MSG(hwnd, WM_CLOSE, VideoCd_OnClose);
|
||||
HANDLE_MSG(hwnd, WM_DESTROY, VideoCd_OnDestroy);
|
||||
HANDLE_MSG(hwnd, WM_SIZE, VideoCd_OnSize);
|
||||
HANDLE_MSG(hwnd, WM_SYSCOLORCHANGE, VideoCd_OnSysColorChange);
|
||||
HANDLE_MSG(hwnd, WM_INITMENUPOPUP, VideoCd_OnInitMenuPopup);
|
||||
HANDLE_MSG(hwnd, WM_NOTIFY, VideoCd_OnNotify);
|
||||
HANDLE_MSG(hwnd, WM_KEYUP, VideoCd_OnKeyUp);
|
||||
HANDLE_MSG(hwnd, WM_MOVE, VideoCd_OnMove);
|
||||
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->DisplayModeChanged();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnCreate
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VideoCd_OnCreate(
|
||||
HWND hwnd,
|
||||
LPCREATESTRUCT lpCreateStruct
|
||||
)
|
||||
{
|
||||
InitCommonControls();
|
||||
|
||||
/*
|
||||
** Create the toolbar and statusbar.
|
||||
*/
|
||||
g_hwndToolbar = CreateToolbarEx(hwnd,
|
||||
WS_VISIBLE | WS_CHILD |
|
||||
TBSTYLE_TOOLTIPS | CCS_NODIVIDER,
|
||||
ID_TOOLBAR, NUMBER_OF_BITMAPS,
|
||||
hInst, IDR_TOOLBAR, tbButtons,
|
||||
DEFAULT_TBAR_SIZE, dxBitmap, dyBitmap,
|
||||
dxBitmap, dyBitmap, sizeof(TBBUTTON));
|
||||
|
||||
if(g_hwndToolbar == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnKeyUp
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnKeyUp(
|
||||
HWND hwnd,
|
||||
UINT vk,
|
||||
BOOL fDown,
|
||||
int cRepeat,
|
||||
UINT flags
|
||||
)
|
||||
{
|
||||
// Catch escape sequences to stop fullscreen mode
|
||||
if((vk == VK_ESCAPE) || (vk == VK_RETURN))
|
||||
{
|
||||
if(pMpegMovie && IsFullScreenMode())
|
||||
{
|
||||
SetFullScreenMode(FALSE);
|
||||
SetPlayButtonsEnableState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnPaint
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnPaint(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
RECT rc1;
|
||||
RECT rc2;
|
||||
|
||||
/*
|
||||
** Draw a frame around the movie playback area.
|
||||
*/
|
||||
GetClientRect(hwnd, &rc2);
|
||||
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
|
||||
if(pMpegMovie)
|
||||
{
|
||||
long xPos, yPos, cx, cy;
|
||||
GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
|
||||
SetRect(&rc1, xPos, yPos, xPos + cx, yPos + cy);
|
||||
|
||||
HRGN rgnClient = CreateRectRgnIndirect(&rc2);
|
||||
HRGN rgnVideo = CreateRectRgnIndirect(&rc1);
|
||||
CombineRgn(rgnClient, rgnClient, rgnVideo, RGN_DIFF);
|
||||
|
||||
HBRUSH hbr = GetSysColorBrush(COLOR_BTNFACE);
|
||||
FillRgn(hdc, rgnClient, hbr);
|
||||
DeleteObject(hbr);
|
||||
DeleteObject(rgnClient);
|
||||
DeleteObject(rgnVideo);
|
||||
|
||||
pMpegMovie->RepaintVideo(hwnd, hdc);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1));
|
||||
}
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
|
||||
|
||||
LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
if(wParam == IDOK)
|
||||
{
|
||||
EndDialog(hWnd, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnCommand
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnCommand(
|
||||
HWND hwnd,
|
||||
int id,
|
||||
HWND hwndCtl,
|
||||
UINT codeNotify
|
||||
)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case IDM_FILE_OPEN:
|
||||
if(VcdPlayerOpenCmd())
|
||||
VcdPlayerPlayCmd();
|
||||
break;
|
||||
|
||||
case IDM_FILE_CLOSE:
|
||||
VcdPlayerCloseCmd();
|
||||
QzFreeUnusedLibraries();
|
||||
break;
|
||||
|
||||
case IDM_FILE_ABOUT:
|
||||
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX),
|
||||
hwnd, (DLGPROC) AboutDlgProc);
|
||||
break;
|
||||
|
||||
case IDM_FILE_EXIT:
|
||||
PostMessage(hwnd, WM_CLOSE, 0, 0L);
|
||||
break;
|
||||
|
||||
case IDM_MOVIE_PLAY:
|
||||
VcdPlayerPlayCmd();
|
||||
break;
|
||||
|
||||
case IDM_MOVIE_STOP:
|
||||
VcdPlayerStopCmd();
|
||||
VcdPlayerRewindCmd();
|
||||
break;
|
||||
|
||||
case IDM_MOVIE_PAUSE:
|
||||
VcdPlayerPauseCmd();
|
||||
break;
|
||||
|
||||
case IDM_FULL_SCREEN:
|
||||
if(pMpegMovie)
|
||||
{
|
||||
BOOL bFullScreen = (BOOL)SendMessage(g_hwndToolbar,
|
||||
TB_ISBUTTONCHECKED, IDM_FULL_SCREEN, 0);
|
||||
SetFullScreenMode(bFullScreen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SetPlayButtonsEnableState();
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnDestroy
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnDestroy(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
VideoCd_OnClose(hwnd);
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnClose
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnClose(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
VcdPlayerCloseCmd();
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VideoCd_OnSize
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnSize(
|
||||
HWND hwnd,
|
||||
UINT state,
|
||||
int dx,
|
||||
int dy
|
||||
)
|
||||
{
|
||||
if(IsWindow(g_hwndToolbar))
|
||||
SendMessage(g_hwndToolbar, WM_SIZE, 0, 0L);
|
||||
|
||||
RepositionMovie(hwnd);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnSysColorChange
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnSysColorChange(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
FORWARD_WM_SYSCOLORCHANGE(g_hwndToolbar, SendMessage);
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnInitMenuPopup
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnInitMenuPopup(
|
||||
HWND hwnd,
|
||||
HMENU hMenu,
|
||||
UINT item,
|
||||
BOOL fSystemMenu
|
||||
)
|
||||
{
|
||||
UINT uFlags;
|
||||
|
||||
if(item == 0)
|
||||
{ // File menu
|
||||
|
||||
if(g_State & (VCD_IN_USE | VCD_NO_CD | VCD_DATA_CD_LOADED))
|
||||
{
|
||||
uFlags = (MF_BYCOMMAND | MF_GRAYED);
|
||||
}
|
||||
else
|
||||
{
|
||||
uFlags = (MF_BYCOMMAND | MF_ENABLED);
|
||||
}
|
||||
|
||||
// Disable menu items until a movie is opened
|
||||
EnableMenuItem(hMenu, IDM_FILE_CLOSE, uFlags);
|
||||
EnableMenuItem(hMenu, IDM_MOVIE_STOP, uFlags);
|
||||
EnableMenuItem(hMenu, IDM_MOVIE_PLAY, uFlags);
|
||||
EnableMenuItem(hMenu, IDM_MOVIE_PAUSE, uFlags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnGraphNotify
|
||||
*
|
||||
* This is where we get any notifications from the filter graph.
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VideoCd_OnGraphNotify(
|
||||
int stream
|
||||
)
|
||||
{
|
||||
long lEventCode;
|
||||
|
||||
lEventCode = pMpegMovie->GetMovieEventCode();
|
||||
|
||||
switch(lEventCode)
|
||||
{
|
||||
case EC_FULLSCREEN_LOST:
|
||||
SetPlayButtonsEnableState();
|
||||
break;
|
||||
|
||||
case EC_USERABORT:
|
||||
case EC_ERRORABORT:
|
||||
VcdPlayerStopCmd();
|
||||
SetPlayButtonsEnableState();
|
||||
break;
|
||||
|
||||
case EC_COMPLETE:
|
||||
VcdPlayerRewindCmd();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VideoCd_OnNotify
|
||||
*
|
||||
* This is where we get the text for tooltips
|
||||
*
|
||||
\**************************************************************************/
|
||||
LRESULT
|
||||
VideoCd_OnNotify(
|
||||
HWND hwnd,
|
||||
int idFrom,
|
||||
NMHDR FAR* pnmhdr
|
||||
)
|
||||
{
|
||||
switch(pnmhdr->code)
|
||||
{
|
||||
case TTN_NEEDTEXT:
|
||||
{
|
||||
LPTOOLTIPTEXT lpTt;
|
||||
lpTt = (LPTOOLTIPTEXT)pnmhdr;
|
||||
|
||||
LoadString(hInst, (UINT) lpTt->hdr.idFrom, lpTt->szText,
|
||||
sizeof(lpTt->szText));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetPlayButtonsEnableState
|
||||
*
|
||||
* Sets the play buttons enable state to match the state of the current
|
||||
* cdrom device. See below...
|
||||
*
|
||||
*
|
||||
* VCD Player buttons enable state table
|
||||
* --------------------------------------------------------------------
|
||||
* -E=Enabled D=Disabled - Play - Pause - Eject - Stop - Other -
|
||||
* --------------------------------------------------------------------
|
||||
* -Disk in use - D - D - D - D - D -
|
||||
* --------------------------------------------------------------------
|
||||
* -No video cd or data cdrom - D - D - E - D - D -
|
||||
* --------------------------------------------------------------------
|
||||
* -Video cd (playing) - D - E - E - E - E -
|
||||
* --------------------------------------------------------------------
|
||||
* -Video cd (paused) - E - D - E - E - E -
|
||||
* --------------------------------------------------------------------
|
||||
* -Video cd (stopped) - E - D - E - D - E -
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
SetPlayButtonsEnableState(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fEnable, fPress;
|
||||
BOOL fVideoCdLoaded;
|
||||
|
||||
/*
|
||||
** Do we have a video cd loaded.
|
||||
*/
|
||||
if(g_State & (VCD_NO_CD | VCD_DATA_CD_LOADED | VCD_IN_USE))
|
||||
{
|
||||
fVideoCdLoaded = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fVideoCdLoaded = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
** Do the play button
|
||||
*/
|
||||
if(fVideoCdLoaded
|
||||
&& ((g_State & VCD_STOPPED) || (g_State & VCD_PAUSED)))
|
||||
{
|
||||
fEnable = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fEnable = FALSE;
|
||||
}
|
||||
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PLAY, fEnable);
|
||||
|
||||
/*
|
||||
** Do the stop button
|
||||
*/
|
||||
if(fVideoCdLoaded
|
||||
&& ((g_State & VCD_PLAYING) || (g_State & VCD_PAUSED)))
|
||||
{
|
||||
fEnable = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fEnable = FALSE;
|
||||
}
|
||||
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_STOP, fEnable);
|
||||
|
||||
/*
|
||||
** Do the pause button
|
||||
*/
|
||||
if(fVideoCdLoaded && (g_State & VCD_PLAYING))
|
||||
{
|
||||
fEnable = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fEnable = FALSE;
|
||||
}
|
||||
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PAUSE, fEnable);
|
||||
|
||||
/*
|
||||
** Do the remaining buttons
|
||||
*/
|
||||
/*
|
||||
** Do the fullscreen button
|
||||
*/
|
||||
fPress = (fVideoCdLoaded && IsFullScreenMode());
|
||||
|
||||
SendMessage(g_hwndToolbar, TB_CHECKBUTTON, IDM_FULL_SCREEN, MAKELONG(fPress,0));
|
||||
SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_FULL_SCREEN, fVideoCdLoaded && (g_State & VCD_PLAYING));
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetAdjustedClientRect
|
||||
*
|
||||
* Calculate the size of the client rect and then adjusts it to take into
|
||||
* account the space taken by the toolbar and status bar.
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
GetAdjustedClientRect(
|
||||
RECT *prc
|
||||
)
|
||||
{
|
||||
RECT rcTool;
|
||||
|
||||
GetClientRect(hwndApp, prc);
|
||||
|
||||
if(IsWindowVisible(g_hwndToolbar))
|
||||
{
|
||||
GetWindowRect(g_hwndToolbar, &rcTool);
|
||||
prc->top += (rcTool.bottom - rcTool.top);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* IdStr
|
||||
*
|
||||
* Loads the given string resource ID into the passed storage.
|
||||
*
|
||||
\**************************************************************************/
|
||||
LPCTSTR
|
||||
IdStr(
|
||||
int idResource
|
||||
)
|
||||
{
|
||||
static TCHAR chBuffer[ STR_MAX_STRING_LEN ];
|
||||
|
||||
if(LoadString(hInst, idResource, chBuffer, STR_MAX_STRING_LEN) == 0)
|
||||
{
|
||||
return g_szEmpty;
|
||||
}
|
||||
|
||||
return chBuffer;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetFullScreenMode
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
SetFullScreenMode(BOOL bMode)
|
||||
{
|
||||
static HMENU hMenu=0;
|
||||
static LONG lStyle=0;
|
||||
static int xs=0, ys=0, cxs=0, cys=0;
|
||||
|
||||
// Defer until we activate the movie
|
||||
if(pMpegMovie->GetStateMovie() != State_Running)
|
||||
{
|
||||
if(bMode == TRUE)
|
||||
return;
|
||||
}
|
||||
|
||||
m_bFullScreen = bMode;
|
||||
|
||||
HDC hdcScreen = GetDC(NULL);
|
||||
int cx = GetDeviceCaps(hdcScreen,HORZRES);
|
||||
int cy = GetDeviceCaps(hdcScreen,VERTRES);
|
||||
ReleaseDC(NULL, hdcScreen);
|
||||
|
||||
pMpegMovie->SetFullScreenMode(bMode);
|
||||
|
||||
if(bMode)
|
||||
{
|
||||
hMenu = GetMenu(hwndApp);
|
||||
lStyle = GetWindowStyle(hwndApp);
|
||||
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(hwndApp, &wp);
|
||||
xs = wp.rcNormalPosition.left;
|
||||
ys = wp.rcNormalPosition.top;
|
||||
cxs = wp.rcNormalPosition.right - xs;
|
||||
cys = wp.rcNormalPosition.bottom - ys;
|
||||
ShowWindow(g_hwndToolbar, SW_HIDE);
|
||||
SetMenu(hwndApp, NULL);
|
||||
SetWindowLong(hwndApp, GWL_STYLE, WS_POPUP | WS_VISIBLE);
|
||||
SetWindowPos(hwndApp, HWND_TOP, 0, 0, cx, cy, SWP_NOACTIVATE);
|
||||
ShowCursor(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCursor(TRUE);
|
||||
ShowWindow(g_hwndToolbar, SW_SHOW);
|
||||
SetMenu(hwndApp, hMenu);
|
||||
SetWindowLong(hwndApp, GWL_STYLE, lStyle);
|
||||
SetWindowPos(hwndApp, HWND_TOP, xs, ys, cxs, cys, SWP_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* IsFullScreenMode()
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
IsFullScreenMode()
|
||||
{
|
||||
return m_bFullScreen;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,299 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: app.h
|
||||
//
|
||||
// Desc: DirectShow sample code - prototypes for the Renderless player
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Function prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int DoMainLoop(void);
|
||||
BOOL InitApplication(HINSTANCE hInstance);
|
||||
BOOL InitInstance(HINSTANCE hInstance,int nCmdShow);
|
||||
|
||||
void UpdateMpegMovieRect(void);
|
||||
void GetAdjustedClientRect(RECT *prc);
|
||||
|
||||
BOOL DrawStats(HDC hdc);
|
||||
void CalcMovieRect(LPRECT lprc);
|
||||
|
||||
LPCTSTR IdStr(int idResource);
|
||||
void UpdateSystemColors(void);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Message crackers
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
/* void Cls_OnUser(HWND hwnd, WPARAM wParam, LPARAM lParam ) */
|
||||
#define HANDLE_WM_USER(hwnd, wParam, lParam, fn) \
|
||||
((fn)(hwnd, wParam, lParam), 0L)
|
||||
|
||||
#ifndef HANDLE_WM_NOTIFY
|
||||
/* LRESULT Cls_OnNotify(HWND hwnd, int idFrom, NMHDR FAR* pnmhdr); */
|
||||
#define HANDLE_WM_NOTIFY(hwnd, wParam, lParam, fn) \
|
||||
(fn)((hwnd), (int)(wParam), (NMHDR FAR*)(lParam))
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** VideoCd window class prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
extern "C" LRESULT CALLBACK
|
||||
VideoCdWndProc(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnClose(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnQueryEndSession(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDestroy(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnCommand(
|
||||
HWND hwnd,
|
||||
int id,
|
||||
HWND hwndCtl,
|
||||
UINT codeNotify
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnPaint(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnTimer(
|
||||
HWND hwnd,
|
||||
UINT id
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnCreate(
|
||||
HWND hwnd,
|
||||
LPCREATESTRUCT lpCreateStruct
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSize(
|
||||
HWND hwnd,
|
||||
UINT state,
|
||||
int cx,
|
||||
int cy
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnKeyUp(
|
||||
HWND hwnd,
|
||||
UINT vk,
|
||||
BOOL fDown,
|
||||
int cRepeat,
|
||||
UINT flags
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnHScroll(
|
||||
HWND hwnd,
|
||||
HWND hwndCtl,
|
||||
UINT code,
|
||||
int pos
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnUser(
|
||||
HWND hwnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSysColorChange(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnMenuSelect(
|
||||
HWND hwnd,
|
||||
HMENU hmenu,
|
||||
int item,
|
||||
HMENU hmenuPopup,
|
||||
UINT flags
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnInitMenuPopup(
|
||||
HWND hwnd,
|
||||
HMENU hMenu,
|
||||
UINT item,
|
||||
BOOL fSystemMenu
|
||||
);
|
||||
|
||||
#ifdef WM_NOTIFY
|
||||
LRESULT
|
||||
VideoCd_OnNotify(
|
||||
HWND hwnd,
|
||||
int idFrom,
|
||||
NMHDR FAR* pnmhdr
|
||||
);
|
||||
#endif
|
||||
|
||||
void
|
||||
VideoCd_OnGraphNotify(
|
||||
int stream
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDropFiles(
|
||||
HWND hwnd,
|
||||
HDROP hdrop);
|
||||
|
||||
void
|
||||
SetPlayButtonsEnableState(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Command processing functions
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
BOOL
|
||||
VcdPlayerSetLog(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerSetPerfLogFile(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
);
|
||||
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay = FALSE
|
||||
);
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Recent filename defines
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
typedef TCHAR RECENTFILES[MAX_PATH];
|
||||
#define MAX_RECENT_FILES 5
|
||||
#define ID_RECENT_FILE_BASE 500
|
||||
|
||||
int
|
||||
GetRecentFiles(
|
||||
int LastCount
|
||||
);
|
||||
|
||||
int
|
||||
SetRecentFiles(
|
||||
TCHAR *FileName,
|
||||
int iCount
|
||||
);
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Global Variables
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
extern int cxMovie;
|
||||
extern int cyMovie;
|
||||
extern HWND hwndApp;
|
||||
|
||||
extern int cx;
|
||||
extern int cy;
|
||||
extern int xOffset;
|
||||
extern int yOffset;
|
||||
extern DWORD g_State;
|
||||
extern TCHAR g_szPerfLog[];
|
||||
extern int g_TimeFormat;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
#define LEFT_MARGIN 0
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Video CD Player states
|
||||
**
|
||||
** These are bit flags
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define VCD_PLAYING 0x0001
|
||||
#define VCD_STOPPED 0x0002
|
||||
#define VCD_PAUSED 0x0004
|
||||
#define VCD_SKIP_F 0x0008
|
||||
#define VCD_SKIP_B 0x0010
|
||||
#define VCD_FF 0x0020
|
||||
#define VCD_RW 0x0040
|
||||
#define VCD_SEEKING (VCD_FF | VCD_RW)
|
||||
#define VCD_LOADED 0x0080
|
||||
#define VCD_NO_CD 0x0100
|
||||
#define VCD_DATA_CD_LOADED 0x0200
|
||||
#define VCD_EDITING 0x0400
|
||||
#define VCD_PAUSED_AND_MOVED 0x0800
|
||||
#define VCD_PLAY_PENDING 0x1000
|
||||
#define VCD_WAS_PLAYING 0x2000
|
||||
#define VCD_IN_USE 0x4000
|
||||
|
||||
enum {PerformanceTimer = 32, StatusTimer = 33};
|
||||
@@ -0,0 +1,264 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: commands.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - Processes commands from the user
|
||||
//
|
||||
// Copyright (c) 1994-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "project.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern void RepositionMovie(HWND hwnd);
|
||||
|
||||
extern TCHAR g_achFileName[];
|
||||
extern CMpegMovie *pMpegMovie;
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProcessOpen
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay
|
||||
)
|
||||
{
|
||||
/*
|
||||
** If we currently have a video loaded we need to discard it here.
|
||||
*/
|
||||
if(g_State & VCD_LOADED)
|
||||
{
|
||||
VcdPlayerCloseCmd();
|
||||
}
|
||||
|
||||
lstrcpy(g_achFileName, achFileName);
|
||||
|
||||
pMpegMovie = new CMpegMovie(hwndApp);
|
||||
if(pMpegMovie)
|
||||
{
|
||||
HRESULT hr = pMpegMovie->OpenMovie(g_achFileName);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
TCHAR achTmp[MAX_PATH];
|
||||
|
||||
wsprintf(achTmp, IdStr(STR_APP_TITLE_LOADED), g_achFileName);
|
||||
g_State = (VCD_LOADED | VCD_STOPPED);
|
||||
|
||||
RepositionMovie(hwndApp);
|
||||
InvalidateRect(hwndApp, NULL, TRUE);
|
||||
|
||||
if(bPlay)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp, TEXT("Failed to open the movie! "),
|
||||
IdStr(STR_APP_TITLE), MB_OK);
|
||||
|
||||
pMpegMovie->CloseMovie();
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerOpenCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
static OPENFILENAME ofn;
|
||||
static BOOL fFirstTime = TRUE;
|
||||
BOOL fRet;
|
||||
TCHAR achFileName[MAX_PATH];
|
||||
TCHAR achFilter[MAX_PATH];
|
||||
LPTSTR lp;
|
||||
|
||||
if(fFirstTime)
|
||||
{
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwndApp;
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST |
|
||||
OFN_SHAREAWARE | OFN_PATHMUSTEXIST;
|
||||
}
|
||||
|
||||
lstrcpy(achFilter, IdStr(STR_FILE_FILTER));
|
||||
ofn.lpstrFilter = achFilter;
|
||||
|
||||
/*
|
||||
** Convert the resource string into to something suitable for
|
||||
** GetOpenFileName ie. replace '#' characters with '\0' characters.
|
||||
*/
|
||||
for(lp = achFilter; *lp; lp++)
|
||||
{
|
||||
if(*lp == TEXT('#'))
|
||||
{
|
||||
*lp = TEXT('\0');
|
||||
}
|
||||
}
|
||||
|
||||
ofn.lpstrFile = achFileName;
|
||||
ofn.nMaxFile = sizeof(achFileName) / sizeof(TCHAR);
|
||||
ZeroMemory(achFileName, sizeof(achFileName));
|
||||
|
||||
fRet = GetOpenFileName(&ofn);
|
||||
if(fRet)
|
||||
{
|
||||
fFirstTime = FALSE;
|
||||
ProcessOpen(achFileName);
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerCloseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
g_State = VCD_NO_CD;
|
||||
pMpegMovie->StopMovie();
|
||||
pMpegMovie->CloseMovie();
|
||||
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
|
||||
// Redraw main window
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPlayCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fStopped = (g_State & VCD_STOPPED);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fStopped || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
|
||||
g_State &= ~(fStopped ? VCD_STOPPED : VCD_PAUSED);
|
||||
g_State |= VCD_PLAYING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerStopCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fPlaying || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->StopMovie();
|
||||
pMpegMovie->SetFullScreenMode(FALSE);
|
||||
}
|
||||
|
||||
g_State &= ~(fPlaying ? VCD_PLAYING : VCD_PAUSED);
|
||||
g_State |= VCD_STOPPED;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPauseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if(fPlaying)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PauseMovie();
|
||||
}
|
||||
|
||||
g_State &= ~VCD_PLAYING;
|
||||
g_State |= VCD_PAUSED;
|
||||
}
|
||||
else if(fPaused)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
|
||||
g_State &= ~VCD_PAUSED;
|
||||
g_State |= VCD_PLAYING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerRewindCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: project.h
|
||||
//
|
||||
// Desc: DirectShow sample code - main header file for Renderless player
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "app.h"
|
||||
#include "vcdplyer.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
#ifndef __RELEASE_DEFINED
|
||||
#define __RELEASE_DEFINED
|
||||
template<typename T>
|
||||
__inline void RELEASE( T* &p )
|
||||
{
|
||||
if( p ) {
|
||||
p->Release();
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_HR
|
||||
#define CHECK_HR(expr) do { if (FAILED(expr)) __leave; } while(0);
|
||||
#endif
|
||||
|
||||
// {B87BEB7B-8D29-423f-AE4D-6582C10175AC}
|
||||
//DEFINE_GUID(CLSID_VideoMixingRenderer,0xb87beb7b, 0x8d29, 0x423f, 0xae, 0x4d, 0x65, 0x82, 0xc1, 0x1, 0x75, 0xac);
|
||||
@@ -0,0 +1,8 @@
|
||||
Windows XP DirectShow Sample -- Renderless
|
||||
-------------------------------------------
|
||||
|
||||
This sample demonstrates using the Video Mixing Renderer and
|
||||
a custom allocator-presenter to render video in a window.
|
||||
|
||||
NOTE: This sample requires Windows XP (or greater) functionality
|
||||
and will exit on other systems.
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "RenderLess"=".\RenderLess.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,230 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resrc1.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
//
|
||||
|
||||
IDR_TOOLBAR BITMAP DISCARDABLE "toolbar.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_VIDEOCD_ICON ICON DISCARDABLE "renderless.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_MAIN_MENU MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "&Open Video File...\tCtrl+O", IDM_FILE_OPEN
|
||||
MENUITEM "&Close", IDM_FILE_CLOSE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Play\tCtrl+P", IDM_MOVIE_PLAY
|
||||
MENUITEM "Pa&use\tCtrl+U", IDM_MOVIE_PAUSE
|
||||
MENUITEM "&Stop\tCtrl+S", IDM_MOVIE_STOP
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Ex&it\tCtrl+X", IDM_FILE_EXIT
|
||||
END
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About Renderless Player...", IDM_FILE_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About Renderless Player"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
ICON IDR_VIDEOCD_ICON,-1,11,17,20,20
|
||||
LTEXT "DirectShow VMR Renderless Player Sample",-1,40,10,131,8,
|
||||
SS_NOPREFIX
|
||||
LTEXT "Copyright (C) 1999-2001 Microsoft Corporation",-1,40,34,
|
||||
188,8
|
||||
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
|
||||
LTEXT "Version 8.1",-1,40,22,119,8,SS_NOPREFIX
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_ACCELERATOR ACCELERATORS DISCARDABLE
|
||||
BEGIN
|
||||
"F", IDM_MOVIE_FULLSCREEN, VIRTKEY, CONTROL, NOINVERT
|
||||
"O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
|
||||
"P", IDM_MOVIE_PLAY, VIRTKEY, CONTROL, NOINVERT
|
||||
"S", IDM_MOVIE_STOP, VIRTKEY, CONTROL, NOINVERT
|
||||
"U", IDM_MOVIE_PAUSE, VIRTKEY, CONTROL, NOINVERT
|
||||
"X", IDM_FILE_EXIT, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resrc1.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""resource.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,1,0,0
|
||||
PRODUCTVERSION 8,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "This sample requires Windows XP or greater.\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "RenderLess Application\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "VMR Renderless\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "Renderless.EXE\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "DirectX 8.1 SDK\0"
|
||||
VALUE "ProductVersion", "8.1\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_MOVIE_STOP "Stop"
|
||||
IDM_MOVIE_PLAY "Play"
|
||||
IDM_MOVIE_PAUSE "Pause"
|
||||
IDM_FULL_SCREEN "Full screen playback"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_OPEN "Open a new movie"
|
||||
STR_FILE_CLOSE "Close the movie"
|
||||
STR_FILE_EXIT "Quit Renderless player"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_SYSMENU_RESTORE "Restore the window to normal size"
|
||||
STR_SYSMENU_MOVE "Changes the window position"
|
||||
STR_SYSMENU_MINIMIZE "Reduce the window to an icon"
|
||||
STR_SYSMENU_CLOSE "Closes the window"
|
||||
STR_SYSMENU_MAXIMIZE "Enlarges the window to its maximum size"
|
||||
STR_SYSMENU_TASK_LIST "Opens the task list"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_FILTER "All Movies#*.mpg;*.avi;*.dat;*.mov#Mpeg Files (*.mpg)#*.mpg#Video CD Files (*.dat)#*.dat#QuickTime Files (*.mov)#*.mov#All Files (*.*)#*.*#"
|
||||
STR_APP_TITLE "VMR Renderless Player"
|
||||
STR_APP_TITLE_LOADED "VMR Renderless Player - %s"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: resourcevcdplyer.h
|
||||
//
|
||||
// Desc: DirectShow sample code - resource header file for RenderLess player
|
||||
//
|
||||
// Copyright (c) 1995 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define IDC_STATIC -1
|
||||
|
||||
#define STR_MAX_STRING_LEN 256
|
||||
|
||||
#define IDX_SEPARATOR -1
|
||||
#define IDX_1 0
|
||||
#define IDX_2 1
|
||||
#define IDX_3 2
|
||||
#define IDX_4 3
|
||||
#define IDX_5 4
|
||||
#define IDX_6 5
|
||||
#define IDX_7 6
|
||||
#define IDX_8 7
|
||||
|
||||
#define IDX_10 9
|
||||
#define IDX_11 10
|
||||
#define DEFAULT_TBAR_SIZE 6
|
||||
#define NUMBER_OF_BITMAPS 11
|
||||
|
||||
#define ID_TOOLBAR 9
|
||||
#define IDD_ABOUTBOX 20
|
||||
|
||||
#define IDR_MAIN_MENU 101
|
||||
#define IDR_TOOLBAR 102
|
||||
#define IDR_VIDEOCD_ICON 103
|
||||
#define IDR_ACCELERATOR 104
|
||||
|
||||
#define IDM_FILE_OPEN 40001
|
||||
#define IDM_FILE_CLOSE 40002
|
||||
#define IDM_FILE_EXIT 40003
|
||||
#define IDM_FILE_ABOUT 40004
|
||||
|
||||
|
||||
// Toolbar commands
|
||||
#define IDM_MOVIE_STOP 40010
|
||||
#define IDM_MOVIE_PLAY 40011
|
||||
#define IDM_MOVIE_PAUSE 40012
|
||||
#define IDM_FULL_SCREEN 40013
|
||||
#define IDM_MOVIE_FULLSCREEN 40014
|
||||
|
||||
#define MENU_STRING_BASE 1000
|
||||
|
||||
// File
|
||||
#define STR_FILE_OPEN IDM_FILE_OPEN + MENU_STRING_BASE
|
||||
#define STR_FILE_CLOSE IDM_FILE_CLOSE + MENU_STRING_BASE
|
||||
#define STR_FILE_EXIT IDM_FILE_EXIT + MENU_STRING_BASE
|
||||
|
||||
|
||||
// System Menu
|
||||
#define STR_SYSMENU_RESTORE 1800
|
||||
#define STR_SYSMENU_MOVE 1801
|
||||
#define STR_SYSMENU_MINIMIZE 1802
|
||||
#define STR_SYSMENU_CLOSE 1803
|
||||
#define STR_SYSMENU_MAXIMIZE 1804
|
||||
#define STR_SYSMENU_TASK_LIST 1805
|
||||
|
||||
#define STR_FILE_FILTER 2000
|
||||
#define STR_APP_TITLE 2001
|
||||
#define STR_APP_TITLE_LOADED 2002
|
||||
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40002
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by renderless.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
After Width: | Height: | Size: 598 B |
@@ -0,0 +1,521 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - VMR-based Renderless video player
|
||||
//
|
||||
// Copyright (c) 1994-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
#include <atlbase.h>
|
||||
|
||||
#include "project.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MY_USER_ID 0x1234ACDE
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CMpegMovie
|
||||
*
|
||||
* Constructors and destructors
|
||||
*
|
||||
\**************************************************************************/
|
||||
CMpegMovie::CMpegMovie(HWND hwndApplication)
|
||||
: CUnknown(NAME("Allocator Presenter"), NULL),
|
||||
m_hwndApp(hwndApplication),
|
||||
m_MediaEvent(NULL),
|
||||
m_Mode(MOVIE_NOTOPENED),
|
||||
m_Fg(NULL),
|
||||
m_Gb(NULL),
|
||||
m_Mc(NULL),
|
||||
m_Ms(NULL),
|
||||
m_Me(NULL),
|
||||
m_lpDefSAN(NULL),
|
||||
m_bFullScreen(FALSE),
|
||||
m_bFullScreenPoss(FALSE),
|
||||
m_pddsRenderT(NULL),
|
||||
m_pddsPriText(NULL),
|
||||
m_pddsPrimary(NULL),
|
||||
m_iDuration(-1),
|
||||
m_TimeFormat(TIME_FORMAT_MEDIA_TIME)
|
||||
{
|
||||
AddRef();
|
||||
}
|
||||
|
||||
CMpegMovie::~CMpegMovie()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SetRenderingMode
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
SetRenderingMode(
|
||||
IBaseFilter* pBaseFilter,
|
||||
VMRMode mode
|
||||
)
|
||||
{
|
||||
IVMRFilterConfig* pConfig;
|
||||
HRESULT hr = pBaseFilter->QueryInterface(IID_IVMRFilterConfig,
|
||||
(LPVOID *)&pConfig);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
pConfig->SetRenderingMode(mode);
|
||||
pConfig->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* AddVideoMixingRendererToFG()
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::AddVideoMixingRendererToFG()
|
||||
{
|
||||
IBaseFilter* pBF = NULL;
|
||||
HRESULT hRes = S_OK;
|
||||
|
||||
__try {
|
||||
CHECK_HR(hRes = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL, CLSCTX_INPROC,IID_IBaseFilter,
|
||||
(LPVOID *)&pBF));
|
||||
|
||||
CHECK_HR(hRes = m_Fg->AddFilter(pBF, L"Video Mixing Renderer"));
|
||||
CHECK_HR(hRes = SetRenderingMode(pBF, VMRMode_Renderless));
|
||||
|
||||
CHECK_HR(hRes = pBF->QueryInterface(IID_IVMRSurfaceAllocatorNotify,
|
||||
(LPVOID *)&m_lpDefSAN));
|
||||
|
||||
CHECK_HR(hRes = CreateDefaultAllocatorPresenter());
|
||||
CHECK_HR(hRes = m_lpDefSAN->AdviseSurfaceAllocator(MY_USER_ID, this));
|
||||
}
|
||||
__finally {
|
||||
RELEASE(pBF);
|
||||
}
|
||||
|
||||
return hRes;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* OpenMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::OpenMovie(
|
||||
TCHAR *lpFileName
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
HRESULT hres = S_OK;
|
||||
IUnknown *pUnk = NULL;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
wcscpy(FileName, T2W(lpFileName));
|
||||
|
||||
__try
|
||||
{
|
||||
CHECK_HR(hres = CoCreateInstance(CLSID_FilterGraph,
|
||||
NULL, CLSCTX_INPROC,
|
||||
IID_IUnknown, (LPVOID *)&pUnk));
|
||||
|
||||
m_Mode = MOVIE_OPENED;
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IFilterGraph, (LPVOID *)&m_Fg));
|
||||
CHECK_HR(hres = AddVideoMixingRendererToFG());
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IGraphBuilder, (LPVOID *)&m_Gb));
|
||||
CHECK_HR(hres = m_Gb->RenderFile(FileName, NULL));
|
||||
CHECK_HR(hres = pUnk->QueryInterface(IID_IMediaControl, (LPVOID *)&m_Mc));
|
||||
|
||||
//
|
||||
// Not being able to get the IMediaEvent interface does
|
||||
// necessarly mean that we can't play the graph.
|
||||
//
|
||||
pUnk->QueryInterface(IID_IMediaEvent, (LPVOID *)&m_Me);
|
||||
GetMovieEventHandle();
|
||||
pUnk->QueryInterface(IID_IMediaSeeking, (LPVOID *)&m_Ms);
|
||||
}
|
||||
__finally
|
||||
{
|
||||
if(FAILED(hres))
|
||||
{
|
||||
RELEASE(m_Ms);
|
||||
RELEASE(m_Me);
|
||||
RELEASE(m_Mc);
|
||||
RELEASE(m_Gb);
|
||||
RELEASE(m_Fg);
|
||||
}
|
||||
|
||||
RELEASE(pUnk);
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CloseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
DWORD
|
||||
CMpegMovie::CloseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_NOTOPENED;
|
||||
m_bFullScreen = FALSE;
|
||||
|
||||
RELEASE(m_Mc);
|
||||
RELEASE(m_Me);
|
||||
RELEASE(m_Ms);
|
||||
RELEASE(m_Gb);
|
||||
RELEASE(m_Fg);
|
||||
RELEASE(m_lpDefWC);
|
||||
RELEASE(m_lpDefSA);
|
||||
RELEASE(m_lpDefIP);
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RepaintVideo
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::RepaintVideo(
|
||||
HWND hwnd,
|
||||
HDC hdc
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
if(m_lpDefWC)
|
||||
{
|
||||
bRet = (m_lpDefWC->RepaintVideo(hwnd, hdc) == S_OK);
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PutMoviePosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PutMoviePosition(
|
||||
LONG x,
|
||||
LONG y,
|
||||
LONG cx,
|
||||
LONG cy
|
||||
)
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
SetRect(&rc, x, y, x + cx, y + cy);
|
||||
BOOL bRet = (m_lpDefWC->SetVideoPosition(NULL, &rc) == S_OK);
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PlayMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PlayMovie(
|
||||
)
|
||||
{
|
||||
REFTIME rt;
|
||||
REFTIME rtAbs;
|
||||
REFTIME rtDur;
|
||||
|
||||
rt = GetCurrentPosition();
|
||||
rtDur = GetDuration();
|
||||
|
||||
//
|
||||
// If we are near the end of the movie seek to the start, otherwise
|
||||
// stay where we are.
|
||||
//
|
||||
rtAbs = rt - rtDur;
|
||||
if(rtAbs < (REFTIME)0)
|
||||
{
|
||||
rtAbs = -rtAbs;
|
||||
}
|
||||
|
||||
if(rtAbs <= (REFTIME)1)
|
||||
{
|
||||
SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// Change mode after setting m_Mode but before starting the graph
|
||||
//
|
||||
m_Mode = MOVIE_PLAYING;
|
||||
m_Mc->Run();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PauseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PauseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
m_Mc->Pause();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetStateMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
OAFilterState
|
||||
CMpegMovie::GetStateMovie(
|
||||
)
|
||||
{
|
||||
OAFilterState State;
|
||||
m_Mc->GetState(INFINITE,&State);
|
||||
return State;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StopMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::StopMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
m_Mc->Stop();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMediaEventHandle
|
||||
*
|
||||
* Returns the IMediaEvent event hamdle for the filter graph if the
|
||||
* filter graph exists.
|
||||
*
|
||||
\**************************************************************************/
|
||||
HANDLE
|
||||
CMpegMovie::GetMovieEventHandle(
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if(m_Me != NULL)
|
||||
{
|
||||
if(m_MediaEvent == NULL)
|
||||
{
|
||||
hr = m_Me->GetEventHandle((OAEVENT *)&m_MediaEvent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MediaEvent = NULL;
|
||||
}
|
||||
|
||||
return m_MediaEvent;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMovieEventCode
|
||||
*
|
||||
\**************************************************************************/
|
||||
long
|
||||
CMpegMovie::GetMovieEventCode()
|
||||
{
|
||||
HRESULT hr;
|
||||
long lEventCode;
|
||||
LONG_PTR lParam1, lParam2;
|
||||
|
||||
if(m_Me != NULL)
|
||||
{
|
||||
hr = m_Me->GetEvent(&lEventCode, &lParam1, &lParam2, 0);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = m_Me->FreeEventParams(lEventCode, lParam1, lParam2);
|
||||
return lEventCode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetDuration
|
||||
*
|
||||
* Returns the duration of the current movie
|
||||
*
|
||||
\**************************************************************************/
|
||||
REFTIME
|
||||
CMpegMovie::GetDuration()
|
||||
{
|
||||
HRESULT hr;
|
||||
LONGLONG Duration;
|
||||
|
||||
// Should we seek using IMediaSelection
|
||||
|
||||
if(m_Ms != NULL && m_TimeFormat != TIME_FORMAT_MEDIA_TIME)
|
||||
{
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Duration);
|
||||
}
|
||||
}
|
||||
else if(m_Ms != NULL)
|
||||
{
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Duration) / UNITS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetCurrentPosition
|
||||
*
|
||||
* Returns the current movie position
|
||||
*
|
||||
\**************************************************************************/
|
||||
REFTIME
|
||||
CMpegMovie::GetCurrentPosition()
|
||||
{
|
||||
REFTIME rt = (REFTIME)0;
|
||||
HRESULT hr;
|
||||
LONGLONG Position;
|
||||
|
||||
// Should we return a media position?
|
||||
|
||||
if(m_Ms != NULL && m_TimeFormat != TIME_FORMAT_MEDIA_TIME)
|
||||
{
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Position);
|
||||
}
|
||||
}
|
||||
else if(m_Ms != NULL)
|
||||
{
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Position) / UNITS;
|
||||
}
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SeekToPosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SeekToPosition(
|
||||
REFTIME rt,
|
||||
BOOL bFlushData
|
||||
)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
LONGLONG llTime =
|
||||
LONGLONG(m_TimeFormat == TIME_FORMAT_MEDIA_TIME ? rt * double(UNITS) : rt);
|
||||
|
||||
if(m_Ms != NULL)
|
||||
{
|
||||
FILTER_STATE fs;
|
||||
|
||||
m_Mc->GetState(100, (OAFilterState *)&fs);
|
||||
hr = m_Ms->SetPositions(&llTime, AM_SEEKING_AbsolutePositioning, NULL, 0);
|
||||
|
||||
// This gets new data through to the renderers
|
||||
|
||||
if(fs == State_Stopped && bFlushData)
|
||||
{
|
||||
m_Mc->Pause();
|
||||
hr = m_Mc->GetState(INFINITE, (OAFilterState *)&fs);
|
||||
m_Mc->Stop();
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetFullScreenMode
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
CMpegMovie::SetFullScreenMode(
|
||||
BOOL bMode
|
||||
)
|
||||
{
|
||||
if(bMode && m_bFullScreenPoss)
|
||||
{
|
||||
HRESULT hr = m_pddsPriText->Blt(NULL, m_pddsPrimary,
|
||||
NULL, DDBLT_WAIT, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
m_iDuration = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL VerifyVMR(void)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
// Verify that the VMR exists on this system
|
||||
IBaseFilter* pBF = NULL;
|
||||
hres = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
pBF->Release();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp,
|
||||
TEXT("This application requires the Video Mixing Renderer, which is present\r\n")
|
||||
TEXT("only on Windows XP.\r\n\r\n")
|
||||
TEXT("The Video Mixing Renderer (VMR) is also not enabled when viewing a \r\n")
|
||||
TEXT("remote Windows XP machine through a Remote Desktop session.\r\n")
|
||||
TEXT("You can run VMR-enabled applications only on your local machine.")
|
||||
TEXT("\r\n\r\nThis sample will now exit."),
|
||||
TEXT("Video Mixing Renderer capabilities are required"), MB_OK);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for CMpegMovie class
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <ddraw.h>
|
||||
#define D3D_OVERLOADS
|
||||
#include <d3d.h>
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** CMpegMovie - an Mpeg movie playback class.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
enum EMpegMovieMode { MOVIE_NOTOPENED = 0x00,
|
||||
MOVIE_OPENED = 0x01,
|
||||
MOVIE_PLAYING = 0x02,
|
||||
MOVIE_STOPPED = 0x03,
|
||||
MOVIE_PAUSED = 0x04 };
|
||||
|
||||
|
||||
|
||||
BOOL VerifyVMR(void);
|
||||
|
||||
class CMpegMovie :
|
||||
public CUnknown,
|
||||
public IVMRSurfaceAllocator,
|
||||
public IVMRImagePresenter,
|
||||
public IVMRSurfaceAllocatorNotify
|
||||
{
|
||||
|
||||
private:
|
||||
// Our state variable - records whether we are opened, playing etc.
|
||||
EMpegMovieMode m_Mode;
|
||||
HANDLE m_MediaEvent;
|
||||
HWND m_hwndApp;
|
||||
BOOL m_bFullScreen;
|
||||
BOOL m_bFullScreenPoss;
|
||||
int m_iDuration;
|
||||
GUID m_TimeFormat;
|
||||
|
||||
LPDIRECTDRAWSURFACE7 m_pddsPrimary;
|
||||
LPDIRECTDRAWSURFACE7 m_pddsPriText;
|
||||
LPDIRECTDRAWSURFACE7 m_pddsRenderT;
|
||||
|
||||
IFilterGraph* m_Fg;
|
||||
IGraphBuilder* m_Gb;
|
||||
IMediaControl* m_Mc;
|
||||
IMediaSeeking* m_Ms;
|
||||
IMediaEvent* m_Me;
|
||||
|
||||
IVMRSurfaceAllocator* m_lpDefSA;
|
||||
IVMRImagePresenter* m_lpDefIP;
|
||||
IVMRWindowlessControl* m_lpDefWC;
|
||||
IVMRSurfaceAllocatorNotify* m_lpDefSAN;
|
||||
|
||||
HRESULT CreateDefaultAllocatorPresenter();
|
||||
HRESULT AddVideoMixingRendererToFG();
|
||||
HRESULT OnSetDDrawDevice(LPDIRECTDRAW7 pDD, HMONITOR hMon);
|
||||
|
||||
|
||||
public:
|
||||
CMpegMovie(HWND hwndApplication);
|
||||
~CMpegMovie();
|
||||
|
||||
DECLARE_IUNKNOWN
|
||||
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void**);
|
||||
|
||||
// IVMRSurfaceAllocator
|
||||
STDMETHODIMP AllocateSurface(DWORD_PTR dwUserID,
|
||||
VMRALLOCATIONINFO* lpAllocInfo,
|
||||
DWORD* lpdwActualBackBuffers,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface);
|
||||
STDMETHODIMP FreeSurface(DWORD_PTR dwUserID);
|
||||
STDMETHODIMP PrepareSurface(DWORD_PTR dwUserID,
|
||||
LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags);
|
||||
STDMETHODIMP AdviseNotify(IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify);
|
||||
|
||||
// IVMRSurfaceAllocatorNotify
|
||||
STDMETHODIMP AdviseSurfaceAllocator(DWORD_PTR dwUserID,
|
||||
IVMRSurfaceAllocator* lpIVRMSurfaceAllocator);
|
||||
STDMETHODIMP SetDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor);
|
||||
STDMETHODIMP ChangeDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor);
|
||||
STDMETHODIMP RestoreDDrawSurfaces();
|
||||
STDMETHODIMP NotifyEvent(LONG EventCode, LONG_PTR lp1, LONG_PTR lp2);
|
||||
STDMETHODIMP SetBorderColor(COLORREF clr);
|
||||
|
||||
// IVMRImagePresenter
|
||||
STDMETHODIMP StartPresenting(DWORD_PTR dwUserID);
|
||||
STDMETHODIMP StopPresenting(DWORD_PTR dwUserID);
|
||||
STDMETHODIMP PresentImage(DWORD_PTR dwUserID,
|
||||
VMRPRESENTATIONINFO* lpPresInfo);
|
||||
|
||||
HRESULT OpenMovie(TCHAR *lpFileName);
|
||||
DWORD CloseMovie();
|
||||
|
||||
BOOL PlayMovie();
|
||||
BOOL PauseMovie();
|
||||
BOOL StopMovie();
|
||||
|
||||
OAFilterState GetStateMovie();
|
||||
|
||||
HANDLE GetMovieEventHandle();
|
||||
long GetMovieEventCode();
|
||||
|
||||
BOOL PutMoviePosition(LONG x, LONG y, LONG cx, LONG cy);
|
||||
|
||||
REFTIME GetDuration();
|
||||
REFTIME GetCurrentPosition();
|
||||
BOOL SeekToPosition(REFTIME rt,BOOL bFlushData);
|
||||
|
||||
BOOL RepaintVideo(HWND hwnd, HDC hdc);
|
||||
|
||||
void SetFullScreenMode(BOOL bMode);
|
||||
BOOL IsFullScreenMode();
|
||||
|
||||
void DisplayModeChanged() {
|
||||
if (m_lpDefWC) {
|
||||
m_lpDefWC->DisplayModeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: AllocLib.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for VMR sample applications
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __INC_ALLOCLIB_H__
|
||||
#define __INC_ALLOCLIB_H__
|
||||
|
||||
#ifndef __ZEROSTRUCT_DEFINED
|
||||
#define __ZEROSTRUCT_DEFINED
|
||||
template <typename T>
|
||||
__inline void ZeroStruct(T& t)
|
||||
{
|
||||
ZeroMemory(&t, sizeof(t));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __INITDDSTRUCT_DEFINED
|
||||
#define __INITDDSTRUCT_DEFINED
|
||||
template <typename T>
|
||||
__inline void INITDDSTRUCT(T& dd)
|
||||
{
|
||||
ZeroStruct(dd);
|
||||
dd.dwSize = sizeof(dd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
HRESULT
|
||||
PaintDDrawSurfaceBlack(
|
||||
LPDIRECTDRAWSURFACE7 pDDrawSurface
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,762 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: allocpresenter.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - Custom Allocator Presenter for VMR sample
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include "project.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "alloclib.h"
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* NonDelegatingQueryInterface
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NonDelegatingQueryInterface(
|
||||
REFIID riid,
|
||||
void** ppv
|
||||
)
|
||||
{
|
||||
if(riid == IID_IVMRSurfaceAllocator)
|
||||
{
|
||||
return GetInterface((IVMRSurfaceAllocator*)this, ppv);
|
||||
}
|
||||
else if(riid == IID_IVMRImagePresenter)
|
||||
{
|
||||
return GetInterface((IVMRImagePresenter*)this, ppv);
|
||||
}
|
||||
|
||||
return CUnknown::NonDelegatingQueryInterface(riid,ppv);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRSurfaceAllocator
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AllocateSurfaces
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AllocateSurface(
|
||||
DWORD_PTR x,
|
||||
VMRALLOCATIONINFO *w,
|
||||
DWORD* lpdwBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface
|
||||
)
|
||||
{
|
||||
DWORD dwFlags = w->dwFlags;
|
||||
LPBITMAPINFOHEADER lpHdr = w->lpHdr;
|
||||
LPDDPIXELFORMAT lpPixFmt = w->lpPixFmt;
|
||||
LPSIZE lpAspectRatio = &w->szAspectRatio;
|
||||
DWORD dwMinBuffers = w->dwMinBuffers;
|
||||
DWORD dwMaxBuffers = w->dwMaxBuffers;
|
||||
|
||||
if(!lpHdr)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if(!lpAspectRatio)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if(dwFlags & AMAP_PIXELFORMAT_VALID)
|
||||
{
|
||||
if(!lpPixFmt)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = AllocateSurfaceWorker(dwFlags, lpHdr, lpPixFmt,
|
||||
lpAspectRatio,
|
||||
dwMinBuffers, dwMaxBuffers,
|
||||
lpdwBuffer, lplpSurface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AllocateSurfaceWorker
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::AllocateSurfaceWorker(
|
||||
DWORD dwFlags,
|
||||
LPBITMAPINFOHEADER lpHdr,
|
||||
LPDDPIXELFORMAT lpPixFmt,
|
||||
LPSIZE lpAspectRatio,
|
||||
DWORD dwMinBuffers,
|
||||
DWORD dwMaxBuffers,
|
||||
DWORD* lpdwBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface
|
||||
)
|
||||
{
|
||||
LPBITMAPINFOHEADER lpHeader = lpHdr;
|
||||
if(!lpHeader)
|
||||
{
|
||||
DbgLog((LOG_ERROR, 1, TEXT("Can't get bitmapinfoheader from media type!!")));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 ddsd;
|
||||
INITDDSTRUCT(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH | DDSD_PIXELFORMAT;
|
||||
ddsd.dwWidth = abs(lpHeader->biWidth);
|
||||
ddsd.dwHeight = abs(lpHeader->biHeight);
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY /*| DDSCAPS_TEXTURE */;
|
||||
|
||||
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
|
||||
if(lpHdr->biCompression <= BI_BITFIELDS &&
|
||||
m_DispInfo.bmiHeader.biBitCount <= lpHdr->biBitCount)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
|
||||
if(lpHdr->biBitCount == 32)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
|
||||
ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000;
|
||||
ddsd.ddpfPixelFormat.dwGBitMask = 0xff00;
|
||||
ddsd.ddpfPixelFormat.dwBBitMask = 0xff;
|
||||
}
|
||||
else if(lpHdr->biBitCount == 16)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
|
||||
ddsd.ddpfPixelFormat.dwRBitMask = 0xF800;
|
||||
ddsd.ddpfPixelFormat.dwGBitMask = 0x07e0;
|
||||
ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
|
||||
}
|
||||
}
|
||||
else if(lpHdr->biCompression > BI_BITFIELDS)
|
||||
{
|
||||
const DWORD dwCaps = (DDCAPS_BLTFOURCC | DDCAPS_BLTSTRETCH);
|
||||
if((dwCaps & m_ddHWCaps.dwCaps) != dwCaps)
|
||||
{
|
||||
DbgLog((LOG_ERROR, 1,
|
||||
TEXT("Can't BLT_FOURCC | BLT_STRETCH!!")));
|
||||
return E_FAIL;
|
||||
}
|
||||
ddsd.ddpfPixelFormat.dwFourCC = lpHdr->biCompression;
|
||||
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
|
||||
ddsd.ddpfPixelFormat.dwYUVBitCount = lpHdr->biBitCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
// Adjust width and height, if the driver requires it
|
||||
DWORD dwWidth = ddsd.dwWidth;
|
||||
DWORD dwHeight = ddsd.dwHeight;
|
||||
|
||||
HRESULT hr = m_lpDDObj->CreateSurface(&ddsd, &m_lpDDTexture, NULL);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
m_VideoAR = *lpAspectRatio;
|
||||
|
||||
m_VideoSize.cx = abs(lpHeader->biWidth);
|
||||
m_VideoSize.cy = abs(lpHeader->biHeight);
|
||||
|
||||
SetRect(&m_rcDst, 0, 0, m_VideoSize.cx, m_VideoSize.cy);
|
||||
m_rcSrc = m_rcDst;
|
||||
|
||||
hr = PaintDDrawSurfaceBlack(m_lpDDTexture);
|
||||
|
||||
*lplpSurface = m_lpDDTexture;
|
||||
*lpdwBuffer = 1;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* FreeSurfaces()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::FreeSurface(DWORD_PTR w)
|
||||
{
|
||||
if(m_lpDDTexture)
|
||||
{
|
||||
m_lpDDTexture->Release();
|
||||
m_lpDDTexture = NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PrepareSurface
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PrepareSurface(
|
||||
DWORD_PTR w,
|
||||
LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags
|
||||
)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AdviseNotify
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AdviseNotify(
|
||||
IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify
|
||||
)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRImagePresenter
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StartPresenting()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StartPresenting(DWORD_PTR w)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StopPresenting()
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StopPresenting(DWORD_PTR w)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PresentImage
|
||||
*
|
||||
\**************************************************************************/
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PresentImage(
|
||||
DWORD_PTR w,
|
||||
VMRPRESENTATIONINFO* p
|
||||
)
|
||||
{
|
||||
//
|
||||
// Call the app specific function to render the scene
|
||||
//
|
||||
LPDIRECTDRAWSURFACE7 lpSurface = p->lpSurf;
|
||||
const REFERENCE_TIME rtNow = p->rtStart;
|
||||
const DWORD dwSurfaceFlags = p->dwFlags;
|
||||
|
||||
CAutoLock Lock(&m_AppImageLock);
|
||||
|
||||
RECT rSrc = {0, 0, m_VideoSize.cx, m_VideoSize.cy};
|
||||
RECT rDst = {0, 0, WIDTH(&m_rcDst), HEIGHT(&m_rcDst)};
|
||||
|
||||
//PaintDDrawSurfaceBlack(m_lpBackBuffer);
|
||||
//m_lpBltAlpha->AlphaBlt(&rDst, m_lpDDTexture, &rSrc, 0xFF);
|
||||
m_lpBackBuffer->Blt(&rDst, m_lpDDTexture, &rSrc, DDBLT_WAIT, NULL);
|
||||
|
||||
rDst.left = m_cxFontImg;
|
||||
rDst.top = m_cyFontImg * 1;
|
||||
rDst.right = rDst.left + (m_cxFontImg * 40);
|
||||
rDst.bottom = rDst.top + (m_cyFontImg * 4);
|
||||
|
||||
rSrc.left = 0;
|
||||
rSrc.top = 0;
|
||||
rSrc.right = (m_cxFontImg * 40);
|
||||
rSrc.bottom = (m_cyFontImg * 4);
|
||||
m_lpBltAlpha->AlphaBlt(&rDst, m_lpDDAppImage, &rSrc, 0x80);
|
||||
|
||||
|
||||
RECT rc = m_rcDst;
|
||||
RECT rcSrc;
|
||||
|
||||
SetRect(&rcSrc, 0, 0, WIDTH(&rc), HEIGHT(&rc));
|
||||
m_lpPriSurf->Blt(&rc, m_lpBackBuffer, &rcSrc, DDBLT_WAIT, NULL);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Allocator Presenter helper functions
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* InitDisplayInfo
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
InitDisplayInfo(
|
||||
AMDISPLAYINFO* lpDispInfo
|
||||
)
|
||||
{
|
||||
static char szDisplay[] = "DISPLAY";
|
||||
ZeroMemory(lpDispInfo, sizeof(*lpDispInfo));
|
||||
|
||||
HDC hdcDisplay = CreateDCA(szDisplay, NULL, NULL, NULL);
|
||||
HBITMAP hbm = CreateCompatibleBitmap(hdcDisplay, 1, 1);
|
||||
|
||||
lpDispInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
GetDIBits(hdcDisplay, hbm, 0, 1, NULL, (BITMAPINFO *)lpDispInfo, DIB_RGB_COLORS);
|
||||
GetDIBits(hdcDisplay, hbm, 0, 1, NULL, (BITMAPINFO *)lpDispInfo, DIB_RGB_COLORS);
|
||||
|
||||
DeleteObject(hbm);
|
||||
DeleteDC(hdcDisplay);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* DDARGB32SurfaceInit
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::DDARGB32SurfaceInit(
|
||||
LPDIRECTDRAWSURFACE7* lplpDDS,
|
||||
BOOL bTexture,
|
||||
DWORD cx,
|
||||
DWORD cy
|
||||
)
|
||||
{
|
||||
DDSURFACEDESC2 ddsd;
|
||||
HRESULT hRet;
|
||||
|
||||
*lplpDDS = NULL;
|
||||
|
||||
INITDDSTRUCT(ddsd);
|
||||
|
||||
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
if(bTexture)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS;
|
||||
}
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
|
||||
if(bTexture)
|
||||
{
|
||||
ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
|
||||
}
|
||||
ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
|
||||
ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
|
||||
ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
|
||||
|
||||
|
||||
if(bTexture)
|
||||
{
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
||||
ddsd.ddsCaps.dwCaps2 = (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_HINTDYNAMIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN;
|
||||
}
|
||||
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
||||
ddsd.dwBackBufferCount = 0;
|
||||
|
||||
if(bTexture)
|
||||
{
|
||||
for(ddsd.dwWidth=1; cx>ddsd.dwWidth; ddsd.dwWidth<<=1);
|
||||
for(ddsd.dwHeight=1; cy>ddsd.dwHeight; ddsd.dwHeight<<=1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ddsd.dwWidth=cx;
|
||||
ddsd.dwHeight=cy;
|
||||
}
|
||||
|
||||
|
||||
// Attempt to create the surface with theses settings
|
||||
hRet = m_lpDDObj->CreateSurface(&ddsd, lplpDDS, NULL);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* CreateFontCache
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::CreateFontCache(
|
||||
int cyFont
|
||||
)
|
||||
{
|
||||
//
|
||||
// Initialize the LOGFONT structure - we want to
|
||||
// create an "anti-aliased" Lucida Consol font
|
||||
//
|
||||
LOGFONT lfChar;
|
||||
ZeroMemory(&lfChar, sizeof(lfChar));
|
||||
lfChar.lfHeight = -cyFont;
|
||||
lfChar.lfCharSet = OEM_CHARSET ;
|
||||
lfChar.lfPitchAndFamily = FIXED_PITCH | FF_MODERN ;
|
||||
lstrcpy(lfChar.lfFaceName, TEXT("Lucida Console")) ;
|
||||
lfChar.lfWeight = FW_NORMAL ;
|
||||
lfChar.lfOutPrecision = OUT_STRING_PRECIS ;
|
||||
lfChar.lfClipPrecision = CLIP_STROKE_PRECIS ;
|
||||
lfChar.lfQuality = ANTIALIASED_QUALITY;
|
||||
|
||||
|
||||
HFONT hFont = CreateFontIndirect(&lfChar) ;
|
||||
if(!hFont)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
//
|
||||
// The following magic is necessary to get GDI to rasterize
|
||||
// the font with anti-aliasing switched on when we later use
|
||||
// the font in a DDraw Surface. The doc's say that this is only
|
||||
// necessary in Win9X - but Win2K seems to require it too.
|
||||
//
|
||||
SIZE size;
|
||||
HDC hdcWin = GetDC(NULL);
|
||||
hFont = (HFONT)SelectObject(hdcWin, hFont);
|
||||
GetTextExtentPoint32(hdcWin, TEXT("A"), 1, &size);
|
||||
hFont = (HFONT)SelectObject(hdcWin, hFont);
|
||||
ReleaseDC(NULL, hdcWin);
|
||||
|
||||
//
|
||||
// Make sure that the font doesn't get too big.
|
||||
//
|
||||
if(size.cx * GRID_CX > 1024)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Delete the old font and assign the new one
|
||||
//
|
||||
RELEASE(m_lpDDSFontCache);
|
||||
if(m_hFont)
|
||||
{
|
||||
DeleteObject(m_hFont);
|
||||
}
|
||||
m_cxFont = size.cx; m_cyFont = size.cy;
|
||||
m_hFont = hFont;
|
||||
|
||||
|
||||
//
|
||||
// Create the DDraw ARGB32 surface that we will use
|
||||
// for the font cache.
|
||||
//
|
||||
|
||||
HRESULT hr = DDARGB32SurfaceInit(&m_lpDDSFontCache, TRUE, 16 * size.cx, 6 * size.cy);
|
||||
if(hr == DD_OK)
|
||||
{
|
||||
|
||||
HDC hdcDest;
|
||||
|
||||
m_lpDDSFontCache->GetDC(&hdcDest);
|
||||
|
||||
//
|
||||
// Select the font into the DDraw surface and draw the characters
|
||||
//
|
||||
m_hFont = (HFONT)SelectObject(hdcDest, m_hFont);
|
||||
SetTextColor(hdcDest, RGB(255,255,255));
|
||||
SetBkColor(hdcDest, RGB(0,0,0));
|
||||
SetBkMode(hdcDest, OPAQUE);
|
||||
|
||||
int row, col; TCHAR ch = (TCHAR)32;
|
||||
for(row = 0; row < 6; row++)
|
||||
{
|
||||
for(col = 0; col < 16; col++)
|
||||
{
|
||||
TextOut(hdcDest, col * size.cx, row * size.cy, &ch, 1);
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
m_hFont = (HFONT)SelectObject(hdcDest, m_hFont);
|
||||
m_lpDDSFontCache->ReleaseDC(hdcDest);
|
||||
|
||||
DDSURFACEDESC2 surfDesc;
|
||||
INITDDSTRUCT(surfDesc);
|
||||
HRESULT hr = m_lpDDSFontCache->Lock(NULL, &surfDesc, DDLOCK_WAIT, NULL);
|
||||
if(hr == DD_OK)
|
||||
{
|
||||
|
||||
LPDWORD lpDst = (LPDWORD)surfDesc.lpSurface;
|
||||
for(row = 0; row < 6 * size.cy; row++)
|
||||
{
|
||||
|
||||
LPDWORD lp = lpDst;
|
||||
for(col = 0; col < 16 * size.cx; col++)
|
||||
{
|
||||
|
||||
DWORD dwPel = *lp;
|
||||
if(dwPel)
|
||||
{
|
||||
dwPel <<= 24;
|
||||
dwPel |= 0x00FFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwPel = 0x80000000;
|
||||
}
|
||||
|
||||
*lp++ = dwPel;
|
||||
}
|
||||
lpDst += (surfDesc.lPitch / 4);
|
||||
}
|
||||
m_lpDDSFontCache->Unlock(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* Initialize3DEnvironment
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::Initialize3DEnvironment(
|
||||
HWND hWnd
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
//
|
||||
// Create the IDirectDraw interface. The first parameter is the GUID,
|
||||
// which is allowed to be NULL. If there are more than one DirectDraw
|
||||
// drivers on the system, a NULL guid requests the primary driver. For
|
||||
// non-GDI hardware cards like the 3DFX and PowerVR, the guid would need
|
||||
// to be explicity specified . (Note: these guids are normally obtained
|
||||
// from enumeration, which is convered in a subsequent tutorial.)
|
||||
//
|
||||
|
||||
m_hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
|
||||
hr = DirectDrawCreateEx(NULL, (VOID**)&m_lpDDObj, IID_IDirectDraw7, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// get the h/w caps for this device
|
||||
//
|
||||
INITDDSTRUCT(m_ddHWCaps);
|
||||
hr = m_lpDDObj->GetCaps(&m_ddHWCaps, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
InitDisplayInfo(&m_DispInfo);
|
||||
|
||||
//
|
||||
// Set the Windows cooperative level. This is where we tell the system
|
||||
// whether we will be rendering in fullscreen mode or in a window. Note
|
||||
// that some hardware (non-GDI) may not be able to render into a window.
|
||||
// The flag DDSCL_NORMAL specifies windowed mode. Using fullscreen mode
|
||||
// is the topic of a subsequent tutorial. The DDSCL_FPUSETUP flag is a
|
||||
// hint to DirectX to optomize floating points calculations. See the docs
|
||||
// for more info on this. Note: this call could fail if another application
|
||||
// already controls a fullscreen, exclusive mode.
|
||||
//
|
||||
hr = m_lpDDObj->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// Initialize a surface description structure for the primary surface. The
|
||||
// primary surface represents the entire display, with dimensions and a
|
||||
// pixel format of the display. Therefore, none of that information needs
|
||||
// to be specified in order to create the primary surface.
|
||||
//
|
||||
DDSURFACEDESC2 ddsd;
|
||||
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
||||
ddsd.dwFlags = DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
|
||||
//
|
||||
// Create the primary surface.
|
||||
//
|
||||
hr = m_lpDDObj->CreateSurface(&ddsd, &m_lpPriSurf, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// Create a clipper object which handles all our clipping for cases when
|
||||
// our window is partially obscured by other windows. This is not needed
|
||||
// for apps running in fullscreen mode.
|
||||
//
|
||||
LPDIRECTDRAWCLIPPER pcClipper;
|
||||
hr = m_lpDDObj->CreateClipper(0, &pcClipper, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// Associate the clipper with our window. Note that, afterwards, the
|
||||
// clipper is internally referenced by the primary surface, so it is safe
|
||||
// to release our local reference to it.
|
||||
//
|
||||
pcClipper->SetHWnd(0, hWnd);
|
||||
m_lpPriSurf->SetClipper(pcClipper);
|
||||
pcClipper->Release();
|
||||
|
||||
//
|
||||
// Before creating the device, check that we are NOT in a palettized
|
||||
// display. That case will cause CreateDevice() to fail, since this simple
|
||||
// tutorial does not bother with palettes.
|
||||
//
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
||||
m_lpDDObj->GetDisplayMode(&ddsd);
|
||||
if(ddsd.ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||
return DDERR_INVALIDMODE;
|
||||
|
||||
DWORD dwRenderWidth = ddsd.dwWidth;
|
||||
DWORD dwRenderHeight = ddsd.dwHeight;
|
||||
|
||||
|
||||
//
|
||||
// Setup a surface description to create a backbuffer. This is an
|
||||
// offscreen plain surface with dimensions equal to the current display
|
||||
// size.
|
||||
|
||||
// The DDSCAPS_3DDEVICE is needed so we can later query this surface
|
||||
// for an IDirect3DDevice interface.
|
||||
//
|
||||
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
||||
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE;
|
||||
ddsd.dwWidth = dwRenderWidth;
|
||||
ddsd.dwHeight = dwRenderHeight;
|
||||
|
||||
|
||||
//
|
||||
// Create the backbuffer. The most likely reason for failure is running
|
||||
// out of video memory. (A more sophisticated app should handle this.)
|
||||
//
|
||||
hr = m_lpDDObj->CreateSurface(&ddsd, &m_lpBackBuffer, NULL);
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
//
|
||||
// Create the textbuffer.
|
||||
//
|
||||
// The text buffer should be RGB32 (for now - later I'll try
|
||||
// ARGB16:4:4:4:4, but that is a lot more work).
|
||||
//
|
||||
hr = DDARGB32SurfaceInit(&m_lpDDAppImage, TRUE,
|
||||
1024, MulDiv(4, (int)dwRenderHeight, GRID_CY));
|
||||
if(FAILED(hr))
|
||||
return hr;
|
||||
|
||||
PaintDDrawSurfaceBlack(m_lpDDAppImage);
|
||||
|
||||
|
||||
//
|
||||
// Create the device. The device is created off of our back buffer, which
|
||||
// becomes the render target for the newly created device. Note that the
|
||||
// z-buffer must be created BEFORE the device
|
||||
//
|
||||
m_lpBltAlpha = new CAlphaBlt(m_lpBackBuffer, &hr);
|
||||
if(m_lpBltAlpha == NULL || hr != DD_OK)
|
||||
{
|
||||
if(m_lpBltAlpha == NULL)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
delete m_lpBltAlpha;
|
||||
}
|
||||
|
||||
hr = CreateFontCache(32);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
POINT LookUpChar(char ch, int cxFont, int cyFont)
|
||||
{
|
||||
ch -= 32;
|
||||
|
||||
int row = ch / 16;
|
||||
int col = ch % 16;
|
||||
|
||||
POINT pt;
|
||||
|
||||
pt.x = col * cxFont;
|
||||
pt.y = row * cyFont;
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetAppText
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SetAppText(
|
||||
char* sz
|
||||
)
|
||||
{
|
||||
DDBLTFX ddFX;
|
||||
INITDDSTRUCT(ddFX);
|
||||
ddFX.dwFillColor = 0xFF80FF80;
|
||||
CAutoLock Lock(&m_AppImageLock);
|
||||
m_lpDDAppImage->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &ddFX);
|
||||
|
||||
m_cxFontImg = m_cxFont;
|
||||
m_cyFontImg = m_cyFont;
|
||||
RECT rcDst = {0, 0, m_cxFont, m_cyFont};
|
||||
|
||||
while(*sz)
|
||||
{
|
||||
if(*sz == '\n')
|
||||
{
|
||||
OffsetRect(&rcDst, 0, m_cyFont);
|
||||
rcDst.left = 0;
|
||||
rcDst.right = m_cxFont;
|
||||
}
|
||||
else
|
||||
{
|
||||
POINT pt = LookUpChar(*sz, m_cxFont, m_cyFont);
|
||||
|
||||
RECT rcSrc;
|
||||
rcSrc.left = pt.x;
|
||||
rcSrc.top = pt.y;
|
||||
rcSrc.right = pt.x + m_cxFont;
|
||||
rcSrc.bottom = pt.y + m_cyFont;
|
||||
|
||||
m_lpDDAppImage->Blt(&rcDst, m_lpDDSFontCache, &rcSrc, DDBLT_WAIT, NULL);
|
||||
OffsetRect(&rcDst, m_cxFont, 0);
|
||||
}
|
||||
sz++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,442 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: BltAlpha.h
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of CAlphaBlt class.
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __INITDDSTRUCT_DEFINED
|
||||
#define __INITDDSTRUCT_DEFINED
|
||||
template <typename T>
|
||||
__inline void INITDDSTRUCT(T& dd)
|
||||
{
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
dd.dwSize = sizeof(dd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __RELEASE_DEFINED
|
||||
#define __RELEASE_DEFINED
|
||||
template<typename T>
|
||||
__inline void RELEASE( T* &p )
|
||||
{
|
||||
if( p ) {
|
||||
p->Release();
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_HR
|
||||
#define CHECK_HR(expr) do { if (FAILED(expr)) __leave; } while(0);
|
||||
#endif
|
||||
|
||||
|
||||
class CAlphaBlt
|
||||
{
|
||||
private:
|
||||
|
||||
LPDIRECTDRAW7 m_pDD;
|
||||
LPDIRECT3D7 m_pD3D;
|
||||
LPDIRECT3DDEVICE7 m_pD3DDevice;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDBackBuffer;
|
||||
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDMirror;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDM32;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDM16;
|
||||
DDSURFACEDESC2 m_ddsdM32;
|
||||
DDSURFACEDESC2 m_ddsdM16;
|
||||
|
||||
bool m_fPowerOf2;
|
||||
bool m_fSquare;
|
||||
|
||||
//
|
||||
// IsSurfaceBlendable
|
||||
//
|
||||
// Checks the DD surface description and the given
|
||||
// alpha value to determine if this surface is blendable.
|
||||
//
|
||||
bool
|
||||
IsSurfaceBlendable(
|
||||
DDSURFACEDESC2& ddsd,
|
||||
BYTE fAlpha
|
||||
)
|
||||
{
|
||||
//
|
||||
// Is the blend really a blend ?
|
||||
//
|
||||
|
||||
//if (fAlpha == 0 || fAlpha == 255) {
|
||||
// return true;
|
||||
//}
|
||||
|
||||
//
|
||||
// Is the surface already a D3D texture ?
|
||||
//
|
||||
if (ddsd.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// OK we have to mirror the surface
|
||||
//
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// MirrorSourceSurface
|
||||
//
|
||||
// The mirror surface can be either 16 or 32 bit RGB depending
|
||||
// upon the format of the source surface.
|
||||
//
|
||||
// Of course it should have the "texture" flag
|
||||
// set and should be in VRAM. If we can't create the
|
||||
// surface then the AlphaBlt should fail
|
||||
//
|
||||
HRESULT MirrorSourceSurface(
|
||||
LPDIRECTDRAWSURFACE7 lpDDS,
|
||||
DDSURFACEDESC2& ddsd
|
||||
)
|
||||
{
|
||||
HRESULT hr = DD_OK;
|
||||
DWORD dwMirrorBitDepth = 0;
|
||||
DDSURFACEDESC2 ddsdMirror={0};
|
||||
|
||||
|
||||
//
|
||||
// OK - is it suitable for our needs.
|
||||
//
|
||||
// The following rules apply:
|
||||
// if ddsd is a FOURCC surface the mirror should be 32 bit
|
||||
// if ddsd is RGB then the mirror's bit depth should match that of ddsd.
|
||||
//
|
||||
// Also, the mirror must be large enough to actually hold
|
||||
// the surface to be blended
|
||||
//
|
||||
|
||||
m_lpDDMirror = NULL;
|
||||
|
||||
if (ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC ||
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount == 32) {
|
||||
|
||||
if (ddsd.dwWidth > m_ddsdM32.dwWidth ||
|
||||
ddsd.dwHeight > m_ddsdM32.dwHeight) {
|
||||
|
||||
RELEASE(m_lpDDM32);
|
||||
}
|
||||
|
||||
if (!m_lpDDM32) {
|
||||
dwMirrorBitDepth = 32;
|
||||
}
|
||||
else {
|
||||
m_lpDDMirror = m_lpDDM32;
|
||||
ddsdMirror = m_ddsdM32;
|
||||
}
|
||||
}
|
||||
else if (ddsd.ddpfPixelFormat.dwRGBBitCount == 16) {
|
||||
|
||||
if (ddsd.dwWidth > m_ddsdM16.dwWidth ||
|
||||
ddsd.dwHeight > m_ddsdM16.dwHeight) {
|
||||
|
||||
RELEASE(m_lpDDM16);
|
||||
}
|
||||
|
||||
if (!m_lpDDM16) {
|
||||
dwMirrorBitDepth = 16;
|
||||
}
|
||||
else {
|
||||
m_lpDDMirror = m_lpDDM16;
|
||||
ddsdMirror = m_ddsdM16;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// No support for RGB24 or RGB8 !
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (!m_lpDDMirror) {
|
||||
|
||||
INITDDSTRUCT(ddsdMirror);
|
||||
ddsdMirror.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
ddsdMirror.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
ddsdMirror.ddpfPixelFormat.dwRGBBitCount = dwMirrorBitDepth;
|
||||
|
||||
switch (dwMirrorBitDepth) {
|
||||
case 16:
|
||||
ddsdMirror.ddpfPixelFormat.dwRBitMask = 0x0000F800;
|
||||
ddsdMirror.ddpfPixelFormat.dwGBitMask = 0x000007E0;
|
||||
ddsdMirror.ddpfPixelFormat.dwBBitMask = 0x0000001F;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
ddsdMirror.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
|
||||
ddsdMirror.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
|
||||
ddsdMirror.ddpfPixelFormat.dwBBitMask = 0x000000FF;
|
||||
break;
|
||||
}
|
||||
|
||||
ddsdMirror.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE;
|
||||
ddsdMirror.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
||||
|
||||
if (m_fPowerOf2) {
|
||||
|
||||
for (ddsdMirror.dwWidth = 1;
|
||||
ddsd.dwWidth > ddsdMirror.dwWidth;
|
||||
ddsdMirror.dwWidth <<= 1);
|
||||
|
||||
for (ddsdMirror.dwHeight = 1;
|
||||
ddsd.dwHeight > ddsdMirror.dwHeight;
|
||||
ddsdMirror.dwHeight <<= 1);
|
||||
}
|
||||
else {
|
||||
ddsdMirror.dwWidth = ddsd.dwWidth;
|
||||
ddsdMirror.dwHeight = ddsd.dwHeight;
|
||||
}
|
||||
|
||||
if (m_fSquare) {
|
||||
|
||||
if (ddsdMirror.dwHeight > ddsdMirror.dwWidth) {
|
||||
ddsdMirror.dwWidth = ddsdMirror.dwHeight;
|
||||
}
|
||||
|
||||
if (ddsdMirror.dwWidth > ddsdMirror.dwHeight) {
|
||||
ddsdMirror.dwHeight = ddsdMirror.dwWidth;
|
||||
}
|
||||
}
|
||||
|
||||
__try {
|
||||
|
||||
// Attempt to create the surface with theses settings
|
||||
CHECK_HR(hr = m_pDD->CreateSurface(&ddsdMirror, &m_lpDDMirror, NULL));
|
||||
|
||||
INITDDSTRUCT(ddsdMirror);
|
||||
CHECK_HR(hr = m_lpDDMirror->GetSurfaceDesc(&ddsdMirror));
|
||||
|
||||
switch (dwMirrorBitDepth) {
|
||||
case 16:
|
||||
m_ddsdM16 = ddsdMirror;
|
||||
m_lpDDM16 = m_lpDDMirror;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
m_ddsdM32 = ddsdMirror;
|
||||
m_lpDDM32 = m_lpDDMirror;
|
||||
break;
|
||||
}
|
||||
|
||||
} __finally {}
|
||||
}
|
||||
|
||||
if (hr == DD_OK) {
|
||||
|
||||
//ASSERT(m_lpDDMirror != NULL);
|
||||
|
||||
__try {
|
||||
RECT rc = {0, 0, ddsd.dwWidth, ddsd.dwHeight};
|
||||
CHECK_HR(hr = m_lpDDMirror->Blt(&rc, lpDDS, &rc, DDBLT_WAIT, NULL));
|
||||
ddsd = ddsdMirror;
|
||||
} __finally {}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
~CAlphaBlt()
|
||||
{
|
||||
RELEASE(m_lpDDBackBuffer);
|
||||
RELEASE(m_lpDDM32);
|
||||
RELEASE(m_lpDDM16);
|
||||
|
||||
RELEASE(m_pD3DDevice);
|
||||
RELEASE(m_pD3D);
|
||||
RELEASE(m_pDD);
|
||||
}
|
||||
|
||||
CAlphaBlt(LPDIRECTDRAWSURFACE7 lpDDSDst, HRESULT* phr) :
|
||||
m_pDD(NULL),
|
||||
m_pD3D(NULL),
|
||||
m_pD3DDevice(NULL),
|
||||
m_lpDDBackBuffer(NULL),
|
||||
m_lpDDMirror(NULL),
|
||||
m_lpDDM32(NULL),
|
||||
m_lpDDM16(NULL),
|
||||
m_fPowerOf2(false),
|
||||
m_fSquare(false)
|
||||
{
|
||||
|
||||
ZeroMemory(&m_ddsdM32, sizeof(m_ddsdM32));
|
||||
ZeroMemory(&m_ddsdM16, sizeof(m_ddsdM16));
|
||||
|
||||
HRESULT hr;
|
||||
hr = lpDDSDst->GetDDInterface((LPVOID *)&m_pDD);
|
||||
if (FAILED(hr)) {
|
||||
m_pDD = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = m_pDD->QueryInterface(IID_IDirect3D7, (LPVOID *)&m_pD3D);
|
||||
if (FAILED(hr)) {
|
||||
m_pD3D = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = m_pD3D->CreateDevice(IID_IDirect3DHALDevice,
|
||||
lpDDSDst,
|
||||
&m_pD3DDevice);
|
||||
if (FAILED(hr)) {
|
||||
m_pD3DDevice = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
else {
|
||||
m_lpDDBackBuffer = lpDDSDst;
|
||||
m_lpDDBackBuffer->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
||||
D3DDEVICEDESC7 ddDesc;
|
||||
if (DD_OK == m_pD3DDevice->GetCaps(&ddDesc)) {
|
||||
|
||||
if (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) {
|
||||
m_fPowerOf2 = true;
|
||||
}
|
||||
|
||||
if (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) {
|
||||
m_fSquare = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*phr = hr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
AlphaBlt(RECT* lpDst,
|
||||
LPDIRECTDRAWSURFACE7 lpDDSSrc,
|
||||
RECT* lpSrc,
|
||||
BYTE bAlpha
|
||||
)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
struct {
|
||||
float x, y, z, rhw;
|
||||
D3DCOLOR clr;
|
||||
float tu, tv;
|
||||
} pVertices[4];
|
||||
|
||||
__try {
|
||||
|
||||
INITDDSTRUCT(ddsd);
|
||||
CHECK_HR(hr = lpDDSSrc->GetSurfaceDesc(&ddsd));
|
||||
|
||||
if (!IsSurfaceBlendable(ddsd, bAlpha)) {
|
||||
CHECK_HR(hr = MirrorSourceSurface(lpDDSSrc, ddsd));
|
||||
lpDDSSrc = m_lpDDMirror;
|
||||
}
|
||||
|
||||
float fWid = (float)ddsd.dwWidth;
|
||||
float fHgt = (float)ddsd.dwHeight;
|
||||
|
||||
BYTE alpha = bAlpha;
|
||||
|
||||
//
|
||||
// Setup the DST info
|
||||
//
|
||||
pVertices[0].x = (float)lpDst->left;
|
||||
pVertices[0].y = (float)lpDst->top;
|
||||
pVertices[0].z = 0.5f;
|
||||
pVertices[0].rhw = 2.0f;
|
||||
pVertices[0].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[1].x = (float)lpDst->right;
|
||||
pVertices[1].y = (float)lpDst->top;
|
||||
pVertices[1].z = 0.5f;
|
||||
pVertices[1].rhw = 2.0f;
|
||||
pVertices[1].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[2].x = (float)lpDst->left;
|
||||
pVertices[2].y = (float)lpDst->bottom;
|
||||
pVertices[2].z = 0.5f;
|
||||
pVertices[2].rhw = 2.0f;
|
||||
pVertices[2].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[3].x = (float)lpDst->right;
|
||||
pVertices[3].y = (float)lpDst->bottom;
|
||||
pVertices[3].z = 0.5f;
|
||||
pVertices[3].rhw = 2.0f;
|
||||
pVertices[3].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
//
|
||||
// Setup the SRC info
|
||||
//
|
||||
pVertices[0].tu = (float)lpSrc->left / fWid;
|
||||
pVertices[0].tv = (float)lpSrc->top / fHgt;
|
||||
|
||||
pVertices[1].tu = (float)lpSrc->right / fWid;
|
||||
pVertices[1].tv = (float)lpSrc->top / fHgt;
|
||||
|
||||
pVertices[2].tu = (float)lpSrc->left / fWid;
|
||||
pVertices[2].tv = (float)lpSrc->bottom / fHgt;
|
||||
|
||||
pVertices[3].tu = (float)lpSrc->right / fWid;
|
||||
pVertices[3].tv = (float)lpSrc->bottom / fHgt;
|
||||
|
||||
//
|
||||
// Setup some random D3D stuff
|
||||
//
|
||||
m_pD3DDevice->SetTexture(0, lpDDSSrc);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_BLENDENABLE, TRUE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
// use diffuse alpha from vertices, not texture alpha
|
||||
// m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
|
||||
|
||||
//
|
||||
// Do the alpha BLT
|
||||
//
|
||||
CHECK_HR(hr = m_pD3DDevice->BeginScene());
|
||||
CHECK_HR(hr = m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
pVertices, 4, D3DDP_WAIT));
|
||||
CHECK_HR(hr = m_pD3DDevice->EndScene());
|
||||
|
||||
} __finally {
|
||||
m_pD3DDevice->SetTexture(0, NULL);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool TextureSquare() {
|
||||
return m_fSquare;
|
||||
}
|
||||
|
||||
bool TexturePower2() {
|
||||
return m_fPowerOf2;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,164 @@
|
||||
# Microsoft Developer Studio Project File - Name="TxtPlayer" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=TxtPlayer - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TxtPlayer.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TxtPlayer.mak" CFG="TxtPlayer - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "TxtPlayer - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "TxtPlayer - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "TxtPlayer - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\DirectShow\BaseClasses" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 ..\..\..\DirectShow\baseclasses\release\strmbase.lib strmiids.lib quartz.lib ddraw.lib dxguid.lib version.lib shell32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /OPT:NOREF /OPT:ICF
|
||||
|
||||
!ELSEIF "$(CFG)" == "TxtPlayer - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\DirectShow\BaseClasses" /D "_DEBUG" /D "DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 dxguid.lib quartz.lib ..\..\..\DirectShow\baseclasses\debug\strmbasd.lib strmiids.lib ddraw.lib version.lib shell32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /profile /nodefaultlib
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "TxtPlayer - Win32 Release"
|
||||
# Name "TxtPlayer - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\alloclib.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AllocPresenter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\commands.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\persist.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BltAlpha.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mpgcodec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\project.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\perftool.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\toolbar.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TxtPlayer.rc
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "TxtPlayer"=".\TxtPlayer.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resrc1.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
//
|
||||
|
||||
IDR_TOOLBAR BITMAP DISCARDABLE "toolbar.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_VIDEOCD_ICON ICON DISCARDABLE "perftool.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_MAIN_MENU MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "&Open...", IDM_FILE_OPEN
|
||||
MENUITEM "&Close", IDM_FILE_CLOSE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", IDM_FILE_EXIT
|
||||
END
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About VMR TextPlayer Sample...", IDM_HELP_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About VMR Text Player"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
ICON IDR_VIDEOCD_ICON,-1,11,17,20,20
|
||||
LTEXT "DirectShow VMR TextPlayer Sample",-1,40,10,131,8,
|
||||
SS_NOPREFIX
|
||||
LTEXT "Copyright (C) 1999-2001 Microsoft Corporation",-1,40,34,
|
||||
188,8
|
||||
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
|
||||
LTEXT "Version 8.1",-1,40,22,119,8,SS_NOPREFIX
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_ACCELERATOR ACCELERATORS DISCARDABLE
|
||||
BEGIN
|
||||
"P", IDM_MOVIE_PLAY, VIRTKEY, CONTROL, NOINVERT
|
||||
"S", IDM_MOVIE_STOP, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resrc1.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""resource.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,1,0,0
|
||||
PRODUCTVERSION 8,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "DirectShow Windows XP Sample\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "Text Player Application\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "VMR TxtPlayer\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "TxtPlayer.EXE\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "DirectX 8.1 SDK\0"
|
||||
VALUE "ProductVersion", "8.1\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_MOVIE_STOP "Stop"
|
||||
IDM_MOVIE_PLAY "Play"
|
||||
IDM_MOVIE_PREVTRACK "Rewind to beginning"
|
||||
IDM_MOVIE_PAUSE "Pause"
|
||||
IDM_MOVIE_SKIP_FORE "Fast Forward"
|
||||
IDM_MOVIE_SKIP_BACK "Rewind"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_FULL_SCREEN "Full screen playback"
|
||||
IDM_MOVIE_STEP "Step one frame"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_OPEN "Open a new movie to play"
|
||||
STR_FILE_CLOSE "Close the movie"
|
||||
STR_FILE_EXIT "Quit DirectShow VMR TextPlayer Sample"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_HELP_ABOUT "Display information about DirectShow VMR TextPlayer Sample"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_SYSMENU_RESTORE "Restore the window to normal size"
|
||||
STR_SYSMENU_MOVE "Changes the window position"
|
||||
STR_SYSMENU_MINIMIZE "Reduce the window to an icon"
|
||||
STR_SYSMENU_CLOSE "Closes the window"
|
||||
STR_SYSMENU_MAXIMIZE "Enlarges the window to its maximum size"
|
||||
STR_SYSMENU_TASK_LIST "Opens the task list"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_FILTER "All Movies#*.mpg;*.avi;*.dat;*.mov#Mpeg Files (*.mpg)#*.mpg#Video CD Files (*.dat)#*.dat#QuickTime Files (*.mov)#*.mov#All Files (*.*)#*.*#"
|
||||
STR_APP_TITLE "DirectShow VMR TextPlayer Sample"
|
||||
STR_APP_TITLE_LOADED "DirectShow VMR TextPlayer Sample - %s"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: alloclib.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "AllocLib.h"
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* YV12PaintSurfaceBlack
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
YV12PaintSurfaceBlack(
|
||||
LPDIRECTDRAWSURFACE7 pDDrawSurface
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("YV12PaintSurfaceBlack")));
|
||||
HRESULT hr = NOERROR;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
// now lock the surface so we can start filling the surface with black
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
hr = pDDrawSurface->Lock(NULL, &ddsd,
|
||||
DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
|
||||
|
||||
if (hr == DD_OK || hr != DDERR_WASSTILLDRAWING) {
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
if (hr == DD_OK)
|
||||
{
|
||||
DWORD y;
|
||||
LPBYTE pDst = (LPBYTE)ddsd.lpSurface;
|
||||
LONG OutStride = ddsd.lPitch;
|
||||
DWORD VSize = ddsd.dwHeight;
|
||||
DWORD HSize = ddsd.dwWidth;
|
||||
|
||||
// Y Component
|
||||
for (y = 0; y < VSize; y++) {
|
||||
FillMemory(pDst, HSize, (BYTE)0x10); // 1 line at a time
|
||||
pDst += OutStride;
|
||||
}
|
||||
|
||||
HSize /= 2;
|
||||
VSize /= 2;
|
||||
OutStride /= 2;
|
||||
|
||||
// Cb Component
|
||||
for (y = 0; y < VSize; y++) {
|
||||
FillMemory(pDst, HSize, (BYTE)0x80); // 1 line at a time
|
||||
pDst += OutStride;
|
||||
}
|
||||
|
||||
// Cr Component
|
||||
for (y = 0; y < VSize; y++) {
|
||||
FillMemory(pDst, HSize, (BYTE)0x80); // 1 line at a time
|
||||
pDst += OutStride;
|
||||
}
|
||||
|
||||
pDDrawSurface->Unlock(NULL);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* YUV16PaintSurfaceBlack
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
YUV16PaintSurfaceBlack(
|
||||
LPDIRECTDRAWSURFACE7 pdds,
|
||||
DWORD dwBlack
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("YUV16PaintSurfaceBlack")));
|
||||
HRESULT hr = NOERROR;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
// now lock the surface so we can start filling the surface with black
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
hr = pdds->Lock(NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
|
||||
|
||||
if (hr == DD_OK || hr != DDERR_WASSTILLDRAWING) {
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
if (hr == DD_OK)
|
||||
{
|
||||
DWORD y, x;
|
||||
LPDWORD pDst = (LPDWORD)ddsd.lpSurface;
|
||||
LONG OutStride = ddsd.lPitch;
|
||||
|
||||
for (y = 0; y < ddsd.dwHeight; y++) {
|
||||
|
||||
for (x = 0; x < ddsd.dwWidth / 2; x++) {
|
||||
pDst[x] = dwBlack;
|
||||
}
|
||||
|
||||
// Dont forget that the stride is a byte count
|
||||
*((LPBYTE*)&pDst) += OutStride;
|
||||
}
|
||||
|
||||
pdds->Unlock(NULL);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* BlackPaintProc
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
BlackPaintProc(
|
||||
LPDIRECTDRAWSURFACE7 pDDrawSurface,
|
||||
DDSURFACEDESC2* lpddSurfaceDesc
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("BlackPaintProc")));
|
||||
|
||||
//
|
||||
// If the surface is YUV take care of the types that we
|
||||
// know the pixel format for. Those surfaces that we don't know
|
||||
// about will get painted '0' which may be bright green for
|
||||
// YUV surfaces.
|
||||
//
|
||||
|
||||
if (lpddSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
|
||||
|
||||
//
|
||||
// compute the black value if the fourCC code is suitable,
|
||||
// otherwise can't handle it
|
||||
//
|
||||
|
||||
switch (lpddSurfaceDesc->ddpfPixelFormat.dwFourCC) {
|
||||
|
||||
case mmioFOURCC('Y','V','1','2'):
|
||||
case mmioFOURCC('I','4','2','0'):
|
||||
case mmioFOURCC('I','Y','U','V'):
|
||||
return YV12PaintSurfaceBlack(pDDrawSurface);
|
||||
|
||||
case mmioFOURCC('Y','U','Y','2'):
|
||||
return YUV16PaintSurfaceBlack(pDDrawSurface, 0x80108010);
|
||||
|
||||
case mmioFOURCC('U','Y','V','Y'):
|
||||
return YUV16PaintSurfaceBlack(pDDrawSurface, 0x10801080);
|
||||
}
|
||||
}
|
||||
|
||||
DDBLTFX ddFX;
|
||||
INITDDSTRUCT(ddFX);
|
||||
return pDDrawSurface->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &ddFX);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* PaintSurfaceBlack
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
PaintDDrawSurfaceBlack(
|
||||
LPDIRECTDRAWSURFACE7 pDDrawSurface
|
||||
)
|
||||
{
|
||||
AMTRACE((TEXT("PaintDDrawSurfaceBlack")));
|
||||
|
||||
LPDIRECTDRAWSURFACE7 *ppDDrawSurface = NULL;
|
||||
DDSCAPS2 ddSurfaceCaps;
|
||||
DDSURFACEDESC2 ddSurfaceDesc;
|
||||
DWORD dwAllocSize;
|
||||
DWORD i = 0, dwBackBufferCount = 0;
|
||||
|
||||
// get the surface description
|
||||
INITDDSTRUCT(ddSurfaceDesc);
|
||||
HRESULT hr = pDDrawSurface->GetSurfaceDesc(&ddSurfaceDesc);
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
||||
if (ddSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT) {
|
||||
dwBackBufferCount = ddSurfaceDesc.dwBackBufferCount;
|
||||
}
|
||||
|
||||
hr = BlackPaintProc(pDDrawSurface, &ddSurfaceDesc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
DbgLog((LOG_ERROR,1,
|
||||
TEXT("pDDrawSurface->Blt failed, hr = 0x%x"), hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (dwBackBufferCount > 0) {
|
||||
|
||||
dwAllocSize = (dwBackBufferCount + 1) * sizeof(LPDIRECTDRAWSURFACE);
|
||||
ppDDrawSurface = (LPDIRECTDRAWSURFACE7*)_alloca(dwAllocSize);
|
||||
|
||||
ZeroMemory(ppDDrawSurface, dwAllocSize);
|
||||
ZeroMemory(&ddSurfaceCaps, sizeof(ddSurfaceCaps));
|
||||
ddSurfaceCaps.dwCaps = DDSCAPS_FLIP | DDSCAPS_COMPLEX;
|
||||
|
||||
if( DDSCAPS_OVERLAY & ddSurfaceDesc.ddsCaps.dwCaps ) {
|
||||
ddSurfaceCaps.dwCaps |= DDSCAPS_OVERLAY;
|
||||
}
|
||||
|
||||
for (i = 0; i < dwBackBufferCount; i++) {
|
||||
|
||||
LPDIRECTDRAWSURFACE7 pCurrentDDrawSurface = NULL;
|
||||
if (i == 0) {
|
||||
pCurrentDDrawSurface = pDDrawSurface;
|
||||
}
|
||||
else {
|
||||
pCurrentDDrawSurface = ppDDrawSurface[i];
|
||||
}
|
||||
ASSERT(pCurrentDDrawSurface);
|
||||
|
||||
|
||||
//
|
||||
// Get the back buffer surface and store it in the
|
||||
// next (in the circular sense) entry
|
||||
//
|
||||
|
||||
hr = pCurrentDDrawSurface->GetAttachedSurface(
|
||||
&ddSurfaceCaps,
|
||||
&ppDDrawSurface[i + 1]);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
DbgLog((LOG_ERROR,1,
|
||||
TEXT("Function pDDrawSurface->GetAttachedSurface ")
|
||||
TEXT("failed, hr = 0x%x"), hr ));
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT(ppDDrawSurface[i+1]);
|
||||
|
||||
//
|
||||
// Peform a DirectDraw colorfill BLT
|
||||
//
|
||||
|
||||
hr = BlackPaintProc(ppDDrawSurface[i + 1], &ddSurfaceDesc);
|
||||
if (FAILED(hr)) {
|
||||
DbgLog((LOG_ERROR,1,
|
||||
TEXT("ppDDrawSurface[i + 1]->Blt failed, ")
|
||||
TEXT("hr = 0x%x"), hr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ppDDrawSurface) {
|
||||
for (i = 0; i < dwBackBufferCount + 1; i++) {
|
||||
if (ppDDrawSurface[i]) {
|
||||
ppDDrawSurface[i]->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hr != DD_OK) {
|
||||
DbgLog((LOG_ERROR, 1, TEXT("PaintSurfaceBlack failed")));
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: app.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for TxtPlayer sample
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Function prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
DoMainLoop(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
InitApplication(
|
||||
HINSTANCE hInstance
|
||||
);
|
||||
|
||||
BOOL
|
||||
InitInstance(
|
||||
HINSTANCE hInstance,
|
||||
int nCmdShow
|
||||
);
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
PatB(
|
||||
HDC hdc,
|
||||
int x,
|
||||
int y,
|
||||
int dx,
|
||||
int dy,
|
||||
DWORD rgb
|
||||
);
|
||||
|
||||
void
|
||||
UpdateMpegMovieRect(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
GetAdjustedClientRect(
|
||||
RECT *prc
|
||||
);
|
||||
|
||||
BOOL
|
||||
DrawStats(
|
||||
HDC hdc
|
||||
);
|
||||
|
||||
void
|
||||
CalcMovieRect(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
LPCTSTR
|
||||
IdStr(
|
||||
int idResource
|
||||
);
|
||||
|
||||
void
|
||||
UpdateSystemColors(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
SetDurationLength(
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
void
|
||||
SetCurrentPosition(
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
TCHAR *
|
||||
FormatRefTime(
|
||||
TCHAR *sz,
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
void
|
||||
DoMpegVideoPropertyPage();
|
||||
|
||||
void
|
||||
DoMpegAudioPropertyPage();
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Registry stuff
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
ProfileIntIn(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
);
|
||||
|
||||
BOOL
|
||||
ProfileIntOut(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
);
|
||||
|
||||
void
|
||||
ProfileStringOut (
|
||||
LPTSTR szKey,
|
||||
LPTSTR sz
|
||||
);
|
||||
|
||||
UINT
|
||||
ProfileStringIn (
|
||||
LPTSTR szKey,
|
||||
LPTSTR szDef,
|
||||
LPTSTR sz,
|
||||
DWORD cb
|
||||
);
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
HKEY
|
||||
GetAppKey(
|
||||
BOOL fCreate
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Message crackers
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
/* void Cls_OnUser(HWND hwnd, WPARAM wParam, LPARAM lParam ) */
|
||||
#define HANDLE_WM_USER(hwnd, wParam, lParam, fn) \
|
||||
((fn)(hwnd, wParam, lParam), 0L)
|
||||
|
||||
#ifndef HANDLE_WM_NOTIFY
|
||||
/* LRESULT Cls_OnNotify(HWND hwnd, int idFrom, NMHDR FAR* pnmhdr); */
|
||||
#define HANDLE_WM_NOTIFY(hwnd, wParam, lParam, fn) \
|
||||
(fn)((hwnd), (int)(wParam), (NMHDR FAR*)(lParam))
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** VideoCd window class prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
extern "C" LRESULT CALLBACK
|
||||
VideoCdWndProc(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnClose(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnQueryEndSession(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDestroy(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnCommand(
|
||||
HWND hwnd,
|
||||
int id,
|
||||
HWND hwndCtl,
|
||||
UINT codeNotify
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnPaint(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnTimer(
|
||||
HWND hwnd,
|
||||
UINT id
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnCreate(
|
||||
HWND hwnd,
|
||||
LPCREATESTRUCT lpCreateStruct
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSize(
|
||||
HWND hwnd,
|
||||
UINT state,
|
||||
int cx,
|
||||
int cy
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnActivate(
|
||||
HWND hwnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnHScroll(
|
||||
HWND hwnd,
|
||||
HWND hwndCtl,
|
||||
UINT code,
|
||||
int pos
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnUser(
|
||||
HWND hwnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSysColorChange(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnMenuSelect(
|
||||
HWND hwnd,
|
||||
HMENU hmenu,
|
||||
int item,
|
||||
HMENU hmenuPopup,
|
||||
UINT flags
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnInitMenuPopup(
|
||||
HWND hwnd,
|
||||
HMENU hMenu,
|
||||
UINT item,
|
||||
BOOL fSystemMenu
|
||||
);
|
||||
|
||||
#ifdef WM_NOTIFY
|
||||
LRESULT
|
||||
VideoCd_OnNotify(
|
||||
HWND hwnd,
|
||||
int idFrom,
|
||||
NMHDR FAR* pnmhdr
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
VideoCd_OnGraphNotify(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDropFiles(
|
||||
HWND hwnd,
|
||||
HDROP hdrop);
|
||||
|
||||
void
|
||||
SetPlayButtonsEnableState(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Command processing functions
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStepCmd(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
);
|
||||
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay = FALSE
|
||||
);
|
||||
|
||||
int
|
||||
VcdPlayerChangeTimeFormat(
|
||||
int id
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Recent filename stuff
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
typedef TCHAR RECENTFILES[MAX_PATH];
|
||||
#define MAX_RECENT_FILES 5
|
||||
#define ID_RECENT_FILE_BASE 500
|
||||
|
||||
int
|
||||
GetRecentFiles(
|
||||
int LastCount
|
||||
);
|
||||
|
||||
int
|
||||
SetRecentFiles(
|
||||
TCHAR *FileName,
|
||||
int iCount
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Global Variables
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
extern int cxMovie;
|
||||
extern int cyMovie;
|
||||
extern HWND hwndApp;
|
||||
extern HWND g_hwndStatusbar;
|
||||
|
||||
extern int cx;
|
||||
extern int cy;
|
||||
extern int xOffset;
|
||||
extern int yOffset;
|
||||
extern TCHAR g_achFileName[];
|
||||
extern OPENFILENAME ofn;
|
||||
extern DWORD g_State;
|
||||
extern int nRecentFiles;
|
||||
extern LONG lMovieOrgX, lMovieOrgY;
|
||||
extern int g_TimeFormat;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
#define LEFT_MARGIN 0
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Video CD Player states
|
||||
**
|
||||
** These are bit flags
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
#define VCD_PLAYING 0x0001
|
||||
#define VCD_STOPPED 0x0002
|
||||
#define VCD_PAUSED 0x0004
|
||||
#define VCD_SKIP_F 0x0008
|
||||
#define VCD_SKIP_B 0x0010
|
||||
#define VCD_FF 0x0020
|
||||
#define VCD_RW 0x0040
|
||||
#define VCD_SEEKING (VCD_FF | VCD_RW)
|
||||
#define VCD_LOADED 0x0080
|
||||
#define VCD_NO_CD 0x0100
|
||||
#define VCD_DATA_CD_LOADED 0x0200
|
||||
#define VCD_EDITING 0x0400
|
||||
#define VCD_PAUSED_AND_MOVED 0x0800
|
||||
#define VCD_PLAY_PENDING 0x1000
|
||||
#define VCD_WAS_PLAYING 0x2000
|
||||
#define VCD_IN_USE 0x4000
|
||||
#define VCD_STEPPING 0x8000
|
||||
|
||||
enum {PerformanceTimer = 32, StatusTimer = 33};
|
||||
@@ -0,0 +1,393 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: commands.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - Processes commands from the user.
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "project.h"
|
||||
#include "mpgcodec.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
extern void RepositionMovie(HWND hwnd);
|
||||
extern CMpegMovie *pMpegMovie;
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerOpenCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
static BOOL fFirstTime = TRUE;
|
||||
BOOL fRet;
|
||||
TCHAR achFileName[MAX_PATH];
|
||||
TCHAR achFilter[MAX_PATH];
|
||||
LPTSTR lp;
|
||||
|
||||
if(fFirstTime)
|
||||
{
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwndApp;
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST |
|
||||
OFN_SHAREAWARE | OFN_PATHMUSTEXIST;
|
||||
}
|
||||
|
||||
lstrcpy(achFilter, IdStr(STR_FILE_FILTER));
|
||||
ofn.lpstrFilter = achFilter;
|
||||
|
||||
/*
|
||||
** Convert the resource string into to something suitable for
|
||||
** GetOpenFileName ie. replace '#' characters with '\0' characters.
|
||||
*/
|
||||
for(lp = achFilter; *lp; lp++)
|
||||
{
|
||||
if(*lp == TEXT('#'))
|
||||
{
|
||||
*lp = TEXT('\0');
|
||||
}
|
||||
}
|
||||
|
||||
ofn.lpstrFile = achFileName;
|
||||
ofn.nMaxFile = sizeof(achFileName) / sizeof(TCHAR);
|
||||
ZeroMemory(achFileName, sizeof(achFileName));
|
||||
|
||||
fRet = GetOpenFileName(&ofn);
|
||||
if(fRet)
|
||||
{
|
||||
fFirstTime = FALSE;
|
||||
ProcessOpen(achFileName);
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerCloseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
LONG cx, cy;
|
||||
|
||||
g_State = VCD_NO_CD;
|
||||
pMpegMovie->GetMoviePosition(&lMovieOrgX, &lMovieOrgY, &cx, &cy);
|
||||
pMpegMovie->StopMovie();
|
||||
pMpegMovie->CloseMovie();
|
||||
|
||||
SetDurationLength((REFTIME)0);
|
||||
SetCurrentPosition((REFTIME)0);
|
||||
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPlayCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fStopped = (g_State & VCD_STOPPED);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fStopped || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
|
||||
g_State &= ~(fStopped ? VCD_STOPPED : VCD_PAUSED);
|
||||
g_State |= VCD_PLAYING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPlayCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fPlaying || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->StopMovie();
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
g_State &= ~(fPlaying ? VCD_PLAYING : VCD_PAUSED);
|
||||
g_State |= VCD_STOPPED;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerStepCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerStepCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
// Ensure that the video is paused to update toolbar buttons
|
||||
if(g_State & VCD_PLAYING)
|
||||
VcdPlayerPauseCmd();
|
||||
|
||||
if(pMpegMovie->FrameStepMovie())
|
||||
{
|
||||
g_State |= VCD_STEPPING;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPauseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if(fPlaying)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PauseMovie();
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
g_State &= ~VCD_PLAYING;
|
||||
g_State |= VCD_PAUSED;
|
||||
}
|
||||
else if(fPaused)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
|
||||
g_State &= ~VCD_PAUSED;
|
||||
g_State |= VCD_PLAYING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerSeekCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
)
|
||||
{
|
||||
REFTIME rt;
|
||||
REFTIME rtDur;
|
||||
|
||||
rtDur = pMpegMovie->GetDuration();
|
||||
rt = pMpegMovie->GetCurrentPosition() + rtSeekBy;
|
||||
|
||||
rt = max(0, min(rt, rtDur));
|
||||
|
||||
pMpegMovie->SeekToPosition(rt,TRUE);
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProcessOpen
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay
|
||||
)
|
||||
{
|
||||
/*
|
||||
** If we currently have a video loaded we need to discard it here.
|
||||
*/
|
||||
if(g_State & VCD_LOADED)
|
||||
{
|
||||
VcdPlayerCloseCmd();
|
||||
}
|
||||
|
||||
lstrcpy(g_achFileName, achFileName);
|
||||
|
||||
pMpegMovie = new CMpegMovie(hwndApp);
|
||||
|
||||
if(pMpegMovie)
|
||||
{
|
||||
HRESULT hr = pMpegMovie->OpenMovie(g_achFileName);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
TCHAR achTmp[MAX_PATH];
|
||||
|
||||
nRecentFiles = SetRecentFiles(achFileName, nRecentFiles);
|
||||
|
||||
wsprintf(achTmp, IdStr(STR_APP_TITLE_LOADED),
|
||||
g_achFileName);
|
||||
g_State = (VCD_LOADED | VCD_STOPPED);
|
||||
|
||||
// SetDurationLength(pMpegMovie->GetDuration());
|
||||
g_TimeFormat = VcdPlayerChangeTimeFormat(g_TimeFormat);
|
||||
|
||||
RepositionMovie(hwndApp);
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
|
||||
// If play option specified on the command line
|
||||
if(bPlay)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCHAR Buffer[MAX_ERROR_TEXT_LEN];
|
||||
|
||||
if(AMGetErrorText(hr, Buffer, MAX_ERROR_TEXT_LEN))
|
||||
{
|
||||
MessageBox(hwndApp, Buffer,
|
||||
IdStr(STR_APP_TITLE), MB_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp,
|
||||
TEXT("Failed to open the movie! ")
|
||||
TEXT("Either the file was not found or the wave device is in use."),
|
||||
IdStr(STR_APP_TITLE), MB_OK);
|
||||
}
|
||||
|
||||
pMpegMovie->CloseMovie();
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerChangeTimeFormat
|
||||
*
|
||||
* Tries to change the time format to id. Returns the time format that
|
||||
* actually got set. This may differ from id if the graph does not support
|
||||
* the requested time format.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
VcdPlayerChangeTimeFormat(
|
||||
int id
|
||||
)
|
||||
{
|
||||
// Menu items are disabled while we are playing
|
||||
BOOL bRet = FALSE;
|
||||
int idActual = id;
|
||||
|
||||
ASSERT(pMpegMovie);
|
||||
ASSERT(pMpegMovie->StatusMovie() != MOVIE_NOTOPENED);
|
||||
|
||||
// Change the time format with the filtergraph
|
||||
switch(id)
|
||||
{
|
||||
case IDM_FRAME:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_FRAME);
|
||||
break;
|
||||
|
||||
case IDM_FIELD:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_FIELD);
|
||||
break;
|
||||
|
||||
case IDM_SAMPLE:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_SAMPLE);
|
||||
break;
|
||||
|
||||
case IDM_BYTES:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_BYTE);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bRet)
|
||||
{
|
||||
// IDM_TIME and all other cases, everyone should support IDM_TIME
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_MEDIA_TIME);
|
||||
ASSERT(bRet);
|
||||
idActual = IDM_TIME;
|
||||
}
|
||||
|
||||
// Pause the movie to get a current position
|
||||
SetDurationLength(pMpegMovie->GetDuration());
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
|
||||
return idActual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerRewindCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: mpgcodec.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for TxtPlayer sample
|
||||
//
|
||||
// Copyright (c) 1995 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <mpegtype.h> // IMpegAudioDecoder
|
||||
|
||||
typedef struct {
|
||||
LONG lWidth; // Native Width in pixels
|
||||
LONG lHeight; // Native Height in pixels
|
||||
LONG lvbv; // vbv
|
||||
REFERENCE_TIME PictureTime; // Time per picture in 100ns units
|
||||
LONG lTimePerFrame; // Time per picture in MPEG units
|
||||
LONG dwBitRate; // Bits per second
|
||||
LONG lXPelsPerMeter; // Pel aspect ratio
|
||||
LONG lYPelsPerMeter; // Pel aspect ratio
|
||||
DWORD dwStartTimeCode; // First GOP time code (or -1)
|
||||
LONG lActualHeaderLen; // Length of valid bytes in raw seq hdr
|
||||
BYTE RawHeader[140]; // The real sequence header
|
||||
} SEQHDR_INFO;
|
||||
|
||||
|
||||
#define DECODE_I 0x0001L
|
||||
#define DECODE_IP 0x0003L
|
||||
#define DECODE_IPB 0x0007L // Normal B Frame
|
||||
#define DECODE_IPB1 0x000FL // Decode 1 out of 4 B frames
|
||||
#define DECODE_IPB2 0x0010L // Decode 2 out of 4 B frames
|
||||
#define DECODE_IPB3 0x0020L // Decode 3 out of 4 B frames
|
||||
#define DECODE_DIS 0x0040L // No Decode, Convert only
|
||||
|
||||
#define DECODE_BQUAL_HIGH 0x00000000L // Normal B Decode
|
||||
#define DECODE_BQUAL_MEDIUM 0x10000000L // Fast B Frame (No Half Pixel)
|
||||
#define DECODE_BQUAL_LOW 0x20000000L // Super Fast B Frame (No Half Pixel & Fast IDCT)
|
||||
|
||||
#define MM_NOCONV 0x00000000L // No Conversion
|
||||
#define MM_HRESOLUTION 0x10000000L // Half Resolution
|
||||
#define MM_CLIPPED 0x20000000L // Clipped version (RGB8 only at present)
|
||||
|
||||
#define MM_420PL 0x00000001L // YU12 :: YCbCr
|
||||
#define MM_420PL_ 0x00000002L // YV12 :: YCrCb
|
||||
|
||||
#define MM_422PK 0x00000010L // YUY2 :: YCbCr
|
||||
#define MM_422PK_ 0x00000020L // YVY2 :: YCrCb
|
||||
#define MM_422SPK 0x00000040L // :: CbYCrY
|
||||
#define MM_422SPK_ 0x00000080L // :: CrYCbY
|
||||
#define MM_411PK 0x00000100L // BT41
|
||||
#define MM_410PL_ 0x00000200L // YVU9 - 16:1:1 Planar format
|
||||
|
||||
|
||||
#define MM_Y_DIB 0x00001000L // Luminance Only DIB
|
||||
#define MM_Y_DDB 0x00002000L // Luminance Only DDB
|
||||
|
||||
#define MM_RGB24_DIB 0x00010000L // RGB 8:8:8 DIB (Not Supported)
|
||||
#define MM_RGB24_DDB 0x00020000L // RGB 8:8:8 DDB (Not Supported)
|
||||
#define MM_RGB32_DIB 0x00040000L // RGB a:8:8:8 DIB (Not Supported)
|
||||
#define MM_RGB32_DDB 0x00080000L // RGB a:8:8:8 DDB (Not Supported)
|
||||
|
||||
#define MM_RGB565_DIB 0x00100000L // RGB 5:6:5 DIB
|
||||
#define MM_RGB565_DDB 0x00200000L // RGB 5:6:5 DDB
|
||||
#define MM_RGB555_DIB 0x00400000L // RGB 5:5:5 DIB
|
||||
#define MM_RGB555_DDB 0x00800000L // RGB 5:5:5 DDB
|
||||
|
||||
#define MM_RGB8_DIB 0x01000000L // 8 Bit Paletized RGB DIB
|
||||
#define MM_RGB8_DDB 0x02000000L // 8 Bit Paletized RGB DDB
|
||||
|
||||
|
||||
#define DECODE_HALF_HIQ 0x00004000L
|
||||
#define DECODE_HALF_FULLQ 0x00008000L
|
||||
|
||||
|
||||
//
|
||||
// Structure to describe the caps of the mpeg video decoder.
|
||||
//
|
||||
typedef struct {
|
||||
DWORD VideoMaxBitRate;
|
||||
} MPEG_VIDEO_DECODER_CAPS;
|
||||
|
||||
|
||||
//
|
||||
// IMpegVideoDecoder
|
||||
//
|
||||
DECLARE_INTERFACE_(IMpegVideoDecoder, IUnknown) {
|
||||
|
||||
STDMETHOD(get_CurrentDecoderOption)
|
||||
( THIS_
|
||||
DWORD *pOptions
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(set_CurrentDecoderOption)
|
||||
( THIS_
|
||||
DWORD Options
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_DefaultDecoderOption)
|
||||
( THIS_
|
||||
DWORD *pOptions
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(set_DefaultDecoderOption)
|
||||
( THIS_
|
||||
DWORD Options
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_QualityMsgProcessing)
|
||||
( THIS_
|
||||
BOOL *pfIgnore
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(set_QualityMsgProcessing)
|
||||
( THIS_
|
||||
BOOL fIgnore
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_GreyScaleOutput)
|
||||
( THIS_
|
||||
BOOL *pfGrey
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(set_GreyScaleOutput)
|
||||
( THIS_
|
||||
BOOL fGrey
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_SequenceHeader)
|
||||
( THIS_
|
||||
SEQHDR_INFO *pSeqHdrInfo
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_OutputFormat)
|
||||
( THIS_
|
||||
DWORD *pOutputFormat
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_FrameStatistics)
|
||||
( THIS_
|
||||
DWORD *pIFramesDecoded,
|
||||
DWORD *pPFramesDecoded,
|
||||
DWORD *pBFramesDecoded,
|
||||
DWORD *pIFramesSkipped,
|
||||
DWORD *pPFramesSkipped,
|
||||
DWORD *pBFramesSkipped
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(ResetFrameStatistics)
|
||||
( THIS_
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_DecoderPaletteInfo)
|
||||
( THIS_
|
||||
LPDWORD lpdwFirstEntry,
|
||||
LPDWORD lpdwLastEntry
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_DecoderPaletteEntries)
|
||||
( THIS_
|
||||
DWORD dwStartEntry,
|
||||
DWORD dwNumEntries,
|
||||
LPPALETTEENTRY lppe
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_EncryptionKey)
|
||||
( THIS_
|
||||
DWORD *dwEncrptionKey
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(put_EncryptionKey)
|
||||
( THIS_
|
||||
DWORD dwEncrptionKey
|
||||
) PURE;
|
||||
|
||||
STDMETHOD(get_DecoderCaps)
|
||||
( THIS_
|
||||
MPEG_VIDEO_DECODER_CAPS *pCaps
|
||||
) PURE;
|
||||
|
||||
};
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,408 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: persist.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - State persistence helper functions
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlconv.cpp>
|
||||
#include <mmreg.h>
|
||||
|
||||
#include "project.h"
|
||||
|
||||
// Global data
|
||||
RECENTFILES aRecentFiles[MAX_RECENT_FILES];
|
||||
int nRecentFiles;
|
||||
|
||||
static TCHAR cszWindow[] = TEXT("Window");
|
||||
static TCHAR cszAppKey[] = TEXT("Software\\Microsoft\\Multimedia Tools\\VMRTxtPlayer");
|
||||
|
||||
const int CX_DEFAULT = 400; /* Default window width */
|
||||
const int CY_DEFAULT = 400; /* Default window height */
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetAppKey
|
||||
*
|
||||
\**************************************************************************/
|
||||
HKEY
|
||||
GetAppKey(
|
||||
BOOL fCreate
|
||||
)
|
||||
{
|
||||
HKEY hKey = 0;
|
||||
|
||||
if(fCreate)
|
||||
{
|
||||
if(RegCreateKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
|
||||
return hKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RegOpenKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
|
||||
return hKey;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProfileIntIn
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
ProfileIntIn(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
)
|
||||
{
|
||||
DWORD dwType=0;
|
||||
int iValue=0;
|
||||
BYTE aData[20];
|
||||
DWORD cb;
|
||||
HKEY hKey;
|
||||
|
||||
if((hKey = GetAppKey(TRUE)) == 0)
|
||||
{
|
||||
return iDefault;
|
||||
}
|
||||
|
||||
*(UINT *)&aData = 0;
|
||||
cb = sizeof(aData);
|
||||
|
||||
if(RegQueryValueEx(hKey, szKey, NULL, &dwType, aData, &cb))
|
||||
{
|
||||
iValue = iDefault;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dwType == REG_DWORD || dwType == REG_BINARY)
|
||||
{
|
||||
iValue = *(int *)&aData;
|
||||
}
|
||||
#ifdef UNICODE
|
||||
else if(dwType == REG_SZ)
|
||||
{
|
||||
iValue = atoiW((LPWSTR)aData);
|
||||
}
|
||||
#else
|
||||
else if(dwType == REG_SZ)
|
||||
{
|
||||
iValue = atoiA((LPSTR)aData);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return iValue;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProfileIntOut
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
ProfileIntOut(
|
||||
const TCHAR *szKey,
|
||||
int iVal
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
hKey = GetAppKey(TRUE);
|
||||
if(hKey)
|
||||
{
|
||||
RegSetValueEx(hKey, szKey, 0, REG_DWORD, (LPBYTE)&iVal, sizeof(DWORD));
|
||||
RegCloseKey(hKey);
|
||||
bRet = TRUE;
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProfileString
|
||||
*
|
||||
\**************************************************************************/
|
||||
UINT
|
||||
ProfileStringIn(
|
||||
LPTSTR szKey,
|
||||
LPTSTR szDef,
|
||||
LPTSTR sz,
|
||||
DWORD cb
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD dwType;
|
||||
|
||||
if((hKey = GetAppKey(FALSE)) == 0)
|
||||
{
|
||||
lstrcpy(sz, szDef);
|
||||
return lstrlen(sz);
|
||||
}
|
||||
|
||||
if(RegQueryValueEx(hKey, szKey, NULL, &dwType, (LPBYTE)sz, &cb) || dwType != REG_SZ)
|
||||
{
|
||||
lstrcpy(sz, szDef);
|
||||
cb = lstrlen(sz);
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return cb;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProfileStringOut
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
ProfileStringOut(
|
||||
LPTSTR szKey,
|
||||
LPTSTR sz
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
hKey = GetAppKey(TRUE);
|
||||
if(hKey)
|
||||
RegSetValueEx(hKey, szKey, 0, REG_SZ, (LPBYTE)sz,
|
||||
sizeof(TCHAR) * (lstrlen(sz)+1));
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* LoadWindowPos
|
||||
*
|
||||
* retrieve the window position information from dragn.ini
|
||||
*
|
||||
\**************************************************************************/
|
||||
|
||||
#ifndef SPI_GETWORKAREA
|
||||
#define SPI_GETWORKAREA 48 // because NT doesnt have this define yet
|
||||
#endif
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
)
|
||||
{
|
||||
static RECT rcDefault = {0,0,CX_DEFAULT,CY_DEFAULT};
|
||||
RECT rcScreen;
|
||||
RECT rc;
|
||||
HKEY hKey = GetAppKey(FALSE);
|
||||
|
||||
// read window placement from the registry.
|
||||
//
|
||||
*lprc = rcDefault;
|
||||
if(hKey)
|
||||
{
|
||||
DWORD cb;
|
||||
DWORD dwType;
|
||||
|
||||
cb = sizeof(rc);
|
||||
if(! RegQueryValueEx(hKey, cszWindow, NULL, &dwType, (LPBYTE)&rc, &cb)
|
||||
&& dwType == REG_BINARY && cb == sizeof(RECT))
|
||||
{
|
||||
*lprc = rc;
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
// if we fail to get the working area (screen-tray), then assume
|
||||
// the screen is 640x480
|
||||
//
|
||||
if(! SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, FALSE))
|
||||
{
|
||||
rcScreen.top = rcScreen.left = 0;
|
||||
rcScreen.right = 640;
|
||||
rcScreen.bottom = 480;
|
||||
}
|
||||
|
||||
// if the proposed window position is outside the screen,
|
||||
// use the default placement
|
||||
//
|
||||
if(! IntersectRect(&rc, &rcScreen, lprc))
|
||||
{
|
||||
*lprc = rcDefault;
|
||||
}
|
||||
|
||||
return ! IsRectEmpty(lprc);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SaveWindowPos
|
||||
*
|
||||
* store the window position information in dragn.ini
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
WINDOWPLACEMENT wpl;
|
||||
HKEY hKey = GetAppKey(TRUE);
|
||||
|
||||
if(!hKey)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// save the current size and position of the window to the registry
|
||||
//
|
||||
ZeroMemory(&wpl, sizeof(wpl));
|
||||
wpl.length = sizeof(wpl);
|
||||
GetWindowPlacement(hwnd, &wpl);
|
||||
|
||||
|
||||
RegSetValueEx(hKey, cszWindow, 0, REG_BINARY,
|
||||
(LPBYTE)&wpl.rcNormalPosition,
|
||||
sizeof(wpl.rcNormalPosition));
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetRecentFiles
|
||||
*
|
||||
* Reads at most MAX_RECENT_FILES from vcdplyer.ini. Returns the number
|
||||
* of files actually read. Updates the File menu to show the "recent" files.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
GetRecentFiles(
|
||||
int iLastCount
|
||||
)
|
||||
{
|
||||
int i;
|
||||
TCHAR FileName[MAX_PATH];
|
||||
TCHAR szKey[32];
|
||||
HMENU hSubMenu;
|
||||
|
||||
//
|
||||
// Delete the files from the menu
|
||||
//
|
||||
hSubMenu = GetSubMenu(GetMenu(hwndApp), 0);
|
||||
|
||||
// Delete the separator at slot 2 and all the other recent file entries
|
||||
|
||||
if(iLastCount != 0)
|
||||
{
|
||||
DeleteMenu(hSubMenu, 2, MF_BYPOSITION);
|
||||
|
||||
for(i = 1; i <= iLastCount; i++)
|
||||
{
|
||||
DeleteMenu(hSubMenu, ID_RECENT_FILE_BASE + i, MF_BYCOMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(i = 1; i <= MAX_RECENT_FILES; i++)
|
||||
{
|
||||
DWORD len;
|
||||
TCHAR szMenuName[MAX_PATH + 3];
|
||||
|
||||
wsprintf(szKey, TEXT("File %d"), i);
|
||||
len = ProfileStringIn(szKey, TEXT(""), FileName, MAX_PATH * sizeof(TCHAR));
|
||||
if(len == 0)
|
||||
{
|
||||
i = i - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
lstrcpy(aRecentFiles[i - 1], FileName);
|
||||
wsprintf(szMenuName, TEXT("&%d %s"), i, FileName);
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
InsertMenu(hSubMenu, 2, MF_SEPARATOR | MF_BYPOSITION, (UINT)-1, NULL);
|
||||
}
|
||||
|
||||
InsertMenu(hSubMenu, 2 + i, MF_STRING | MF_BYPOSITION,
|
||||
ID_RECENT_FILE_BASE + i, szMenuName);
|
||||
}
|
||||
|
||||
//
|
||||
// i is the number of recent files in the array.
|
||||
//
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SetRecentFiles
|
||||
*
|
||||
* Writes the most recent files to the vcdplyer.ini file. Purges the oldest
|
||||
* file if necessary.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
SetRecentFiles(
|
||||
TCHAR *FileName, // File name to add
|
||||
int iCount // Current count of files
|
||||
)
|
||||
{
|
||||
TCHAR FullPathFileName[MAX_PATH];
|
||||
TCHAR *lpFile;
|
||||
TCHAR szKey[32];
|
||||
int iCountNew;
|
||||
int i;
|
||||
|
||||
//
|
||||
// Check for dupes - we don't allow them !
|
||||
//
|
||||
for(i = 0; i < iCount; i++)
|
||||
{
|
||||
if(0 == lstrcmpi(FileName, aRecentFiles[i]))
|
||||
{
|
||||
return iCount;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Throw away the oldest entry
|
||||
//
|
||||
MoveMemory(&aRecentFiles[1], &aRecentFiles[0],
|
||||
sizeof(aRecentFiles) - sizeof(aRecentFiles[1]));
|
||||
|
||||
//
|
||||
// Copy in the full path of the new file.
|
||||
//
|
||||
GetFullPathName(FileName, MAX_PATH, FullPathFileName, &lpFile);
|
||||
lstrcpy(aRecentFiles[0], FullPathFileName);
|
||||
|
||||
//
|
||||
// Update the count of files, saturate to MAX_RECENT_FILES.
|
||||
//
|
||||
iCountNew = min(iCount + 1, MAX_RECENT_FILES);
|
||||
|
||||
//
|
||||
// Clear the old stuff and the write out the recent files to disk
|
||||
//
|
||||
for(i = 1; i <= iCountNew; i++)
|
||||
{
|
||||
wsprintf(szKey, TEXT("File %d"), i);
|
||||
ProfileStringOut(szKey, aRecentFiles[i - 1]);
|
||||
}
|
||||
|
||||
//
|
||||
// Update the file menu
|
||||
//
|
||||
GetRecentFiles(iCount);
|
||||
|
||||
return iCountNew; // the updated count of files.
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: project.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for TxtPlayer sample
|
||||
// Master header file that includes all the other header files used by the
|
||||
// project. This enables compiled headers to work using build.
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "app.h"
|
||||
#include "vcdplyer.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <strmif.h>
|
||||
#include <uuids.h>
|
||||
@@ -0,0 +1,15 @@
|
||||
Windows XP DirectShow Sample -- TxtPlayer
|
||||
-----------------------------------------
|
||||
|
||||
This sample demonstrates using the Video Mixing Renderer and
|
||||
a custom allocator-presenter to render alpha-blended text over
|
||||
a running video.
|
||||
|
||||
NOTE: This sample requires Windows XP (or greater) functionality
|
||||
and will exit on other systems.
|
||||
|
||||
Usage:
|
||||
TxtPlayer </P filename>
|
||||
|
||||
/P: Optional filename to automatically render and play at startup
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: resource.h
|
||||
//
|
||||
// Desc: DirectShow sample code - resource header file for TxtPlayer sample
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// These are indexes used by the toolbar.
|
||||
//
|
||||
#define IDC_STATIC -1
|
||||
|
||||
#define IDX_SEPARATOR -1
|
||||
#define IDX_1 0
|
||||
#define IDX_2 1
|
||||
#define IDX_3 2
|
||||
#define IDX_4 3
|
||||
#define IDX_5 4
|
||||
#define IDX_6 5
|
||||
#define IDX_7 6
|
||||
#define IDX_8 7
|
||||
#define IDX_9 8
|
||||
#define IDX_10 9
|
||||
#define IDX_11 10
|
||||
#define IDX_12 11
|
||||
|
||||
#define DEFAULT_TBAR_SIZE 10
|
||||
#define NUMBER_OF_BITMAPS 12
|
||||
|
||||
#define ID_STATUSBAR 8
|
||||
#define ID_TOOLBAR 9
|
||||
#define ID_TRACKBAR 10
|
||||
|
||||
// Dialogs
|
||||
#define IDD_ABOUTBOX 200
|
||||
|
||||
#define IDR_MAIN_MENU 101
|
||||
#define IDR_TOOLBAR 102
|
||||
#define IDR_VIDEOCD_ICON 103
|
||||
#define IDR_ACCELERATOR 104
|
||||
|
||||
#define IDM_FILE_OPEN 40001
|
||||
#define IDM_FILE_CLOSE 40002
|
||||
#define IDM_FILE_EXIT 40003
|
||||
|
||||
#define IDM_HELP_ABOUT 40102
|
||||
|
||||
// Different time formats
|
||||
#define IDM_TIME 40150
|
||||
#define IDM_FRAME 40151
|
||||
#define IDM_FIELD 40152
|
||||
#define IDM_SAMPLE 40153
|
||||
#define IDM_BYTES 40154
|
||||
|
||||
// Toolbar commands
|
||||
#define IDM_MOVIE_STOP 40010
|
||||
#define IDM_MOVIE_PLAY 40011
|
||||
#define IDM_MOVIE_PREVTRACK 40012
|
||||
#define IDM_MOVIE_PAUSE 40013
|
||||
#define IDM_MOVIE_SKIP_FORE 40014
|
||||
#define IDM_MOVIE_SKIP_BACK 40015
|
||||
#define IDM_FULL_SCREEN 40017
|
||||
#define IDM_MOVIE_STEP 40019
|
||||
|
||||
|
||||
#define MENU_STRING_BASE 1000
|
||||
|
||||
// File
|
||||
#define STR_FILE_OPEN IDM_FILE_OPEN + MENU_STRING_BASE
|
||||
#define STR_FILE_CLOSE IDM_FILE_CLOSE + MENU_STRING_BASE
|
||||
#define STR_FILE_EXIT IDM_FILE_EXIT + MENU_STRING_BASE
|
||||
|
||||
// Help Menu HELP_MENU_BASE
|
||||
#define STR_HELP_ABOUT IDM_HELP_ABOUT + MENU_STRING_BASE
|
||||
|
||||
// System Menu
|
||||
#define STR_SYSMENU_RESTORE 1800
|
||||
#define STR_SYSMENU_MOVE 1801
|
||||
#define STR_SYSMENU_MINIMIZE 1802
|
||||
#define STR_SYSMENU_CLOSE 1803
|
||||
#define STR_SYSMENU_MAXIMIZE 1804
|
||||
#define STR_SYSMENU_TASK_LIST 1805
|
||||
|
||||
#define STR_FILE_FILTER 2000
|
||||
#define STR_APP_TITLE 2001
|
||||
#define STR_APP_TITLE_LOADED 2002
|
||||
|
||||
|
||||
#define MPEG_CODEC_BASE 4000
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by TxtPlayer.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,944 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - VMR-enabled player app with text
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
#include <atlbase.h>
|
||||
|
||||
#include "project.h"
|
||||
#include "mpgcodec.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern int FrameStepCount;
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CMpegMovie
|
||||
*
|
||||
* Constructors and destructors
|
||||
*
|
||||
\**************************************************************************/
|
||||
CMpegMovie::CMpegMovie(HWND hwndApplication)
|
||||
: CUnknown(NAME("Allocator Presenter"), NULL),
|
||||
m_hwndApp(hwndApplication),
|
||||
m_MediaEvent(NULL),
|
||||
m_Mode(MOVIE_NOTOPENED),
|
||||
m_Fg(NULL),
|
||||
m_Gb(NULL),
|
||||
m_Mc(NULL),
|
||||
m_Ms(NULL),
|
||||
m_Me(NULL),
|
||||
m_Wc(NULL),
|
||||
m_SAN(NULL),
|
||||
m_bRndLess(TRUE),
|
||||
pMpegAudioDecoder(NULL),
|
||||
pVideoRenderer(NULL),
|
||||
m_TimeFormat(TIME_FORMAT_MEDIA_TIME),
|
||||
m_hFont(NULL),
|
||||
m_cxFont(0), m_cxFontImg(0),
|
||||
m_cyFont(0), m_cyFontImg(0),
|
||||
m_lpDDSFontCache(NULL)
|
||||
{
|
||||
m_hMonitor = NULL;
|
||||
m_lpDDObj = NULL;
|
||||
m_lpPriSurf = NULL;
|
||||
m_lpBackBuffer = NULL;
|
||||
m_lpDDTexture = NULL;
|
||||
|
||||
AddRef();
|
||||
}
|
||||
CMpegMovie::~CMpegMovie()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static HRESULT SetRenderingMode( IBaseFilter* pBaseFilter, VMRMode mode )
|
||||
{
|
||||
// Test VMRConfig, VMRMonitorConfig
|
||||
IVMRFilterConfig* pConfig;
|
||||
HRESULT hr = pBaseFilter->QueryInterface(IID_IVMRFilterConfig, (LPVOID *)&pConfig);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
pConfig->SetRenderingMode(mode);
|
||||
pConfig->SetRenderingPrefs(RenderPrefs_AllowOverlays);
|
||||
pConfig->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AddVideoMixingRendererToFG
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::AddVideoMixingRendererToFG()
|
||||
{
|
||||
IBaseFilter* pBF = NULL;
|
||||
HRESULT hRes = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = m_Fg->AddFilter(pBF, L"Video Mixing Renderer");
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
if(m_bRndLess)
|
||||
{
|
||||
hRes = SetRenderingMode(pBF, VMRMode_Renderless);
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = pBF->QueryInterface(IID_IVMRSurfaceAllocatorNotify,
|
||||
(LPVOID *)&m_SAN);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = m_SAN->AdviseSurfaceAllocator(0, this);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = m_SAN->SetDDrawDevice(m_lpDDObj, m_hMonitor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hRes = SetRenderingMode(pBF, VMRMode_Windowless);
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = pBF->QueryInterface(IID_IVMRWindowlessControl, (LPVOID *)&m_Wc);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
m_Wc->SetVideoClippingWindow(m_hwndApp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_Wc)
|
||||
{
|
||||
m_Wc->Release();
|
||||
m_Wc = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pBF)
|
||||
{
|
||||
pBF->Release();
|
||||
}
|
||||
|
||||
if(FAILED(hRes))
|
||||
{
|
||||
if(m_SAN)
|
||||
{
|
||||
m_SAN->Release();
|
||||
m_SAN = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return hRes;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* OpenMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::OpenMovie(
|
||||
TCHAR *lpFileName
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
IUnknown *pUnk;
|
||||
HRESULT hres;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
wcscpy(FileName, T2W(lpFileName));
|
||||
|
||||
hres = CoInitialize(NULL);
|
||||
if(hres == S_FALSE)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
Initialize3DEnvironment(m_hwndApp);
|
||||
|
||||
hres = CoCreateInstance(
|
||||
CLSID_FilterGraph,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IUnknown,
|
||||
(LPVOID *)&pUnk);
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
m_Mode = MOVIE_OPENED;
|
||||
hres = pUnk->QueryInterface(IID_IFilterGraph, (LPVOID *)&m_Fg);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = AddVideoMixingRendererToFG();
|
||||
if(FAILED(hres))
|
||||
{
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = pUnk->QueryInterface(IID_IGraphBuilder, (LPVOID *)&m_Gb);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = m_Gb->RenderFile(FileName, NULL);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
if(m_Wc)
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
m_Gb->Release(); m_Gb = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = pUnk->QueryInterface(IID_IMediaControl, (LPVOID *)&m_Mc);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
m_Gb->Release(); m_Gb = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
//
|
||||
// Not being able to get the IMediaEvent interface does not
|
||||
// necessarly mean that we can't play the graph.
|
||||
//
|
||||
pUnk->QueryInterface(IID_IMediaEvent, (LPVOID *)&m_Me);
|
||||
pUnk->QueryInterface(IID_IMediaSeeking, (LPVOID *)&m_Ms);
|
||||
|
||||
GetMovieEventHandle();
|
||||
GetPerformanceInterfaces();
|
||||
|
||||
pUnk->Release();
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Fg = NULL;
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CloseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
DWORD
|
||||
CMpegMovie::CloseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_NOTOPENED;
|
||||
|
||||
if(m_Mc)
|
||||
{
|
||||
if(pMpegAudioDecoder)
|
||||
{
|
||||
pMpegAudioDecoder->Release();
|
||||
pMpegAudioDecoder = NULL;
|
||||
}
|
||||
|
||||
if(pVideoRenderer)
|
||||
{
|
||||
pVideoRenderer->Release();
|
||||
pVideoRenderer = NULL;
|
||||
}
|
||||
|
||||
if(m_Me)
|
||||
{
|
||||
m_MediaEvent = NULL;
|
||||
m_Me->Release();
|
||||
m_Me = NULL;
|
||||
}
|
||||
|
||||
if(m_Ms)
|
||||
{
|
||||
m_Ms->Release();
|
||||
m_Ms = NULL;
|
||||
}
|
||||
|
||||
if(m_Wc)
|
||||
{
|
||||
m_Wc->Release();
|
||||
m_Wc = NULL;
|
||||
}
|
||||
|
||||
m_Mc->Release();
|
||||
m_Mc = NULL;
|
||||
|
||||
if(m_SAN)
|
||||
{
|
||||
m_SAN->Release();
|
||||
m_SAN = NULL;
|
||||
}
|
||||
|
||||
if(m_Gb)
|
||||
{
|
||||
m_Gb->Release();
|
||||
m_Gb = NULL;
|
||||
}
|
||||
|
||||
if(m_Fg)
|
||||
{
|
||||
m_Fg->Release();
|
||||
m_Fg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
delete m_lpBltAlpha;
|
||||
|
||||
RELEASE(m_lpDDObj);
|
||||
RELEASE(m_lpPriSurf);
|
||||
RELEASE(m_lpBackBuffer);
|
||||
RELEASE(m_lpDDTexture);
|
||||
RELEASE(m_lpDDAppImage);
|
||||
|
||||
if(m_hFont)
|
||||
{
|
||||
DeleteObject(m_hFont);
|
||||
m_hFont = NULL;
|
||||
}
|
||||
|
||||
RELEASE(m_lpDDSFontCache);
|
||||
|
||||
QzUninitialize();
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CMpegMovie::GetNativeMovieSize
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::GetNativeMovieSize(
|
||||
LONG *pcx,
|
||||
LONG *pcy
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
if(m_Wc)
|
||||
{
|
||||
bRet = (m_Wc->GetNativeVideoSize(pcx, pcy, NULL, NULL) == S_OK);
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMoviePosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::GetMoviePosition(
|
||||
LONG *px,
|
||||
LONG *py,
|
||||
LONG *pcx,
|
||||
LONG *pcy
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
if(m_Wc)
|
||||
{
|
||||
RECT src={0}, dest={0};
|
||||
HRESULT hr = m_Wc->GetVideoPosition(&src, &dest);
|
||||
*px = dest.left;
|
||||
*py = dest.right;
|
||||
*pcx = dest.right - dest.left;
|
||||
*pcy = dest.bottom - dest.top;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PutMoviePosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PutMoviePosition(
|
||||
LONG x,
|
||||
LONG y,
|
||||
LONG cx,
|
||||
LONG cy
|
||||
)
|
||||
{
|
||||
BOOL bRet = TRUE;
|
||||
|
||||
RECT rc;
|
||||
SetRect(&rc, x, y, x + cx, y + cy);
|
||||
|
||||
if(m_bRndLess)
|
||||
{
|
||||
CAutoLock Lock(&m_AppImageLock);
|
||||
MapWindowRect(m_hwndApp, HWND_DESKTOP, &rc);
|
||||
m_rcDst = rc;
|
||||
CreateFontCache(HEIGHT(&m_rcDst) / GRID_CY);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_Wc)
|
||||
{
|
||||
bRet = (m_Wc->SetVideoPosition(NULL, &rc) == S_OK);
|
||||
}
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PlayMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PlayMovie(
|
||||
)
|
||||
{
|
||||
REFTIME rt;
|
||||
REFTIME rtAbs;
|
||||
REFTIME rtDur;
|
||||
|
||||
rt = GetCurrentPosition();
|
||||
rtDur = GetDuration();
|
||||
|
||||
//
|
||||
// If we are near the end of the movie seek to the start, otherwise
|
||||
// stay where we are.
|
||||
//
|
||||
rtAbs = rt - rtDur;
|
||||
if(rtAbs < (REFTIME)0)
|
||||
{
|
||||
rtAbs = -rtAbs;
|
||||
}
|
||||
|
||||
if(rtAbs < (REFTIME)1)
|
||||
{
|
||||
SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// Change mode after setting m_Mode but before starting the graph
|
||||
//
|
||||
m_Mode = MOVIE_PLAYING;
|
||||
|
||||
//
|
||||
// Start playing from the begining of the movie
|
||||
//
|
||||
m_Mc->Run();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PauseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PauseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
m_Mc->Pause();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetStateMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
|
||||
OAFilterState
|
||||
CMpegMovie::GetStateMovie(
|
||||
)
|
||||
{
|
||||
OAFilterState State;
|
||||
m_Mc->GetState(INFINITE,&State);
|
||||
return State;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StopMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::StopMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
m_Mc->Stop();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StatusMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
EMpegMovieMode
|
||||
CMpegMovie::StatusMovie(
|
||||
)
|
||||
{
|
||||
if(m_Mc)
|
||||
{
|
||||
FILTER_STATE fs;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Mc->GetState(100, (OAFilterState *)&fs);
|
||||
|
||||
// Don't know what the state is so just stay at old state.
|
||||
if(hr == VFW_S_STATE_INTERMEDIATE)
|
||||
{
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
switch(fs)
|
||||
{
|
||||
case State_Stopped:
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
break;
|
||||
|
||||
case State_Paused:
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
break;
|
||||
|
||||
case State_Running:
|
||||
m_Mode = MOVIE_PLAYING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CanMovieFrameStep
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::CanMovieFrameStep()
|
||||
{
|
||||
IVideoFrameStep* lpFS;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Fg->QueryInterface(__uuidof(IVideoFrameStep), (LPVOID *)&lpFS);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = lpFS->CanStep(0L, NULL);
|
||||
lpFS->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* FrameStepMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::FrameStepMovie()
|
||||
{
|
||||
IVideoFrameStep* lpFS;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Fg->QueryInterface(__uuidof(IVideoFrameStep), (LPVOID *)&lpFS);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
FrameStepCount++;
|
||||
|
||||
hr = lpFS->Step(1, NULL);
|
||||
lpFS->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMediaEventHandle
|
||||
*
|
||||
* Returns the IMediaEvent event hamdle for the filter graph iff the
|
||||
* filter graph exists.
|
||||
*
|
||||
\**************************************************************************/
|
||||
HANDLE
|
||||
CMpegMovie::GetMovieEventHandle(
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if(m_Me != NULL)
|
||||
{
|
||||
if(m_MediaEvent == NULL)
|
||||
{
|
||||
hr = m_Me->GetEventHandle((OAEVENT *)&m_MediaEvent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MediaEvent = NULL;
|
||||
}
|
||||
|
||||
return m_MediaEvent;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMovieEventCode
|
||||
*
|
||||
\**************************************************************************/
|
||||
long
|
||||
CMpegMovie::GetMovieEventCode()
|
||||
{
|
||||
HRESULT hr;
|
||||
long lEventCode;
|
||||
LONG_PTR lParam1, lParam2;
|
||||
|
||||
if(m_Me != NULL)
|
||||
{
|
||||
hr = m_Me->GetEvent(&lEventCode, &lParam1, &lParam2, 0);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = m_Me->FreeEventParams(lEventCode, lParam1, lParam2);
|
||||
return lEventCode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetDuration
|
||||
*
|
||||
* Returns the duration of the current movie
|
||||
*
|
||||
\**************************************************************************/
|
||||
REFTIME
|
||||
CMpegMovie::GetDuration()
|
||||
{
|
||||
HRESULT hr;
|
||||
LONGLONG Duration;
|
||||
|
||||
if(m_TimeFormat != TIME_FORMAT_MEDIA_TIME)
|
||||
{
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Duration);
|
||||
}
|
||||
}
|
||||
else if(m_Ms != NULL)
|
||||
{
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Duration) / UNITS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetCurrentPosition
|
||||
*
|
||||
* Returns the duration of the current movie
|
||||
*
|
||||
\**************************************************************************/
|
||||
REFTIME
|
||||
CMpegMovie::GetCurrentPosition()
|
||||
{
|
||||
REFTIME rt = (REFTIME)0;
|
||||
HRESULT hr;
|
||||
LONGLONG Position;
|
||||
|
||||
// Should we return a media position
|
||||
|
||||
if(m_TimeFormat != TIME_FORMAT_MEDIA_TIME)
|
||||
{
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Position);
|
||||
}
|
||||
}
|
||||
else if(m_Ms != NULL)
|
||||
{
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Position) / UNITS;
|
||||
}
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SeekToPosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SeekToPosition(
|
||||
REFTIME rt,
|
||||
BOOL bFlushData
|
||||
)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
LONGLONG llTime = LONGLONG(m_TimeFormat == TIME_FORMAT_MEDIA_TIME ? rt * double(UNITS) : rt );
|
||||
|
||||
if(m_Ms != NULL)
|
||||
{
|
||||
FILTER_STATE fs;
|
||||
m_Mc->GetState(100, (OAFilterState *)&fs);
|
||||
|
||||
hr = m_Ms->SetPositions(&llTime, AM_SEEKING_AbsolutePositioning, NULL, 0);
|
||||
|
||||
// This gets new data through to the renderers
|
||||
if(fs == State_Stopped && bFlushData)
|
||||
{
|
||||
m_Mc->Pause();
|
||||
hr = m_Mc->GetState(INFINITE, (OAFilterState *)&fs);
|
||||
m_Mc->Stop();
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetPerformanceInterfaces
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
CMpegMovie::GetPerformanceInterfaces(
|
||||
)
|
||||
{
|
||||
FindInterfaceFromFilterGraph(IID_IMpegAudioDecoder, (LPVOID *)&pMpegAudioDecoder);
|
||||
FindInterfaceFromFilterGraph(IID_IQualProp, (LPVOID *)&pVideoRenderer);
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
CMpegMovie::FindInterfaceFromFilterGraph(
|
||||
REFIID iid, // interface to look for
|
||||
LPVOID *lp // place to return interface pointer in
|
||||
)
|
||||
{
|
||||
IEnumFilters* pEF;
|
||||
IBaseFilter* pFilter;
|
||||
|
||||
// Grab an enumerator for the filter graph.
|
||||
HRESULT hr = m_Fg->EnumFilters(&pEF);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Check out each filter.
|
||||
while(pEF->Next(1, &pFilter, NULL) == S_OK)
|
||||
{
|
||||
hr = pFilter->QueryInterface(iid, lp);
|
||||
pFilter->Release();
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pEF->Release();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* IsTimeFormatSupported
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::IsTimeFormatSupported(GUID Format)
|
||||
{
|
||||
return m_Ms != NULL && m_Ms->IsFormatSupported(&Format) == S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* IsTimeSupported
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::IsTimeSupported()
|
||||
{
|
||||
return m_Ms != NULL && m_Ms->IsFormatSupported(&TIME_FORMAT_MEDIA_TIME) == S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* GetTimeFormat
|
||||
*
|
||||
\**************************************************************************/
|
||||
GUID
|
||||
CMpegMovie::GetTimeFormat()
|
||||
{
|
||||
return m_TimeFormat;
|
||||
}
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* SetTimeFormat
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SetTimeFormat(GUID Format)
|
||||
{
|
||||
HRESULT hr = m_Ms->SetTimeFormat(&Format);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
m_TimeFormat = Format;
|
||||
}
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetFocus
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
CMpegMovie::SetFocus()
|
||||
{
|
||||
if(m_Fg)
|
||||
{
|
||||
// Tell the resource manager that we are being made active. This
|
||||
// will then cause the sound to switch to us. This is especially
|
||||
// important when playing audio only files as there is no other
|
||||
// playback window.
|
||||
IResourceManager* pResourceManager;
|
||||
|
||||
HRESULT hr = m_Fg->QueryInterface(IID_IResourceManager, (void**)&pResourceManager);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
IUnknown* pUnknown;
|
||||
|
||||
hr = m_Fg->QueryInterface(IID_IUnknown, (void**)&pUnknown);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
pResourceManager->SetFocus(pUnknown);
|
||||
pUnknown->Release();
|
||||
}
|
||||
|
||||
pResourceManager->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RepaintVideo
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::RepaintVideo(
|
||||
HWND hwnd,
|
||||
HDC hdc
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
if(m_Wc)
|
||||
{
|
||||
bRet = (m_Wc->RepaintVideo(hwnd, hdc) == S_OK);
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VerifyVMR
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL VerifyVMR(void)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
// Verify that the VMR exists on this system
|
||||
IBaseFilter* pBF = NULL;
|
||||
hres = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
pBF->Release();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp,
|
||||
TEXT("This application requires the Video Mixing Renderer, which is present\r\n")
|
||||
TEXT("only on Windows XP.\r\n\r\n")
|
||||
TEXT("The Video Mixing Renderer (VMR) is also not enabled when viewing a \r\n")
|
||||
TEXT("remote Windows XP machine through a Remote Desktop session.\r\n")
|
||||
TEXT("You can run VMR-enabled applications only on your local machine.")
|
||||
TEXT("\r\n\r\nThis sample will now exit."),
|
||||
TEXT("Video Mixing Renderer capabilities are required"), MB_OK);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for TxtPlayer sample
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#define D3D_OVERLOADS
|
||||
#include <d3d.h>
|
||||
#include "BltAlpha.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** CMpegMovie - an Mpeg movie playback class.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
enum EMpegMovieMode { MOVIE_NOTOPENED = 0x00,
|
||||
MOVIE_OPENED = 0x01,
|
||||
MOVIE_PLAYING = 0x02,
|
||||
MOVIE_STOPPED = 0x03,
|
||||
MOVIE_PAUSED = 0x04 };
|
||||
|
||||
#define GRID_CY 24
|
||||
#define GRID_CX 40
|
||||
|
||||
struct IMpegAudioDecoder;
|
||||
struct IMpegVideoDecoder;
|
||||
struct IQualProp;
|
||||
|
||||
typedef struct {
|
||||
BITMAPINFOHEADER bmiHeader;
|
||||
union {
|
||||
RGBQUAD bmiColors[iPALETTE_COLORS];
|
||||
DWORD dwBitMasks[iMASK_COLORS];
|
||||
TRUECOLORINFO TrueColorInfo;
|
||||
};
|
||||
} AMDISPLAYINFO;
|
||||
|
||||
#define NUM_CUBE_VERTICES (4*6)
|
||||
|
||||
BOOL VerifyVMR(void);
|
||||
|
||||
|
||||
class CMpegMovie :
|
||||
public CUnknown,
|
||||
public IVMRSurfaceAllocator,
|
||||
public IVMRImagePresenter
|
||||
{
|
||||
private:
|
||||
// Our state variable - records whether we are opened, playing etc.
|
||||
EMpegMovieMode m_Mode;
|
||||
HANDLE m_MediaEvent;
|
||||
HWND m_hwndApp;
|
||||
GUID m_TimeFormat;
|
||||
|
||||
RECT m_rcSrc;
|
||||
RECT m_rcDst;
|
||||
SIZE m_VideoSize;
|
||||
SIZE m_VideoAR;
|
||||
|
||||
HRESULT Initialize3DEnvironment(HWND hwndApp);
|
||||
HRESULT InitDeviceObjects(LPDIRECT3DDEVICE7 pd3dDevice);
|
||||
HRESULT FrameMove(LPDIRECT3DDEVICE7 pd3dDevice,FLOAT fTimeKey);
|
||||
HRESULT Render(LPDIRECT3DDEVICE7 pd3dDevice, LPDIRECTDRAWSURFACE7 pDDSBlend, BYTE alpha);
|
||||
HRESULT RenderAppImage(LPDIRECT3DDEVICE7 pd3dDevice, LPDIRECTDRAWSURFACE7 pDDSBlend, BYTE alpha);
|
||||
HRESULT AllocateSurfaceWorker(DWORD dwFlags,
|
||||
LPBITMAPINFOHEADER lpHdr,
|
||||
LPDDPIXELFORMAT lpPixFmt,
|
||||
LPSIZE lpAspectRatio,
|
||||
DWORD dwMinBackBuffers,
|
||||
DWORD dwMaxBackBuffers,
|
||||
DWORD* lpdwBackBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface);
|
||||
HRESULT DDARGB32SurfaceInit(
|
||||
LPDIRECTDRAWSURFACE7* lplpDDS,
|
||||
BOOL bTexture, DWORD cx, DWORD cy);
|
||||
|
||||
|
||||
HRESULT CreateFontCache(int cyFont);
|
||||
CCritSec m_AppImageLock;
|
||||
HFONT m_hFont;
|
||||
int m_cxFont;
|
||||
int m_cyFont;
|
||||
int m_cxFontImg;
|
||||
int m_cyFontImg;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDSFontCache;
|
||||
|
||||
HMONITOR m_hMonitor;
|
||||
LPDIRECTDRAW7 m_lpDDObj;
|
||||
CAlphaBlt* m_lpBltAlpha;
|
||||
|
||||
LPDIRECTDRAWSURFACE7 m_lpPriSurf;
|
||||
LPDIRECTDRAWSURFACE7 m_lpBackBuffer;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDTexture;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDAppImage;
|
||||
D3DVERTEX m_pCubeVertices[NUM_CUBE_VERTICES];
|
||||
DDCAPS m_ddHWCaps;
|
||||
AMDISPLAYINFO m_DispInfo;
|
||||
BOOL m_bRndLess;
|
||||
|
||||
IFilterGraph *m_Fg;
|
||||
IGraphBuilder *m_Gb;
|
||||
IMediaControl *m_Mc;
|
||||
IMediaSeeking *m_Ms;
|
||||
IMediaEvent *m_Me;
|
||||
IVMRSurfaceAllocatorNotify *m_SAN;
|
||||
IVMRWindowlessControl *m_Wc;
|
||||
|
||||
HRESULT AddVideoMixingRendererToFG();
|
||||
void GetPerformanceInterfaces();
|
||||
HRESULT FindInterfaceFromFilterGraph(
|
||||
REFIID iid, // interface to look for
|
||||
LPVOID *lp // place to return interface pointer in
|
||||
);
|
||||
|
||||
public:
|
||||
CMpegMovie(HWND hwndApplication);
|
||||
~CMpegMovie();
|
||||
|
||||
DECLARE_IUNKNOWN
|
||||
STDMETHODIMP NonDelegatingQueryInterface(REFIID, void**);
|
||||
|
||||
// IVMRSurfaceAllocator
|
||||
STDMETHODIMP AllocateSurface(DWORD_PTR w,
|
||||
VMRALLOCATIONINFO *lpAllocInfo,
|
||||
DWORD* lpdwActualBackBuffers,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface);
|
||||
STDMETHODIMP FreeSurface(DWORD_PTR w);
|
||||
STDMETHODIMP PrepareSurface(DWORD_PTR w, LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags);
|
||||
STDMETHODIMP AdviseNotify(IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify);
|
||||
|
||||
|
||||
// IVMRImagePresenter
|
||||
STDMETHODIMP StartPresenting(DWORD_PTR w);
|
||||
STDMETHODIMP StopPresenting(DWORD_PTR w);
|
||||
STDMETHODIMP PresentImage(DWORD_PTR w, VMRPRESENTATIONINFO* p);
|
||||
|
||||
HRESULT OpenMovie(TCHAR *lpFileName);
|
||||
DWORD CloseMovie();
|
||||
BOOL PlayMovie();
|
||||
BOOL PauseMovie();
|
||||
BOOL StopMovie();
|
||||
OAFilterState GetStateMovie();
|
||||
HANDLE GetMovieEventHandle();
|
||||
long GetMovieEventCode();
|
||||
BOOL PutMoviePosition(LONG x, LONG y, LONG cx, LONG cy);
|
||||
BOOL GetMoviePosition(LONG *x, LONG *y, LONG *cx, LONG *cy);
|
||||
BOOL GetNativeMovieSize(LONG *cx, LONG *cy);
|
||||
BOOL CanMovieFrameStep();
|
||||
BOOL FrameStepMovie();
|
||||
REFTIME GetDuration();
|
||||
REFTIME GetCurrentPosition();
|
||||
BOOL SeekToPosition(REFTIME rt,BOOL bFlushData);
|
||||
EMpegMovieMode StatusMovie();
|
||||
BOOL IsTimeFormatSupported(GUID Format);
|
||||
BOOL IsTimeSupported();
|
||||
BOOL SetTimeFormat(GUID Format);
|
||||
GUID GetTimeFormat();
|
||||
void SetFocus();
|
||||
BOOL ConfigDialog(HWND hwnd);
|
||||
BOOL RepaintVideo(HWND hwnd, HDC hdc);
|
||||
BOOL SetAppText(char* sz);
|
||||
|
||||
LPDIRECTDRAWSURFACE7 GetAppImage() {
|
||||
return m_lpDDAppImage;
|
||||
}
|
||||
|
||||
|
||||
IMpegAudioDecoder *pMpegAudioDecoder;
|
||||
IQualProp *pVideoRenderer;
|
||||
};
|
||||
|
||||
119
Library/dxx8/samples/Multimedia/DirectShow_WinXP/VMR/VMR.dsw
Normal file
@@ -0,0 +1,119 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "BaseClasses"=..\..\DirectShow\BaseClasses\baseclasses.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Cube"=.\Cube\Cube.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name BaseClasses
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "RenderLess"=.\Renderless\RenderLess.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name BaseClasses
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "TxtPlayer"=.\TxtPlayer\TxtPlayer.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name BaseClasses
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "VMRMix"=.\VMRMix\VMRMix.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name BaseClasses
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "VMRPlayer"=.\VMRPlayer\VMRPlayer.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name BaseClasses
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "VMRXcl"=.\VMRXcl\VMRXcl.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name BaseClasses
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Demonstration.CPP
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of CDemonstration,
|
||||
// "special effects" module to represent capabilities of VMR.
|
||||
// This class is called from CVMRMixDlg by "Play" button.
|
||||
// CDemonstration contains CVMRCore member (VMR engine) through which
|
||||
// it performs initialization of the graph builder and presentation.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Demonstration.h"
|
||||
#include <math.h>
|
||||
|
||||
#define DO_NOT_RUN_YET true
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Perform
|
||||
// Desc: Performs presentation. Just call it from the 'parent' dialog
|
||||
// Return HRESULT
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CDemonstration::Perform()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
clock_t tStart;
|
||||
clock_t tCurrent;
|
||||
clock_t tUpdate;
|
||||
|
||||
if( false == m_bInitialized )
|
||||
{
|
||||
hr = Initialize();
|
||||
}
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
hr = m_pCore->Play();
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
sprintf( m_szMsg, "Failed to run VMR, method returned %s\n", hresultNameLookup(hr));
|
||||
OutputDebugString(m_szMsg);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
OutputDebugString("Unhandled exception in CDemonstration::Perform()\n");
|
||||
ShellAbort(m_pCore);
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
tStart = clock();
|
||||
tCurrent = clock();
|
||||
tUpdate = clock();
|
||||
|
||||
|
||||
// presentation loop: wait until presentation is over
|
||||
// or user closed the window and VMRCore is inactive
|
||||
while( (tCurrent - tStart) / CLOCKS_PER_SEC < m_MList.GetAvgDuration() / 10000000L &&
|
||||
m_pCore->IsActive() )
|
||||
{
|
||||
Sleep(10);
|
||||
UpdateStreams(tStart);
|
||||
tCurrent = clock();
|
||||
}// while
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Initialize()
|
||||
// Desc: Initializes demonstration; fills start parameters,
|
||||
// creates the graph for VMR; renders files
|
||||
// Return: HRESULT
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CDemonstration::Initialize()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
LONGLONG llCurrent = 0L;
|
||||
LONGLONG llStop = 0L;
|
||||
LONGLONG llDelay = 0L;
|
||||
clock_t tStart;
|
||||
|
||||
// calculate playback time
|
||||
m_MList.AdjustDuration();
|
||||
|
||||
m_MList.SetInitialParameters();
|
||||
|
||||
// create VMRCore
|
||||
m_pCore = new CVMRCore(m_pDlg, &m_MList );
|
||||
|
||||
tStart = clock();
|
||||
|
||||
if( !m_pCore)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// here, VMRCore creates the graph and if successfully, runs IMediaControl
|
||||
// for the first file from the media list
|
||||
hr = m_pCore->Play(DO_NOT_RUN_YET);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
// if user selected "show bitmap" option, load the bitmap
|
||||
// from the resource and apply color key
|
||||
if( m_pDlg->IsBitmapToUse())
|
||||
{
|
||||
hr = SetAlphaBitmapColorKey(IDB_BITMAP_LOGO);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Failed to SetAlphaBitmapColorKey() in CDemonstration::Initialize()\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
m_bInitialized = true;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// SetAlphaBitmapColorKey
|
||||
// Desc: initializes proper members of VMRALPHABITMAP for solor key support
|
||||
// Parameters: [in] UINT ImageID - resource ID
|
||||
// Return: HRESULT
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CDemonstration::SetAlphaBitmapColorKey(UINT ImageID)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if( ! m_pCore )
|
||||
{
|
||||
OutputDebugString("Function SetAlphaBitmapColorKey() is called before initializing m_pCore\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
// prepare the valid default bitmap
|
||||
if (GetValidVMRBitmap(ImageID) != FNS_PASS)
|
||||
{
|
||||
OutputDebugString("Unable to get a valid VMRALPHABITMAP\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
m_sBmpParams.fAlpha = 1.0f;
|
||||
m_sBmpParams.clrSrcKey = RGB(255,255,255);
|
||||
m_sBmpParams.dwFlags |= VMRBITMAP_SRCCOLORKEY;
|
||||
|
||||
try
|
||||
{
|
||||
hr = m_pCore->GetMixerBitmap()->SetAlphaBitmap(&m_sBmpParams);
|
||||
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
} // try
|
||||
catch(...)
|
||||
{
|
||||
return ShellAbort(m_pCore);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// GetValidVMRBitmap
|
||||
// Desc: creates bitmap compatible with VMR
|
||||
// Parameters: [in] UINT ImageID - resource ID
|
||||
// [out] VMRALPHABITMAP * vmrBmp - what IVMRMixerBitmap uses
|
||||
// Return: HRESULT
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CDemonstration::GetValidVMRBitmap(UINT ImageID)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
long cx, cy;
|
||||
HDC hdc;
|
||||
HBITMAP hbmpVmr;
|
||||
BITMAP bmp;
|
||||
|
||||
hr = m_pCore->GetVMRWndless()->GetNativeVideoSize(&cx, &cy, NULL, NULL);
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
OutputDebugString("Failed in GetNativeVideoSize()\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
// get compatible DC
|
||||
hdc = GetDC(m_pCore->GetClientHwnd());
|
||||
|
||||
m_hbmp = CreateCompatibleBitmap(hdc, cx, cy); /*** RELEASE ***/
|
||||
|
||||
hbmpVmr = (HBITMAP)LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(ImageID),IMAGE_BITMAP,0,0,/*LR_LOADFROMFILE|*/LR_CREATEDIBSECTION);
|
||||
if( !hbmpVmr )
|
||||
{
|
||||
OutputDebugString("Failed to load resource\n");
|
||||
DeleteObject(m_hbmp);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Get size of the bitmap
|
||||
GetObject( hbmpVmr, sizeof(bmp), &bmp );
|
||||
|
||||
HDC hdcBmp = CreateCompatibleDC(hdc); /*** RELEASE ***/
|
||||
HDC hdcVMR = CreateCompatibleDC(hdc);
|
||||
|
||||
ReleaseDC(m_pCore->GetClientHwnd(), hdc);
|
||||
|
||||
HBITMAP hbmpold = (HBITMAP)SelectObject(hdcBmp, m_hbmp);// in hdcBmp, select hbmp
|
||||
hbmpVmr = (HBITMAP)SelectObject(hdcVMR, hbmpVmr);// in hdcVmr, select hbmpVmr (the pic we loaded)
|
||||
|
||||
BitBlt(hdcBmp, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcVMR, 0, 0, SRCPAINT);// put loaded pic from hdcVmr to hdcBmp
|
||||
DeleteObject(SelectObject(hdcVMR, hbmpVmr));// ok, we do not need hbmpVmr any more
|
||||
DeleteDC(hdcVMR);
|
||||
|
||||
RECT rc;
|
||||
|
||||
ZeroMemory(&m_sBmpParams, sizeof(VMRALPHABITMAP) );
|
||||
m_sBmpParams.dwFlags = VMRBITMAP_HDC;
|
||||
m_sBmpParams.hdc = hdcBmp;
|
||||
|
||||
// set source rectangle (entire original bitmap)
|
||||
SetRect(&rc, 0, 0, bmp.bmWidth, bmp.bmHeight);
|
||||
m_sBmpParams.rSrc = rc;
|
||||
|
||||
float fCoeff = 0.2f + 1.7f * (float)rand()/RAND_MAX;
|
||||
// set destination rectangle (keeping aspect ratio of the original image)
|
||||
// please note that normalized rect is always in [0.0, 1.0] range for
|
||||
// all its members
|
||||
m_sBmpParams.rDest.left = 0.f;
|
||||
m_sBmpParams.rDest.top = 0.f;
|
||||
m_sBmpParams.rDest.right = 0.9f*(float)bmp.bmWidth / (float)cx;
|
||||
m_sBmpParams.rDest.bottom = 0.9f*(float)bmp.bmHeight / (float)cy;
|
||||
m_sBmpParams.fAlpha = 0.5f;
|
||||
|
||||
// quite important, otherwise VMR would give error
|
||||
m_sBmpParams.pDDS = NULL;
|
||||
|
||||
// Note: this demo uses bitmap directly, but often it is better to create
|
||||
// DirectDrawSurface of appropriate format and set m_sBmpParams.pDDS to it
|
||||
// (especially if you experience performance issues)
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// UpdateStreams
|
||||
// Desc: updates presentation parameters (destination rectangles and alpha level)
|
||||
// for each media file
|
||||
// Parameters: clock_t tStart -- presentation start; used as a 'time' variable
|
||||
// in calculations
|
||||
// Return: HRESULT
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CDemonstration::UpdateStreams(clock_t tStart)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
int i;
|
||||
clock_t tCurrent;
|
||||
NORMALIZEDRECT rectD0;
|
||||
NORMALIZEDRECT rectD;
|
||||
NORMALIZEDRECT rectDRes;
|
||||
double Alpha0;
|
||||
double Alpha;
|
||||
|
||||
ASSERT( tStart >0 );
|
||||
|
||||
for( i=0; i< this->m_MList.Size(); i++)
|
||||
{
|
||||
if( false == m_MList.GetItem(i)->m_bInUse)
|
||||
continue;
|
||||
|
||||
tCurrent = clock() - tStart;
|
||||
|
||||
rectD0 = m_MList.GetItem(i)->m_rD;
|
||||
Alpha0 = m_MList.GetItem(i)->m_fAlpha;
|
||||
|
||||
Alpha = 1.f;
|
||||
rectD.left = rectD.top = 0.f;
|
||||
rectD.right = rectD.bottom = 1.f;
|
||||
|
||||
FountainPath( tCurrent,
|
||||
(long)(m_MList.GetAvgDuration() / 10000000 * CLOCKS_PER_SEC),
|
||||
i,
|
||||
rectD0,
|
||||
Alpha0,
|
||||
&rectD,
|
||||
&Alpha);
|
||||
|
||||
hr = m_pCore->GetMixerControl()->SetAlpha(i, (float)Alpha);
|
||||
if( !SUCCEEDED(hr))
|
||||
{
|
||||
sprintf( m_szMsg, "Failure in CDemonstration::UpdateStreams, GetMixerControl()->SetAlpha, method returned %s\n",
|
||||
hresultNameLookup(hr));
|
||||
OutputDebugString(m_szMsg);
|
||||
}
|
||||
hr = m_pCore->GetMixerControl()->SetOutputRect(i, &rectD);
|
||||
if( !SUCCEEDED(hr))
|
||||
{
|
||||
sprintf( m_szMsg, "Failure in CDemonstration::UpdateStreams, GetMixerControl()->SetOutputRect, method returned %s\n",
|
||||
hresultNameLookup(hr));
|
||||
OutputDebugString(m_szMsg);
|
||||
}
|
||||
|
||||
hr = m_pCore->GetMixerControl()->GetOutputRect(i, &rectDRes);
|
||||
if( !SUCCEEDED(hr))
|
||||
{
|
||||
sprintf( m_szMsg, "Failure in CDemonstration::UpdateStreams, GetMixerControl()->GetOutputRect, method returned %s\n",
|
||||
hresultNameLookup(hr));
|
||||
OutputDebugString(m_szMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( fabs(rectD.top - rectDRes.top) > 0.01 ||
|
||||
fabs(rectD.bottom - rectDRes.bottom) > 0.01 ||
|
||||
fabs(rectD.left - rectDRes.left) > 0.01 ||
|
||||
fabs(rectD.right - rectDRes.right) > 0.01 )
|
||||
{
|
||||
sprintf( m_szMsg, "Failed invalidation of SetOutputRect(): required [l,t,r,b] = [%f,%f,%f,%f] and returned [%f,%f,%f,%f]\n",
|
||||
rectD.left, rectD.top, rectD.right, rectD.bottom,
|
||||
rectDRes.left, rectDRes.top, rectDRes.right, rectDRes.bottom );
|
||||
OutputDebugString(m_szMsg);
|
||||
}
|
||||
}// else
|
||||
|
||||
}// for
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: FountainPath
|
||||
// Purpose: creates 'movie fountain' effect; for each stream, center point
|
||||
// moves by a random ellipse around the center of a playback window;
|
||||
// size and alpha-level of stream's output rect changes by cosine with
|
||||
// some random initial delay (to desynchronize streams)
|
||||
// Parameters:
|
||||
// [IN] long t - current timestamp (any units, we use relative time)
|
||||
// [IN] long T - expected total playback time (in the same units as t)
|
||||
// [IN] int n - id of particular stream we want to set
|
||||
// [IN] NORMALIZEDRECT r0 - original OutputRect of the stream
|
||||
// [IN] double A0 - original alpha level (used as a parameter for smoothly
|
||||
// changing alpha level)
|
||||
// [OUT] NORMALIZEDRECT * pR - dest. part of playback window
|
||||
// [OUT] double * pA - new alpha level
|
||||
//------------------------------------------------------------------------------
|
||||
void CDemonstration::FountainPath( long t,
|
||||
long T,
|
||||
int n,
|
||||
NORMALIZEDRECT r0,
|
||||
double A0,
|
||||
NORMALIZEDRECT * pR,
|
||||
double * pA)
|
||||
{
|
||||
double cx0; // original center of the output rect, in normalized coordinates
|
||||
double cy0;
|
||||
double cx; // new center of the output rect, in normalized coordinates
|
||||
double cy;
|
||||
double cx1; // auxiliary center of the output rect, in normalized coordinates
|
||||
double cy1;
|
||||
double L0; // original half-diagonal measure of the rectangle
|
||||
double w; // orig. rect width
|
||||
double h; // orig. rect height
|
||||
double beta; // shift in cosine for L(t). see below
|
||||
double L; // new half-diagonal measure of the rectangle
|
||||
double tau; // time in relative units
|
||||
double gamma; // shift in sine for A(t). see below
|
||||
double coeff; // coefficient that is used to create 'mirror-flip' effect
|
||||
double dx; // new half-width
|
||||
double dy; // new half-heights
|
||||
|
||||
// relative time, to have about 3 periods over the total playtime
|
||||
tau = 18.0 * (double)t / T;
|
||||
|
||||
// alpha level, A = 0.2 + 0.8 sin( tau + gamma) where gamma is such that A(0)=A0
|
||||
gamma = (A0 - 0.2)/0.8;
|
||||
gamma = (gamma < -1.) ? -1. : gamma;
|
||||
gamma = (gamma > 1. ) ? 1. : gamma;
|
||||
gamma = asin( gamma);
|
||||
*pA = 0.6 + 0.4 * sin(tau + gamma + A0);
|
||||
|
||||
cx0 = (r0.left + r0.right)/2.;
|
||||
cy0 = (r0.top + r0.bottom)/2.;
|
||||
w = r0.right - r0.left;
|
||||
h = r0.bottom - r0.top;
|
||||
L0 = 0.5 * sqrt(w*w + h*h);
|
||||
|
||||
L0 = (L0 < 0.0001) ? 0.1 : L0;
|
||||
// now rectangle. Its half-diagonal measure L = 0.1 + 0.7 cos( tau + beta)
|
||||
// where beta is such that L(0) = LO;
|
||||
beta = (L0 - 0.1)/0.7;
|
||||
beta = (beta < -1.) ? -1. : beta;
|
||||
beta = (beta > 1.) ? 1. : beta;
|
||||
beta = acos( beta);
|
||||
L = 0.35 + 0.45 * cos( tau + beta + 3.*A0);
|
||||
|
||||
// center of the rectangle is moving by ellips
|
||||
// cx = cx0 + (-1)^n 0.1 sin(tau);
|
||||
// cy = cy0 - 0.2 + 0.2 cos( tau);
|
||||
// and turn it buy... say, theta = 7.85 A0 - 1.57;
|
||||
coeff = (n%2) ? -1. : 1.;
|
||||
cx1 = cx0 + coeff * 0.2 * sin(tau + A0);
|
||||
cy1 = cy0 - 0.05 + 0.2 * cos( tau + A0);
|
||||
|
||||
// the lines below are unnecessary, but we could want some
|
||||
// additional transformation here, like turn trajectory ellipse
|
||||
// by some angle
|
||||
cx = cx1;
|
||||
cy = cy1;
|
||||
|
||||
dx = L * w / L0;
|
||||
dy = L * h / L0;
|
||||
|
||||
pR->left = (float)(cx - dx);
|
||||
pR->right = (float)(cx + dx);
|
||||
pR->top = (float)(cy - dy);
|
||||
pR->bottom = (float)(cy + dy);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Demonstration.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Header file and class description for CDemonstration,
|
||||
// "special effects" module to represent capabilities of VMR.
|
||||
// This class is called from CVMRMixDlg by the "Play" button.
|
||||
// CDemonstration contains CVMRCore member (VMR engine), through which
|
||||
// it performs initialization of the graph builder and presentation.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef HDR_DEMONSTRATION
|
||||
#define HDR_DEMONSTRATION
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
class CVMRMixDlg;
|
||||
|
||||
class CDemonstration
|
||||
{
|
||||
private:
|
||||
CVMRMixDlg * m_pDlg; // 'parent' dialog
|
||||
char m_szMsg[MAX_PATH]; // auxiliary string for debug messages
|
||||
bool m_bInitialized; // true if graph is build and files are rendered;
|
||||
// false otherwise
|
||||
CMediaList m_MList; // media list to be played
|
||||
CVMRCore * m_pCore; // 'main' class that implements VMR management
|
||||
VMRALPHABITMAP m_sBmpParams; // used in IVMRMixerBitmap; parameters
|
||||
// of the bitmap overlapping the video
|
||||
HBITMAP m_hbmp; // handle to the bitmap overlapping the video
|
||||
|
||||
HRESULT SetAlphaBitmapColorKey(UINT ImageID); // set color key for overlapping bitmap
|
||||
HRESULT GetValidVMRBitmap(UINT ImageID); // create bitmap compatible with renderer's settings
|
||||
|
||||
public:
|
||||
CDemonstration( CVMRMixDlg * pDlg, // 'parent' dialog
|
||||
CMediaList * pMajorList,// media list to play
|
||||
int nSize, // size of pMajorList
|
||||
HRESULT *phr) :
|
||||
m_pDlg(pDlg),
|
||||
m_hbmp(NULL),
|
||||
m_pCore(NULL),
|
||||
m_bInitialized(false)
|
||||
{
|
||||
ASSERT(phr);
|
||||
ASSERT( nSize > 0);
|
||||
|
||||
strcpy( m_szMsg, "");
|
||||
|
||||
*phr = S_OK;
|
||||
|
||||
ZeroMemory( &m_sBmpParams, sizeof(VMRALPHABITMAP));
|
||||
srand( clock());
|
||||
|
||||
pMajorList->Shuffle();
|
||||
if( false == pMajorList->Clone(nSize, &m_MList))
|
||||
{
|
||||
*phr = E_INVALIDARG;
|
||||
return;
|
||||
}
|
||||
};
|
||||
virtual ~CDemonstration()
|
||||
{
|
||||
if( m_pCore )
|
||||
{
|
||||
delete m_pCore;
|
||||
}
|
||||
if( m_hbmp)
|
||||
{
|
||||
DeleteObject( m_hbmp );
|
||||
}
|
||||
if( m_sBmpParams.hdc )
|
||||
{
|
||||
DeleteDC( m_sBmpParams.hdc );
|
||||
}
|
||||
m_MList.Clean();
|
||||
};
|
||||
|
||||
HRESULT Initialize();
|
||||
HRESULT UpdateStreams(clock_t tStart);
|
||||
virtual HRESULT Perform();
|
||||
|
||||
// this function calculates parameters for the 'swirling windows' effect
|
||||
void FountainPath( long t,
|
||||
long T,
|
||||
int n,
|
||||
NORMALIZEDRECT r0,
|
||||
double A0,
|
||||
NORMALIZEDRECT * pR,
|
||||
double * pA);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: DlgWait.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Progress bar 'wait' dialog
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "VMRMix.h"
|
||||
#include "DlgWait.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDlgWait dialog
|
||||
|
||||
|
||||
CDlgWait::CDlgWait(int nMax, CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CDlgWait::IDD, pParent)
|
||||
{
|
||||
m_Max = nMax;
|
||||
//{{AFX_DATA_INIT(CDlgWait)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
|
||||
void CDlgWait::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CDlgWait)
|
||||
DDX_Control(pDX, IDC_PROGRESS, m_Progress);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDlgWait, CDialog)
|
||||
//{{AFX_MSG_MAP(CDlgWait)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDlgWait message handlers
|
||||
|
||||
BOOL CDlgWait::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
m_Progress.SetRange(0, (WORD) m_Max);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void CDlgWait::SetPos( int n)
|
||||
{
|
||||
m_Progress.SetPos( n);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: DlgWait.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(AFX_DLGWAIT_H__E66757E7_0C93_448B_B402_50E8111FCD7E__INCLUDED_)
|
||||
#define AFX_DLGWAIT_H__E66757E7_0C93_448B_B402_50E8111FCD7E__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// DlgWait.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDlgWait dialog
|
||||
|
||||
class CDlgWait : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CDlgWait(int nMax, CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
virtual ~CDlgWait()
|
||||
{
|
||||
DestroyWindow();
|
||||
};
|
||||
|
||||
void SetPos( int n);
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CDlgWait)
|
||||
enum { IDD = IDD_DIALOG_PROGRESS };
|
||||
CProgressCtrl m_Progress;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CDlgWait)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CDlgWait)
|
||||
virtual BOOL OnInitDialog();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
private:
|
||||
int m_Max;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_DLGWAIT_H__E66757E7_0C93_448B_B402_50E8111FCD7E__INCLUDED_)
|
||||
@@ -0,0 +1,30 @@
|
||||
Windows XP DirectShow Sample -- VMRMix
|
||||
--------------------------------------
|
||||
|
||||
Description: This application shows capabilities of the new
|
||||
video mixing renderer (VMR) that is the default video
|
||||
renderer in Windows XP. In particular, it demonstrates
|
||||
how to use the VMR in a mixing mode with several sources,
|
||||
how to apply a bitmap image with a color key over the video,
|
||||
and how to take advantage of the IVMRMixerControl interface
|
||||
to manage source and destination rectangles and alpha-level
|
||||
for each media stream.
|
||||
|
||||
Usage:
|
||||
Upon initialization, VMRMix asks the user to specify a
|
||||
media folder that contains at least two valid media files,
|
||||
after which it loads media settings from that folder.
|
||||
The user is asked to specify playback options:
|
||||
number of source files, size of the playback window, and
|
||||
whether to display a static bitmap image. When the user
|
||||
clicks on the 'Play' button, a new window appears to mix
|
||||
the selected streams. The demonstration lasts until the
|
||||
longest media file reaches the end. You can interrupt the
|
||||
demonstration by closing the playback window.
|
||||
|
||||
Troubleshooting:
|
||||
This application was originally created as a stress test,
|
||||
so it uses more system resources when displaying a maximum
|
||||
number of streams and when using "full-screen" mode. If
|
||||
video is freezing or slows down, try selecting fewer sources
|
||||
and turn off the "full-screen" option.
|
||||
@@ -0,0 +1,293 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: SourceInfo.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of CMediaList, play-list of media files
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "SourceInfo.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CMediaList::CMediaList() :
|
||||
m_avgDuration(0L),
|
||||
m_N(0),
|
||||
m_ppSI(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CMediaList::~CMediaList()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void CMediaList::Clean()
|
||||
{
|
||||
for( int i=0; i<m_N; i++)
|
||||
{
|
||||
delete m_ppSI[i];
|
||||
m_ppSI[i] = NULL;
|
||||
}// for
|
||||
|
||||
delete[] m_ppSI;
|
||||
m_ppSI = NULL;
|
||||
m_N = 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CMediaList::Add
|
||||
// Desc: adds a new source to the media list
|
||||
// return: true if success, false otherwise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CMediaList::Add( SourceInfo * pSI)
|
||||
{
|
||||
SourceInfo ** ppSInew = NULL;
|
||||
|
||||
ppSInew = new SourceInfo*[m_N+1];
|
||||
if( !ppSInew )
|
||||
return false;
|
||||
|
||||
for( int i=0; i<m_N; i++)
|
||||
{
|
||||
ppSInew[i] = m_ppSI[i];
|
||||
}// for
|
||||
|
||||
ppSInew[m_N] = pSI;
|
||||
delete[] m_ppSI;
|
||||
m_ppSI = ppSInew;
|
||||
m_N++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CMediaList::Shuffle()
|
||||
// Desc: randomly shuffles media list content to
|
||||
// have different playback settings every time
|
||||
//------------------------------------------------------------------------------
|
||||
void CMediaList::Shuffle()
|
||||
{
|
||||
SourceInfo *pSIaux = NULL;
|
||||
int n1;
|
||||
int n2;
|
||||
|
||||
for(int i=0; i< m_N; i++)
|
||||
{
|
||||
n1 = rand() * (m_N+1) / RAND_MAX;
|
||||
n2 = rand() * (m_N+1) / RAND_MAX;
|
||||
|
||||
n1 = ( n1<0) ? 0 : n1;
|
||||
n2 = ( n2<0) ? 0 : n2;
|
||||
|
||||
n1 = ( n1>m_N-1) ? m_N-1 : n1;
|
||||
n2 = ( n2>m_N-1) ? m_N-1 : n2;
|
||||
|
||||
if( n1 == n2 )
|
||||
continue;
|
||||
|
||||
pSIaux = m_ppSI[n1];
|
||||
m_ppSI[n1] = m_ppSI[n2];
|
||||
m_ppSI[n2] = pSIaux;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: SetInitialParameters
|
||||
// Purpose: calculates initial demonstration parameters for each media file --
|
||||
// destination rectangles and alpha levels
|
||||
// Note that these values are used as parameters in CDemonstration and
|
||||
// that changing them can cause different appearence of the demonstration
|
||||
//------------------------------------------------------------------------------
|
||||
void CMediaList::SetInitialParameters()
|
||||
{
|
||||
NORMALIZEDRECT rectD;
|
||||
double Alpha;
|
||||
int i;
|
||||
// set alpha levels and destination rectangles here
|
||||
for( i=0; i< m_N; i++)
|
||||
{
|
||||
Alpha = 0.3 + 0.68 * (double)rand() / RAND_MAX; // random in [0.3; 0.98]
|
||||
|
||||
rectD.left = rectD.top = 0.1f;
|
||||
rectD.right = rectD.bottom = 0.9f;
|
||||
|
||||
this->GetItem(i)->m_fAlpha = Alpha;
|
||||
this->GetItem(i)->m_rD = rectD;
|
||||
}// for
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: Initialize
|
||||
// Purpose: go through m_szMediaFolder and retrieve all media files into
|
||||
// Parameters: none
|
||||
// Return: true if folder contains at least one valid file;
|
||||
// false otherewise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CMediaList::Initialize(char *szFolder)
|
||||
{
|
||||
struct _finddata_t fileinfo;
|
||||
long filehandle = -1L;
|
||||
int nRes;
|
||||
int nCounter = 0; // to prevent loading huge number of files,
|
||||
// let's restrict it to 50
|
||||
char szMask[MAX_PATH];
|
||||
char szExt[] = "*.AVI;*.MOV;*.MPG;*.MPEG;*.VOB;*.QT;";
|
||||
char szCurExt[MAX_PATH];
|
||||
char szFilePath[MAX_PATH];
|
||||
char *psz = NULL;
|
||||
|
||||
// clean the list
|
||||
Clean();
|
||||
|
||||
if( !_strcmpi(szFolder,""))
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
strcpy(szCurExt,szExt);
|
||||
psz = strstr(szCurExt,";");
|
||||
if( psz)
|
||||
{
|
||||
*psz = 0;
|
||||
psz = NULL;
|
||||
psz = strstr( szExt, ";");
|
||||
if( psz )
|
||||
{
|
||||
strcpy( szExt, psz+1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy( szExt, "");
|
||||
}
|
||||
sprintf(szMask, "%s%s", szFolder, szCurExt);
|
||||
|
||||
filehandle = _findfirst(szMask, &fileinfo);
|
||||
|
||||
if( filehandle == -1L)
|
||||
continue;
|
||||
|
||||
SourceInfo * pSI = NULL;
|
||||
pSI = new SourceInfo;
|
||||
if( !pSI )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
sprintf( szFilePath, "%s%s", szFolder, fileinfo.name);
|
||||
strcpy( pSI->m_szPath, (const char*)szFilePath);
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*)szFilePath, -1, pSI->m_wszPath, _MAX_PATH);
|
||||
|
||||
Add( pSI );
|
||||
nCounter++;
|
||||
|
||||
nRes = _findnext(filehandle, &fileinfo);
|
||||
|
||||
while( -1L != nRes )
|
||||
{
|
||||
pSI = NULL;
|
||||
pSI = new SourceInfo;
|
||||
if( !pSI )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
sprintf( szFilePath, "%s%s", szFolder,fileinfo.name);
|
||||
strcpy( pSI->m_szPath, (const char*)szFilePath);
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*)szFilePath, -1, pSI->m_wszPath, _MAX_PATH);
|
||||
|
||||
Add( pSI );
|
||||
nCounter++;
|
||||
nRes = _findnext(filehandle, &fileinfo);
|
||||
}// while
|
||||
|
||||
} while( _strcmpi(szExt, "") && nCounter < 50 );
|
||||
|
||||
if( 0 == Size() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: Clone
|
||||
// Purpose: copies elements (nStart; nStart+n) to the list pML
|
||||
// Parameters: n - number of elements
|
||||
// pML - cloned media list
|
||||
// nStart - start position in (this) list; default: 0
|
||||
// Return: true if success;
|
||||
// false otherewise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CMediaList::Clone(int n, CMediaList *pML, int nStart /* = 0 */)
|
||||
{
|
||||
bool bRes = true;
|
||||
|
||||
if( n < 1 || nStart < 0 || nStart + n > m_N)
|
||||
return false;
|
||||
|
||||
pML->Clean();
|
||||
|
||||
for(int i = nStart; i< nStart + n; i++)
|
||||
{
|
||||
SourceInfo *pSI = NULL;
|
||||
|
||||
pSI = new SourceInfo;
|
||||
|
||||
if( !pSI )
|
||||
goto cleanup;
|
||||
|
||||
bRes = bRes && GetItem(i)->CopyTo( pSI);
|
||||
|
||||
if( false == bRes)
|
||||
{
|
||||
delete pSI;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pSI->m_bInUse = false;
|
||||
|
||||
bRes = bRes && pML->Add(pSI);
|
||||
if( false == bRes)
|
||||
goto cleanup;
|
||||
}// for
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
pML->Clean();
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Name: AdjustDuration
|
||||
// Purpose: calculates demonstration time. Here, it is duration of the longest file
|
||||
// Change this function to set a fixed time, average time etc.
|
||||
//------------------------------------------------------------------------------
|
||||
void CMediaList::AdjustDuration()
|
||||
{
|
||||
m_avgDuration = 0L;
|
||||
|
||||
if( 0 == m_N )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( int i=0; i<m_N; i++)
|
||||
{
|
||||
|
||||
m_avgDuration = (this->GetItem(i)->m_llDuration > m_avgDuration) ?
|
||||
this->GetItem(i)->m_llDuration :
|
||||
m_avgDuration;
|
||||
}// for
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: SourceInfo.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Header file and class description for CMediaList,
|
||||
// play-list of media files
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(AFX_SOURCEINFO_H__707CCC42_D3CC_40F1_B722_4E3ED3D7EAFF__INCLUDED_)
|
||||
#define AFX_SOURCEINFO_H__707CCC42_D3CC_40F1_B722_4E3ED3D7EAFF__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Name: SourceInfo
|
||||
// Purpose: this class describes properties of media file to be played by VMR
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct SourceInfo
|
||||
{
|
||||
SourceInfo::SourceInfo() :
|
||||
m_fAlpha(0.5f),
|
||||
m_dwSeekingFlags(NULL),
|
||||
m_fRate(1.0f),
|
||||
m_llDuration(NULL)
|
||||
|
||||
{
|
||||
m_rD.top = m_rD.left = 0.f;
|
||||
m_rD.right = m_rD.bottom = 1.f;
|
||||
strcpy( m_szPath, "");
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*)m_szPath, -1, m_wszPath, _MAX_PATH);
|
||||
};
|
||||
|
||||
SourceInfo::~SourceInfo()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
bool CopyTo( SourceInfo* pSI)
|
||||
{
|
||||
if( !pSI )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
strcpy( pSI->m_szPath, m_szPath);
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*)m_szPath, -1, pSI->m_wszPath, _MAX_PATH);
|
||||
pSI->m_dwSeekingFlags = m_dwSeekingFlags;
|
||||
pSI->m_fAlpha = m_fAlpha;
|
||||
pSI->m_fRate = m_fRate;
|
||||
pSI->m_llDuration = m_llDuration;
|
||||
pSI->m_rD = m_rD;
|
||||
return true;
|
||||
};
|
||||
|
||||
bool m_bInUse;
|
||||
char m_szPath[MAX_PATH];
|
||||
WCHAR m_wszPath[_MAX_PATH];
|
||||
DWORD m_dwSeekingFlags;
|
||||
double m_fAlpha;
|
||||
double m_fRate;
|
||||
LONGLONG m_llDuration;
|
||||
NORMALIZEDRECT m_rD;
|
||||
|
||||
} SourceInfo;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Name: CMediaList
|
||||
// Purpose: List of SourceInfo objects; a storage of available media files
|
||||
// to be played by VMR
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CMediaList
|
||||
{
|
||||
public:
|
||||
CMediaList();
|
||||
virtual ~CMediaList();
|
||||
|
||||
int Size(){ return m_N; };
|
||||
|
||||
SourceInfo * GetItem( int n)
|
||||
{
|
||||
return (n<0 || n>m_N-1) ? NULL : m_ppSI[n];
|
||||
};
|
||||
|
||||
LONGLONG GetAvgDuration()
|
||||
{
|
||||
return (m_avgDuration);
|
||||
};
|
||||
|
||||
const WCHAR * GetFileNameW( int n)
|
||||
{
|
||||
return (n>=0 && n<m_N) ? m_ppSI[n]->m_wszPath : NULL;
|
||||
};
|
||||
|
||||
bool Add( SourceInfo * pSI);
|
||||
bool Initialize(char *szFolder);
|
||||
bool Clone(int n, CMediaList *pML, int nStart=0 );
|
||||
|
||||
void Clean();
|
||||
void Shuffle();
|
||||
void AdjustDuration();
|
||||
void SetInitialParameters();
|
||||
|
||||
private:
|
||||
int m_N;
|
||||
SourceInfo ** m_ppSI;
|
||||
LONGLONG m_avgDuration;
|
||||
};
|
||||
#endif // !defined(AFX_SOURCEINFO_H__707CCC42_D3CC_40F1_B722_4E3ED3D7EAFF__INCLUDED_)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// VMRMix.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Stdafx.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Include file for standard system include files or project-specific
|
||||
// include files that are used frequently, but are changed infrequently.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(AFX_STDAFX_H__62FCB452_013F_45F5_ADDE_C3314ACD44C9__INCLUDED_)
|
||||
#define AFX_STDAFX_H__62FCB452_013F_45F5_ADDE_C3314ACD44C9__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <afxwin.h> // MFC core and standard components
|
||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxcmn.h> // MFC support for Windows Common Controls
|
||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||
|
||||
#if !defined(_WIN32_WINNT)
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
|
||||
#define D3D_OVERLOADS
|
||||
|
||||
// included files
|
||||
#pragma warning(push,3)
|
||||
#include <streams.h>
|
||||
#include <commdlg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <commctrl.h>
|
||||
#include <strmif.h>
|
||||
#include <combase.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <uuids.h>
|
||||
#pragma warning(pop)
|
||||
#pragma warning(disable:4100 4189)
|
||||
|
||||
#include "resource.h"
|
||||
#include "sourceinfo.h"
|
||||
#include "VMRMixDlg.h"
|
||||
#include "vmrcore.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define DllImport __declspec( dllimport )
|
||||
|
||||
// needed for the surface tests
|
||||
DEFINE_GUID(IID_IDirectDraw7,
|
||||
0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b);
|
||||
|
||||
// various constants
|
||||
|
||||
const ULONG MAXFILTERS = 128;
|
||||
#define FNS_PASS 0
|
||||
#define FNS_FAIL 1
|
||||
|
||||
// macros
|
||||
#define SAFERELEASE(punk) if (NULL != punk) (punk)->Release(), (punk) = NULL; else
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__62FCB452_013F_45F5_ADDE_C3314ACD44C9__INCLUDED_)
|
||||
@@ -0,0 +1,370 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Utils.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Helper functions
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Function: MyMessage
|
||||
// Purpose: Displays a quick message box
|
||||
// Arguments: Input strings that will be displayed
|
||||
// Returns: button pushed in box
|
||||
//-----------------------------------------------------------------------------------------*/
|
||||
DWORD MyMessage(char *sQuestion, char *sTitle)
|
||||
{
|
||||
int iReturn = AfxMessageBox( sQuestion, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1);
|
||||
return iReturn == IDYES ? FNS_PASS : FNS_FAIL;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Function: hresultNameLookup
|
||||
// Purpose: returns a string value for the given hresult
|
||||
// Arguments: HRESULT that needs verifying
|
||||
// Returns: string
|
||||
//-----------------------------------------------------------------------------------------*/
|
||||
const char * hresultNameLookup(HRESULT hres)
|
||||
{
|
||||
switch(hres)
|
||||
{
|
||||
case VFW_E_CANNOT_RENDER:
|
||||
return "VFW_E_CANNOT_RENDER";
|
||||
break;
|
||||
case VFW_E_INVALID_FILE_FORMAT:
|
||||
return "VFW_E_INVALID_FILE_FORMAT";
|
||||
break;
|
||||
case VFW_E_NOT_FOUND:
|
||||
return "VFW_E_NOT_FOUND";
|
||||
break;
|
||||
case VFW_E_NOT_IN_GRAPH:
|
||||
return "VFW_E_NOT_IN_GRAPH";
|
||||
break;
|
||||
case VFW_E_UNKNOWN_FILE_TYPE:
|
||||
return "VFW_E_UNKNOWN_FILE_TYPE";
|
||||
break;
|
||||
case VFW_E_UNSUPPORTED_STREAM:
|
||||
return "VFW_E_UNSUPPORTED_STREAM";
|
||||
break;
|
||||
case VFW_E_CANNOT_CONNECT:
|
||||
return "VFW_E_CANNOT_CONNECT";
|
||||
break;
|
||||
case VFW_E_CANNOT_LOAD_SOURCE_FILTER:
|
||||
return "VFW_E_CANNOT_LOAD_SOURCE_FILTER";
|
||||
break;
|
||||
case VFW_S_PARTIAL_RENDER:
|
||||
return "VFW_S_PARTIAL_RENDER";
|
||||
break;
|
||||
case VFW_S_VIDEO_NOT_RENDERED:
|
||||
return "VFW_S_VIDEO_NOT_RENDERED";
|
||||
break;
|
||||
case VFW_S_AUDIO_NOT_RENDERED:
|
||||
return "VFW_S_AUDIO_NOT_RENDERED";
|
||||
break;
|
||||
case VFW_S_DUPLICATE_NAME:
|
||||
return "VFW_S_DUPLICATE_NAME";
|
||||
break;
|
||||
case VFW_S_MEDIA_TYPE_IGNORED:
|
||||
return "VFW_S_MEDIA_TYPE_IGNORED";
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
return "E_INVALIDARG";
|
||||
break;
|
||||
case DDERR_INCOMPATIBLEPRIMARY:
|
||||
return "DDERR_INCOMPATIBLEPRIMARY";
|
||||
break;
|
||||
case DDERR_INVALIDCAPS:
|
||||
return "DDERR_INVALIDCAPS";
|
||||
break;
|
||||
case DDERR_INVALIDOBJECT :
|
||||
return "DDERR_INVALIDOBJECT";
|
||||
break;
|
||||
case DDERR_INVALIDPIXELFORMAT:
|
||||
return "DDERR_INVALIDPIXELFORMAT";
|
||||
break;
|
||||
case DDERR_NOALPHAHW :
|
||||
return "DDERR_NOALPHAHW";
|
||||
break;
|
||||
case DDERR_NOCOOPERATIVELEVELSET :
|
||||
return "DDERR_NOCOOPERATIVELEVELSET";
|
||||
break;
|
||||
case DDERR_NODIRECTDRAWHW :
|
||||
return "DDERR_NODIRECTDRAWHW";
|
||||
break;
|
||||
case DDERR_NOEMULATION :
|
||||
return "DDERR_NOEMULATION";
|
||||
break;
|
||||
case VFW_E_BUFFERS_OUTSTANDING:
|
||||
return "VFW_E_BUFFERS_OUTSTANDING";
|
||||
break;
|
||||
case DDERR_NOEXCLUSIVEMODE :
|
||||
return "DDERR_NOEXCLUSIVEMODE ";
|
||||
break;
|
||||
case DDERR_NOFLIPHW:
|
||||
return "DDERR_NOFLIPHW";
|
||||
break;
|
||||
case DDERR_NOMIPMAPHW:
|
||||
return "DDERR_NOMIPMAPHW";
|
||||
break;
|
||||
case DDERR_NOOVERLAYHW :
|
||||
return "DDERR_NOOVERLAYHW ";
|
||||
break;
|
||||
case E_OUTOFMEMORY:
|
||||
return "E_OUTOFMEMORY";
|
||||
break;
|
||||
case VFW_E_NO_DISPLAY_PALETTE:
|
||||
return "VFW_E_NO_DISPLAY_PALETTE";
|
||||
break;
|
||||
case VFW_E_NO_COLOR_KEY_FOUND:
|
||||
return "VFW_E_NO_COLOR_KEY_FOUND";
|
||||
break;
|
||||
case VFW_E_PALETTE_SET:
|
||||
return "VFW_E_PALETTE_SET";
|
||||
break;
|
||||
case DDERR_NOZBUFFERHW :
|
||||
return "DDERR_NOZBUFFERHW ";
|
||||
break;
|
||||
case DDERR_OUTOFVIDEOMEMORY :
|
||||
return "DDERR_OUTOFVIDEOMEMORY";
|
||||
break;
|
||||
case DDERR_PRIMARYSURFACEALREADYEXISTS:
|
||||
return "DDERR_PRIMARYSURFACEALREADYEXISTS ";
|
||||
break;
|
||||
case DDERR_UNSUPPORTEDMODE:
|
||||
return "DDERR_UNSUPPORTEDMODE";
|
||||
break;
|
||||
case VFW_E_NO_ADVISE_SET:
|
||||
return "VFW_E_NO_ADVISE_SET";
|
||||
break;
|
||||
case S_OK:
|
||||
return "S_OK";
|
||||
break;
|
||||
case S_FALSE:
|
||||
return "S_FALSE";
|
||||
break;
|
||||
case VFW_S_CONNECTIONS_DEFERRED:
|
||||
return "VFW_S_CONNECTIONS_DEFERRED";
|
||||
break;
|
||||
case 0x80040154:
|
||||
return "Class not registered";
|
||||
break;
|
||||
case E_FAIL:
|
||||
return "E_FAIL";
|
||||
break;
|
||||
case VFW_E_DVD_OPERATION_INHIBITED:
|
||||
return "VFW_E_DVD_OPERATION_INHIBITED";
|
||||
break;
|
||||
case VFW_E_DVD_INVALIDDOMAIN:
|
||||
return "VFW_E_DVD_INVALIDDOMAIN";
|
||||
break;
|
||||
case E_NOTIMPL:
|
||||
return "E_NOTIMPL";
|
||||
break;
|
||||
case VFW_E_WRONG_STATE:
|
||||
return "VFW_E_WRONG_STATE";
|
||||
break;
|
||||
case E_PROP_SET_UNSUPPORTED:
|
||||
return "E_PROP_SET_UNSUPPORTED";
|
||||
break;
|
||||
case VFW_E_NO_PALETTE_AVAILABLE:
|
||||
return "VFW_E_NO_PALETTE_AVAILABLE";
|
||||
break;
|
||||
case E_UNEXPECTED:
|
||||
return "E_UNEXPECTED";
|
||||
break;
|
||||
case VFW_E_DVD_NO_BUTTON:
|
||||
return "VFW_E_DVD_NO_BUTTON";
|
||||
break;
|
||||
case VFW_E_DVD_GRAPHNOTREADY:
|
||||
return "VFW_E_DVD_GRAPHNOTREADY";
|
||||
break;
|
||||
case VFW_E_NOT_OVERLAY_CONNECTION:
|
||||
return "VFW_E_NOT_OVERLAY_CONNECTION";
|
||||
break;
|
||||
case VFW_E_DVD_RENDERFAIL:
|
||||
return "VFW_E_DVD_RENDERFAIL";
|
||||
break;
|
||||
case VFW_E_NOT_CONNECTED:
|
||||
return "VFW_E_NOT_CONNECTED";
|
||||
break;
|
||||
case E_NOINTERFACE:
|
||||
return "E_NOINTERFACE";
|
||||
break;
|
||||
case VFW_E_NO_COLOR_KEY_SET :
|
||||
return "VFW_E_NO_COLOR_KEY_SET ";
|
||||
break;
|
||||
case VFW_E_NO_INTERFACE:
|
||||
return "VFW_E_NO_INTERFACE";
|
||||
break;
|
||||
case 0x8004020c:
|
||||
return "VFW_E_BUFFER_NOTSET";
|
||||
break;
|
||||
case 0x80040225:
|
||||
return "VFW_E_NOT_PAUSED";
|
||||
case 0x80070002:
|
||||
return "System cannot find the file specified";
|
||||
break;
|
||||
case 0x80070003:
|
||||
return "System cannot find the path specified";
|
||||
break;
|
||||
case VFW_E_DVD_DECNOTENOUGH:
|
||||
return "VFW_E_DVD_DECNOTENOUGH";
|
||||
break;
|
||||
case VFW_E_ADVISE_ALREADY_SET:
|
||||
return "VFW_E_ADVISE_ALREADY_SET";
|
||||
break;
|
||||
case VFW_E_DVD_CMD_CANCELLED:
|
||||
return "VFW_E_DVD_CMD_CANCELLED";
|
||||
break;
|
||||
case VFW_E_DVD_MENU_DOES_NOT_EXIST:
|
||||
return "VFW_E_DVD_MENU_DOES_NOT_EXIST";
|
||||
break;
|
||||
case VFW_E_DVD_WRONG_SPEED:
|
||||
return "VFW_E_DVD_WRONG_SPEED";
|
||||
break;
|
||||
case VFW_S_DVD_NON_ONE_SEQUENTIAL:
|
||||
return "VFW_S_DVD_NON_ONE_SEQUENTIAL";
|
||||
break;
|
||||
case E_POINTER:
|
||||
return "E_POINTER";
|
||||
break;
|
||||
case VFW_E_DVD_NOT_IN_KARAOKE_MODE:
|
||||
return "VFW_E_DVD_NOT_IN_KARAOKE_MODE";
|
||||
break;
|
||||
case VFW_E_DVD_INVALID_DISC:
|
||||
return "VFW_E_DVD_INVALID_DISC";
|
||||
break;
|
||||
case VFW_E_DVD_STREAM_DISABLED:
|
||||
return "VFW_E_DVD_STREAM_DISABLED";
|
||||
break;
|
||||
case VFW_E_NOT_STOPPED:
|
||||
return "VFW_E_NOT_STOPPED";
|
||||
break;
|
||||
default:
|
||||
return "Unrecognized";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Function: MySleep
|
||||
// Purpose: if the application is in automated mode, then sleep func is turned off
|
||||
// Arguments: checks m_bAutomatedStatus to see if the func is in automation
|
||||
// Returns: true if automated, false otherwist
|
||||
//-----------------------------------------------------------------------------------------*/
|
||||
bool MySleep(DWORD dwTime)
|
||||
{
|
||||
HANDLE hNeverHappensEvent;
|
||||
hNeverHappensEvent = CreateEvent(NULL, FALSE, FALSE, "EVENTTHATNEVERHAPPENS");
|
||||
WaitForSingleObject( hNeverHappensEvent, dwTime);
|
||||
return false;
|
||||
|
||||
} // end of checkHResult method
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Function: ShellAbort
|
||||
// Purpose: Prints a crash message text to the appropriate log(s)
|
||||
// Arguments: none
|
||||
// Returns: FNS_ABORTED
|
||||
//-----------------------------------------------------------------------------------------*/
|
||||
DWORD ShellAbort(CVMRCore *core)
|
||||
{
|
||||
AfxMessageBox("Unhandled exception, press OK to abort...");
|
||||
exit(-1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Function: GetMessageName
|
||||
// Purpose: Updates Name to the string version of the windows message
|
||||
// Arguments: Name, long pointer to a string that will be updated
|
||||
// msg - message id that we want displayed
|
||||
//-----------------------------------------------------------------------------------------*/
|
||||
void GetMessageName(LPSTR Name, UINT msg)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
// For put_MessageDrain and get_MessageDrain
|
||||
|
||||
case WM_KEYDOWN: lstrcpy(Name, "WM_KEYDOWN"); break;
|
||||
case WM_KEYUP: lstrcpy(Name, "WM_KEYUP"); break;
|
||||
case WM_LBUTTONDBLCLK: lstrcpy(Name, "WM_LBUTTONDBLCLK"); break;
|
||||
case WM_LBUTTONDOWN: lstrcpy(Name, "WM_LBUTTONDOWN"); break;
|
||||
case WM_LBUTTONUP: lstrcpy(Name, "WM_LBUTTONUP"); break;
|
||||
case WM_MBUTTONDBLCLK: lstrcpy(Name, "WM_MBUTTONDBLCLK"); break;
|
||||
case WM_MBUTTONDOWN: lstrcpy(Name, "WM_MBUTTONDOWN"); break;
|
||||
case WM_MBUTTONUP: lstrcpy(Name, "WM_MBUTTONUP"); break;
|
||||
case WM_MOUSEACTIVATE: lstrcpy(Name, "WM_MOUSEACTIVATE"); break;
|
||||
case WM_MOUSEMOVE: lstrcpy(Name, "WM_MOUSEMOVE"); break;
|
||||
case WM_NCHITTEST: lstrcpy(Name, "WM_NCHITTEST"); break;
|
||||
case WM_NCLBUTTONDBLCLK: lstrcpy(Name, "WM_NCLBUTTONDBLCLK"); break;
|
||||
case WM_NCLBUTTONDOWN: lstrcpy(Name, "WM_NCLBUTTONDOWN"); break;
|
||||
case WM_NCLBUTTONUP: lstrcpy(Name, "WM_NCLBUTTONUP"); break;
|
||||
case WM_NCMBUTTONDBLCLK: lstrcpy(Name, "WM_NCMBUTTONDBLCLK"); break;
|
||||
case WM_NCMBUTTONDOWN: lstrcpy(Name, "WM_NCMBUTTONDOWN"); break;
|
||||
case WM_NCMBUTTONUP: lstrcpy(Name, "WM_NCMBUTTONUP"); break;
|
||||
case WM_NCMOUSEMOVE: lstrcpy(Name, "WM_NCMOUSEMOVE"); break;
|
||||
case WM_NCRBUTTONDBLCLK: lstrcpy(Name, "WM_NCRBUTTONDBLCLK"); break;
|
||||
case WM_NCRBUTTONDOWN: lstrcpy(Name, "WM_NCRBUTTONDOWN"); break;
|
||||
case WM_NCRBUTTONUP: lstrcpy(Name, "WM_NCRBUTTONUP"); break;
|
||||
case WM_RBUTTONDBLCLK: lstrcpy(Name, "WM_RBUTTONDBLCLK"); break;
|
||||
case WM_RBUTTONDOWN: lstrcpy(Name, "WM_RBUTTONDOWN"); break;
|
||||
case WM_RBUTTONUP: lstrcpy(Name, "WM_RBUTTONUP"); break;
|
||||
|
||||
// For NotifyOwnerMessage
|
||||
|
||||
case WM_DEVMODECHANGE: lstrcpy(Name,"WM_DEVMODECHANGE"); break;
|
||||
case WM_DISPLAYCHANGE: lstrcpy(Name,"WM_DISPLAYCHANGE"); break;
|
||||
case WM_MOVE: lstrcpy(Name,"WM_MOVE"); break;
|
||||
case WM_PALETTECHANGED: lstrcpy(Name,"WM_PALETTECHANGED"); break;
|
||||
case WM_PALETTEISCHANGING: lstrcpy(Name,"WM_PALETTEISCHANGING"); break;
|
||||
case WM_QUERYNEWPALETTE: lstrcpy(Name,"WM_QUERYNEWPALETTE"); break;
|
||||
case WM_SYSCOLORCHANGE: lstrcpy(Name,"WM_SYSCOLORCHANGE"); break;
|
||||
|
||||
default: wsprintf(Name, "Unknown Messgage %u", msg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VerifyVMR
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL VerifyVMR(void)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
// Verify that the VMR exists on this system
|
||||
IBaseFilter* pBF = NULL;
|
||||
hres = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
pBF->Release();
|
||||
CoUninitialize();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(NULL,
|
||||
TEXT("This application requires the Video Mixing Renderer, which is present\r\n")
|
||||
TEXT("only on Windows XP.\r\n\r\n")
|
||||
TEXT("The Video Mixing Renderer (VMR) is also not enabled when viewing a \r\n")
|
||||
TEXT("remote Windows XP machine through a Remote Desktop session.\r\n")
|
||||
TEXT("You can run VMR-enabled applications only on your local machine.")
|
||||
TEXT("\r\n\r\nThis sample will now exit."),
|
||||
TEXT("Video Mixing Renderer capabilities are required"), MB_OK);
|
||||
|
||||
CoUninitialize();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Utils.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Helper function prototypes
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(UTILS_H)
|
||||
#define UTILS_H
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// helper function prototypes
|
||||
|
||||
DWORD MyMessage(char *sQuestion, char *sTitle);
|
||||
DWORD ShellAbort(CVMRCore *core);
|
||||
|
||||
const char * hresultNameLookup(HRESULT hres);
|
||||
|
||||
bool MySleep(DWORD dwTime = 2500);
|
||||
void GetMessageName(LPSTR Name, UINT msg);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,972 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: VMRCore.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Header file and class description for CVMRCore,
|
||||
// "main" module to manage VMR and its interfaces
|
||||
// This class is called from CDemonstration;
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "resource.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
DWORD WINAPI WndlessControlThread(LPVOID lpvThreadParam);
|
||||
|
||||
CVMRCore::CVMRCore(CVMRMixDlg * pDlg, // pointer to the 'parent' dialog
|
||||
CMediaList * pML) : // media play-list
|
||||
m_tID(NULL),
|
||||
m_hEventResumeCore(NULL),
|
||||
m_hEventStopTest(NULL),
|
||||
m_hEventCloseWindow(NULL),
|
||||
m_hEventKillCore(NULL),
|
||||
m_hWinThread(NULL),
|
||||
m_pDlg(pDlg),
|
||||
m_pMixerBitmap(NULL),
|
||||
m_pML(pML),
|
||||
m_pIMediaSeeking(NULL),
|
||||
m_pIMixerControl(NULL),
|
||||
m_nConnectedPins(0),
|
||||
m_pIMonConfig(NULL),
|
||||
m_hwnd(NULL),
|
||||
m_pIMC(NULL),
|
||||
m_pIVidWindow(NULL),
|
||||
m_pIWndless(NULL),
|
||||
m_dwVMRMode(NULL),
|
||||
m_dwVMRPrefs(NULL),
|
||||
m_pConfig(NULL),
|
||||
m_pGraph(NULL),
|
||||
m_pTestFilter(NULL),
|
||||
m_lpDestRect(NULL),
|
||||
m_lpSrcRect(NULL)
|
||||
{
|
||||
// by default, set windowless mode and allow overlays
|
||||
m_dwVMRMode = VMRMode_Windowless;
|
||||
m_dwVMRPrefs = RenderPrefs_AllowOverlays;
|
||||
m_dwID = (DWORD) rand();
|
||||
|
||||
sprintf( m_szEventStopTest, "STOP_TEST_%ld", m_dwID);
|
||||
sprintf( m_szEventCloseWindow, "CLOSE_WINDOW_%ld", m_dwID);
|
||||
sprintf( m_szEventKillCore, "KILL_CORE_%ld", m_dwID);
|
||||
sprintf( m_szEventResumeCore, "RESUME_CORE_%ld", m_dwID);
|
||||
|
||||
m_hEventResumeCore = CreateEvent(NULL, FALSE, FALSE, m_szEventResumeCore);
|
||||
m_hEventCloseWindow = CreateEvent(NULL, FALSE, FALSE, m_szEventCloseWindow);
|
||||
m_hEventKillCore = CreateEvent(NULL, FALSE, FALSE, m_szEventKillCore);
|
||||
m_hEventStopTest = CreateEvent(NULL, FALSE, FALSE, m_szEventStopTest);
|
||||
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
CVMRCore::CVMRCore( CVMRMixDlg * pDlg, // 'parent dialog
|
||||
DWORD dwVMRMode, // rendering mode
|
||||
DWORD dwVMRPrefs, // rendering preferences
|
||||
CMediaList * pML) : // play-list
|
||||
m_tID(NULL),
|
||||
m_hEventStopTest(NULL),
|
||||
m_hEventCloseWindow(NULL),
|
||||
m_hEventKillCore(NULL),
|
||||
m_pDlg(pDlg),
|
||||
m_pMixerBitmap(NULL),
|
||||
m_pML( pML),
|
||||
m_pIMediaSeeking(NULL),
|
||||
m_pIMixerControl(NULL),
|
||||
m_nConnectedPins(0),
|
||||
m_hEventResumeCore(NULL),
|
||||
m_hWinThread(NULL),
|
||||
m_pIMonConfig(NULL),
|
||||
m_hwnd(NULL),
|
||||
m_pIMC(NULL),
|
||||
m_pIVidWindow(NULL),
|
||||
m_pIWndless(NULL),
|
||||
m_dwVMRMode(NULL),
|
||||
m_dwVMRPrefs(NULL),
|
||||
m_pConfig(NULL),
|
||||
m_pGraph(NULL),
|
||||
m_pTestFilter(NULL),
|
||||
m_lpDestRect(NULL),
|
||||
m_lpSrcRect(NULL)
|
||||
{
|
||||
|
||||
(dwVMRPrefs) ? (m_dwVMRPrefs = dwVMRPrefs)
|
||||
:(m_dwVMRPrefs = RenderPrefs_AllowOverlays);
|
||||
|
||||
(dwVMRMode) ? (m_dwVMRMode = dwVMRMode)
|
||||
: (m_dwVMRMode = VMRMode_Windowless);
|
||||
|
||||
m_dwID = (DWORD) rand();
|
||||
|
||||
sprintf( m_szEventStopTest, "STOP_TEST_%ld", m_dwID);
|
||||
sprintf( m_szEventCloseWindow, "CLOSE_WINDOW_%ld", m_dwID);
|
||||
sprintf( m_szEventKillCore, "KILL_CORE_%ld", m_dwID);
|
||||
sprintf( m_szEventResumeCore, "RESUME_CORE_%ld", m_dwID);
|
||||
|
||||
m_hEventResumeCore = CreateEvent(NULL, FALSE, FALSE, m_szEventResumeCore);
|
||||
m_hEventCloseWindow = CreateEvent(NULL, FALSE, FALSE, m_szEventCloseWindow);
|
||||
m_hEventKillCore = CreateEvent(NULL, FALSE, FALSE, m_szEventKillCore);
|
||||
m_hEventStopTest = CreateEvent(NULL, FALSE, FALSE, m_szEventStopTest);
|
||||
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
CVMRCore::~CVMRCore()
|
||||
{
|
||||
ReleaseInterfaces();
|
||||
|
||||
CloseHandle(m_hEventResumeCore);
|
||||
CloseHandle(m_hEventStopTest);
|
||||
CloseHandle(m_hEventKillCore);
|
||||
CloseHandle(m_hWinThread);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CreateGraph
|
||||
// Desc: Creates a valid filter graph for VMR
|
||||
// Returns: S_OK if everything succeeds, else the hresult
|
||||
// returned by the API called that failed
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CVMRCore::CreateGraph()
|
||||
{
|
||||
// keeps track of any nonessential initializations
|
||||
HRESULT hrInit = S_OK;
|
||||
int ncount; // counter for media files from the play list
|
||||
|
||||
// graph has already been successfully created
|
||||
if (m_pGraph)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
// get the graph interface
|
||||
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
|
||||
reinterpret_cast<void**>(&m_pGraph));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
// add VMR (called 'Default Video Renderer' in WindowsXP)
|
||||
hr = AddTestFilter();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't add the Test Filter to the Graph\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// convert filename from module to unicode and render
|
||||
if( m_pML->Size() < 1)
|
||||
{
|
||||
OutputDebugString("There is nothing to render!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Render the files
|
||||
for( ncount =0; ncount < m_pML->Size(); ncount++)
|
||||
{
|
||||
hr = m_pGraph->RenderFile(m_pML->GetFileNameW(ncount), NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
char szMsg[MAX_PATH];
|
||||
sprintf( szMsg, "Error while rendering file, method returned %s\n",
|
||||
hresultNameLookup(hr) );
|
||||
OutputDebugString( szMsg);
|
||||
continue;
|
||||
}
|
||||
m_pML->GetItem(ncount)->m_bInUse = true;
|
||||
m_nConnectedPins++;
|
||||
}
|
||||
if( FAILED(hr))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// verify that there is only one renderer in the graph
|
||||
if (!ListFilters())
|
||||
{
|
||||
OutputDebugString("There is more than one renderer in the graph.\n");
|
||||
hr = E_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// get the media control so we can play
|
||||
hr = m_pGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&m_pIMC));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't get IMediaControl interface!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// now that file is rendered, initialize the appropriate interfaces
|
||||
hr = InitRelevantInterfaces();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Not all interfaces were initialized.\n");
|
||||
hrInit = S_FALSE;
|
||||
}
|
||||
|
||||
// create the window for the windowless control if needed
|
||||
if (m_dwVMRMode & VMRMode_Windowless)
|
||||
{
|
||||
// if windowless mode is desired, the window needs to be setup
|
||||
CreateWindowlessWindow();
|
||||
|
||||
// only applicable for windoless control
|
||||
hr = m_pIWndless->SetVideoClippingWindow(m_hwnd);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Error while setting the Video Clipping Window\n");
|
||||
goto cleanup;
|
||||
}
|
||||
} // if (m_dwVMRMode & VMRMode_Windowless)
|
||||
|
||||
return hrInit;
|
||||
|
||||
cleanup:
|
||||
// if we fail, release interfaces
|
||||
SAFERELEASE(m_pGraph);
|
||||
SAFERELEASE(m_pTestFilter);
|
||||
return hr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// AddTestFilter
|
||||
// Desc: Adds the VMR to the graph
|
||||
// Returns: S_OK if the filter is added, otherwise the corresponding
|
||||
// DShow COM error
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CVMRCore::AddTestFilter()
|
||||
{
|
||||
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,
|
||||
reinterpret_cast<void**>(&m_pTestFilter));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't load VideoMixingRenderer Filter\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
// now add this filter to the graph
|
||||
// add the VMR to the filter graph
|
||||
hr = m_pGraph->AddFilter(m_pTestFilter, L"Default Video Renderer");
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't add Video Mixing Renderer Filter to the graph\n");
|
||||
SAFERELEASE(m_pTestFilter);
|
||||
return hr;
|
||||
}
|
||||
|
||||
// make dynamic reconnection possible
|
||||
IGraphConfig * pIGraphConfig = NULL;
|
||||
hr = m_pGraph->QueryInterface( __uuidof(IGraphConfig), (LPVOID *) &pIGraphConfig);
|
||||
if( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = pIGraphConfig->SetFilterFlags(m_pTestFilter, AM_FILTER_FLAGS_REMOVABLE);
|
||||
}
|
||||
SAFERELEASE( pIGraphConfig );
|
||||
|
||||
|
||||
// the VMR requires certain setup procedures:
|
||||
// first get the pin config interface (that is IVMRFilterConfig and
|
||||
// set up the initialization settings for the VMR
|
||||
hr = m_pTestFilter->QueryInterface(__uuidof(IVMRFilterConfig), reinterpret_cast<void**>(&m_pConfig));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't get IVMRFilterConfig interface\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
// We MUST set the number of streams first
|
||||
// it sets VMR to mixing or non-mixing mode.
|
||||
// By specifying SetNumberOfStreams(1) we guarantee that the came copy
|
||||
// of the rendering filter will be used when rendering several sources
|
||||
int nSources;
|
||||
nSources = (m_pML->Size() >1) ? 16 : 1;
|
||||
|
||||
hr = m_pConfig->SetNumberOfStreams(nSources);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't Set the number of streams.\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
// now set the rendering mode
|
||||
hr = m_pConfig->SetRenderingMode(m_dwVMRMode);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Failed to set the rendering mode\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
// now set the preferences
|
||||
hr = m_pConfig->SetRenderingPrefs(m_dwVMRPrefs);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
char szMsg[MAX_PATH];
|
||||
sprintf( szMsg, "hr = %s\n", hresultNameLookup(hr));
|
||||
OutputDebugString( szMsg);
|
||||
OutputDebugString("Error while setting rendering preferences!\n");
|
||||
OutputDebugString("Attempting to continue rendering file\n");
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// InitRelevantInterfaces
|
||||
// Desc: QIs for all the interfaces that are appropriate
|
||||
// Returns: S_OK if the all of the relevant interfaces are gotten
|
||||
// correctly
|
||||
// Notes: This method also verifies which mode the VMR is in
|
||||
// and if it needs a window created that will be
|
||||
// by the windowless control
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CVMRCore::InitRelevantInterfaces()
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
HRESULT hrComplete = S_OK;
|
||||
|
||||
if (m_dwVMRMode & VMRMode_Windowless)
|
||||
{
|
||||
hr = m_pTestFilter->QueryInterface(__uuidof(IVMRWindowlessControl),
|
||||
reinterpret_cast<void**>(&m_pIWndless));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't get IVMRWindowlessControl interface\n");
|
||||
hrComplete = hr;
|
||||
}
|
||||
// now that the interface is ready, place the video on the screen
|
||||
RECT rect;
|
||||
if( !m_hwnd )
|
||||
{
|
||||
CreateWindowlessWindow();
|
||||
}
|
||||
ASSERT( m_hwnd);
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
hr = m_pIWndless->SetVideoPosition(NULL, &rect);
|
||||
} // if mode is windowless
|
||||
|
||||
hr = m_pTestFilter->QueryInterface(__uuidof(IVMRMonitorConfig),
|
||||
reinterpret_cast<void**>(&m_pIMonConfig));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't get IVMRMonitorConfig interface\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_pTestFilter->QueryInterface( __uuidof(IVMRMixerControl), (LPVOID *) &m_pIMixerControl ) ;
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Cannot find IVMRMixerControl interface\n");
|
||||
return hr;
|
||||
}
|
||||
hr = m_pTestFilter->QueryInterface( __uuidof(IVMRMixerBitmap), (LPVOID *) &m_pMixerBitmap ) ;
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Cannot find IVMRMixerBitmap interface\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = GetIGraphBuilder()->QueryInterface(__uuidof(IMediaSeeking), reinterpret_cast<void**>(&m_pIMediaSeeking));
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Cannot find IMediaSeeking interface\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_pGraph->QueryInterface(IID_IVideoWindow,
|
||||
reinterpret_cast<void**>(&m_pIVidWindow));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Couldn't get IVideoWindow interface\n");
|
||||
hrComplete = hr;
|
||||
}
|
||||
return hrComplete;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: Play
|
||||
// Desc: Begins to play the core video, checks for window initiziation
|
||||
// Parameter: bool bDoNotRunYet, if true, then do not run IMediaControl
|
||||
// Returns: HRESULT returned by the the MediaControlers call to run
|
||||
// Note: We catch all unhandled exceptions here
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CVMRCore::Play(bool bDoNotRunYet /* = false */)
|
||||
{
|
||||
try
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// if there is no media control interface, get it created
|
||||
// return successfully with the graph running or the error
|
||||
if (!m_pIMC)
|
||||
hr = CreateGraph();
|
||||
if( bDoNotRunYet )
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
hr = (SUCCEEDED(hr)) ? m_pIMC->Run() : hr;
|
||||
return hr;
|
||||
} // try
|
||||
catch (HRESULT hr)
|
||||
{
|
||||
if (hr == E_FAIL)
|
||||
{
|
||||
OutputDebugString("Unhandled exception in CVMRCore::Play\n");
|
||||
SetAbort();
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
SetAbort();
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: Pause
|
||||
// Purpose: Begins the core video paused, checks for window initiziation
|
||||
// Returns: HRESULT returned by the the MediaControlers call to run
|
||||
// Note: We catch all unhandled exceptions here
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CVMRCore::Pause()
|
||||
{
|
||||
try
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// if there is no media control interface, get it created
|
||||
// return successfully with the graph running or the error
|
||||
if (!m_pIMC)
|
||||
hr = CreateGraph();
|
||||
return (SUCCEEDED(hr)) ? m_pIMC->Pause() : hr;
|
||||
} // try
|
||||
catch (HRESULT hr)
|
||||
{
|
||||
if (hr == E_FAIL)
|
||||
{
|
||||
OutputDebugString("Failed to pause the graph.\n");
|
||||
SetAbort();
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
SetAbort();
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: Stop
|
||||
// Purpose: Begins to the core video stopped, checks for window initiziation
|
||||
// Returns: HRESULT returned by the the MediaControlers call to run
|
||||
// Note: We catch all unhandled exceptions here
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CVMRCore::Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// if there is no media control interface, get it created
|
||||
// return successfully with the graph running or the error
|
||||
if (!m_pIMC)
|
||||
hr = CreateGraph();
|
||||
return (SUCCEEDED(hr)) ? m_pIMC->Stop() : hr;
|
||||
} // try
|
||||
catch (HRESULT hr)
|
||||
{
|
||||
if (hr == E_FAIL)
|
||||
{
|
||||
OutputDebugString("Failed to stop the graph.\n");
|
||||
SetAbort();
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
SetAbort();
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ReleaseInterfaces
|
||||
// Desc: Releases the IUnknown interfaces for all member variable
|
||||
// interfaces created by this object
|
||||
//------------------------------------------------------------------------------
|
||||
void CVMRCore::ReleaseInterfaces()
|
||||
{
|
||||
// close the window if it exists
|
||||
KillWindow();
|
||||
SAFERELEASE(m_pMixerBitmap);
|
||||
SAFERELEASE(m_pIMediaSeeking);
|
||||
SAFERELEASE(m_pIMixerControl);
|
||||
SAFERELEASE(m_pIMonConfig);
|
||||
SAFERELEASE(m_pIWndless);
|
||||
SAFERELEASE(m_pConfig);
|
||||
SAFERELEASE(m_pIMC);
|
||||
SAFERELEASE(m_pTestFilter);
|
||||
SAFERELEASE(m_pGraph);
|
||||
SAFERELEASE(m_pIVidWindow);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IsActive
|
||||
// Desc: checks if VMRCore is active
|
||||
// return: false if m_hEventKillCore is set (user closes the window);
|
||||
// true otherwise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CVMRCore::IsActive()
|
||||
{
|
||||
DWORD dwRes = NULL;
|
||||
dwRes = WaitForSingleObject( m_hEventKillCore, 10);
|
||||
|
||||
if( WAIT_OBJECT_0 != dwRes)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ListFilters
|
||||
// Desc: Logs to the debugger output the filters in our created filter graph
|
||||
// Returns: true if one VMR filter was found; false otherwise
|
||||
//------------------------------------------------------------------------------
|
||||
bool CVMRCore::ListFilters()
|
||||
{
|
||||
if (m_pGraph)
|
||||
{
|
||||
IEnumFilters * ppEnum;
|
||||
ULONG cFilters, cFetched;
|
||||
IBaseFilter *ppFilter[MAXFILTERS];
|
||||
FILTER_INFO pInfo;
|
||||
HRESULT hr;
|
||||
char sLogBuffer[MAX_PATH];
|
||||
|
||||
int iRendererCount = 0;
|
||||
|
||||
char buffer[MAX_PATH];
|
||||
|
||||
// get pointer to list of filters in graph
|
||||
hr = m_pGraph->EnumFilters(&ppEnum);
|
||||
cFilters = MAXFILTERS; // number of filters to retrieve
|
||||
hr = ppEnum->Next(cFilters, &(ppFilter[0]), &cFetched);
|
||||
|
||||
sprintf(buffer, "Filter List (%d found): \n", cFetched);
|
||||
OutputDebugString(buffer);
|
||||
for (UINT i = 0; i < cFetched; i++)
|
||||
{
|
||||
//get, covert and display filter name
|
||||
ppFilter[i]->QueryFilterInfo(&pInfo);
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, pInfo.achName, -1, buffer, MAX_PATH, NULL, NULL);
|
||||
|
||||
// keep count of renderers to throw an exception when there is more than
|
||||
// one renderer
|
||||
if (IsRenderer(buffer))
|
||||
iRendererCount++;
|
||||
|
||||
if( 2 == iRendererCount )
|
||||
{
|
||||
// with some cards, a glitch can occur and there will be several
|
||||
// VMR filters in the same graph. Here, we try to prevent it
|
||||
// (okay, if you do not like the line below, go trough the graph
|
||||
// and reconnect all the spources to one VMR)
|
||||
hr = m_pGraph->RemoveFilter(ppFilter[i]);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
iRendererCount--;
|
||||
}
|
||||
}// if
|
||||
|
||||
sprintf(sLogBuffer, "(%d) = %s\n", i+1 , buffer);
|
||||
OutputDebugString(sLogBuffer);
|
||||
|
||||
// release any IUnknowns that were addrefed by successful calls of Enum and Query
|
||||
SAFERELEASE(pInfo.pGraph);
|
||||
SAFERELEASE(ppFilter[i]);
|
||||
} // for
|
||||
SAFERELEASE(ppEnum);
|
||||
|
||||
// if more than one renderer is present, the wrong renderer may get tested
|
||||
if (iRendererCount > 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} // if m_pGraph
|
||||
return false;
|
||||
} // ListFilters
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CreateWindowlessWindow
|
||||
// Desc: Creates the events and thread that will handle the windowless control's
|
||||
// playback window
|
||||
// Returns: S_OK when the thread is completed
|
||||
//------------------------------------------------------------------------------
|
||||
HRESULT CVMRCore::CreateWindowlessWindow()
|
||||
{
|
||||
if( NULL != m_hwnd)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// spin off and create the playback window on another thread so that
|
||||
// it will have its own message pump so that any messages that the
|
||||
// VMR is supposed to be handled can be set
|
||||
m_hWinThread = CreateThread(NULL, NULL, WndlessControlThread, this, NULL, &m_tID);
|
||||
::WaitForSingleObject(m_hEventResumeCore, INFINITE);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WndlessControlThread
|
||||
// Desc: Thread code that creates a playback window for the VMR
|
||||
// Arguments: Pointer to thread paramters in this case a structure holding the hwnd and
|
||||
// a pointer to the core object that is calling it.
|
||||
// Returns: S_OK when the thread is completed
|
||||
// Remarks: Requires a call to the core's KillThread so that
|
||||
// this thread will end!
|
||||
//------------------------------------------------------------------------------
|
||||
DWORD WINAPI WndlessControlThread(LPVOID lpvThreadParam)
|
||||
{
|
||||
// passed a to the thread
|
||||
CVMRCore * pCore = static_cast<CVMRCore *>(lpvThreadParam);
|
||||
HWND hwnd;
|
||||
|
||||
if( !pCore )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
// this code will create the window and run the windows proc for each test
|
||||
// each test will be on its own thread
|
||||
// register playback window
|
||||
WNDCLASSEX wndclass = {
|
||||
sizeof(WNDCLASSEX),
|
||||
CS_HREDRAW * CS_VREDRAW,
|
||||
CVMRCore::WndProc,
|
||||
0,
|
||||
0,
|
||||
AfxGetInstanceHandle(),
|
||||
LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)),
|
||||
LoadCursor(NULL, IDC_ARROW),
|
||||
HBRUSH(COLOR_WINDOW+1),
|
||||
NULL,
|
||||
TEXT("EventWindow"),
|
||||
NULL
|
||||
};
|
||||
|
||||
RegisterClassEx(&wndclass);
|
||||
|
||||
// create the playback window
|
||||
// it is always in dlg client coordinates
|
||||
RECT rPlayback;
|
||||
|
||||
int cx = GetSystemMetrics(SM_CXFULLSCREEN);
|
||||
int cy = GetSystemMetrics(SM_CYFULLSCREEN);
|
||||
|
||||
if( !pCore->GetDlg()->IsFullScreen())
|
||||
{
|
||||
cx /=4;
|
||||
cy /=4;
|
||||
}
|
||||
rPlayback.left = 0;
|
||||
rPlayback.top = 0;
|
||||
rPlayback.right = cx;
|
||||
rPlayback.bottom = cy;
|
||||
|
||||
// need to update member variable of class with this
|
||||
hwnd = CreateWindow(
|
||||
TEXT("EventWindow"),
|
||||
TEXT("VMRMix Playback Window"),
|
||||
WS_OVERLAPPEDWINDOW | WS_MAXIMIZE,
|
||||
rPlayback.left,
|
||||
rPlayback.top,
|
||||
rPlayback.right - rPlayback.left,
|
||||
rPlayback.bottom - rPlayback.top,
|
||||
NULL,
|
||||
NULL,
|
||||
AfxGetInstanceHandle(),
|
||||
pCore); // we send the this pointer here so we can retrieve it from WM_CREATE later
|
||||
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pCore));
|
||||
|
||||
// for the windowless controls clipping window
|
||||
pCore->SetHwnd(hwnd);
|
||||
ShowWindow(hwnd , SW_SHOWNORMAL);
|
||||
UpdateWindow(hwnd ) ;
|
||||
|
||||
// set an event here so that our other thread can continue now that the window is created
|
||||
HANDLE hCoreEvent = ::OpenEvent(EVENT_ALL_ACCESS, NULL, pCore->m_szEventResumeCore);
|
||||
SetEvent(hCoreEvent);
|
||||
CloseHandle(hCoreEvent);
|
||||
|
||||
// now run a message loop so that this thread will not die
|
||||
MSG msg;
|
||||
HANDLE hTestOverEvent = ::OpenEvent(EVENT_ALL_ACCESS, NULL, pCore->m_szEventStopTest);
|
||||
HANDLE hWindowClose = ::OpenEvent(EVENT_ALL_ACCESS, NULL, pCore->m_szEventCloseWindow);
|
||||
while (WAIT_OBJECT_0 != WaitForSingleObject(hTestOverEvent, 1000))
|
||||
{
|
||||
OutputDebugString("WndlessControlThread:: Inside while Wait(hTestOverEvent)\n");
|
||||
while (::PeekMessage(&msg, NULL, 0, 0, 0))
|
||||
{
|
||||
OutputDebugString("WndlessControlThread:: Inside while (::PeekMessage\n");
|
||||
MSG msgCur;
|
||||
if (!::GetMessage(&msgCur, NULL, NULL, NULL)) // the quit message came
|
||||
{
|
||||
::PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
::TranslateMessage(&msgCur);
|
||||
::DispatchMessage(&msgCur);
|
||||
} ///while peeke
|
||||
}// while wait
|
||||
|
||||
// trigger remaining events and close all locally opened handles
|
||||
SetEvent(hWindowClose);
|
||||
CloseHandle(hWindowClose);
|
||||
CloseHandle(hTestOverEvent);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WndProc
|
||||
// Desc: Window procedure for multithreaded implementation
|
||||
// Returns: LRESULT
|
||||
//------------------------------------------------------------------------------
|
||||
LRESULT CALLBACK CVMRCore::WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// retrieve the pointer to the instance of CVMRCore that this window belongs to
|
||||
// because WndProc is a static method, it doesn't have a this pointer
|
||||
CVMRCore * pCore = NULL;
|
||||
BOOL bRetVal = false;
|
||||
|
||||
pCore = reinterpret_cast<CVMRCore *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
|
||||
|
||||
if( !pCore )
|
||||
{
|
||||
return DefWindowProc(hWnd, uMessage, wParam, lParam);
|
||||
}
|
||||
|
||||
switch (uMessage)
|
||||
{
|
||||
case WM_CREATE:
|
||||
return 0;
|
||||
case WM_SIZE:
|
||||
return pCore->OnSize(wParam, lParam);
|
||||
|
||||
case WM_PAINT:
|
||||
return pCore->OnPaint(hWnd);
|
||||
|
||||
case WM_CLOSE:
|
||||
OutputDebugString("message WM_CLOSE obtained by CVMRCore::WndProc\n");
|
||||
return pCore->KillWindow();
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, uMessage, wParam, lParam);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// KillWindow
|
||||
// Desc: Sets the event when multithreaded that the playback thread may close the
|
||||
// playback window
|
||||
//------------------------------------------------------------------------------
|
||||
LRESULT CVMRCore::KillWindow()
|
||||
{
|
||||
if( m_pIMC)
|
||||
{
|
||||
m_pIMC->Stop();
|
||||
}
|
||||
if( !SetEvent( m_hEventStopTest ))
|
||||
{
|
||||
DWORD dwRes = GetLastError();
|
||||
OutputDebugString("KillWindow::Failed to set event m_hEventStopTest\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDebugString("KillWindow::Event m_hEventStopTest is set\n");
|
||||
}
|
||||
if( this->m_hWinThread )
|
||||
{
|
||||
if( !PostThreadMessage(m_tID, WM_QUIT, NULL, NULL) )
|
||||
{
|
||||
DWORD dwRes = GetLastError();
|
||||
}
|
||||
|
||||
}
|
||||
SetEvent( m_hEventKillCore );
|
||||
OutputDebugString("KillWindow::m_hEventKillCore is set ...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: OnSize
|
||||
// Purpose: Resets the video in the newly sized window
|
||||
// Arguments: lParam - height and width of the window
|
||||
// wparam - type of resizing requested
|
||||
// Returns: Nothing
|
||||
//------------------------------------------------------------------------------
|
||||
LRESULT CVMRCore::OnSize(LPARAM lParam, WPARAM wParam)
|
||||
{
|
||||
SetClientVideo();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: SetClientVideo
|
||||
// Purpose: Sets the video position to the current client area size of the playback
|
||||
// window if the m_lpSrcRect and m_lpDestRect have been given valid values.
|
||||
// Arguments: None
|
||||
// Returns: True if the rectangles have been initialized, false if the client
|
||||
// window's default size is used
|
||||
// Notes: One might wish to post a WM_PAINT message since this code will reset
|
||||
// any source and destination changes to the windowless control
|
||||
//------------------------------------------------------------------------------
|
||||
bool CVMRCore::SetClientVideo()
|
||||
{
|
||||
if ( m_pIWndless)
|
||||
{
|
||||
// both of the rectangles have been set
|
||||
if (m_lpSrcRect && m_lpDestRect)
|
||||
{
|
||||
HRESULT hr = m_pIWndless->SetVideoPosition(m_lpSrcRect, m_lpDestRect);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
RECT rect;
|
||||
// reset video window, this will change any previous settings
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
ASSERT(m_pIWndless);
|
||||
|
||||
if (m_pIWndless)
|
||||
HRESULT hr = m_pIWndless->SetVideoPosition(NULL, &rect);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: SetAbort
|
||||
// Purpose: emergency abort
|
||||
// Other: Alerts the module to not allow any more test to be executed
|
||||
//------------------------------------------------------------------------------
|
||||
void CVMRCore::SetAbort()
|
||||
{
|
||||
// an unhandled exception has been thrown
|
||||
ReleaseInterfaces();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: OnPaint
|
||||
// Purpose: Paints the playback window's client area
|
||||
// Arguments: hWnd of the client window
|
||||
//------------------------------------------------------------------------------
|
||||
LRESULT CVMRCore::OnPaint(HWND hWnd)
|
||||
{
|
||||
if (NULL == m_pIWndless)
|
||||
return 0;
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
|
||||
hdc = BeginPaint(hWnd, &ps);
|
||||
HRESULT hr = m_pIWndless->RepaintVideo(hWnd, hdc);
|
||||
|
||||
if(!SUCCEEDED(hr))
|
||||
{
|
||||
char szMsg[MAX_PATH];
|
||||
sprintf( szMsg, "%s", hresultNameLookup(hr));
|
||||
}
|
||||
|
||||
EndPaint(hWnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: GetClientHwnd
|
||||
// Purpose: Access to the private core's client's hwnd
|
||||
// Returns: handle to the renderer's playback controlling window
|
||||
//------------------------------------------------------------------------------
|
||||
HWND CVMRCore::GetClientHwnd()
|
||||
{
|
||||
// we may have already set this up in windowless control
|
||||
if (m_hwnd)
|
||||
return m_hwnd;
|
||||
|
||||
HWND hwnd; // handle to the window we are looking for
|
||||
TCHAR buffer[MAX_PATH];
|
||||
|
||||
hwnd = GetTopWindow(NULL);
|
||||
while (hwnd)
|
||||
{
|
||||
// get title bar's window and compare
|
||||
if (GetWindowText(hwnd, buffer, MAX_PATH))
|
||||
{
|
||||
// old renderer, windowed mode of VMR
|
||||
if (!strcmp(buffer, "ActiveMovie Window"))
|
||||
break; // title found save use hwnd
|
||||
if (!strcmp(buffer, "Windowless Control"))
|
||||
break;
|
||||
} //
|
||||
hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
|
||||
} // while
|
||||
if (!hwnd)
|
||||
{
|
||||
OutputDebugString("Could not find window handle for playback window\n");
|
||||
return NULL;
|
||||
}
|
||||
m_hwnd = hwnd;
|
||||
return m_hwnd;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Function: IsRenderer
|
||||
// Purpose: Defines if a given filter is a video renderer
|
||||
// Arguments: strFilterName - NON wide string pointer that holds
|
||||
// the name of the filter being checked
|
||||
// Returns: true if the filter name is a filter that is being sought, false otherwise
|
||||
// Other: This function can be useful because sometimes with some videocards
|
||||
// several copies of VMR appear in the same graph.
|
||||
// Name 'Video renderer' corresponds to older version of venderer
|
||||
//------------------------------------------------------------------------------
|
||||
bool CVMRCore::IsRenderer(char *strFilterName)
|
||||
{
|
||||
if (!strncmp(strFilterName, "Video Mixing", 12))
|
||||
return true;
|
||||
|
||||
if (!strncmp(strFilterName, "Video Render", 12))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: VMRCore.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Header file and class description for CVMRCore,
|
||||
// "main" module to manage VMR and its interfaces
|
||||
// This class is called from CDemonstration.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(AFX_NEWCORE_H__9D74D6FC_F94C_45E6_A991_E38D47C3441D__INCLUDED_)
|
||||
#define AFX_NEWCORE_H__9D74D6FC_F94C_45E6_A991_E38D47C3441D__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
class CVMRMixDlg;
|
||||
|
||||
class CVMRCore
|
||||
{
|
||||
public:
|
||||
CVMRCore(CVMRMixDlg * pDlg, CMediaList *pML);
|
||||
|
||||
|
||||
CVMRCore( CVMRMixDlg * pDlg,
|
||||
DWORD dwVMRMode,
|
||||
DWORD dwVMRPrefs,
|
||||
CMediaList *pML);
|
||||
|
||||
|
||||
virtual ~CVMRCore();
|
||||
|
||||
HWND GetClientHwnd();
|
||||
virtual bool ListFilters();
|
||||
|
||||
HRESULT Pause();
|
||||
HRESULT Stop();
|
||||
HRESULT Play(bool bDoNotRunYet = false);
|
||||
|
||||
bool IsActive();
|
||||
|
||||
// functions to get information about the video playback window
|
||||
void SetAbort();
|
||||
void SetHwnd(HWND hwnd){m_hwnd = hwnd;};
|
||||
bool SetClientVideo();
|
||||
CVMRMixDlg * GetDlg(){ return m_pDlg;};
|
||||
|
||||
// windows procedure function for the windowless control
|
||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
|
||||
char m_szEventStopTest[MAX_PATH];
|
||||
char m_szEventCloseWindow[MAX_PATH];
|
||||
char m_szEventKillCore[MAX_PATH];
|
||||
char m_szEventResumeCore[MAX_PATH];
|
||||
|
||||
// access to interfaces and member variables
|
||||
IVMRWindowlessControl * GetVMRWndless(){return m_pIWndless;};
|
||||
IGraphBuilder * GetIGraphBuilder(){return m_pGraph;};
|
||||
IBaseFilter * GetTestFilter(){return m_pTestFilter;};
|
||||
IVMRFilterConfig * GetVMRConfig() { return m_pConfig; };
|
||||
IVMRMonitorConfig * GetVMRMonitorConfig() { return m_pIMonConfig; };
|
||||
IMediaControl * GetMediaControl(){return m_pIMC;};
|
||||
IVMRMixerControl * GetMixerControl(){ return m_pIMixerControl;};
|
||||
IMediaSeeking * GetMediaSeeking() { return m_pIMediaSeeking;};
|
||||
IVMRMixerBitmap * GetMixerBitmap(){ return m_pMixerBitmap;};
|
||||
|
||||
protected:
|
||||
// protected member variables
|
||||
HWND m_hwnd;
|
||||
|
||||
IGraphBuilder * m_pGraph; // graph
|
||||
IBaseFilter * m_pTestFilter;// the renderer filter
|
||||
IVMRWindowlessControl * m_pIWndless;
|
||||
IMediaControl * m_pIMC;
|
||||
IVMRFilterConfig * m_pConfig;
|
||||
IVMRMonitorConfig * m_pIMonConfig;
|
||||
IVideoWindow * m_pIVidWindow;
|
||||
IVMRMixerControl * m_pIMixerControl;
|
||||
IMediaSeeking * m_pIMediaSeeking;
|
||||
IVMRMixerBitmap * m_pMixerBitmap;
|
||||
|
||||
DWORD m_dwVMRMode; // VMR Mode setup flags
|
||||
DWORD m_dwVMRPrefs; // VMR Prefs setup
|
||||
LPRECT m_lpSrcRect; // pointer to SRC rect for painting
|
||||
LPRECT m_lpDestRect; // pointer to Dest rect for painting
|
||||
|
||||
// working functions
|
||||
|
||||
virtual HRESULT CreateGraph();
|
||||
virtual HRESULT AddTestFilter();
|
||||
virtual HRESULT InitRelevantInterfaces();
|
||||
HRESULT CreateWindowlessWindow();
|
||||
virtual void ReleaseInterfaces();
|
||||
|
||||
virtual LRESULT OnPaint(HWND hWnd);
|
||||
virtual LRESULT OnSize(LPARAM lParam, WPARAM wParam);
|
||||
|
||||
private:
|
||||
DWORD m_tID; // thread identifier for windless mode
|
||||
DWORD m_dwID; // ID of this copy of CVMRCore. Generated as rand();
|
||||
CVMRMixDlg * m_pDlg; // 'parent' dialog
|
||||
CMediaList * m_pML; // media list to render
|
||||
int m_nConnectedPins; // number of active input pins of VMR
|
||||
HANDLE m_hWinThread; // windowless control's window thread
|
||||
|
||||
HANDLE m_hEventStopTest;
|
||||
HANDLE m_hEventCloseWindow;
|
||||
HANDLE m_hEventKillCore;
|
||||
HANDLE m_hEventResumeCore; // control window
|
||||
|
||||
// private working functions
|
||||
bool IsRenderer(char * strFilterName); // determines if a filter is a video renderer
|
||||
LRESULT KillWindow(); // process closing window by user
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NEWCORE_H__9D74D6FC_F94C_45E6_A991_E38D47C3441D__INCLUDED_)
|
||||
@@ -0,0 +1,90 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: VMRMix.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of CVMRMixApp
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "VMRMix.h"
|
||||
#include "VMRMixDlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
extern BOOL VerifyVMR(void);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CVMRMixApp
|
||||
|
||||
BEGIN_MESSAGE_MAP(CVMRMixApp, CWinApp)
|
||||
//{{AFX_MSG_MAP(CVMRMixApp)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code!
|
||||
//}}AFX_MSG
|
||||
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CVMRMixApp construction
|
||||
|
||||
CVMRMixApp::CVMRMixApp()
|
||||
{
|
||||
// TODO: add construction code here,
|
||||
// Place all significant initialization in InitInstance
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// The one and only CVMRMixApp object
|
||||
|
||||
CVMRMixApp theApp;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CVMRMixApp initialization
|
||||
|
||||
BOOL CVMRMixApp::InitInstance()
|
||||
{
|
||||
// Standard initialization
|
||||
// If you are not using these features and wish to reduce the size
|
||||
// of your final executable, you should remove from the following
|
||||
// the specific initialization routines you do not need.
|
||||
|
||||
// In MFC 5.0, Enable3dControls and Enable3dControlsStatic are obsolete because
|
||||
// their functionality is incorporated into Microsoft's 32-bit operating systems.
|
||||
#if (_MSC_VER <= 1200)
|
||||
#ifdef _AFXDLL
|
||||
Enable3dControls(); // Call this when using MFC in a shared DLL
|
||||
#else
|
||||
Enable3dControlsStatic(); // Call this when linking to MFC statically
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Verify that the Video Mixing Renderer is present (requires Windows XP).
|
||||
// Otherwise, this sample cannot continue.
|
||||
if (!VerifyVMR())
|
||||
return FALSE;
|
||||
|
||||
CVMRMixDlg dlg;
|
||||
m_pMainWnd = &dlg;
|
||||
int nResponse = dlg.DoModal();
|
||||
if (nResponse == IDOK)
|
||||
{
|
||||
// TODO: Place code here to handle when the dialog is
|
||||
// dismissed with OK
|
||||
}
|
||||
else if (nResponse == IDCANCEL)
|
||||
{
|
||||
// TODO: Place code here to handle when the dialog is
|
||||
// dismissed with Cancel
|
||||
}
|
||||
|
||||
// Since the dialog has been closed, return FALSE so that we exit the
|
||||
// application, rather than start the application's message pump.
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
# Microsoft Developer Studio Project File - Name="VMRMix" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=VMRMix - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "VMRMix.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "VMRMix.mak" CFG="VMRMix - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "VMRMix - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "VMRMix - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "VMRMix - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 5
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 5
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\DirectShow\BaseClasses" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 ..\..\..\DirectShow\baseclasses\release\strmbase.lib strmiids.lib quartz.lib ddraw.lib dxguid.lib version.lib shell32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib shell32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /OPT:NOREF /OPT:ICF
|
||||
|
||||
!ELSEIF "$(CFG)" == "VMRMix - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 5
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 6
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\DirectShow\BaseClasses" /D "_DEBUG" /D "_AFXDLL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX"stdafx.h" /FD /GZ /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 ..\..\..\DirectShow\baseclasses\debug\strmbasd.lib strmiids.lib comctl32.lib winmm.lib ddraw.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /map
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "VMRMix - Win32 Release"
|
||||
# Name "VMRMix - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Demonstration.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DlgWait.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SourceInfo.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"stdafx.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Utils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRCore.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRMix.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRMix.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRMixDlg.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Demonstration.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DlgWait.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SourceInfo.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Utils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRCore.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRMix.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRMixDlg.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\bitmap1.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\bitmap2.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\bitmap3.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\close.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\Logo.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\VMRMix.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\VMRMix.rc2
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ReadMe.txt
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "VMRMix"=.\VMRMix.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: VMRMix.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Header file and class description for CVMRMixApp
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(AFX_VMRMix_H__D7D7485E_84F1_4BE2_ACF2_569097C46073__INCLUDED_)
|
||||
#define AFX_VMRMix_H__D7D7485E_84F1_4BE2_ACF2_569097C46073__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error include 'stdafx.h' before including this file for PCH
|
||||
#endif
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CVMRMixApp:
|
||||
// See VMRMix.cpp for the implementation of this class
|
||||
//
|
||||
|
||||
class CVMRMixApp : public CWinApp
|
||||
{
|
||||
public:
|
||||
CVMRMixApp();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CVMRMixApp)
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
//{{AFX_MSG(CVMRMixApp)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_VMRMix_H__D7D7485E_84F1_4BE2_ACF2_569097C46073__INCLUDED_)
|
||||
@@ -0,0 +1,268 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
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"
|
||||
"#ifdef _WIN32\r\n"
|
||||
"LANGUAGE 9, 1\r\n"
|
||||
"#pragma code_page(1252)\r\n"
|
||||
"#endif //_WIN32\r\n"
|
||||
"#include ""res\\VMRMix.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
|
||||
"#include ""afxres.rc"" // Standard components\r\n"
|
||||
"#endif\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_MAINFRAME ICON DISCARDABLE "res\\VMRMix.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 81
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About VMRMix"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
ICON IDR_MAINFRAME,IDC_STATIC,11,17,21,20
|
||||
LTEXT "VMRMix Version 8.1",IDC_STATIC,40,10,119,8,SS_NOPREFIX
|
||||
LTEXT "Copyright (C) 2001 Microsoft Corporation",IDC_STATIC,40,
|
||||
25,188,8
|
||||
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
|
||||
LTEXT "This sample demonstrates some of the mixing, blending, and rendering capabilities of the Video Mixing Renderer in Windows XP. ",
|
||||
IDC_STATIC,40,40,187,30
|
||||
END
|
||||
|
||||
IDD_VMRMIX_DIALOG DIALOGEX 0, 0, 216, 110
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE |
|
||||
WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "VMRMix for Windows XP"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "Slider1",IDC_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS |
|
||||
TBS_TOP | TBS_ENABLESELRANGE | WS_TABSTOP,69,36,123,21
|
||||
CONTROL "&Display bitmap over the video?",IDC_CHECK_APPLYBITMAP,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,66,116,10
|
||||
CONTROL "&Maximize window?",IDC_CHECK_FULLSCREEN,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,132,66,75,10
|
||||
PUSHBUTTON "&Start",IDC_BUTTON_PLAY,52,87,50,16,BS_CENTER |
|
||||
BS_VCENTER
|
||||
DEFPUSHBUTTON "E&xit",IDOK,113,87,50,16
|
||||
CTEXT "Number of sources:",IDC_STATIC_STREAMS_TITLE,3,36,67,16,
|
||||
SS_CENTERIMAGE
|
||||
CTEXT "16",IDC_STATIC_NSRC,195,36,15,16,SS_CENTERIMAGE
|
||||
CTEXT "Select the number of video streams to mix together. These streams will be randomly selected from the specified media directory and will be blended together in a new window.",
|
||||
IDC_STATIC,3,5,209,30
|
||||
END
|
||||
|
||||
IDD_DIALOG_PROGRESS DIALOG DISCARDABLE 0, 0, 187, 20
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
|
||||
CAPTION "Loading media settings..."
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,
|
||||
7,173,6
|
||||
END
|
||||
|
||||
IDD_DIALOG_PLAYBACK DIALOG DISCARDABLE 0, 0, 246, 183
|
||||
STYLE WS_CHILD
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
END
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,1,0,0
|
||||
PRODUCTVERSION 8,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "DirectShow Windows XP Sample\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "VMRMix Application\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "VMR Mix\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "VMRMix.EXE\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "DirectX 8.1 SDK\0"
|
||||
VALUE "ProductVersion", "8.1\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_ABOUTBOX, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 228
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 74
|
||||
END
|
||||
|
||||
IDD_DIALOG_PROGRESS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 180
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 13
|
||||
END
|
||||
|
||||
IDD_DIALOG_PLAYBACK, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 239
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 176
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_MENU MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP "File"
|
||||
BEGIN
|
||||
MENUITEM "Select media folder...", ID_FILE_SELECTMEDIAFOLDER
|
||||
MENUITEM "Exit", ID_FILE_EXIT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitmap
|
||||
//
|
||||
|
||||
IDB_BITMAP_LOGO BITMAP DISCARDABLE "res\\Logo.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_ABOUTBOX "&About VMRMix..."
|
||||
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)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE 9, 1
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
#include "res\VMRMix.rc2" // non-Microsoft Visual C++ edited resources
|
||||
#include "afxres.rc" // Standard components
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,511 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: VMRMixDlg.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of the settings dialog
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "VMRMix.h"
|
||||
#include "VMRMixDlg.h"
|
||||
#include "DlgWait.h"
|
||||
#include "Demonstration.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
class CDemonstration;
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAboutDlg dialog used for App About
|
||||
|
||||
class CAboutDlg : public CDialog
|
||||
{
|
||||
public:
|
||||
CAboutDlg();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAboutDlg)
|
||||
enum { IDD = IDD_ABOUTBOX };
|
||||
//}}AFX_DATA
|
||||
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAboutDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
//{{AFX_MSG(CAboutDlg)
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAboutDlg)
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAboutDlg)
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CAboutDlg)
|
||||
// No message handlers
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CVMRMixDlg dialog
|
||||
|
||||
CVMRMixDlg::CVMRMixDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CVMRMixDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CVMRMixDlg)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
|
||||
m_bFullScreen = true;
|
||||
m_bUseBitmap = true;
|
||||
m_nMaxSources = 16;
|
||||
m_nStreams = 5; // Initial number of streams
|
||||
m_eState = eStop;
|
||||
strcpy(m_szFolder,"");
|
||||
}
|
||||
|
||||
void CVMRMixDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CVMRMixDlg)
|
||||
DDX_Control(pDX, IDC_CHECK_FULLSCREEN, m_chkFullScreen);
|
||||
DDX_Control(pDX, IDC_CHECK_APPLYBITMAP, m_chkBitmap);
|
||||
DDX_Control(pDX, IDC_SLIDER, m_Slider);
|
||||
DDX_Control(pDX, IDOK, m_btnOK);
|
||||
DDX_Control(pDX, IDC_BUTTON_PLAY, m_btnPlay);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CVMRMixDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CVMRMixDlg)
|
||||
ON_WM_SYSCOMMAND()
|
||||
ON_WM_PAINT()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
|
||||
ON_COMMAND(ID_FILE_SELECTMEDIAFOLDER, SelectFolder)
|
||||
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER, OnReleasedcaptureSlider)
|
||||
ON_BN_CLICKED(IDC_CHECK_APPLYBITMAP, OnCheckApplybitmap)
|
||||
ON_BN_CLICKED(IDC_CHECK_FULLSCREEN, OnCheckFullscreen)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CVMRMixDlg message handlers
|
||||
|
||||
BOOL CVMRMixDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// Add "About..." menu item to system menu.
|
||||
|
||||
// IDM_ABOUTBOX must be in the system command range.
|
||||
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
|
||||
ASSERT(IDM_ABOUTBOX < 0xF000);
|
||||
|
||||
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
||||
if (pSysMenu != NULL)
|
||||
{
|
||||
CString strAboutMenu;
|
||||
strAboutMenu.LoadString(IDS_ABOUTBOX);
|
||||
if (!strAboutMenu.IsEmpty())
|
||||
{
|
||||
pSysMenu->AppendMenu(MF_SEPARATOR);
|
||||
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the icon for this dialog. The framework does this automatically
|
||||
// when the application's main window is not a dialog
|
||||
SetIcon(m_hIcon, TRUE); // Set big icon
|
||||
SetIcon(m_hIcon, FALSE); // Set small icon
|
||||
|
||||
|
||||
SetNumberOfStreams(m_nStreams);
|
||||
|
||||
// upon initialization, ask user to specify media folder
|
||||
// if failed, app cannot continue and quits
|
||||
while( !strlen(m_szFolder) )
|
||||
{
|
||||
SelectFolder();
|
||||
if( !strlen(m_szFolder) )
|
||||
{
|
||||
// If no media directory was specified, just exit
|
||||
PostQuitMessage(0);
|
||||
return FALSE;
|
||||
}
|
||||
m_MediaList.Initialize( m_szFolder );
|
||||
if( 0 == m_MediaList.Size() )
|
||||
{
|
||||
AfxMessageBox("Selected folder does not contain any media file");
|
||||
strcpy( m_szFolder, "");
|
||||
}
|
||||
}
|
||||
|
||||
// Read settings for the selected media file
|
||||
BOOL bRes = GetMediaSettings();
|
||||
|
||||
if( bRes )
|
||||
{
|
||||
m_nMaxSources = (m_MediaList.Size() > 16) ? 16 : m_MediaList.Size();
|
||||
m_Slider.SetRange(1, m_nMaxSources);
|
||||
|
||||
if( m_nStreams > m_nMaxSources)
|
||||
{
|
||||
SetNumberOfStreams( m_nMaxSources );
|
||||
}
|
||||
}
|
||||
|
||||
m_chkFullScreen.SetCheck( m_bFullScreen);
|
||||
m_chkBitmap.SetCheck( m_bUseBitmap);
|
||||
|
||||
RECT rSlider;
|
||||
m_Slider.GetWindowRect( &rSlider );
|
||||
LPARAM lparam = MAKELPARAM( (rSlider.left + rSlider.right)/2, (rSlider.top + rSlider.bottom)/2);
|
||||
m_Slider.SendMessage(WM_LBUTTONUP, NULL, lparam);
|
||||
|
||||
return bRes; // return TRUE unless you set the focus to a control
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Windows message processing for CVMRMixDlg
|
||||
//-------------------------------------------------------------
|
||||
|
||||
void CVMRMixDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
{
|
||||
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
|
||||
{
|
||||
CAboutDlg dlgAbout;
|
||||
dlgAbout.DoModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnSysCommand(nID, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
// If you add a minimize button to your dialog, you will need the code below
|
||||
// to draw the icon. For MFC applications using the document/view model,
|
||||
// this is automatically done for you by the framework.
|
||||
|
||||
void CVMRMixDlg::OnPaint()
|
||||
{
|
||||
if (IsIconic())
|
||||
{
|
||||
CPaintDC dc(this); // device context for painting
|
||||
|
||||
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
|
||||
|
||||
// Center icon in client rectangle
|
||||
int cxIcon = GetSystemMetrics(SM_CXICON);
|
||||
int cyIcon = GetSystemMetrics(SM_CYICON);
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
int x = (rect.Width() - cxIcon + 1) / 2;
|
||||
int y = (rect.Height() - cyIcon + 1) / 2;
|
||||
|
||||
// Draw the icon
|
||||
dc.DrawIcon(x, y, m_hIcon);
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnPaint();
|
||||
}
|
||||
}
|
||||
|
||||
// The system calls this to obtain the cursor to display while the user drags
|
||||
// the minimized window.
|
||||
HCURSOR CVMRMixDlg::OnQueryDragIcon()
|
||||
{
|
||||
return (HCURSOR) m_hIcon;
|
||||
}
|
||||
|
||||
void CVMRMixDlg::OnButtonPlay()
|
||||
{
|
||||
ShowWindow(SW_HIDE);
|
||||
RunDemonstration();
|
||||
ShowWindow(SW_SHOW);
|
||||
}
|
||||
|
||||
void CVMRMixDlg::OnCheckApplybitmap()
|
||||
{
|
||||
m_bUseBitmap = ( m_chkBitmap.GetCheck() ) ? true : false;
|
||||
}
|
||||
|
||||
void CVMRMixDlg::OnCheckFullscreen()
|
||||
{
|
||||
m_bFullScreen = ( m_chkFullScreen.GetCheck() ) ? true : false;
|
||||
}
|
||||
|
||||
void CVMRMixDlg::OnReleasedcaptureSlider(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
int nPos = m_Slider.GetPos();
|
||||
|
||||
SetNumberOfStreams( nPos);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// CVMRMixDlg::SetNumberOfStreams
|
||||
// Desc: Sets number of source streams for presentation (m_nStreams)
|
||||
// and positions slider
|
||||
// Return: true if successful and false otherwise
|
||||
//-------------------------------------------------------------
|
||||
bool CVMRMixDlg::SetNumberOfStreams( int n)
|
||||
{
|
||||
if( n<1 || n>m_nMaxSources )
|
||||
return false;
|
||||
|
||||
char szMsg[MAX_PATH];
|
||||
m_nStreams = n;
|
||||
sprintf( szMsg, "%d", m_nStreams);
|
||||
GetDlgItem(IDC_STATIC_NSRC)->SetWindowText(szMsg);
|
||||
m_Slider.SetPos( n);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CVMRMixDlg::SelectFolder()
|
||||
{
|
||||
OPENFILENAME ofn;
|
||||
TCHAR szBuffer[MAX_PATH];
|
||||
bool bFolderIsBad = true;
|
||||
|
||||
lstrcpy(szBuffer, TEXT(""));
|
||||
|
||||
static char szFilter[] = "Video Files (.MOV, .AVI, .MPG, .VOB, .QT)\0*.AVI;*.MOV;*.MPG;*.VOB;*.QT\0" \
|
||||
"All Files (*.*)\0*.*\0\0";
|
||||
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = NULL;
|
||||
ofn.hInstance = NULL;
|
||||
ofn.lpstrFilter = szFilter;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrCustomFilter = NULL;
|
||||
ofn.nMaxCustFilter = 0;
|
||||
ofn.lpstrFile = szBuffer;
|
||||
ofn.nMaxFile = _MAX_PATH;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.lpstrTitle = "Please open any video file to select the folder...";
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
|
||||
ofn.nFileOffset = 0;
|
||||
ofn.nFileExtension = 0;
|
||||
ofn.lpstrDefExt = NULL;//"";
|
||||
ofn.lCustData = 0L;
|
||||
ofn.lpfnHook = NULL;
|
||||
ofn.lpTemplateName = NULL;
|
||||
|
||||
while( bFolderIsBad )
|
||||
{
|
||||
if (GetOpenFileName (&ofn)) // user specified a file
|
||||
{
|
||||
char szTmp[MAX_PATH];
|
||||
char *psz = NULL;
|
||||
lstrcpy(szTmp, ofn.lpstrFile);
|
||||
|
||||
// write a profile string to test
|
||||
strrev(szTmp);
|
||||
psz = strstr(szTmp,"\\");
|
||||
if( !psz )
|
||||
{
|
||||
if(MB_OK != AfxMessageBox("You must select a file folder with at least one media file. Continue?"))
|
||||
{
|
||||
bFolderIsBad = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
strcpy( m_szFolder, psz);
|
||||
strrev( m_szFolder );
|
||||
return;
|
||||
}// if
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}// while( bFolderIsBad )
|
||||
|
||||
if( bFolderIsBad )
|
||||
{
|
||||
strcpy( m_szFolder, "\0");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void CVMRMixDlg::PostNcDestroy()
|
||||
{
|
||||
CDialog::PostNcDestroy();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// CVMRMixDlg::GetMediaSettings
|
||||
// Desc: scans media settings list, verifies media files,
|
||||
// and reads duration info
|
||||
// return: true if success and false otherwise
|
||||
//---------------------------------------------------------------
|
||||
bool CVMRMixDlg::GetMediaSettings()
|
||||
{
|
||||
HRESULT hr;
|
||||
int n;
|
||||
char szMsg[MAX_PATH];
|
||||
char szInfo[MAX_PATH];
|
||||
bool bRes;
|
||||
|
||||
CMediaList * pML = NULL;
|
||||
CMediaList MLClone; // cloned and verified copy of the media list
|
||||
CMediaList mlDirty;
|
||||
|
||||
if( 2 > m_MediaList.Size())
|
||||
{
|
||||
AfxMessageBox("You must select a folder with at least two valid media files.\r\n\r\nPlease try again.", MB_OK);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
CDlgWait dlgWait(m_MediaList.Size());
|
||||
|
||||
m_MediaList.Clone(m_MediaList.Size(), &mlDirty, 0);
|
||||
m_MediaList.Clean();
|
||||
|
||||
pML = &mlDirty;
|
||||
ASSERT(pML);
|
||||
|
||||
dlgWait.Create(IDD_DIALOG_PROGRESS);
|
||||
dlgWait.ShowWindow( SW_SHOW);
|
||||
|
||||
for(n=0; n<pML->Size(); n++)
|
||||
{
|
||||
MLClone.Clean();
|
||||
bRes = pML->Clone(1, &MLClone, n);
|
||||
if( false == bRes )
|
||||
{
|
||||
sprintf( szMsg, "CVMRModule::GetMediaSettings(): failed to clone element %ld, setting source for 5 sec",n);
|
||||
OutputDebugString( szMsg);
|
||||
pML->GetItem(n)->m_llDuration = (5L * 10000000L);
|
||||
continue;
|
||||
}
|
||||
|
||||
IMediaSeeking * pMediaSeeking = NULL;
|
||||
LONGLONG llDuration = 0L;
|
||||
|
||||
CVMRCore core(this, VMRMode_Renderless, NULL, &MLClone);
|
||||
|
||||
hr = core.Play(true);
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
sprintf( szMsg, "*** failed to render source %s, method returned %s",
|
||||
pML->GetItem(n)->m_szPath, hresultNameLookup(hr));
|
||||
OutputDebugString( szMsg);
|
||||
continue;
|
||||
}
|
||||
|
||||
hr = core.GetIGraphBuilder()->QueryInterface(__uuidof(IMediaSeeking), reinterpret_cast<void**>(&pMediaSeeking));
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Cannot find IMediaSeeking interface\n");
|
||||
dlgWait.EndDialog(IDOK);
|
||||
continue;
|
||||
}
|
||||
|
||||
// get source parameters
|
||||
core.GetMediaControl()->Stop();
|
||||
hr = pMediaSeeking->GetDuration( &llDuration);
|
||||
if( FAILED(hr) || llDuration < 100L)
|
||||
{
|
||||
OutputDebugString("Failed to obtain sample duration, setting to 5 sec\n");
|
||||
llDuration = 5L * 10000000L;
|
||||
}
|
||||
|
||||
pML->GetItem(n)->m_llDuration = llDuration;
|
||||
|
||||
sprintf( szInfo, "Source %d: name:%s, duration: %ld\n",
|
||||
n, pML->GetItem(n)->m_szPath, llDuration);
|
||||
OutputDebugString(szInfo);
|
||||
|
||||
SAFERELEASE(pMediaSeeking);
|
||||
|
||||
// this media file is valid, we can add it to the media list
|
||||
SourceInfo * psi = NULL;
|
||||
psi = new SourceInfo;
|
||||
pML->GetItem(n)->CopyTo( psi);
|
||||
m_MediaList.Add(psi);
|
||||
dlgWait.SetPos(n);
|
||||
}
|
||||
|
||||
dlgWait.EndDialog(IDOK);
|
||||
if( 1 > m_MediaList.Size() )
|
||||
{
|
||||
AfxMessageBox("Some media sources are not supported with this application\r\n\r\nPlease try again with other sources.", MB_OK);
|
||||
exit(-1);
|
||||
}
|
||||
m_MediaList.AdjustDuration();
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// CVMRMixDlg::RunDemonstration
|
||||
// Desc: runs demonstration module
|
||||
// return: HRESULT code
|
||||
//---------------------------------------------------------------
|
||||
HRESULT CVMRMixDlg::RunDemonstration()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
m_MediaList.Shuffle();
|
||||
|
||||
CDemonstration demo(this, &m_MediaList, m_nStreams, &hr);
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Failed to initialize class CDemonstration\n");
|
||||
return FNS_FAIL;
|
||||
}
|
||||
clock_t tStart = clock();
|
||||
hr = demo.Perform();
|
||||
|
||||
char szMsg[MAX_PATH];
|
||||
sprintf( szMsg, "TIME:: Actual: %ld ms, Expected: %ld ms\n",
|
||||
(clock() - tStart) * 1000 / CLOCKS_PER_SEC, m_MediaList.GetAvgDuration() / 10000);
|
||||
OutputDebugString( szMsg);
|
||||
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Failed to Perform() demonstration\n");
|
||||
}
|
||||
|
||||
if( FAILED(hr))
|
||||
{
|
||||
return FNS_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FNS_PASS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: VMRMixDlg.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Headers and class description for the settings dialog
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(AFX_VMRMixDLG_H__023F795A_822F_482F_8EC9_00EC8D8AA54F__INCLUDED_)
|
||||
#define AFX_VMRMixDLG_H__023F795A_822F_482F_8EC9_00EC8D8AA54F__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CVMRMixDlg dialog
|
||||
|
||||
class CVMRMixDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
HRESULT RunDemonstration();
|
||||
bool GetMediaSettings();
|
||||
bool IsFullScreen(){ return m_bFullScreen;};
|
||||
bool IsBitmapToUse(){ return m_bUseBitmap;};
|
||||
CVMRMixDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
typedef enum eState
|
||||
{
|
||||
eStop,
|
||||
ePlay
|
||||
} eState;
|
||||
|
||||
CMediaList m_MediaList;
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CVMRMixDlg)
|
||||
enum { IDD = IDD_VMRMIX_DIALOG };
|
||||
CButton m_chkFullScreen;
|
||||
CButton m_chkBitmap;
|
||||
CSliderCtrl m_Slider;
|
||||
CButton m_btnOK;
|
||||
CButton m_btnStop;
|
||||
CButton m_btnPlay;
|
||||
CButton m_btnPause;
|
||||
//}}AFX_DATA
|
||||
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CVMRMixDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
virtual void PostNcDestroy();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
bool SetNumberOfStreams( int n);
|
||||
bool SwitchStateTo( eState eNewState);
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CVMRMixDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
afx_msg void OnSize(UINT nType, int cx, int cy);
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnButtonPlay();
|
||||
afx_msg void SelectFolder();
|
||||
afx_msg void OnReleasedcaptureSlider(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnCheckApplybitmap();
|
||||
afx_msg void OnCheckFullscreen();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
private:
|
||||
bool m_bFullScreen;
|
||||
bool m_bUseBitmap;
|
||||
int m_nStreams;
|
||||
eState m_eState;
|
||||
char m_szFolder[MAX_PATH];
|
||||
int m_nMaxSources;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_VMRMixDLG_H__023F795A_822F_482F_8EC9_00EC8D8AA54F__INCLUDED_)
|
||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// VMRMIX.RC2 - resources Microsoft Visual C++ does not edit directly
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#error this file is not editable by Microsoft Visual C++
|
||||
#endif //APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Add manually edited resources here...
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,33 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by VMRMix.rc
|
||||
//
|
||||
#define IDM_ABOUTBOX 0x0010
|
||||
#define IDD_ABOUTBOX 100
|
||||
#define IDS_ABOUTBOX 101
|
||||
#define IDD_VMRMIX_DIALOG 102
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDR_MENU 129
|
||||
#define IDD_DIALOG_PROGRESS 133
|
||||
#define IDB_BITMAP_LOGO 136
|
||||
#define IDD_DIALOG_PLAYBACK 137
|
||||
#define IDC_STATIC_NSRC 1001
|
||||
#define IDC_BUTTON_PLAY 1003
|
||||
#define IDC_STATIC_STREAMS_TITLE 1006
|
||||
#define IDC_PROGRESS 1009
|
||||
#define IDC_SLIDER 1011
|
||||
#define IDC_CHECK_APPLYBITMAP 1012
|
||||
#define IDC_CHECK_FULLSCREEN 1013
|
||||
#define ID_FILE_SELECTMEDIAFOLDER 32771
|
||||
#define ID_FILE_EXIT 32772
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 138
|
||||
#define _APS_NEXT_COMMAND_VALUE 32773
|
||||
#define _APS_NEXT_CONTROL_VALUE 1014
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,151 @@
|
||||
# Microsoft Developer Studio Project File - Name="VMRPlayer" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=VMRPlayer - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "VMRPlayer.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "VMRPlayer.mak" CFG="VMRPlayer - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "VMRPlayer - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "VMRPlayer - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "VMRPlayer - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\DirectShow\BaseClasses" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 ..\..\..\DirectShow\baseclasses\release\strmbase.lib strmiids.lib quartz.lib ddraw.lib dxguid.lib version.lib shell32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib shell32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /OPT:NOREF /OPT:ICF
|
||||
|
||||
!ELSEIF "$(CFG)" == "VMRPlayer - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\DirectShow\BaseClasses" /D "_DEBUG" /D "DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 ..\..\..\DirectShow\baseclasses\debug\strmbasd.lib strmiids.lib quartz.lib ddraw.lib dxguid.lib version.lib shell32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib comctl32.lib shell32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "VMRPlayer - Win32 Release"
|
||||
# Name "VMRPlayer - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\commands.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\persist.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\project.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\perftool.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\toolbar.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vmr.bmp
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "VMRPlayer"=".\VMRPlayer.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,443 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: app.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - Main header file for VMRPlayer sample
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Function prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
DoMainLoop(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
InitApplication(
|
||||
HINSTANCE hInstance
|
||||
);
|
||||
|
||||
BOOL
|
||||
InitInstance(
|
||||
HINSTANCE hInstance,
|
||||
int nCmdShow
|
||||
);
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
PatB(
|
||||
HDC hdc,
|
||||
int x,
|
||||
int y,
|
||||
int dx,
|
||||
int dy,
|
||||
DWORD rgb
|
||||
);
|
||||
|
||||
void
|
||||
UpdateMpegMovieRect(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
GetAdjustedClientRect(
|
||||
RECT *prc
|
||||
);
|
||||
|
||||
BOOL
|
||||
DrawStats(
|
||||
HDC hdc
|
||||
);
|
||||
|
||||
void
|
||||
CalcMovieRect(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
LPCTSTR
|
||||
IdStr(
|
||||
int idResource
|
||||
);
|
||||
|
||||
void
|
||||
UpdateSystemColors(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
SetDurationLength(
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
void
|
||||
SetCurrentPosition(
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
TCHAR *
|
||||
FormatRefTime(
|
||||
TCHAR *sz,
|
||||
REFTIME rt
|
||||
);
|
||||
|
||||
void
|
||||
DoMpegVideoPropertyPage();
|
||||
|
||||
void
|
||||
DoMpegAudioPropertyPage();
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Registry routines
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
ProfileIntIn(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
);
|
||||
|
||||
BOOL
|
||||
ProfileIntOut(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
);
|
||||
|
||||
void
|
||||
ProfileStringOut (
|
||||
LPTSTR szKey,
|
||||
LPTSTR sz
|
||||
);
|
||||
|
||||
UINT
|
||||
ProfileStringIn (
|
||||
LPTSTR szKey,
|
||||
LPTSTR szDef,
|
||||
LPTSTR sz,
|
||||
DWORD cb
|
||||
);
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
);
|
||||
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
HKEY
|
||||
GetAppKey(
|
||||
BOOL fCreate
|
||||
);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Message crackers
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
/* void Cls_OnUser(HWND hwnd, WPARAM wParam, LPARAM lParam ) */
|
||||
#define HANDLE_WM_USER(hwnd, wParam, lParam, fn) \
|
||||
((fn)(hwnd, wParam, lParam), 0L)
|
||||
|
||||
/* LRESULT Cls_OnNotify(HWND hwnd, int idFrom, NMHDR FAR* pnmhdr); */
|
||||
#ifndef HANDLE_WM_NOTIFY
|
||||
#define HANDLE_WM_NOTIFY(hwnd, wParam, lParam, fn) \
|
||||
(fn)((hwnd), (int)(wParam), (NMHDR FAR*)(lParam))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** VideoCd window class prototypes
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
extern "C" LRESULT CALLBACK
|
||||
VideoCdWndProc(
|
||||
HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnClose(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnQueryEndSession(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDestroy(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnCommand(
|
||||
HWND hwnd,
|
||||
int id,
|
||||
HWND hwndCtl,
|
||||
UINT codeNotify
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnPaint(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnTimer(
|
||||
HWND hwnd,
|
||||
UINT id
|
||||
);
|
||||
|
||||
BOOL
|
||||
VideoCd_OnCreate(
|
||||
HWND hwnd,
|
||||
LPCREATESTRUCT lpCreateStruct
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSize(
|
||||
HWND hwnd,
|
||||
UINT state,
|
||||
int cx,
|
||||
int cy
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnActivate(
|
||||
HWND hwnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnHScroll(
|
||||
HWND hwnd,
|
||||
HWND hwndCtl,
|
||||
UINT code,
|
||||
int pos
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnUser(
|
||||
HWND hwnd,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnSysColorChange(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnMenuSelect(
|
||||
HWND hwnd,
|
||||
HMENU hmenu,
|
||||
int item,
|
||||
HMENU hmenuPopup,
|
||||
UINT flags
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnInitMenuPopup(
|
||||
HWND hwnd,
|
||||
HMENU hMenu,
|
||||
UINT item,
|
||||
BOOL fSystemMenu
|
||||
);
|
||||
|
||||
#ifdef WM_NOTIFY
|
||||
LRESULT
|
||||
VideoCd_OnNotify(
|
||||
HWND hwnd,
|
||||
int idFrom,
|
||||
NMHDR FAR* pnmhdr
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
VideoCd_OnGraphNotify(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VideoCd_OnDropFiles(
|
||||
HWND hwnd,
|
||||
HDROP hdrop);
|
||||
|
||||
void
|
||||
SetPlayButtonsEnableState(
|
||||
void
|
||||
);
|
||||
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Command processing functions
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
BOOL
|
||||
VcdPlyerCaptureImage(
|
||||
LPCSTR szFile
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlyerDisplayCapturedImage(
|
||||
LPCSTR szFile
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
int i
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
);
|
||||
|
||||
BOOL
|
||||
VcdPlayerStepCmd(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
);
|
||||
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay = FALSE
|
||||
);
|
||||
|
||||
int
|
||||
VcdPlayerChangeTimeFormat(
|
||||
int id
|
||||
);
|
||||
|
||||
BOOL CALLBACK TransDlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
|
||||
BOOL CALLBACK AppImgDlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
|
||||
LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Recent filename stuff
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
typedef TCHAR RECENTFILES[MAX_PATH];
|
||||
#define MAX_RECENT_FILES 10
|
||||
#define ID_RECENT_FILE_BASE 500
|
||||
|
||||
int
|
||||
GetRecentFiles(
|
||||
int LastCount
|
||||
);
|
||||
|
||||
int
|
||||
SetRecentFiles(
|
||||
TCHAR *FileName,
|
||||
int iCount
|
||||
);
|
||||
|
||||
#define CAPTURED_IMAGE_NAME TEXT("VMRImage.bmp\0")
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Global Variables
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
extern int cxMovie;
|
||||
extern int cyMovie;
|
||||
extern HWND hwndApp;
|
||||
extern HWND g_hwndStatusbar;
|
||||
|
||||
extern int cx;
|
||||
extern int cy;
|
||||
extern int xOffset;
|
||||
extern int yOffset;
|
||||
extern TCHAR g_achFileName[];
|
||||
extern OPENFILENAME ofn;
|
||||
extern DWORD g_State;
|
||||
extern int nRecentFiles;
|
||||
extern int g_TimeFormat;
|
||||
extern LONG lMovieOrgX, lMovieOrgY;
|
||||
extern BOOL g_bSecondFileLoaded;
|
||||
extern RECENTFILES aRecentFiles[MAX_RECENT_FILES];
|
||||
|
||||
extern FLOAT g_xPos, g_yPos, g_xSize, g_ySize, g_Alpha;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Constants
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
#define LEFT_MARGIN 0
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** Video CD Player states
|
||||
**
|
||||
** These are bit flags
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define VCD_PLAYING 0x0001
|
||||
#define VCD_STOPPED 0x0002
|
||||
#define VCD_PAUSED 0x0004
|
||||
#define VCD_SKIP_F 0x0008
|
||||
#define VCD_SKIP_B 0x0010
|
||||
#define VCD_FF 0x0020
|
||||
#define VCD_RW 0x0040
|
||||
#define VCD_SEEKING (VCD_FF | VCD_RW)
|
||||
#define VCD_LOADED 0x0080
|
||||
#define VCD_NO_CD 0x0100
|
||||
#define VCD_DATA_CD_LOADED 0x0200
|
||||
#define VCD_EDITING 0x0400
|
||||
#define VCD_PAUSED_AND_MOVED 0x0800
|
||||
#define VCD_PLAY_PENDING 0x1000
|
||||
#define VCD_WAS_PLAYING 0x2000
|
||||
#define VCD_IN_USE 0x4000
|
||||
#define VCD_STEPPING 0x8000
|
||||
|
||||
enum {PerformanceTimer = 32, StatusTimer = 33};
|
||||
@@ -0,0 +1,486 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: commands.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - Processes commands from the user.
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
#include <streams.h>
|
||||
#include "project.h"
|
||||
|
||||
typedef LPBITMAPINFOHEADER PDIB;
|
||||
|
||||
extern CMpegMovie *pMpegMovie;
|
||||
extern void RepositionMovie(HWND hwnd);
|
||||
|
||||
// Constants
|
||||
#define BFT_BITMAP 0x4d42 /* 'BM' */
|
||||
|
||||
// Macros
|
||||
#define DibNumColors(lpbi) ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
|
||||
? (int)(1 << (int)(lpbi)->biBitCount) \
|
||||
: (int)(lpbi)->biClrUsed)
|
||||
|
||||
#define DibSize(lpbi) ((lpbi)->biSize + (lpbi)->biSizeImage + (int)(lpbi)->biClrUsed * sizeof(RGBQUAD))
|
||||
|
||||
#define DibPaletteSize(lpbi) (DibNumColors(lpbi) * sizeof(RGBQUAD))
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlyerCaptureImage
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlyerCaptureImage(
|
||||
LPCSTR szFile
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
BYTE* lpCurrImage = NULL;
|
||||
|
||||
if(pMpegMovie->GetCurrentImage(&lpCurrImage) == S_OK)
|
||||
{
|
||||
BITMAPFILEHEADER hdr;
|
||||
HFILE fh;
|
||||
OFSTRUCT of;
|
||||
DWORD dwSize;
|
||||
PDIB pdib = (PDIB)lpCurrImage;
|
||||
|
||||
fh = OpenFile(szFile,&of,OF_CREATE|OF_READWRITE);
|
||||
|
||||
if(fh == -1)
|
||||
return FALSE;
|
||||
|
||||
dwSize = DibSize(pdib);
|
||||
|
||||
hdr.bfType = BFT_BITMAP;
|
||||
hdr.bfSize = dwSize + sizeof(BITMAPFILEHEADER);
|
||||
hdr.bfReserved1 = 0;
|
||||
hdr.bfReserved2 = 0;
|
||||
hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + pdib->biSize +
|
||||
DibPaletteSize(pdib);
|
||||
|
||||
_lwrite(fh,(LPCSTR)(LPVOID)&hdr,sizeof(BITMAPFILEHEADER));
|
||||
_hwrite(fh,(LPCSTR)(LPVOID)pdib,dwSize);
|
||||
|
||||
_lclose(fh);
|
||||
|
||||
CoTaskMemFree(lpCurrImage);
|
||||
|
||||
TCHAR szText[128], szDir[MAX_PATH];
|
||||
GetCurrentDirectory(MAX_PATH, szDir);
|
||||
wsprintf(szText, TEXT("Captured current image to %s\\%s."), szDir, szFile);
|
||||
MessageBox(hwndApp, szText, TEXT("Captured bitmap"), MB_OK);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlyerDisplayCapturedImage
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlyerDisplayCapturedImage(
|
||||
LPCSTR szFile
|
||||
)
|
||||
{
|
||||
// Open the bitmap with the system-default application
|
||||
ShellExecute(hwndApp, "open\0", szFile, NULL, NULL, SW_SHOWNORMAL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerOpenCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerOpenCmd(
|
||||
int strmID
|
||||
)
|
||||
{
|
||||
static BOOL fFirstTime = TRUE;
|
||||
BOOL fRet;
|
||||
TCHAR achFileName[MAX_PATH];
|
||||
TCHAR achFilter[MAX_PATH];
|
||||
LPTSTR lp;
|
||||
|
||||
if(fFirstTime)
|
||||
{
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwndApp;
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST |
|
||||
OFN_SHAREAWARE | OFN_PATHMUSTEXIST;
|
||||
}
|
||||
|
||||
lstrcpy(achFilter, IdStr(STR_FILE_FILTER));
|
||||
ofn.lpstrFilter = achFilter;
|
||||
|
||||
/*
|
||||
** Convert the resource string into to something suitable for
|
||||
** GetOpenFileName ie. replace '#' characters with '\0' characters.
|
||||
*/
|
||||
for(lp = achFilter; *lp; lp++)
|
||||
{
|
||||
if(*lp == TEXT('#'))
|
||||
{
|
||||
*lp = TEXT('\0');
|
||||
}
|
||||
}
|
||||
|
||||
ofn.lpstrFile = achFileName;
|
||||
ofn.nMaxFile = sizeof(achFileName) / sizeof(TCHAR);
|
||||
ZeroMemory(achFileName, sizeof(achFileName));
|
||||
|
||||
fRet = GetOpenFileName(&ofn);
|
||||
if(fRet)
|
||||
{
|
||||
if(strmID == 0)
|
||||
{
|
||||
fFirstTime = FALSE;
|
||||
ProcessOpen(achFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->RenderSecondFile(achFileName);
|
||||
}
|
||||
}
|
||||
|
||||
InitStreamParams(strmID);
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerCloseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerCloseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
LONG cx, cy;
|
||||
|
||||
g_State = VCD_NO_CD;
|
||||
pMpegMovie->GetMoviePosition(&lMovieOrgX, &lMovieOrgY, &cx, &cy);
|
||||
pMpegMovie->StopMovie();
|
||||
pMpegMovie->CloseMovie();
|
||||
|
||||
SetDurationLength((REFTIME)0);
|
||||
SetCurrentPosition((REFTIME)0);
|
||||
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
|
||||
g_bSecondFileLoaded = FALSE;
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPlayCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPlayCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fStopped = (g_State & VCD_STOPPED);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fStopped || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
|
||||
g_State &= ~(fStopped ? VCD_STOPPED : VCD_PAUSED);
|
||||
g_State |= VCD_PLAYING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPlayCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerStopCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if((fPlaying || fPaused))
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->StopMovie();
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
g_State &= ~(fPlaying ? VCD_PLAYING : VCD_PAUSED);
|
||||
g_State |= VCD_STOPPED;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerStepCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerStepCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
// Ensure that the video is paused to update toolbar buttons
|
||||
if(g_State & VCD_PLAYING)
|
||||
VcdPlayerPauseCmd();
|
||||
|
||||
if(pMpegMovie->FrameStepMovie())
|
||||
{
|
||||
g_State |= VCD_STEPPING;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerPauseCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerPauseCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
BOOL fPlaying = (g_State & VCD_PLAYING);
|
||||
BOOL fPaused = (g_State & VCD_PAUSED);
|
||||
|
||||
if(fPlaying)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PauseMovie();
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
g_State &= ~VCD_PLAYING;
|
||||
g_State |= VCD_PAUSED;
|
||||
}
|
||||
else if(fPaused)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
|
||||
g_State &= ~VCD_PAUSED;
|
||||
g_State |= VCD_PLAYING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerSeekCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
VcdPlayerSeekCmd(
|
||||
REFTIME rtSeekBy
|
||||
)
|
||||
{
|
||||
REFTIME rt;
|
||||
REFTIME rtDur;
|
||||
|
||||
rtDur = pMpegMovie->GetDuration();
|
||||
rt = pMpegMovie->GetCurrentPosition() + rtSeekBy;
|
||||
|
||||
rt = max(0, min(rt, rtDur));
|
||||
|
||||
pMpegMovie->SeekToPosition(rt,TRUE);
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* ProcessOpen
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
ProcessOpen(
|
||||
TCHAR *achFileName,
|
||||
BOOL bPlay
|
||||
)
|
||||
{
|
||||
/*
|
||||
** If we currently have a video loaded we need to discard it here.
|
||||
*/
|
||||
if(g_State & VCD_LOADED)
|
||||
{
|
||||
VcdPlayerCloseCmd();
|
||||
}
|
||||
|
||||
lstrcpy(g_achFileName, achFileName);
|
||||
|
||||
pMpegMovie = new CMpegMovie(hwndApp);
|
||||
if(pMpegMovie)
|
||||
{
|
||||
HRESULT hr = pMpegMovie->OpenMovie(g_achFileName);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
TCHAR achTmp[MAX_PATH];
|
||||
|
||||
nRecentFiles = SetRecentFiles(achFileName, nRecentFiles);
|
||||
|
||||
wsprintf(achTmp, IdStr(STR_APP_TITLE_LOADED),
|
||||
g_achFileName);
|
||||
g_State = (VCD_LOADED | VCD_STOPPED);
|
||||
|
||||
// SetDurationLength(pMpegMovie->GetDuration());
|
||||
g_TimeFormat = VcdPlayerChangeTimeFormat(g_TimeFormat);
|
||||
|
||||
RepositionMovie(hwndApp);
|
||||
pMpegMovie->SetBorderClr(RGB(0x00, 0x80, 0x80));
|
||||
|
||||
// If play
|
||||
if(bPlay)
|
||||
{
|
||||
pMpegMovie->PlayMovie();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCHAR Buffer[MAX_ERROR_TEXT_LEN];
|
||||
|
||||
if(AMGetErrorText(hr, Buffer, MAX_ERROR_TEXT_LEN))
|
||||
{
|
||||
MessageBox(hwndApp, Buffer,
|
||||
IdStr(STR_APP_TITLE), MB_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp,
|
||||
TEXT("Failed to open the movie. Either the file was ")
|
||||
TEXT("not found or the wave device is in use."),
|
||||
IdStr(STR_APP_TITLE), MB_OK);
|
||||
}
|
||||
|
||||
pMpegMovie->CloseMovie();
|
||||
delete pMpegMovie;
|
||||
pMpegMovie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InitStreamParams(0);
|
||||
|
||||
InvalidateRect(hwndApp, NULL, FALSE);
|
||||
UpdateWindow(hwndApp);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerChangeTimeFormat
|
||||
*
|
||||
* Tries to change the time format to id. Returns the time format that
|
||||
* actually got set. This may differ from id if the graph does not support
|
||||
* the requested time format.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
VcdPlayerChangeTimeFormat(
|
||||
int id
|
||||
)
|
||||
{
|
||||
// Menu items are disabled while we are playing
|
||||
BOOL bRet = FALSE;
|
||||
int idActual = id;
|
||||
|
||||
ASSERT(pMpegMovie);
|
||||
ASSERT(pMpegMovie->StatusMovie() != MOVIE_NOTOPENED);
|
||||
|
||||
// Change the time format with the filtergraph
|
||||
switch(id)
|
||||
{
|
||||
case IDM_FRAME:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_FRAME);
|
||||
break;
|
||||
|
||||
case IDM_FIELD:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_FIELD);
|
||||
break;
|
||||
|
||||
case IDM_SAMPLE:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_SAMPLE);
|
||||
break;
|
||||
|
||||
case IDM_BYTES:
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_BYTE);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bRet)
|
||||
{
|
||||
// IDM_TIME and all other cases, everyone should support IDM_TIME
|
||||
bRet = pMpegMovie->SetTimeFormat(TIME_FORMAT_MEDIA_TIME);
|
||||
ASSERT(bRet);
|
||||
idActual = IDM_TIME;
|
||||
}
|
||||
|
||||
// Pause the movie to get a current position
|
||||
|
||||
SetDurationLength(pMpegMovie->GetDuration());
|
||||
SetCurrentPosition(pMpegMovie->GetCurrentPosition());
|
||||
|
||||
return idActual;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* VcdPlayerRewindCmd
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
VcdPlayerRewindCmd(
|
||||
void
|
||||
)
|
||||
{
|
||||
if(pMpegMovie)
|
||||
{
|
||||
pMpegMovie->SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,401 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: persist.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - State persistence helper functions
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlconv.cpp>
|
||||
#include <mmreg.h>
|
||||
|
||||
#include "project.h"
|
||||
|
||||
// Constants
|
||||
const int CX_DEFAULT = 400; /* Default window width */
|
||||
const int CY_DEFAULT = 400; /* Default window height */
|
||||
|
||||
// Global data
|
||||
RECENTFILES aRecentFiles[MAX_RECENT_FILES];
|
||||
int nRecentFiles;
|
||||
|
||||
// Global static data
|
||||
static TCHAR cszWindow[] = TEXT("Window");
|
||||
static TCHAR cszAppKey[] = TEXT("Software\\Microsoft\\Multimedia Tools\\VMRPlayer");
|
||||
|
||||
|
||||
/*+ GetAppKey
|
||||
*
|
||||
*-=================================================================*/
|
||||
|
||||
HKEY
|
||||
GetAppKey(
|
||||
BOOL fCreate
|
||||
)
|
||||
{
|
||||
HKEY hKey = 0;
|
||||
|
||||
if(fCreate)
|
||||
{
|
||||
if(RegCreateKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
|
||||
return hKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RegOpenKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
|
||||
return hKey;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*+ ProfileIntIn
|
||||
*
|
||||
*-=================================================================*/
|
||||
|
||||
int
|
||||
ProfileIntIn(
|
||||
const TCHAR *szKey,
|
||||
int iDefault
|
||||
)
|
||||
{
|
||||
DWORD dwType=0;
|
||||
int iValue=0;
|
||||
BYTE aData[20];
|
||||
DWORD cb;
|
||||
HKEY hKey;
|
||||
|
||||
if((hKey = GetAppKey(TRUE)) == 0)
|
||||
{
|
||||
return iDefault;
|
||||
}
|
||||
|
||||
*(UINT *)&aData = 0;
|
||||
cb = sizeof(aData);
|
||||
|
||||
if(RegQueryValueEx(hKey, szKey, NULL, &dwType, aData, &cb))
|
||||
{
|
||||
iValue = iDefault;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dwType == REG_DWORD || dwType == REG_BINARY)
|
||||
{
|
||||
iValue = *(int *)&aData;
|
||||
}
|
||||
else if(dwType == REG_SZ)
|
||||
{
|
||||
iValue = atoi((LPSTR)aData);
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return iValue;
|
||||
}
|
||||
|
||||
|
||||
/*+ ProfileIntOut
|
||||
*
|
||||
*-=================================================================*/
|
||||
|
||||
BOOL
|
||||
ProfileIntOut(
|
||||
const TCHAR *szKey,
|
||||
int iVal
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
hKey = GetAppKey(TRUE);
|
||||
if(hKey)
|
||||
{
|
||||
RegSetValueEx(hKey, szKey, 0, REG_DWORD, (LPBYTE)&iVal, sizeof(DWORD));
|
||||
RegCloseKey(hKey);
|
||||
bRet = TRUE;
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/*+ ProfileStringIn
|
||||
*
|
||||
*-=================================================================*/
|
||||
|
||||
UINT
|
||||
ProfileStringIn(
|
||||
LPTSTR szKey,
|
||||
LPTSTR szDef,
|
||||
LPTSTR sz,
|
||||
DWORD cb
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD dwType;
|
||||
|
||||
if((hKey = GetAppKey(FALSE)) == 0)
|
||||
{
|
||||
lstrcpy(sz, szDef);
|
||||
return lstrlen(sz);
|
||||
}
|
||||
|
||||
if(RegQueryValueEx(hKey, szKey, NULL, &dwType, (LPBYTE)sz, &cb) || dwType != REG_SZ)
|
||||
{
|
||||
lstrcpy(sz, szDef);
|
||||
cb = lstrlen(sz);
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return cb;
|
||||
}
|
||||
|
||||
|
||||
/*+ ProfileStringOut
|
||||
*
|
||||
*-=================================================================*/
|
||||
|
||||
void
|
||||
ProfileStringOut(
|
||||
LPTSTR szKey,
|
||||
LPTSTR sz
|
||||
)
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
hKey = GetAppKey(TRUE);
|
||||
if(hKey)
|
||||
RegSetValueEx(hKey, szKey, 0, REG_SZ, (LPBYTE)sz, sizeof(TCHAR) * (lstrlen(sz)+1));
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
|
||||
/*+ LoadWindowPos
|
||||
*
|
||||
* retrieve the window position information from dragn.ini
|
||||
*
|
||||
*-=================================================================*/
|
||||
|
||||
#ifndef SPI_GETWORKAREA
|
||||
#define SPI_GETWORKAREA 48 // because NT doesnt have this define yet
|
||||
#endif
|
||||
|
||||
BOOL
|
||||
LoadWindowPos(
|
||||
LPRECT lprc
|
||||
)
|
||||
{
|
||||
static RECT rcDefault = {0,0,CX_DEFAULT,CY_DEFAULT};
|
||||
RECT rcScreen;
|
||||
RECT rc;
|
||||
HKEY hKey = GetAppKey(FALSE);
|
||||
|
||||
// read window placement from the registry.
|
||||
//
|
||||
*lprc = rcDefault;
|
||||
|
||||
if(hKey)
|
||||
{
|
||||
DWORD cb;
|
||||
DWORD dwType;
|
||||
|
||||
cb = sizeof(rc);
|
||||
if(! RegQueryValueEx(hKey, cszWindow, NULL, &dwType, (LPBYTE)&rc, &cb)
|
||||
&& dwType == REG_BINARY && cb == sizeof(RECT))
|
||||
{
|
||||
*lprc = rc;
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
// if we fail to get the working area (screen-tray), then assume
|
||||
// the screen is 640x480
|
||||
//
|
||||
if(! SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, FALSE))
|
||||
{
|
||||
rcScreen.top = rcScreen.left = 0;
|
||||
rcScreen.right = 640;
|
||||
rcScreen.bottom = 480;
|
||||
}
|
||||
|
||||
// if the proposed window position is outside the screen,
|
||||
// use the default placement
|
||||
//
|
||||
if(! IntersectRect(&rc, &rcScreen, lprc))
|
||||
{
|
||||
*lprc = rcDefault;
|
||||
}
|
||||
|
||||
return ! IsRectEmpty(lprc);
|
||||
}
|
||||
|
||||
|
||||
/*+ SaveWindowPos
|
||||
*
|
||||
* store the window position information in dragn.ini
|
||||
*
|
||||
*-=================================================================*/
|
||||
|
||||
BOOL
|
||||
SaveWindowPos(
|
||||
HWND hwnd
|
||||
)
|
||||
{
|
||||
WINDOWPLACEMENT wpl;
|
||||
HKEY hKey = GetAppKey(TRUE);
|
||||
|
||||
if(!hKey)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// save the current size and position of the window to the registry
|
||||
//
|
||||
ZeroMemory(&wpl, sizeof(wpl));
|
||||
wpl.length = sizeof(wpl);
|
||||
GetWindowPlacement(hwnd, &wpl);
|
||||
|
||||
RegSetValueEx(hKey, cszWindow, 0, REG_BINARY,
|
||||
(LPBYTE)&wpl.rcNormalPosition,
|
||||
sizeof(wpl.rcNormalPosition));
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* GetRecentFiles
|
||||
*
|
||||
* Reads at most MAX_RECENT_FILES from vcdplyer.ini. Returns the number
|
||||
* of files actually read. Updates the File menu to show the "recent" files.
|
||||
*
|
||||
\**************************************************************************/
|
||||
|
||||
int
|
||||
GetRecentFiles(
|
||||
int iLastCount
|
||||
)
|
||||
{
|
||||
int i;
|
||||
TCHAR FileName[MAX_PATH];
|
||||
TCHAR szKey[32];
|
||||
HMENU hSubMenu;
|
||||
|
||||
//
|
||||
// Delete the files from the menu
|
||||
//
|
||||
hSubMenu = GetSubMenu(GetMenu(hwndApp), 0);
|
||||
|
||||
// Delete the separator at slot 3 and all the other recent file entries
|
||||
if(iLastCount != 0)
|
||||
{
|
||||
DeleteMenu(hSubMenu, 3, MF_BYPOSITION);
|
||||
|
||||
for(i = 1; i <= iLastCount; i++)
|
||||
{
|
||||
DeleteMenu(hSubMenu, ID_RECENT_FILE_BASE + i, MF_BYCOMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 1; i <= MAX_RECENT_FILES; i++)
|
||||
{
|
||||
DWORD len;
|
||||
TCHAR szMenuName[MAX_PATH + 3];
|
||||
|
||||
wsprintf(szKey, TEXT("File %d"), i);
|
||||
len = ProfileStringIn(szKey, TEXT(""), FileName, MAX_PATH * sizeof(TCHAR));
|
||||
if(len == 0)
|
||||
{
|
||||
i = i - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
lstrcpy(aRecentFiles[i - 1], FileName);
|
||||
wsprintf(szMenuName, TEXT("&%d %s"), i, FileName);
|
||||
|
||||
if(i == 1)
|
||||
{
|
||||
InsertMenu(hSubMenu, 3, MF_SEPARATOR | MF_BYPOSITION, (UINT)-1, NULL);
|
||||
}
|
||||
|
||||
InsertMenu(hSubMenu, 3 + i, MF_STRING | MF_BYPOSITION,
|
||||
ID_RECENT_FILE_BASE + i, szMenuName);
|
||||
}
|
||||
|
||||
//
|
||||
// i is the number of recent files in the array.
|
||||
//
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SetRecentFiles
|
||||
*
|
||||
* Writes the most recent files to the vcdplyer.ini file. Purges the oldest
|
||||
* file if necessary.
|
||||
*
|
||||
\**************************************************************************/
|
||||
int
|
||||
SetRecentFiles(
|
||||
TCHAR *FileName, // File name to add
|
||||
int iCount // Current count of files
|
||||
)
|
||||
{
|
||||
TCHAR FullPathFileName[MAX_PATH];
|
||||
TCHAR *lpFile;
|
||||
TCHAR szKey[32];
|
||||
int iCountNew;
|
||||
int i;
|
||||
|
||||
//
|
||||
// Check for dupes - we don't allow them !
|
||||
//
|
||||
for(i = 0; i < iCount; i++)
|
||||
{
|
||||
if(0 == lstrcmpi(FileName, aRecentFiles[i]))
|
||||
{
|
||||
return iCount;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Throw away the oldest entry
|
||||
//
|
||||
MoveMemory(&aRecentFiles[1], &aRecentFiles[0],
|
||||
sizeof(aRecentFiles) - sizeof(aRecentFiles[1]));
|
||||
|
||||
//
|
||||
// Copy in the full path of the new file.
|
||||
//
|
||||
GetFullPathName(FileName, MAX_PATH, FullPathFileName, &lpFile);
|
||||
lstrcpy(aRecentFiles[0], FullPathFileName);
|
||||
|
||||
//
|
||||
// Update the count of files, saturate to MAX_RECENT_FILES.
|
||||
//
|
||||
iCountNew = min(iCount + 1, MAX_RECENT_FILES);
|
||||
|
||||
//
|
||||
// Clear the old stuff and the write out the recent files to disk
|
||||
//
|
||||
for(i = 1; i <= iCountNew; i++)
|
||||
{
|
||||
wsprintf(szKey, TEXT("File %d"), i);
|
||||
ProfileStringOut(szKey, aRecentFiles[i - 1]);
|
||||
}
|
||||
|
||||
//
|
||||
// Update the file menu
|
||||
//
|
||||
GetRecentFiles(iCount);
|
||||
|
||||
return iCountNew; // the updated count of files.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: project.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - Master header file that includes all other header files used
|
||||
// by the project. This enables precompiled headers during build.
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <windows.h>
|
||||
#include <commdlg.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "app.h"
|
||||
#include "vcdplyer.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
void InitStreamParams(int i);
|
||||
@@ -0,0 +1,29 @@
|
||||
Windows XP DirectShow Sample -- VMRPlayer
|
||||
-----------------------------------------
|
||||
|
||||
This sample demonstrates using the Video Mixing Renderer to blend
|
||||
one or two running videos and a static image.
|
||||
|
||||
Begin by opening a primary video stream from the File menu. If you
|
||||
would like to render a second file that will be alpha-blended with
|
||||
the primary file, then open a secondary video stream from the File menu.
|
||||
|
||||
To control size, position, and alpha blending properties of the
|
||||
primary or secondary video, choose "Primary Stream" or "Secondary Stream"
|
||||
from the VMR Properties menu. By default, the Primary stream will have
|
||||
an alpha value of 1.0 and the secondary stream will blend with an
|
||||
alpha value of 0.5. The properties dialogs are implemented as modal dialogs.
|
||||
|
||||
You may also overlay an alpha-blended static image by opening the
|
||||
"Static App Image" option on the VMR Properties menu. Enable the
|
||||
"Display App Image" checkbox to cause the image to appear. By default,
|
||||
the image will be centered and will blend with an alpha value of 0.5.
|
||||
|
||||
NOTE: This sample requires Windows XP (or greater) functionality
|
||||
and will exit on other systems.
|
||||
|
||||
Usage:
|
||||
VMRPlayer </P filename>
|
||||
|
||||
/P: Optional filename to automatically render and play at startup
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) 1995-2001 Microsoft Corporation. All Rights Reserved.
|
||||
//
|
||||
// These are indexes used by the toolbar.
|
||||
//
|
||||
#define IDC_STATIC -1
|
||||
|
||||
#define IDX_SEPARATOR -1
|
||||
#define IDX_1 0
|
||||
#define IDX_2 1
|
||||
#define IDX_3 2
|
||||
#define IDX_4 3
|
||||
#define IDX_5 4
|
||||
#define IDX_6 5
|
||||
#define IDX_7 6
|
||||
#define IDX_8 7
|
||||
#define IDX_9 8
|
||||
#define IDX_10 9
|
||||
#define IDX_11 10
|
||||
#define IDX_12 11
|
||||
#define DEFAULT_TBAR_SIZE 10
|
||||
#define NUMBER_OF_BITMAPS 12
|
||||
|
||||
#define ID_STATUSBAR 28
|
||||
#define ID_TOOLBAR 29
|
||||
#define ID_TRACKBAR 30
|
||||
|
||||
#define IDR_MAIN_MENU 101
|
||||
#define IDR_TOOLBAR 102
|
||||
#define IDR_VIDEOCD_ICON 103
|
||||
#define IDR_ACCELERATOR 104
|
||||
#define IDR_VMR 105
|
||||
#define IDD_ABOUTBOX 200
|
||||
|
||||
#define IDC_XPOS_TRK 1000
|
||||
#define IDC_YPOS_TRK 1001
|
||||
#define IDC_XPOS 1002
|
||||
#define IDC_YPOS 1003
|
||||
#define IDC_XSIZE_TRK 1004
|
||||
#define IDC_YSIZE_TRK 1005
|
||||
#define IDC_XSIZE 1006
|
||||
#define IDC_YSIZE 1007
|
||||
#define IDC_IMAGE_ENABLE 1008
|
||||
#define IDC_ALPHA_TRK2 1009
|
||||
#define IDC_ALPHA 1010
|
||||
|
||||
#define IDM_FILE_OPEN 40001
|
||||
#define IDM_FILE_OPEN2 40005
|
||||
#define IDM_FILE_CLOSE 40002
|
||||
#define IDM_FILE_EXIT 40003
|
||||
|
||||
#define IDM_APP_IMAGE 42000
|
||||
#define IDM_STREAM_A 42001
|
||||
#define IDM_STREAM_B 42002
|
||||
#define IDM_CAPTURE_IMAGE 42003
|
||||
#define IDM_DISPLAY_CAPTURED_IMAGE 42004
|
||||
|
||||
#define IDM_HELP_ABOUT 40102
|
||||
|
||||
// Toolbar commands
|
||||
#define IDM_MOVIE_STOP 40010
|
||||
#define IDM_MOVIE_PLAY 40011
|
||||
#define IDM_MOVIE_PREVTRACK 40012
|
||||
#define IDM_MOVIE_PAUSE 40013
|
||||
#define IDM_MOVIE_SKIP_FORE 40014
|
||||
#define IDM_MOVIE_SKIP_BACK 40015
|
||||
#define IDM_MOVIE_STEP 40021
|
||||
|
||||
#define MENU_STRING_BASE 1000
|
||||
|
||||
// Different time formats
|
||||
#define IDM_TIME 40150
|
||||
#define IDM_FRAME 40151
|
||||
#define IDM_FIELD 40152
|
||||
#define IDM_SAMPLE 40153
|
||||
#define IDM_BYTES 40154
|
||||
|
||||
// File
|
||||
#define STR_FILE_OPEN IDM_FILE_OPEN + MENU_STRING_BASE
|
||||
#define STR_FILE_OPEN2 IDM_FILE_OPEN2 + MENU_STRING_BASE
|
||||
#define STR_FILE_CLOSE IDM_FILE_CLOSE + MENU_STRING_BASE
|
||||
#define STR_FILE_EXIT IDM_FILE_EXIT + MENU_STRING_BASE
|
||||
|
||||
// Properties Menu
|
||||
#define STR_APP_IMAGE IDM_APP_IMAGE + MENU_STRING_BASE
|
||||
#define STR_STREAM_A IDM_STREAM_A + MENU_STRING_BASE
|
||||
#define STR_STREAM_B IDM_STREAM_B + MENU_STRING_BASE
|
||||
#define STR_CAPTURE_IMAGE IDM_CAPTURE_IMAGE + MENU_STRING_BASE
|
||||
#define STR_DISPLAY_CAPTURED_IMAGE IDM_DISPLAY_CAPTURED_IMAGE + MENU_STRING_BASE
|
||||
|
||||
// Help Menu HELP_MENU_BASE
|
||||
#define STR_HELP_ABOUT IDM_HELP_ABOUT + MENU_STRING_BASE
|
||||
|
||||
// System Menu
|
||||
#define STR_SYSMENU_RESTORE 1800
|
||||
#define STR_SYSMENU_MOVE 1801
|
||||
#define STR_SYSMENU_MINIMIZE 1802
|
||||
#define STR_SYSMENU_CLOSE 1803
|
||||
#define STR_SYSMENU_MAXIMIZE 1804
|
||||
#define STR_SYSMENU_TASK_LIST 1805
|
||||
|
||||
#define STR_FILE_FILTER 2000
|
||||
#define STR_APP_TITLE 2001
|
||||
#define STR_APP_TITLE_LOADED 2002
|
||||
|
||||
#define IDD_AUDIOPROP 4000
|
||||
#define IDD_VIDEOPROP 4001
|
||||
|
||||
#define STR_MAX_STRING_LEN 256
|
||||
@@ -0,0 +1,31 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by vcdplyer.rc
|
||||
//
|
||||
#define ID_BUTTON40001 40001
|
||||
#define ID_BUTTON40002 40002
|
||||
#define ID_BUTTON40003 40003
|
||||
#define ID_BUTTON40004 40004
|
||||
#define ID_BUTTON40005 40005
|
||||
#define ID_BUTTON40006 40006
|
||||
#define ID_BUTTON40007 40007
|
||||
#define ID_BUTTON40008 40008
|
||||
#define ID_BUTTON40009 40009
|
||||
#define ID_BUTTON40010 40010
|
||||
#define ID_BUTTON40011 40011
|
||||
#define ID_BUTTON40012 40012
|
||||
#define ID_BUTTON40013 40013
|
||||
#define ID_BUTTON40014 40014
|
||||
#define ID_BUTTON40016 40016
|
||||
#define ID_BUTTON40017 40017
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40019
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,978 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - A VMR-enabled player application
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <streams.h>
|
||||
#include <mmreg.h>
|
||||
#include <commctrl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <atlbase.h>
|
||||
|
||||
#include "project.h"
|
||||
|
||||
#include <initguid.h>
|
||||
|
||||
extern int FrameStepCount;
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CMpegMovie
|
||||
*
|
||||
* Constructors and destructors
|
||||
*
|
||||
\**************************************************************************/
|
||||
CMpegMovie::CMpegMovie(HWND hwndApplication) :
|
||||
m_hwndApp(hwndApplication),
|
||||
m_MediaEvent(NULL),
|
||||
m_Mode(MOVIE_NOTOPENED),
|
||||
m_Fg(NULL),
|
||||
m_Gb(NULL),
|
||||
m_Mc(NULL),
|
||||
m_Ms(NULL),
|
||||
m_Me(NULL),
|
||||
m_Wc(NULL),
|
||||
m_pMixControl(NULL),
|
||||
m_TimeFormat(TIME_FORMAT_MEDIA_TIME)
|
||||
{
|
||||
}
|
||||
CMpegMovie::~CMpegMovie()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetRenderingMode
|
||||
*
|
||||
\**************************************************************************/
|
||||
static HRESULT SetRenderingMode( IBaseFilter* pBaseFilter, VMRMode mode )
|
||||
{
|
||||
// Test VMRConfig, VMRMonitorConfig
|
||||
IVMRFilterConfig* pConfig;
|
||||
|
||||
HRESULT hr = pBaseFilter->QueryInterface(IID_IVMRFilterConfig, (LPVOID *)&pConfig);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = pConfig->SetRenderingMode(mode);
|
||||
hr = pConfig->SetRenderingPrefs(RenderPrefs_ForceOverlays|RenderPrefs_AllowOverlays);
|
||||
pConfig->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* AddVideoMixingRendererToFG
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::AddVideoMixingRendererToFG()
|
||||
{
|
||||
IBaseFilter* pBF = NULL;
|
||||
HRESULT hRes = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = m_Fg->AddFilter(pBF, L"Video Mixing Renderer");
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
// Test VMRConfig, VMRMonitorConfig
|
||||
IVMRFilterConfig* pConfig;
|
||||
HRESULT hRes2 = pBF->QueryInterface(IID_IVMRFilterConfig, (LPVOID *)&pConfig);
|
||||
if(SUCCEEDED(hRes2))
|
||||
{
|
||||
hRes2 = pConfig->SetNumberOfStreams(2);
|
||||
hRes2 = pConfig->SetRenderingMode(VMRMode_Windowless);
|
||||
hRes2 = pConfig->SetRenderingPrefs(RenderPrefs_AllowOverlays);
|
||||
// RenderPrefs_ForceOverlays);
|
||||
// RenderPrefs_ForceOffscreen);
|
||||
// RenderPrefs_DoNotRenderColorKeyAndBorder);
|
||||
pConfig->Release();
|
||||
}
|
||||
|
||||
IVMRMonitorConfig* pMonitorConfig;
|
||||
HRESULT hRes3 = pBF->QueryInterface(IID_IVMRMonitorConfig, (LPVOID *)&pMonitorConfig);
|
||||
if(SUCCEEDED(hRes3))
|
||||
{
|
||||
// STDMETHODIMP SetMonitor( const VMRGUID *pGUID );
|
||||
// STDMETHODIMP GetMonitor( VMRGUID *pGUID );
|
||||
// STDMETHODIMP SetDefaultMonitor( const VMRGUID *pGUID );
|
||||
// STDMETHODIMP GetDefaultMonitor( VMRGUID *pGUID );
|
||||
// STDMETHODIMP GetAvailableMonitors( VMRMONITORINFO* pInfo, DWORD dwMaxInfoArraySize, DWORD* pdwNumDevices );
|
||||
VMRGUID guid;
|
||||
HRESULT hr4 = pMonitorConfig->GetMonitor(&guid);
|
||||
pMonitorConfig->Release();
|
||||
}
|
||||
|
||||
hRes = pBF->QueryInterface(IID_IVMRWindowlessControl, (LPVOID *)&m_Wc);
|
||||
}
|
||||
}
|
||||
|
||||
if(pBF)
|
||||
{
|
||||
pBF->Release();
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hRes))
|
||||
{
|
||||
HRESULT hr = m_Wc->SetVideoClippingWindow(m_hwndApp);
|
||||
hr = m_Wc->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_Wc)
|
||||
{
|
||||
m_Wc->Release();
|
||||
m_Wc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return hRes;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RenderSecondFile
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::RenderSecondFile(
|
||||
TCHAR* lpFileName
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
HRESULT hRes;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
// Since the user might have already rendered the second file,
|
||||
// free it if it has been rendered
|
||||
if (m_Gb)
|
||||
{
|
||||
m_Gb->Release();
|
||||
m_Gb = NULL;
|
||||
|
||||
hRes = m_Fg->QueryInterface(IID_IGraphBuilder, (LPVOID *)&m_Gb);
|
||||
if(FAILED(hRes))
|
||||
{
|
||||
MessageBeep(0);
|
||||
return hRes;
|
||||
}
|
||||
}
|
||||
|
||||
wcscpy(FileName, T2W(lpFileName));
|
||||
|
||||
hRes = m_Gb->RenderFile(FileName, NULL);
|
||||
if(SUCCEEDED(hRes) && m_pMixControl)
|
||||
{
|
||||
hRes = m_pMixControl->SetAlpha(1, 0.5f);
|
||||
g_bSecondFileLoaded = TRUE;
|
||||
}
|
||||
|
||||
return hRes;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* OpenMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::OpenMovie(
|
||||
TCHAR *lpFileName
|
||||
)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
IUnknown *pUnk;
|
||||
HRESULT hres;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
wcscpy(FileName, T2W(lpFileName));
|
||||
|
||||
hres = CoInitialize(NULL);
|
||||
if(hres == S_FALSE)
|
||||
CoUninitialize();
|
||||
|
||||
hres = CoCreateInstance(
|
||||
CLSID_FilterGraph,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IUnknown,
|
||||
(LPVOID *)&pUnk);
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
m_Mode = MOVIE_OPENED;
|
||||
hres = pUnk->QueryInterface(IID_IFilterGraph, (LPVOID *)&m_Fg);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = AddVideoMixingRendererToFG();
|
||||
if(FAILED(hres))
|
||||
{
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = pUnk->QueryInterface(IID_IGraphBuilder, (LPVOID *)&m_Gb);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = m_Gb->RenderFile(FileName, NULL);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
m_Gb->Release(); m_Gb = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = m_Wc->QueryInterface(IID_IVMRMixerControl, (LPVOID *) &m_pMixControl);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
m_Gb->Release(); m_Gb = NULL;
|
||||
m_pMixControl = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = pUnk->QueryInterface(IID_IMediaControl, (LPVOID *)&m_Mc);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
pUnk->Release();
|
||||
m_Fg->Release(); m_Fg = NULL;
|
||||
m_Wc->Release(); m_Wc = NULL;
|
||||
m_Gb->Release(); m_Gb = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
//
|
||||
// Not being able to get the IMediaEvent interface doesn't
|
||||
// necessarly mean that we can't play the graph.
|
||||
//
|
||||
pUnk->QueryInterface(IID_IMediaEvent, (LPVOID *)&m_Me);
|
||||
GetMovieEventHandle();
|
||||
|
||||
pUnk->QueryInterface(IID_IMediaSeeking, (LPVOID *)&m_Ms);
|
||||
pUnk->Release();
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Fg = NULL;
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CloseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
DWORD
|
||||
CMpegMovie::CloseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_NOTOPENED;
|
||||
|
||||
if(m_Mc)
|
||||
{
|
||||
if(m_Me)
|
||||
{
|
||||
m_MediaEvent = NULL;
|
||||
m_Me->Release();
|
||||
m_Me = NULL;
|
||||
}
|
||||
|
||||
if(m_pMixControl)
|
||||
{
|
||||
m_pMixControl->Release();
|
||||
m_pMixControl = NULL;
|
||||
}
|
||||
|
||||
if(m_Ms)
|
||||
{
|
||||
m_Ms->Release();
|
||||
m_Ms = NULL;
|
||||
}
|
||||
|
||||
if(m_Wc)
|
||||
{
|
||||
m_Wc->Release();
|
||||
m_Wc = NULL;
|
||||
}
|
||||
|
||||
m_Mc->Release();
|
||||
m_Mc = NULL;
|
||||
|
||||
if(m_Gb)
|
||||
{
|
||||
m_Gb->Release();
|
||||
m_Gb = NULL;
|
||||
}
|
||||
|
||||
if(m_Fg)
|
||||
{
|
||||
m_Fg->Release();
|
||||
m_Fg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
QzUninitialize();
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CMpegMovie::GetNativeMovieSize
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::GetNativeMovieSize(
|
||||
LONG *pcx,
|
||||
LONG *pcy
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
if(m_Wc)
|
||||
{
|
||||
bRet = (m_Wc->GetNativeVideoSize(pcx, pcy, NULL, NULL) == S_OK);
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMoviePosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::GetMoviePosition(
|
||||
LONG *px,
|
||||
LONG *py,
|
||||
LONG *pcx,
|
||||
LONG *pcy
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
if(m_Wc)
|
||||
{
|
||||
RECT src={0}, dest={0};
|
||||
HRESULT hr = m_Wc->GetVideoPosition(&src, &dest);
|
||||
*px = dest.left;
|
||||
*py = dest.right;
|
||||
*pcx = dest.right - dest.left;
|
||||
*pcy = dest.bottom - dest.top;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PutMoviePosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PutMoviePosition(
|
||||
LONG x,
|
||||
LONG y,
|
||||
LONG cx,
|
||||
LONG cy
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
RECT rc;
|
||||
SetRect(&rc, x, y, x + cx, y + cy);
|
||||
if(m_Wc)
|
||||
{
|
||||
bRet = (m_Wc->SetVideoPosition(NULL, &rc) == S_OK);
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PlayMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PlayMovie(
|
||||
)
|
||||
{
|
||||
REFTIME rt, rtAbs, rtDur;
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
rt = GetCurrentPosition();
|
||||
rtDur = GetDuration();
|
||||
|
||||
//
|
||||
// If we are near the end of the movie seek to the start, otherwise
|
||||
// stay where we are.
|
||||
//
|
||||
rtAbs = rt - rtDur;
|
||||
if(rtAbs < (REFTIME)0)
|
||||
{
|
||||
rtAbs = -rtAbs;
|
||||
}
|
||||
|
||||
if(rtAbs < (REFTIME)1)
|
||||
{
|
||||
SeekToPosition((REFTIME)0,FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// Change mode after setting m_Mode but before starting the graph
|
||||
//
|
||||
m_Mode = MOVIE_PLAYING;
|
||||
hr = m_Mc->Run();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* PauseMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::PauseMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
|
||||
HRESULT hr = m_Mc->Pause();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetStateMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
|
||||
OAFilterState
|
||||
CMpegMovie::GetStateMovie(
|
||||
)
|
||||
{
|
||||
OAFilterState State;
|
||||
|
||||
HRESULT hr = m_Mc->GetState(INFINITE,&State);
|
||||
return State;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StopMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::StopMovie(
|
||||
)
|
||||
{
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
HRESULT hr = m_Mc->Stop();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* StatusMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
EMpegMovieMode
|
||||
CMpegMovie::StatusMovie(
|
||||
)
|
||||
{
|
||||
if(m_Mc)
|
||||
{
|
||||
FILTER_STATE fs;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Mc->GetState(100, (OAFilterState *)&fs);
|
||||
|
||||
// Don't know what the state is so just stay at old state.
|
||||
if(hr == VFW_S_STATE_INTERMEDIATE)
|
||||
{
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
switch(fs)
|
||||
{
|
||||
case State_Stopped:
|
||||
m_Mode = MOVIE_STOPPED;
|
||||
break;
|
||||
|
||||
case State_Paused:
|
||||
m_Mode = MOVIE_PAUSED;
|
||||
break;
|
||||
|
||||
case State_Running:
|
||||
m_Mode = MOVIE_PLAYING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* CanMovieFrameStep
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::CanMovieFrameStep()
|
||||
{
|
||||
IVideoFrameStep* lpFS;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Fg->QueryInterface(__uuidof(IVideoFrameStep), (LPVOID *)&lpFS);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = lpFS->CanStep(0L, NULL);
|
||||
lpFS->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* FrameStepMovie
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::FrameStepMovie()
|
||||
{
|
||||
IVideoFrameStep* lpFS;
|
||||
HRESULT hr;
|
||||
|
||||
hr = m_Fg->QueryInterface(__uuidof(IVideoFrameStep), (LPVOID *)&lpFS);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
FrameStepCount++;
|
||||
|
||||
hr = lpFS->Step(1, NULL);
|
||||
lpFS->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMediaEventHandle
|
||||
*
|
||||
* Returns the IMediaEvent event hamdle for the filter graph iff the
|
||||
* filter graph exists.
|
||||
*
|
||||
\**************************************************************************/
|
||||
HANDLE
|
||||
CMpegMovie::GetMovieEventHandle(
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if(m_Me != NULL)
|
||||
{
|
||||
if(m_MediaEvent == NULL)
|
||||
{
|
||||
hr = m_Me->GetEventHandle((OAEVENT *)&m_MediaEvent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MediaEvent = NULL;
|
||||
}
|
||||
|
||||
return m_MediaEvent;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetMovieEventCode
|
||||
*
|
||||
\**************************************************************************/
|
||||
long
|
||||
CMpegMovie::GetMovieEventCode()
|
||||
{
|
||||
HRESULT hr;
|
||||
long lEventCode;
|
||||
LONG_PTR lParam1, lParam2;
|
||||
|
||||
if(m_Me != NULL)
|
||||
{
|
||||
hr = m_Me->GetEvent(&lEventCode, &lParam1, &lParam2, 0);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = m_Me->FreeEventParams(lEventCode, lParam1, lParam2);
|
||||
return lEventCode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetDuration
|
||||
*
|
||||
* Returns the duration of the current movie
|
||||
*
|
||||
\**************************************************************************/
|
||||
REFTIME
|
||||
CMpegMovie::GetDuration()
|
||||
{
|
||||
HRESULT hr;
|
||||
LONGLONG Duration;
|
||||
|
||||
// Should we seek using IMediaSelection
|
||||
if(m_TimeFormat != TIME_FORMAT_MEDIA_TIME)
|
||||
{
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Duration);
|
||||
}
|
||||
}
|
||||
else if(m_Ms != NULL)
|
||||
{
|
||||
hr = m_Ms->GetDuration(&Duration);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Duration) / UNITS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* GetCurrentPosition
|
||||
*
|
||||
* Returns the duration of the current movie
|
||||
*
|
||||
\**************************************************************************/
|
||||
REFTIME
|
||||
CMpegMovie::GetCurrentPosition()
|
||||
{
|
||||
REFTIME rt = (REFTIME)0;
|
||||
HRESULT hr;
|
||||
LONGLONG Position;
|
||||
|
||||
// Should we return a media position
|
||||
if(m_TimeFormat != TIME_FORMAT_MEDIA_TIME)
|
||||
{
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Position);
|
||||
}
|
||||
}
|
||||
else if(m_Ms != NULL)
|
||||
{
|
||||
hr = m_Ms->GetPositions(&Position, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return double(Position) / UNITS;
|
||||
}
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SeekToPosition
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SeekToPosition(
|
||||
REFTIME rt,
|
||||
BOOL bFlushData
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
LONGLONG llTime = LONGLONG(m_TimeFormat == TIME_FORMAT_MEDIA_TIME ? rt * double(UNITS) : rt );
|
||||
|
||||
if(m_Ms != NULL)
|
||||
{
|
||||
FILTER_STATE fs;
|
||||
hr = m_Mc->GetState(100, (OAFilterState *)&fs);
|
||||
|
||||
hr = m_Ms->SetPositions(&llTime, AM_SEEKING_AbsolutePositioning, NULL, 0);
|
||||
|
||||
// This gets new data through to the renderers
|
||||
if(fs == State_Stopped && bFlushData)
|
||||
{
|
||||
hr = m_Mc->Pause();
|
||||
hr = m_Mc->GetState(INFINITE, (OAFilterState *)&fs);
|
||||
hr = m_Mc->Stop();
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* FindInterfaceFromFilterGraph
|
||||
*
|
||||
\**************************************************************************/
|
||||
HRESULT
|
||||
CMpegMovie::FindInterfaceFromFilterGraph(
|
||||
REFIID iid, // interface to look for
|
||||
LPVOID *lp // place to return interface pointer in
|
||||
)
|
||||
{
|
||||
IEnumFilters* pEF;
|
||||
IBaseFilter* pFilter;
|
||||
|
||||
// Grab an enumerator for the filter graph.
|
||||
HRESULT hr = m_Fg->EnumFilters(&pEF);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Check out each filter.
|
||||
while(pEF->Next(1, &pFilter, NULL) == S_OK)
|
||||
{
|
||||
hr = pFilter->QueryInterface(iid, lp);
|
||||
pFilter->Release();
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pEF->Release();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* IsTimeFormatSupported
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::IsTimeFormatSupported(GUID Format)
|
||||
{
|
||||
return m_Ms != NULL && m_Ms->IsFormatSupported(&Format) == S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* IsTimeSupported
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::IsTimeSupported()
|
||||
{
|
||||
return m_Ms != NULL && m_Ms->IsFormatSupported(&TIME_FORMAT_MEDIA_TIME) == S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* GetTimeFormat
|
||||
*
|
||||
\**************************************************************************/
|
||||
GUID
|
||||
CMpegMovie::GetTimeFormat()
|
||||
{
|
||||
return m_TimeFormat;
|
||||
}
|
||||
|
||||
/*****************************Public*Routine******************************\
|
||||
* SetTimeFormat
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SetTimeFormat(GUID Format)
|
||||
{
|
||||
HRESULT hr = m_Ms->SetTimeFormat(&Format);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
m_TimeFormat = Format;
|
||||
}
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetFocus
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
CMpegMovie::SetFocus()
|
||||
{
|
||||
if(m_Fg)
|
||||
{
|
||||
// Tell the resource manager that we are being made active. This
|
||||
// will then cause the sound to switch to us. This is especially
|
||||
// important when playing audio only files as there is no other
|
||||
// playback window.
|
||||
IResourceManager* pResourceManager;
|
||||
|
||||
HRESULT hr = m_Fg->QueryInterface(IID_IResourceManager, (void**)&pResourceManager);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
IUnknown* pUnknown;
|
||||
|
||||
hr = m_Fg->QueryInterface(IID_IUnknown, (void**)&pUnknown);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = pResourceManager->SetFocus(pUnknown);
|
||||
pUnknown->Release();
|
||||
}
|
||||
|
||||
pResourceManager->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* RepaintVideo
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::RepaintVideo(
|
||||
HWND hwnd,
|
||||
HDC hdc
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
if(m_Wc)
|
||||
{
|
||||
bRet = (m_Wc->RepaintVideo(hwnd, hdc) == S_OK);
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* SetAppImage
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::SetAppImage(
|
||||
VMRALPHABITMAP* lpBmpInfo
|
||||
)
|
||||
{
|
||||
IVMRMixerBitmap* pBmp;
|
||||
HRESULT hres = m_Wc->QueryInterface(IID_IVMRMixerBitmap, (LPVOID *)&pBmp);
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
hres = pBmp->SetAlphaBitmap(lpBmpInfo);
|
||||
pBmp->Release();
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/******************************Public*Routine******************************\
|
||||
* UpdateAppImage
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL
|
||||
CMpegMovie::UpdateAppImage(VMRALPHABITMAP* lpBmpInfo)
|
||||
{
|
||||
IVMRMixerBitmap* pBmp;
|
||||
|
||||
if (!m_Wc)
|
||||
return FALSE;
|
||||
|
||||
HRESULT hres = m_Wc->QueryInterface(IID_IVMRMixerBitmap, (LPVOID *)&pBmp);
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
hres = pBmp->UpdateAlphaBitmapParameters(lpBmpInfo);
|
||||
pBmp->Release();
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* SetBorderClr
|
||||
*
|
||||
\**************************************************************************/
|
||||
void
|
||||
CMpegMovie::SetBorderClr(COLORREF clr)
|
||||
{
|
||||
m_Wc->SetBorderColor(clr);
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VerifyVMR
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL VerifyVMR(void)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
// Verify that the VMR exists on this system
|
||||
IBaseFilter* pBF = NULL;
|
||||
hres = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
pBF->Release();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp,
|
||||
TEXT("This application requires the Video Mixing Renderer, which is present\r\n")
|
||||
TEXT("only on Windows XP.\r\n\r\n")
|
||||
TEXT("The Video Mixing Renderer (VMR) is also not enabled when viewing a \r\n")
|
||||
TEXT("remote Windows XP machine through a Remote Desktop session.\r\n")
|
||||
TEXT("You can run VMR-enabled applications only on your local machine.")
|
||||
TEXT("\r\n\r\nThis sample will now exit."),
|
||||
TEXT("Video Mixing Renderer capabilities are required"), MB_OK);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: vcdplyer.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// - Class header file for VMRPlayer sample
|
||||
//
|
||||
// Copyright (c) 1994 - 2001, Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
** CMpegMovie - an Mpeg movie playback class.
|
||||
** -------------------------------------------------------------------------
|
||||
*/
|
||||
enum EMpegMovieMode { MOVIE_NOTOPENED = 0x00,
|
||||
MOVIE_OPENED = 0x01,
|
||||
MOVIE_PLAYING = 0x02,
|
||||
MOVIE_STOPPED = 0x03,
|
||||
MOVIE_PAUSED = 0x04 };
|
||||
|
||||
BOOL VerifyVMR(void);
|
||||
|
||||
struct IMpegAudioDecoder;
|
||||
struct IMpegVideoDecoder;
|
||||
struct IQualProp;
|
||||
|
||||
class CMpegMovie
|
||||
{
|
||||
private:
|
||||
// Our state variable - records whether we are opened, playing etc.
|
||||
EMpegMovieMode m_Mode;
|
||||
HANDLE m_MediaEvent;
|
||||
HWND m_hwndApp;
|
||||
GUID m_TimeFormat;
|
||||
|
||||
IFilterGraph *m_Fg;
|
||||
IGraphBuilder *m_Gb;
|
||||
IMediaControl *m_Mc;
|
||||
IMediaSeeking *m_Ms;
|
||||
IMediaEvent *m_Me;
|
||||
IVMRWindowlessControl *m_Wc;
|
||||
|
||||
HRESULT AddVideoMixingRendererToFG();
|
||||
HRESULT AddBallToFG();
|
||||
void GetPerformanceInterfaces();
|
||||
HRESULT FindInterfaceFromFilterGraph(
|
||||
REFIID iid, // interface to look for
|
||||
LPVOID *lp // place to return interface pointer in
|
||||
);
|
||||
|
||||
public:
|
||||
CMpegMovie(HWND hwndApplication);
|
||||
~CMpegMovie();
|
||||
|
||||
HRESULT OpenMovie(TCHAR *lpFileName);
|
||||
DWORD CloseMovie();
|
||||
BOOL PlayMovie();
|
||||
BOOL PauseMovie();
|
||||
BOOL StopMovie();
|
||||
OAFilterState GetStateMovie();
|
||||
HANDLE GetMovieEventHandle();
|
||||
long GetMovieEventCode();
|
||||
BOOL PutMoviePosition(LONG x, LONG y, LONG cx, LONG cy);
|
||||
BOOL GetMoviePosition(LONG *x, LONG *y, LONG *cx, LONG *cy);
|
||||
BOOL GetNativeMovieSize(LONG *cx, LONG *cy);
|
||||
BOOL CanMovieFrameStep();
|
||||
BOOL FrameStepMovie();
|
||||
REFTIME GetDuration();
|
||||
REFTIME GetCurrentPosition();
|
||||
BOOL SeekToPosition(REFTIME rt,BOOL bFlushData);
|
||||
EMpegMovieMode StatusMovie();
|
||||
BOOL IsTimeFormatSupported(GUID Format);
|
||||
BOOL IsTimeSupported();
|
||||
BOOL SetTimeFormat(GUID Format);
|
||||
GUID GetTimeFormat();
|
||||
void SetFocus();
|
||||
BOOL ConfigDialog(HWND hwnd);
|
||||
BOOL RepaintVideo(HWND hwnd, HDC hdc);
|
||||
BOOL SetAppImage(VMRALPHABITMAP* lpBmpInfo);
|
||||
BOOL UpdateAppImage(VMRALPHABITMAP* lpBmpInfo);
|
||||
void SetBorderClr(COLORREF clr);
|
||||
|
||||
void DisplayModeChanged() {
|
||||
m_Wc->DisplayModeChanged();
|
||||
}
|
||||
|
||||
HRESULT GetCurrentImage(LPBYTE* lplpDib)
|
||||
{
|
||||
return m_Wc->GetCurrentImage(lplpDib);
|
||||
}
|
||||
|
||||
HRESULT RenderSecondFile(TCHAR *lpFileName);
|
||||
|
||||
IVMRMixerControl *m_pMixControl;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,331 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resrc1.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
//
|
||||
|
||||
IDR_TOOLBAR BITMAP DISCARDABLE "toolbar.bmp"
|
||||
IDR_VMR BITMAP DISCARDABLE "vmr.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_VIDEOCD_ICON ICON DISCARDABLE "perftool.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_MAIN_MENU MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "&Open Primary Stream...", IDM_FILE_OPEN
|
||||
MENUITEM "Open &Second Stream...", IDM_FILE_OPEN2, GRAYED
|
||||
MENUITEM "&Close", IDM_FILE_CLOSE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", IDM_FILE_EXIT
|
||||
END
|
||||
POPUP "&VMR Properties"
|
||||
BEGIN
|
||||
MENUITEM "Static App &Image...", IDM_APP_IMAGE
|
||||
MENUITEM "&Primary Stream...", IDM_STREAM_A
|
||||
MENUITEM "&Secondary Stream...", IDM_STREAM_B
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Capture Bitmap Image", IDM_CAPTURE_IMAGE
|
||||
MENUITEM "&Display Captured Image", IDM_DISPLAY_CAPTURED_IMAGE
|
||||
END
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About DirectShow VMRPlayer Sample...", IDM_HELP_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_AUDIOPROP DIALOG DISCARDABLE 0, 0, 218, 177
|
||||
STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "App Image Control"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
CONTROL "Slider1",IDC_XPOS_TRK,"msctls_trackbar32",TBS_TOP |
|
||||
TBS_NOTICKS | WS_TABSTOP,48,24,155,15
|
||||
CONTROL "Slider2",IDC_YPOS_TRK,"msctls_trackbar32",TBS_TOP |
|
||||
TBS_NOTICKS | WS_TABSTOP,48,44,155,15
|
||||
CONTROL "Slider1",IDC_XSIZE_TRK,"msctls_trackbar32",TBS_TOP |
|
||||
TBS_NOTICKS | WS_TABSTOP,48,81,155,15
|
||||
CONTROL "Slider2",IDC_YSIZE_TRK,"msctls_trackbar32",TBS_TOP |
|
||||
TBS_NOTICKS | WS_TABSTOP,48,101,155,15
|
||||
CONTROL "Slider2",IDC_ALPHA_TRK2,"msctls_trackbar32",TBS_TOP |
|
||||
TBS_NOTICKS | WS_TABSTOP,48,133,155,15
|
||||
CONTROL "Display App Image",IDC_IMAGE_ENABLE,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,13,157,72,10
|
||||
DEFPUSHBUTTON "Close",IDOK,161,154,50,14
|
||||
LTEXT "X = ",IDC_STATIC,10,24,14,8
|
||||
LTEXT "Y =",IDC_STATIC,11,43,13,8
|
||||
GROUPBOX "Position",IDC_STATIC,7,7,204,57
|
||||
LTEXT "0.000",IDC_XPOS,24,24,21,8
|
||||
LTEXT "0.000",IDC_YPOS,24,43,23,8
|
||||
LTEXT "X = ",IDC_STATIC,10,81,14,8
|
||||
LTEXT "Y =",IDC_STATIC,11,100,13,8
|
||||
GROUPBOX "Size",IDC_STATIC,7,64,204,57
|
||||
LTEXT "0.000",IDC_XSIZE,24,81,21,8
|
||||
LTEXT "0.000",IDC_YSIZE,25,100,23,8
|
||||
GROUPBOX "Alpha",IDC_STATIC,7,122,204,29
|
||||
LTEXT "A =",IDC_STATIC,11,132,13,8
|
||||
LTEXT "0.000",IDC_ALPHA,25,132,23,8
|
||||
END
|
||||
|
||||
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About VMRPlayer"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
ICON IDR_VIDEOCD_ICON,-1,11,17,20,20
|
||||
LTEXT "DirectShow VMRPlayer Sample",-1,40,10,131,8,SS_NOPREFIX
|
||||
LTEXT "Copyright (C) 1999-2001 Microsoft Corporation",-1,40,34,
|
||||
188,8
|
||||
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
|
||||
LTEXT "Version 8.1",-1,40,22,119,8,SS_NOPREFIX
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_ACCELERATOR ACCELERATORS DISCARDABLE
|
||||
BEGIN
|
||||
"S", IDM_MOVIE_STOP, VIRTKEY, CONTROL, NOINVERT
|
||||
"P", IDM_MOVIE_PLAY, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resrc1.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""resource.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_AUDIOPROP, DIALOG
|
||||
BEGIN
|
||||
VERTGUIDE, 7
|
||||
VERTGUIDE, 24
|
||||
VERTGUIDE, 48
|
||||
VERTGUIDE, 203
|
||||
VERTGUIDE, 211
|
||||
HORZGUIDE, 32
|
||||
HORZGUIDE, 51
|
||||
HORZGUIDE, 167
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Toolbar
|
||||
//
|
||||
|
||||
IDR_TOOLBAR TOOLBAR DISCARDABLE 16, 15
|
||||
BEGIN
|
||||
BUTTON ID_BUTTON40001
|
||||
BUTTON ID_BUTTON40002
|
||||
BUTTON ID_BUTTON40003
|
||||
BUTTON ID_BUTTON40004
|
||||
BUTTON ID_BUTTON40005
|
||||
BUTTON ID_BUTTON40006
|
||||
BUTTON ID_BUTTON40007
|
||||
BUTTON ID_BUTTON40008
|
||||
BUTTON ID_BUTTON40009
|
||||
BUTTON ID_BUTTON40010
|
||||
BUTTON ID_BUTTON40011
|
||||
BUTTON ID_BUTTON40012
|
||||
BUTTON ID_BUTTON40013
|
||||
BUTTON ID_BUTTON40014
|
||||
BUTTON ID_BUTTON40016
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,1,0,0
|
||||
PRODUCTVERSION 8,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "DirectShow Windows XP Sample\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "VMR Player Application\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "VMR Player\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "VMRPlayer.EXE\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "DirectX 8.1 SDK\0"
|
||||
VALUE "ProductVersion", "8.1\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_MOVIE_STOP "Stop"
|
||||
IDM_MOVIE_PLAY "Play"
|
||||
IDM_MOVIE_PREVTRACK "Rewind to beginning"
|
||||
IDM_MOVIE_PAUSE "Pause"
|
||||
IDM_MOVIE_SKIP_FORE "Fast Forward"
|
||||
IDM_MOVIE_SKIP_BACK "Rewind"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDM_MOVIE_STEP "Step one frame"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_OPEN "Open a new movie to play"
|
||||
STR_FILE_CLOSE "Close the movie"
|
||||
STR_FILE_EXIT "Quit DirectShow VMRPlayer Sample"
|
||||
STR_FILE_OPEN2 "Open a second stream to alpha blend with the primary stream"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_APP_IMAGE "Modify static image properties"
|
||||
STR_STREAM_A "Modify primary image properties"
|
||||
STR_STREAM_B "Modify secondary image properties"
|
||||
STR_CAPTURE_IMAGE "Capture the current frame to disk"
|
||||
STR_DISPLAY_CAPTURED_IMAGE "Display the most recent captured image"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_HELP_ABOUT "Display information about DirectShow VMRPlayer Sample"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_SYSMENU_RESTORE "Restore the window to normal size"
|
||||
STR_SYSMENU_MOVE "Changes the window position"
|
||||
STR_SYSMENU_MINIMIZE "Reduce the window to an icon"
|
||||
STR_SYSMENU_CLOSE "Closes the window"
|
||||
STR_SYSMENU_MAXIMIZE "Enlarges the window to its maximum size"
|
||||
STR_SYSMENU_TASK_LIST "Opens the task list"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
STR_FILE_FILTER "All Movies#*.mpg;*.avi;*.dat;*.mov#Mpeg Files (*.mpg)#*.mpg#Video CD Files (*.dat)#*.dat#QuickTime Files (*.mov)#*.mov#All Files (*.*)#*.*#"
|
||||
STR_APP_TITLE "DirectShow VMRPlayer Sample"
|
||||
STR_APP_TITLE_LOADED "DirectShow VMRPlayer Sample - %s"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
After Width: | Height: | Size: 48 KiB |
@@ -0,0 +1,371 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: AllocPresenter.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of user-provided allocator-presenter for VMR
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "project.h"
|
||||
#include <mmreg.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "resrc1.h"
|
||||
#include "D3DTextr.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifndef __INITDDSTRUCT_DEFINED
|
||||
#define __INITDDSTRUCT_DEFINED
|
||||
template <typename T>
|
||||
__inline void INITDDSTRUCT(T& dd)
|
||||
{
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
dd.dwSize = sizeof(dd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CreateDefaultAllocatorPresenter
|
||||
//
|
||||
// creates user-provides allocator presenter
|
||||
//
|
||||
// Usually you have to actually override several functions of AllocatorPresenter;
|
||||
// For the rest, QI IVMRImagePresenter and call default functions
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
CMpegMovie::CreateDefaultAllocatorPresenter(
|
||||
LPDIRECTDRAW7 lpDD,
|
||||
LPDIRECTDRAWSURFACE7 lpPS
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
IVMRImagePresenterExclModeConfig* lpConfig = NULL;
|
||||
|
||||
__try {
|
||||
// for exclusive mode, we do need AllocPresenterDDXclMode of IVMRSurfaceAllocator
|
||||
CHECK_HR(hr = CoCreateInstance(CLSID_AllocPresenterDDXclMode, NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(IVMRSurfaceAllocator),
|
||||
(LPVOID*)&m_lpDefSA));
|
||||
|
||||
CHECK_HR(hr = m_lpDefSA->QueryInterface(__uuidof(IVMRImagePresenterExclModeConfig),
|
||||
(LPVOID*)&lpConfig));
|
||||
|
||||
CHECK_HR(hr = lpConfig->SetRenderingPrefs(RenderPrefs_ForceOffscreen));
|
||||
|
||||
// this sets exclusive mode
|
||||
CHECK_HR(hr = lpConfig->SetXlcModeDDObjAndPrimarySurface(lpDD, lpPS));
|
||||
|
||||
CHECK_HR(hr = m_lpDefSA->QueryInterface(__uuidof(IVMRImagePresenter),
|
||||
(LPVOID*)&m_lpDefIP));
|
||||
|
||||
CHECK_HR(hr = m_lpDefSA->QueryInterface(__uuidof(IVMRWindowlessControl),
|
||||
(LPVOID*)&m_lpDefWC));
|
||||
|
||||
CHECK_HR(hr = m_lpDefWC->SetVideoClippingWindow(m_hwndApp));
|
||||
CHECK_HR(hr = m_lpDefSA->AdviseNotify(this));
|
||||
}
|
||||
__finally {
|
||||
|
||||
RELEASE(lpConfig);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
RELEASE(m_lpDefWC);
|
||||
RELEASE(m_lpDefIP);
|
||||
RELEASE(m_lpDefSA);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NonDelegatingQueryInterface
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NonDelegatingQueryInterface(
|
||||
REFIID riid,
|
||||
void** ppv
|
||||
)
|
||||
{
|
||||
if (riid == __uuidof(IVMRSurfaceAllocator)) {
|
||||
return GetInterface((IVMRSurfaceAllocator*)this, ppv);
|
||||
}
|
||||
else if (riid == __uuidof(IVMRImagePresenter)) {
|
||||
return GetInterface((IVMRImagePresenter*)this, ppv);
|
||||
}
|
||||
|
||||
return CUnknown::NonDelegatingQueryInterface(riid,ppv);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRSurfaceAllocator-overriden functions
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AllocateSurfaces
|
||||
//
|
||||
// call default AllocateSurface
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AllocateSurface(
|
||||
DWORD_PTR dwUserID,
|
||||
VMRALLOCATIONINFO* lpAllocInfo,
|
||||
DWORD* lpdwBuffer,
|
||||
LPDIRECTDRAWSURFACE7* lplpSurface
|
||||
)
|
||||
{
|
||||
HRESULT hr = m_lpDefSA->AllocateSurface(dwUserID, lpAllocInfo,
|
||||
lpdwBuffer, lplpSurface);
|
||||
if( SUCCEEDED(hr))
|
||||
{
|
||||
m_lpSurf = *lplpSurface;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// FreeSurfaces()
|
||||
//
|
||||
// Call default FreeSurface
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::FreeSurface(
|
||||
DWORD_PTR dwUserID
|
||||
)
|
||||
{
|
||||
HRESULT hr = m_lpDefSA->FreeSurface(dwUserID);
|
||||
|
||||
if( SUCCEEDED(hr))
|
||||
{
|
||||
m_lpSurf = NULL;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PrepareSurface
|
||||
//
|
||||
// call default PrepareSurface
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PrepareSurface(
|
||||
DWORD_PTR dwUserID,
|
||||
LPDIRECTDRAWSURFACE7 lplpSurface,
|
||||
DWORD dwSurfaceFlags
|
||||
)
|
||||
{
|
||||
return m_lpDefSA->PrepareSurface(dwUserID, lplpSurface, dwSurfaceFlags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AdviseNotify
|
||||
//
|
||||
// call default AdviseNotify
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AdviseNotify(
|
||||
IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify
|
||||
)
|
||||
{
|
||||
return m_lpDefSA->AdviseNotify(lpIVMRSurfAllocNotify);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRSurfaceAllocatorNotify-overriden functions
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AdviseSurfaceAllocator
|
||||
//
|
||||
// standard AdviseSurfaceAllocator
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::AdviseSurfaceAllocator(
|
||||
DWORD_PTR dwUserID,
|
||||
IVMRSurfaceAllocator* lpIVRMSurfaceAllocator
|
||||
)
|
||||
{
|
||||
return m_lpDefSAN->AdviseSurfaceAllocator(dwUserID, lpIVRMSurfaceAllocator);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SetDDrawDevice
|
||||
//
|
||||
// standard SetDDrawDevice
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::SetDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor)
|
||||
{
|
||||
return m_lpDefSAN->SetDDrawDevice(lpDDrawDevice, hMonitor);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ChangeDDrawDevice
|
||||
//
|
||||
// standard ChangeDDrawDevice
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::ChangeDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor)
|
||||
{
|
||||
return m_lpDefSAN->ChangeDDrawDevice(lpDDrawDevice, hMonitor);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// RestoreDDrawSurfaces
|
||||
//
|
||||
// standard RestoreDDrawSurfaces
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP CMpegMovie::RestoreDDrawSurfaces()
|
||||
{
|
||||
// Make sure that the menu is redrawn
|
||||
if( m_AlphaBlt )
|
||||
m_AlphaBlt->SetMenuRestoreFlag();
|
||||
|
||||
return m_lpDefSAN->RestoreDDrawSurfaces();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NotifyEvent
|
||||
//
|
||||
// standard NotifyEvent
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::NotifyEvent(LONG EventCode, LONG_PTR lp1, LONG_PTR lp2)
|
||||
{
|
||||
return m_lpDefSAN->NotifyEvent(EventCode, lp1, lp2);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SetBorderColor
|
||||
//
|
||||
// default SetBorderColor
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::SetBorderColor(
|
||||
COLORREF clr
|
||||
)
|
||||
{
|
||||
return m_lpDefSAN->SetBorderColor(clr);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IVMRImagePresenter overriden functions
|
||||
// we perform all user customization here
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// StartPresenting()
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StartPresenting(DWORD_PTR dwUserID)
|
||||
{
|
||||
return m_lpDefIP->StartPresenting(dwUserID);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// StopPresenting()
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::StopPresenting(DWORD_PTR dwUserID)
|
||||
{
|
||||
return m_lpDefIP->StopPresenting(dwUserID);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PresentImage
|
||||
//
|
||||
// Here all the fun happens. lpPresInfo contains surface with current video image
|
||||
// Call m_AlphaBlt->AlphaBlt to perform all the necessary transformation
|
||||
//----------------------------------------------------------------------------
|
||||
STDMETHODIMP
|
||||
CMpegMovie::PresentImage(
|
||||
DWORD_PTR dwUserID,
|
||||
VMRPRESENTATIONINFO* lpPresInfo
|
||||
)
|
||||
{
|
||||
// clear the background
|
||||
DDBLTFX ddFX;
|
||||
INITDDSTRUCT(ddFX);
|
||||
|
||||
RECT rcS = {0, 0, 640, 480};
|
||||
RECT rcD = {128, 96, 512, 384};
|
||||
RECT rcDt ={128, 0, 512, 288};
|
||||
|
||||
m_lpDefWC->GetVideoPosition(&rcS, NULL);
|
||||
if( g_ss.bShowTwist )
|
||||
{
|
||||
m_AlphaBlt->AlphaBlt(&rcDt, lpPresInfo->lpSurf, &rcS, 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_AlphaBlt->AlphaBlt(&rcD, lpPresInfo->lpSurf, &rcS, 0xFF);
|
||||
}
|
||||
|
||||
m_lpSurf->Flip(NULL,0);
|
||||
|
||||
if( g_ss.bShowStatistics && m_Qp)
|
||||
{
|
||||
// call IQualProp functions here to get performance statistics
|
||||
GetPerformance();
|
||||
}
|
||||
|
||||
// Show the scene
|
||||
m_pDDObject.GetFB()->Flip(NULL, /*DDFLIP_WAIT*/ 0);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetPerformance
|
||||
//
|
||||
// Calls IQualProp::get_AvgFrameRate
|
||||
// every 25 frames (to not overload VMR with senseless calculations)
|
||||
// and saves this value to g_ss, global SceneSettings structure
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
CMpegMovie::GetPerformance()
|
||||
{
|
||||
|
||||
static int nCounter = 0;
|
||||
static int nAvgFrameRate = 0;
|
||||
char szFrameRate[MAX_PATH];
|
||||
|
||||
nCounter++;
|
||||
if( 25 == nCounter )
|
||||
{
|
||||
m_Qp->get_AvgFrameRate( &nAvgFrameRate);
|
||||
nCounter = 0;
|
||||
}
|
||||
sprintf( szFrameRate, "FPS: %f ", (float)nAvgFrameRate/100.f);
|
||||
lstrcpy(g_ss.achFPS, TEXT(szFrameRate));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,976 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: BltAlpha.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Header file and class description for CAlphaBlt,
|
||||
// texture surface to be used in PresentImage of the
|
||||
// customized allocator-presenter
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __INITDDSTRUCT_DEFINED
|
||||
#define __INITDDSTRUCT_DEFINED
|
||||
#include <math.h>
|
||||
#include <d3dxmath.h>
|
||||
#include "d3dtextr.h"
|
||||
#include "d3dfont.h"
|
||||
#include "utils.h"
|
||||
#include "resrc1.h"
|
||||
#include "d3dutil.h"
|
||||
|
||||
extern struct SceneSettings g_ss;
|
||||
|
||||
template <typename T>
|
||||
__inline void INITDDSTRUCT(T& dd)
|
||||
{
|
||||
ZeroMemory(&dd, sizeof(dd));
|
||||
dd.dwSize = sizeof(dd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __RELEASE_DEFINED
|
||||
#define __RELEASE_DEFINED
|
||||
template<typename T>
|
||||
__inline void RELEASE( T* &p )
|
||||
{
|
||||
if( p ) {
|
||||
p->Release();
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_HR
|
||||
#define CHECK_HR(expr) do { if (FAILED(expr)) __leave; } while(0);
|
||||
#endif
|
||||
|
||||
#define COMPLVERTSIZE 640 // must be divisible by 4!!!
|
||||
#define pi 3.1415926535f
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CAlphaBlt
|
||||
//
|
||||
// Desc: texture surface to be used in PresentImage of the
|
||||
// customized allocator-presenter
|
||||
//----------------------------------------------------------------------------
|
||||
class CAlphaBlt
|
||||
{
|
||||
private:
|
||||
|
||||
LPDIRECTDRAW7 m_pDD;
|
||||
LPDIRECT3D7 m_pD3D;
|
||||
LPDIRECT3DDEVICE7 m_pD3DDevice;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDBackBuffer;
|
||||
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDMirror;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDM32;
|
||||
LPDIRECTDRAWSURFACE7 m_lpDDM16;
|
||||
DDSURFACEDESC2 m_ddsdM32;
|
||||
DDSURFACEDESC2 m_ddsdM16;
|
||||
|
||||
bool m_fPowerOf2;
|
||||
bool m_fSquare;
|
||||
bool m_bNeedToRestoreMenu;
|
||||
TextureContainer * m_ptxtrMenu;
|
||||
CD3DFont * m_pFont;
|
||||
|
||||
typedef struct Vertex
|
||||
{
|
||||
float x, y, z, rhw;
|
||||
D3DCOLOR clr;
|
||||
float tu, tv;
|
||||
} Vertex;
|
||||
|
||||
Vertex pVertices[4]; // primitive for rotating effect
|
||||
Vertex pVComplex[COMPLVERTSIZE];// primitive for twisting effect
|
||||
Vertex pVMenu[4]; // primitive for menu effect
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CAlphaBlt::Rotate
|
||||
//
|
||||
// Desc: 3D transformation of pVertices that provide rotation around Z and Y
|
||||
//
|
||||
// Parameters:
|
||||
// theta - angle of rotation around Z axis
|
||||
// thetaY - angle of rotation around Y axis
|
||||
// pVertices - array of (Vertex*) to be transformed
|
||||
// nSize - number of vertices
|
||||
// (cx2, cy2) - center of rotation
|
||||
//----------------------------------------------------------------------------
|
||||
void Rotate(float theta, float thetaY,
|
||||
CAlphaBlt::Vertex * pVertices,
|
||||
int nSize, float cx2, float cy2)
|
||||
{
|
||||
D3DXMATRIX mtrV;
|
||||
D3DXMATRIX mtrRotZ;
|
||||
D3DXMATRIX mtrRotY;
|
||||
D3DXMATRIX mtrPrs;
|
||||
D3DXMATRIX mtrRes;
|
||||
|
||||
float pi2 = 1.57079632675f; // pi/2.
|
||||
|
||||
// initialize mtrV
|
||||
mtrV.m[0][0] = pVertices[0].x - cx2;
|
||||
mtrV.m[1][0] = pVertices[0].y - cy2;
|
||||
mtrV.m[2][0] = pVertices[0].z;
|
||||
mtrV.m[3][0] = 0.f;
|
||||
|
||||
mtrV.m[0][1] = pVertices[1].x - cx2;
|
||||
mtrV.m[1][1] = pVertices[1].y - cy2;
|
||||
mtrV.m[2][1] = pVertices[1].z;
|
||||
mtrV.m[3][1] = 0;
|
||||
|
||||
mtrV.m[0][2] = pVertices[2].x - cx2;
|
||||
mtrV.m[1][2] = pVertices[2].y - cy2;
|
||||
mtrV.m[2][2] = pVertices[2].z;
|
||||
mtrV.m[3][2] = 0;
|
||||
|
||||
mtrV.m[0][3] = pVertices[3].x - cx2;
|
||||
mtrV.m[1][3] = pVertices[3].y - cy2;
|
||||
mtrV.m[2][3] = pVertices[3].z;
|
||||
mtrV.m[3][3] = 0;
|
||||
|
||||
D3DXMatrixRotationZ( &mtrRotZ, theta);
|
||||
D3DXMatrixRotationY( &mtrRotY, thetaY);
|
||||
D3DXMatrixPerspectiveFov( &mtrPrs, pi2, 1.1f, 0.f, 1.f);
|
||||
|
||||
|
||||
// mtrRotZ * mtrV
|
||||
D3DXMatrixMultiply( &mtrRes, &mtrRotZ, &mtrV);
|
||||
|
||||
// mtrRotY * mtrRotZ * mtrV
|
||||
D3DXMatrixMultiply( &mtrV, &mtrRotY, &mtrRes);
|
||||
|
||||
// mtrPrs * mtrRotY * mtrRotZ * mtrV
|
||||
D3DXMatrixMultiply( &mtrRes, &mtrPrs, &mtrV);
|
||||
|
||||
// here, mtrRes has what we need; copy it back to pVertices
|
||||
pVertices[0].x = mtrRes.m[0][0] + cx2;
|
||||
pVertices[1].x = mtrRes.m[0][1] + cx2;
|
||||
pVertices[2].x = mtrRes.m[0][2] + cx2;
|
||||
pVertices[3].x = mtrRes.m[0][3] + cx2;
|
||||
|
||||
pVertices[0].y = mtrRes.m[1][0] + cy2;
|
||||
pVertices[1].y = mtrRes.m[1][1] + cy2;
|
||||
pVertices[2].y = mtrRes.m[1][2] + cy2;
|
||||
pVertices[3].y = mtrRes.m[1][3] + cy2;
|
||||
|
||||
pVertices[0].z = mtrRes.m[2][0];
|
||||
pVertices[1].z = mtrRes.m[2][1];
|
||||
pVertices[2].z = mtrRes.m[2][2];
|
||||
pVertices[3].z = mtrRes.m[2][3];
|
||||
return;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// IsSurfaceBlendable
|
||||
//
|
||||
// Checks the DD surface description and the given
|
||||
// alpha value to determine if this surface is blendable.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IsSurfaceBlendable(
|
||||
DDSURFACEDESC2& ddsd,
|
||||
BYTE fAlpha
|
||||
)
|
||||
{
|
||||
// Is the surface already a D3D texture ?
|
||||
if (ddsd.ddsCaps.dwCaps & DDSCAPS_TEXTURE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// OK we have to mirror the surface
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MirrorSourceSurface
|
||||
//
|
||||
// The mirror surface cab be either 16 or 32 bit RGB depending
|
||||
// upon the format of the source surface.
|
||||
//
|
||||
// Of course it should have the "texture" flag set and should be in VRAM.
|
||||
// If we can't create the surface then the AlphaBlt should fail
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT MirrorSourceSurface(
|
||||
LPDIRECTDRAWSURFACE7 lpDDS,
|
||||
DDSURFACEDESC2& ddsd
|
||||
)
|
||||
{
|
||||
HRESULT hr = DD_OK;
|
||||
DWORD dwMirrorBitDepth = 0;
|
||||
DDSURFACEDESC2 ddsdMirror={0};
|
||||
|
||||
|
||||
//
|
||||
// OK - is it suitable for our needs.
|
||||
//
|
||||
// Apply the following rules:
|
||||
// if ddsd is a FOURCC surface the mirror should be 32 bit
|
||||
// if ddsd is RGB then the mirror's bit depth should match
|
||||
// that of ddsd.
|
||||
//
|
||||
// Also, the mirror must be large enough to actually hold
|
||||
// the surface to be blended
|
||||
//
|
||||
|
||||
m_lpDDMirror = NULL;
|
||||
|
||||
if (ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC ||
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount == 32) {
|
||||
|
||||
if (ddsd.dwWidth > m_ddsdM32.dwWidth ||
|
||||
ddsd.dwHeight > m_ddsdM32.dwHeight) {
|
||||
|
||||
RELEASE(m_lpDDM32);
|
||||
}
|
||||
|
||||
if (!m_lpDDM32) {
|
||||
dwMirrorBitDepth = 32;
|
||||
}
|
||||
else {
|
||||
m_lpDDMirror = m_lpDDM32;
|
||||
ddsdMirror = m_ddsdM32;
|
||||
}
|
||||
}
|
||||
else if (ddsd.ddpfPixelFormat.dwRGBBitCount == 16) {
|
||||
|
||||
if (ddsd.dwWidth > m_ddsdM16.dwWidth ||
|
||||
ddsd.dwHeight > m_ddsdM16.dwHeight) {
|
||||
|
||||
RELEASE(m_lpDDM16);
|
||||
}
|
||||
|
||||
if (!m_lpDDM16) {
|
||||
dwMirrorBitDepth = 16;
|
||||
}
|
||||
else {
|
||||
m_lpDDMirror = m_lpDDM16;
|
||||
ddsdMirror = m_ddsdM16;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// No support for RGB24 or RGB8!
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (!m_lpDDMirror) {
|
||||
|
||||
INITDDSTRUCT(ddsdMirror);
|
||||
ddsdMirror.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
ddsdMirror.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
ddsdMirror.ddpfPixelFormat.dwRGBBitCount = dwMirrorBitDepth;
|
||||
|
||||
switch (dwMirrorBitDepth) {
|
||||
case 16:
|
||||
ddsdMirror.ddpfPixelFormat.dwRBitMask = 0x0000F800;
|
||||
ddsdMirror.ddpfPixelFormat.dwGBitMask = 0x000007E0;
|
||||
ddsdMirror.ddpfPixelFormat.dwBBitMask = 0x0000001F;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
ddsdMirror.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
|
||||
ddsdMirror.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
|
||||
ddsdMirror.ddpfPixelFormat.dwBBitMask = 0x000000FF;
|
||||
break;
|
||||
}
|
||||
|
||||
ddsdMirror.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE;
|
||||
ddsdMirror.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
||||
|
||||
if (m_fPowerOf2) {
|
||||
|
||||
for (ddsdMirror.dwWidth = 1;
|
||||
ddsd.dwWidth > ddsdMirror.dwWidth;
|
||||
ddsdMirror.dwWidth <<= 1);
|
||||
|
||||
for (ddsdMirror.dwHeight = 1;
|
||||
ddsd.dwHeight > ddsdMirror.dwHeight;
|
||||
ddsdMirror.dwHeight <<= 1);
|
||||
}
|
||||
else {
|
||||
ddsdMirror.dwWidth = ddsd.dwWidth;
|
||||
ddsdMirror.dwHeight = ddsd.dwHeight;
|
||||
}
|
||||
|
||||
if (m_fSquare) {
|
||||
|
||||
if (ddsdMirror.dwHeight > ddsdMirror.dwWidth) {
|
||||
ddsdMirror.dwWidth = ddsdMirror.dwHeight;
|
||||
}
|
||||
|
||||
if (ddsdMirror.dwWidth > ddsdMirror.dwHeight) {
|
||||
ddsdMirror.dwHeight = ddsdMirror.dwWidth;
|
||||
}
|
||||
}
|
||||
|
||||
__try {
|
||||
|
||||
// Attempt to create the surface with theses settings
|
||||
CHECK_HR(hr = m_pDD->CreateSurface(&ddsdMirror, &m_lpDDMirror, NULL));
|
||||
|
||||
INITDDSTRUCT(ddsdMirror);
|
||||
CHECK_HR(hr = m_lpDDMirror->GetSurfaceDesc(&ddsdMirror));
|
||||
|
||||
switch (dwMirrorBitDepth) {
|
||||
case 16:
|
||||
m_ddsdM16 = ddsdMirror;
|
||||
m_lpDDM16 = m_lpDDMirror;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
m_ddsdM32 = ddsdMirror;
|
||||
m_lpDDM32 = m_lpDDMirror;
|
||||
break;
|
||||
}
|
||||
|
||||
} __finally {}
|
||||
}
|
||||
|
||||
if (hr == DD_OK) {
|
||||
|
||||
__try {
|
||||
RECT rc = {0, 0, ddsd.dwWidth, ddsd.dwHeight};
|
||||
CHECK_HR(hr = m_lpDDMirror->Blt(&rc, lpDDS, &rc, DDBLT_WAIT, NULL));
|
||||
ddsd = ddsdMirror;
|
||||
} __finally {}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//----------------------------------------------------------------------------
|
||||
CAlphaBlt(LPDIRECTDRAWSURFACE7 lpDDSDst, HRESULT* phr) :
|
||||
m_pDD(NULL),
|
||||
m_pD3D(NULL),
|
||||
m_pD3DDevice(NULL),
|
||||
m_lpDDBackBuffer(NULL),
|
||||
m_lpDDMirror(NULL),
|
||||
m_lpDDM32(NULL),
|
||||
m_lpDDM16(NULL),
|
||||
m_ptxtrMenu( NULL),
|
||||
m_pFont(NULL),
|
||||
m_fPowerOf2(false),
|
||||
m_fSquare(false),
|
||||
m_bNeedToRestoreMenu(false)
|
||||
{
|
||||
ZeroMemory(&m_ddsdM32, sizeof(m_ddsdM32));
|
||||
ZeroMemory(&m_ddsdM16, sizeof(m_ddsdM16));
|
||||
|
||||
HRESULT hr;
|
||||
hr = lpDDSDst->GetDDInterface((LPVOID *)&m_pDD);
|
||||
if (FAILED(hr)) {
|
||||
m_pDD = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = m_pDD->QueryInterface(IID_IDirect3D7, (LPVOID *)&m_pD3D);
|
||||
if (FAILED(hr)) {
|
||||
m_pD3D = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = m_pD3D->CreateDevice(IID_IDirect3DHALDevice,
|
||||
lpDDSDst,
|
||||
&m_pD3DDevice);
|
||||
if (FAILED(hr)) {
|
||||
m_pD3DDevice = NULL;
|
||||
*phr = hr;
|
||||
}
|
||||
else {
|
||||
m_lpDDBackBuffer = lpDDSDst;
|
||||
m_lpDDBackBuffer->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
||||
D3DDEVICEDESC7 ddDesc;
|
||||
if (DD_OK == m_pD3DDevice->GetCaps(&ddDesc)) {
|
||||
|
||||
if (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2) {
|
||||
m_fPowerOf2 = true;
|
||||
}
|
||||
|
||||
if (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) {
|
||||
m_fSquare = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*phr = hr;
|
||||
}
|
||||
}
|
||||
|
||||
// here, so far we have D3Device, let's Restore texture surface
|
||||
// it actually loads the bitmap from the resource onto a texture surface
|
||||
m_ptxtrMenu = new TextureContainer(
|
||||
"IDB_MENU", 0, 0, IDB_MENU);
|
||||
|
||||
if( m_ptxtrMenu)
|
||||
{
|
||||
hr = m_ptxtrMenu->LoadImageData();
|
||||
if( m_ptxtrMenu->m_hbmBitmap )
|
||||
{
|
||||
BITMAP bm;
|
||||
GetObject( m_ptxtrMenu->m_hbmBitmap, sizeof(BITMAP), &bm );
|
||||
m_ptxtrMenu->m_dwWidth = (DWORD)bm.bmWidth;
|
||||
m_ptxtrMenu->m_dwHeight = (DWORD)bm.bmHeight;
|
||||
m_ptxtrMenu->m_dwBPP = (DWORD)bm.bmBitsPixel;
|
||||
}
|
||||
|
||||
hr = m_ptxtrMenu->Restore(m_pD3DDevice);
|
||||
if( FAILED(hr))
|
||||
{
|
||||
delete m_ptxtrMenu;
|
||||
m_ptxtrMenu = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// load the font
|
||||
m_pFont = new CD3DFont( TEXT("Comic Sans MS"),18,0);
|
||||
if( m_pFont )
|
||||
{
|
||||
m_pFont->InitDeviceObjects( m_pDD, m_pD3DDevice);
|
||||
}
|
||||
|
||||
// setup menu primitive
|
||||
pVMenu[0].x = 0.f;
|
||||
pVMenu[0].y = 0.f;
|
||||
pVMenu[0].z = 0.0f;
|
||||
pVMenu[0].rhw = 2.0f;
|
||||
pVMenu[0].clr = RGBA_MAKE(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
pVMenu[1].x = 60.f;
|
||||
pVMenu[1].y = 0.f;
|
||||
pVMenu[1].z = 0.0f;
|
||||
pVMenu[1].rhw = 2.0f;
|
||||
pVMenu[1].clr = RGBA_MAKE(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
pVMenu[2].x = 0.f;
|
||||
pVMenu[2].y = 480.f;
|
||||
pVMenu[2].z = 0.0f;
|
||||
pVMenu[2].rhw = 2.0f;
|
||||
pVMenu[2].clr = RGBA_MAKE(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
pVMenu[3].x = 60.f;
|
||||
pVMenu[3].y = 480.f;
|
||||
pVMenu[3].z = 0.0f;
|
||||
pVMenu[3].rhw = 2.0f;
|
||||
pVMenu[3].clr = RGBA_MAKE(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
//
|
||||
// Setup the SRC info
|
||||
//
|
||||
pVMenu[0].tu = 0.f;
|
||||
pVMenu[0].tv = 0.f;
|
||||
|
||||
pVMenu[1].tu = 1.f;
|
||||
pVMenu[1].tv = 0.f;
|
||||
|
||||
pVMenu[2].tu = 0.f;
|
||||
pVMenu[2].tv = 1.f;
|
||||
|
||||
pVMenu[3].tu = 1.f;
|
||||
pVMenu[3].tv = 1.f;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//----------------------------------------------------------------------------
|
||||
~CAlphaBlt()
|
||||
{
|
||||
if( m_ptxtrMenu )
|
||||
{
|
||||
delete m_ptxtrMenu;
|
||||
m_ptxtrMenu = NULL;
|
||||
}
|
||||
|
||||
if( m_pFont )
|
||||
{
|
||||
delete m_pFont;
|
||||
m_pFont = NULL;
|
||||
}
|
||||
|
||||
RELEASE(m_lpDDBackBuffer);
|
||||
RELEASE(m_lpDDM32);
|
||||
RELEASE(m_lpDDM16);
|
||||
|
||||
RELEASE(m_pD3DDevice);
|
||||
RELEASE(m_pD3D);
|
||||
RELEASE(m_pDD);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetMenuTexture
|
||||
//
|
||||
// returns pointer to texture's DD surface or NULL otherwise
|
||||
//----------------------------------------------------------------------------
|
||||
LPDIRECTDRAWSURFACE7 GetMenuTexture()
|
||||
{
|
||||
if( m_ptxtrMenu && m_ptxtrMenu->m_pddsSurface )
|
||||
{
|
||||
return (m_ptxtrMenu->m_pddsSurface);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SetMenuRestoreFlag
|
||||
//
|
||||
// sets m_bNeedToRestoreMenu = true; (called from CMpegMovie::RestoreDDRawSurfaces() )
|
||||
//----------------------------------------------------------------------------
|
||||
void SetMenuRestoreFlag()
|
||||
{
|
||||
m_bNeedToRestoreMenu = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// GetFont
|
||||
//----------------------------------------------------------------------------
|
||||
CD3DFont * GetFont()
|
||||
{
|
||||
return m_pFont;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PrepareVerticesRotate
|
||||
//
|
||||
// This is the 'main' transformation function for foration effect.
|
||||
// It generates rotation angles from 'time' variable that is just
|
||||
// a static counter of images from CMpegMovie:PresentImage function
|
||||
//
|
||||
// Parameters:
|
||||
// lpDst - destination rectangle
|
||||
// lpSrc - source rectangle
|
||||
// alpha - alpha level for the surface
|
||||
// fWid - width of the surface obtained by CMpegMovie:PresentImage
|
||||
// fHgt - height of the surface obtained by CMpegMovie:PresentImage
|
||||
//----------------------------------------------------------------------------
|
||||
void PrepareVerticesRotate( RECT* lpDst, RECT* lpSrc, BYTE alpha,
|
||||
float fWid, float fHgt)
|
||||
{
|
||||
float RotRadZ = 0.f;
|
||||
float RotRadY = 0.f;
|
||||
|
||||
//
|
||||
// Setup the DST info
|
||||
//
|
||||
pVertices[0].x = (float)lpDst->left;
|
||||
pVertices[0].y = (float)lpDst->top;
|
||||
pVertices[0].z = 0.5f;
|
||||
pVertices[0].rhw = 2.0f;
|
||||
pVertices[0].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[1].x = (float)lpDst->right;
|
||||
pVertices[1].y = (float)lpDst->top;
|
||||
pVertices[1].z = 0.5f;
|
||||
pVertices[1].rhw = 2.0f;
|
||||
pVertices[1].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[2].x = (float)lpDst->left;
|
||||
pVertices[2].y = (float)lpDst->bottom;
|
||||
pVertices[2].z = 0.5f;
|
||||
pVertices[2].rhw = 2.0f;
|
||||
pVertices[2].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
pVertices[3].x = (float)lpDst->right;
|
||||
pVertices[3].y = (float)lpDst->bottom;
|
||||
pVertices[3].z = 0.5f;
|
||||
pVertices[3].rhw = 2.0f;
|
||||
pVertices[3].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
|
||||
//
|
||||
// Setup the SRC info
|
||||
//
|
||||
pVertices[0].tu = ((float)lpSrc->left) / fWid;
|
||||
pVertices[0].tv = ((float)lpSrc->top) / fHgt;
|
||||
|
||||
pVertices[1].tu = ((float)lpSrc->right) / fWid;
|
||||
pVertices[1].tv = ((float)lpSrc->top) / fHgt;
|
||||
|
||||
pVertices[2].tu = ((float)lpSrc->left) / fWid;
|
||||
pVertices[2].tv = ((float)lpSrc->bottom) / fHgt;
|
||||
|
||||
pVertices[3].tu = ((float)lpSrc->right) / fWid;
|
||||
pVertices[3].tv = ((float)lpSrc->bottom) / fHgt;
|
||||
|
||||
// g_ss.nGradZ is an angle in grades, so calculate radians
|
||||
RotRadZ = (float) (g_ss.nGradZ++) * pi / 180.f;
|
||||
if( !g_ss.bRotateZ)
|
||||
{
|
||||
g_ss.nGradZ--;
|
||||
}
|
||||
|
||||
RotRadY = (float) (g_ss.nGradY++) * pi / 180.f;
|
||||
if( !g_ss.bRotateY)
|
||||
{
|
||||
g_ss.nGradY--;
|
||||
}
|
||||
|
||||
// to avoid stack overflow, limit counters withing 360 grades
|
||||
if( g_ss.nGradZ > 360)
|
||||
{
|
||||
g_ss.nGradZ = 0;
|
||||
}
|
||||
|
||||
if( g_ss.nGradY > 360)
|
||||
{
|
||||
g_ss.nGradY = 0;
|
||||
}
|
||||
|
||||
// and finally rotate the primitive pVertices
|
||||
// NOTE that rotation center is hardcoded for the case
|
||||
// 640x480 display mode
|
||||
Rotate(RotRadZ, RotRadY, pVertices, 4, 320.f, 240.f);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// PrepareVerticesTwist
|
||||
//
|
||||
// This is the 'main' transformation function for "twist" effect.
|
||||
// It generates transformation parameters 'time' variable that is just
|
||||
// a static counter of images from CMpegMovie:PresentImage function
|
||||
//
|
||||
// Parameters:
|
||||
// lpDst - destination rectangle
|
||||
// lpSrc - source rectangle
|
||||
// alpha - alpha level for the surface
|
||||
// fWid - width of the surface obtained by CMpegMovie:PresentImage
|
||||
// fHgt - height of the surface obtained by CMpegMovie:PresentImage
|
||||
//
|
||||
// Other: put your own effects here
|
||||
// The effect I use is as following:
|
||||
// (a) move picture down to create 'slipping' effect
|
||||
// (b) srink lower part of the picture (parameter c applied to each verticle
|
||||
// so that it would look like a wine glass stem (cosine is what we need)
|
||||
// Shrinking coefficient depends on Y-coordinate of a verticle
|
||||
// (c) twist lower part of the picture around Y axis, angle depends on
|
||||
// Y-coordinate of a verticle
|
||||
//----------------------------------------------------------------------------
|
||||
void PrepareVerticesTwist( RECT* lpDst, RECT* lpSrc, BYTE alpha,
|
||||
float fW, float fH)
|
||||
{
|
||||
CAlphaBlt::Vertex * V = pVComplex;
|
||||
float W = (float)(lpDst->right - lpDst->left);
|
||||
float H = (float)(lpDst->bottom - lpDst->top);
|
||||
float sW = (float)(lpSrc->right - lpSrc->left)/fW;
|
||||
float sH = (float)(lpSrc->bottom - lpSrc->top);
|
||||
float Ht = 480 - H;
|
||||
float c;
|
||||
float radY = 0.f;
|
||||
float radX = pi/4.f;
|
||||
float x;
|
||||
double costh;
|
||||
double sinth;
|
||||
D3DXMATRIX mtrPrs;
|
||||
D3DXMATRIX mtrOrg;
|
||||
D3DXMATRIX mtrRes;
|
||||
|
||||
int N = COMPLVERTSIZE/2;
|
||||
|
||||
g_ss.nDy = g_ss.nDy + 3;
|
||||
if( g_ss.nDy > 480 )
|
||||
{
|
||||
g_ss.nDy = 0;
|
||||
}
|
||||
|
||||
for( int i=0; i<COMPLVERTSIZE; i=i+2)
|
||||
{
|
||||
V[i ].x = (float)(lpDst->left);
|
||||
V[i+1].x = (float)(lpDst->right);
|
||||
V[i ].y = V[i+1].y = (float)(i * H/(N-1)) + g_ss.nDy;
|
||||
V[i ].z = V[i+1].z = 0.5f;
|
||||
V[i ].rhw = V[i+1].rhw = 2.f;
|
||||
V[i ].clr = V[i+1].clr = RGBA_MAKE(0xff, 0xff, 0xff, alpha);
|
||||
V[i ].tu = ((float)lpSrc->left) / fW;
|
||||
V[i+1].tu = ((float)lpSrc->right) / fW;
|
||||
V[i ].tv = V[i+1].tv = (float)(lpSrc->top + sH * (float)i/(N-1.f)/2.f)/fH;
|
||||
|
||||
|
||||
if( V[i].y >= H )
|
||||
{
|
||||
|
||||
c = (float)( W * (1. + cos(pi * (480. - V[i].y)/Ht)) / 4.);
|
||||
//c *= 0.25f;
|
||||
V[i ].x += c;
|
||||
V[i+1].x -= c;
|
||||
|
||||
radY = pi * ( V[i].y - H ) / 2.f / Ht;
|
||||
|
||||
costh = cos(radY);
|
||||
sinth = sin(radY);
|
||||
|
||||
x = V[i].x - 320.f;
|
||||
V[i].x = (float)(costh * x - sinth * V[i].z) + 320.f;
|
||||
V[i].z = (float)(sinth * x + costh * V[i].z);
|
||||
|
||||
x = V[i+1].x - 320.f;
|
||||
V[i+1].x = (float)(costh * x - sinth * V[i+1].z) + 320.f;
|
||||
V[i+1].z = (float)(sinth * x + costh * V[i+1].z);
|
||||
|
||||
} // if
|
||||
|
||||
}// for i
|
||||
|
||||
|
||||
// now let's implement projection
|
||||
D3DXMatrixPerspectiveFov( &mtrPrs, pi/2.f, 1.1f, 0.f, 1.f);
|
||||
for( i=0; i<COMPLVERTSIZE; i = i+4)
|
||||
{
|
||||
mtrOrg.m[0][0] = V[i].x;
|
||||
mtrOrg.m[1][0] = V[i].y;
|
||||
mtrOrg.m[2][0] = V[i].z;
|
||||
mtrOrg.m[3][0] = 0.f;
|
||||
|
||||
mtrOrg.m[0][1] = V[i+1].x;
|
||||
mtrOrg.m[1][1] = V[i+1].y;
|
||||
mtrOrg.m[2][1] = V[i+1].z;
|
||||
mtrOrg.m[3][1] = 0.f;
|
||||
|
||||
mtrOrg.m[0][2] = V[i+2].x;
|
||||
mtrOrg.m[1][2] = V[i+2].y;
|
||||
mtrOrg.m[2][2] = V[i+2].z;
|
||||
mtrOrg.m[3][2] = 0.f;
|
||||
|
||||
mtrOrg.m[0][3] = V[i+3].x;
|
||||
mtrOrg.m[1][3] = V[i+3].y;
|
||||
mtrOrg.m[2][3] = V[i+3].z;
|
||||
mtrOrg.m[3][3] = 0.f;
|
||||
|
||||
D3DXMatrixMultiply( &mtrRes, &mtrPrs, &mtrOrg);
|
||||
|
||||
V[i ].x = mtrRes.m[0][0];
|
||||
V[i ].y = mtrRes.m[1][0];
|
||||
V[i ].z = mtrRes.m[2][0];
|
||||
|
||||
V[i+1].x = mtrRes.m[0][1];
|
||||
V[i+1].y = mtrRes.m[1][1];
|
||||
V[i+1].z = mtrRes.m[2][1];
|
||||
|
||||
V[i+2].x = mtrRes.m[0][2];
|
||||
V[i+2].y = mtrRes.m[1][2];
|
||||
V[i+2].z = mtrRes.m[2][2];
|
||||
|
||||
V[i+3].x = mtrRes.m[0][3];
|
||||
V[i+3].y = mtrRes.m[1][3];
|
||||
V[i+3].z = mtrRes.m[2][3];
|
||||
}// for
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// AlphaBlt
|
||||
//
|
||||
// This function receives LPDIRECTDRAWSURFACE7 from ImagePresenter, calls
|
||||
// transformation functions to provide visual effects, sets the scene and
|
||||
// renders primitives
|
||||
//
|
||||
// Parameters:
|
||||
// lpDst -- destination rectangle
|
||||
// lpDDSSrc -- surface obtained by ImagePresenter
|
||||
// lpSrc -- source rectangle
|
||||
// bAlpha -- alpha value for the surface
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
AlphaBlt(RECT* lpDst,
|
||||
LPDIRECTDRAWSURFACE7 lpDDSSrc,
|
||||
RECT* lpSrc,
|
||||
BYTE bAlpha
|
||||
)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
int nVertSize = 0;
|
||||
|
||||
CAlphaBlt::Vertex * pV = NULL;
|
||||
|
||||
__try {
|
||||
|
||||
INITDDSTRUCT(ddsd);
|
||||
CHECK_HR(hr = lpDDSSrc->GetSurfaceDesc(&ddsd));
|
||||
|
||||
if (!IsSurfaceBlendable(ddsd, bAlpha)) {
|
||||
CHECK_HR(hr = MirrorSourceSurface(lpDDSSrc, ddsd));
|
||||
lpDDSSrc = m_lpDDMirror;
|
||||
}
|
||||
|
||||
float fWid = (float)ddsd.dwWidth;
|
||||
float fHgt = (float)ddsd.dwHeight;
|
||||
|
||||
if( g_ss.bShowTwist )
|
||||
{
|
||||
nVertSize = COMPLVERTSIZE;
|
||||
PrepareVerticesTwist(lpDst, lpSrc, bAlpha, fWid, fHgt);
|
||||
pV = pVComplex;
|
||||
}
|
||||
else
|
||||
{
|
||||
nVertSize = 4;
|
||||
PrepareVerticesRotate(lpDst, lpSrc, bAlpha, fWid, fHgt);
|
||||
pV = pVertices;
|
||||
}
|
||||
|
||||
BYTE alpha = bAlpha;
|
||||
|
||||
m_pD3DDevice->SetTexture(0, lpDDSSrc);
|
||||
// if menu is defined, set it
|
||||
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, TRUE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_BLENDENABLE, TRUE);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, FALSE);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
|
||||
//
|
||||
// Do the alpha BLT
|
||||
//
|
||||
CHECK_HR(hr = m_pD3DDevice->BeginScene());
|
||||
CHECK_HR(hr = m_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,0,0.5,0));
|
||||
CHECK_HR(hr = m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
pV, nVertSize, D3DDP_WAIT));
|
||||
|
||||
// now, draw menu over the video
|
||||
|
||||
// if user switched modes, menu texture may be lost; then restore
|
||||
if( m_bNeedToRestoreMenu )
|
||||
{
|
||||
DDSURFACEDESC2 ddsd;
|
||||
ZeroMemory( &ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_ALL;
|
||||
m_pDD->GetDisplayMode( &ddsd);
|
||||
|
||||
// if we try to restore surface in a different display mode, we will fail
|
||||
// so make the check first
|
||||
if( ddsd.dwWidth == SCRN_WIDTH &&
|
||||
ddsd.dwHeight == SCRN_HEIGHT &&
|
||||
ddsd.ddpfPixelFormat.dwRGBBitCount == SCRN_BITDEPTH )
|
||||
{
|
||||
hr = GetMenuTexture()->Restore();
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("ERROR: Failed to restore menu texture");
|
||||
}
|
||||
else
|
||||
{
|
||||
// surface restored, but its image lost; reload
|
||||
if( m_ptxtrMenu)
|
||||
{
|
||||
hr = m_ptxtrMenu->LoadImageData();
|
||||
if( FAILED(hr))
|
||||
{
|
||||
OutputDebugString("Failed to load the image from resource\n");
|
||||
}
|
||||
if( m_ptxtrMenu->m_hbmBitmap )
|
||||
{
|
||||
BITMAP bm;
|
||||
GetObject( m_ptxtrMenu->m_hbmBitmap, sizeof(BITMAP), &bm );
|
||||
m_ptxtrMenu->m_dwWidth = (DWORD)bm.bmWidth;
|
||||
m_ptxtrMenu->m_dwHeight = (DWORD)bm.bmHeight;
|
||||
m_ptxtrMenu->m_dwBPP = (DWORD)bm.bmBitsPixel;
|
||||
}
|
||||
|
||||
hr = m_ptxtrMenu->Restore(m_pD3DDevice);
|
||||
if( FAILED(hr))
|
||||
{
|
||||
delete m_ptxtrMenu;
|
||||
m_ptxtrMenu = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m_bNeedToRestoreMenu = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDebugString("Failed to restore menu texture");
|
||||
}
|
||||
}
|
||||
|
||||
m_pD3DDevice->SetTexture(0, m_ptxtrMenu->m_pddsSurface);
|
||||
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
|
||||
//
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
|
||||
CHECK_HR(hr = m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
pVMenu, 4, D3DDP_WAIT));
|
||||
m_pD3DDevice->SetTexture(0, NULL);
|
||||
|
||||
// and if necessary, draw the dext over the menu
|
||||
if( g_ss.bShowHelp )
|
||||
{
|
||||
HRESULT hr = m_pFont->DrawText((float)g_ss.nXHelp, (float)g_ss.nYHelp,
|
||||
RGBA_MAKE(0xFF, 0xFF, 0x00, 0xFF),
|
||||
g_ss.achHelp );
|
||||
}
|
||||
if( g_ss.bShowStatistics )
|
||||
{
|
||||
m_pFont->DrawText( 420, 0,
|
||||
RGBA_MAKE(0x00, 0xFF, 0x00, 0xFF),
|
||||
g_ss.achFPS );
|
||||
}
|
||||
|
||||
CHECK_HR(hr = m_pD3DDevice->EndScene());
|
||||
|
||||
} __finally {
|
||||
m_pD3DDevice->SetTexture(0, NULL);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// TextureSquare
|
||||
// true if texture is square
|
||||
//----------------------------------------------------------------------------
|
||||
bool TextureSquare() {
|
||||
return m_fSquare;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// TexturePower2
|
||||
// true if texture size is of a power of 2
|
||||
//----------------------------------------------------------------------------
|
||||
bool TexturePower2() {
|
||||
return m_fPowerOf2;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: DDrawSupport.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Implementation of DDrawObject that provides basic DDraw functionality
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
#include "project.h"
|
||||
#include <d3d.h>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
//
|
||||
// Initialize DDrawObject by getting to fullscreen exclusive mode and
|
||||
// setting front and back buffer
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
CDDrawObject::Initialize(HWND hWndApp)
|
||||
{
|
||||
HRESULT hr;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
|
||||
m_hwndApp = hWndApp;
|
||||
|
||||
hr = DirectDrawCreateEx(NULL, (LPVOID *)&m_pDDObject,
|
||||
IID_IDirectDraw7, NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Get into fullscreen exclusive mode
|
||||
hr = m_pDDObject->SetCooperativeLevel(hWndApp,
|
||||
DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN |
|
||||
DDSCL_ALLOWREBOOT);
|
||||
if (FAILED(hr)) {
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_pDDObject->SetDisplayMode(SCRN_WIDTH, SCRN_HEIGHT, SCRN_BITDEPTH,
|
||||
0, DDSDM_STANDARDVGAMODE);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
// Create the primary surface with 1 back buffer
|
||||
ZeroMemory(&ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
|
||||
DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE;
|
||||
ddsd.dwBackBufferCount = 2;
|
||||
hr = m_pDDObject->CreateSurface(&ddsd, &m_pPrimary, NULL);
|
||||
if (FAILED(hr)) {
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Get a pointer to the back buffer
|
||||
DDSCAPS2 ddscaps = { DDSCAPS_BACKBUFFER, 0, 0, 0 };
|
||||
hr = m_pPrimary->GetAttachedSurface(&ddscaps, &m_pBackBuff);
|
||||
if (FAILED(hr)) {
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
// Get the screen size and save it as a rect
|
||||
ZeroMemory(&ddsd, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
hr = m_pPrimary->GetSurfaceDesc(&ddsd);
|
||||
if (!(SUCCEEDED(hr) &&
|
||||
(ddsd.dwFlags & DDSD_WIDTH) && (ddsd.dwFlags & DDSD_HEIGHT))) {
|
||||
|
||||
Terminate();
|
||||
return hr;
|
||||
}
|
||||
|
||||
SetRect(&m_RectScrn, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Terminate
|
||||
//
|
||||
// return from exclusive mode
|
||||
//----------------------------------------------------------------------------
|
||||
HRESULT
|
||||
CDDrawObject::Terminate()
|
||||
{
|
||||
|
||||
if (m_pBackBuff) {
|
||||
m_pBackBuff->Release();
|
||||
m_pBackBuff = NULL;
|
||||
}
|
||||
|
||||
if (m_pPrimary) {
|
||||
m_pPrimary->Release();
|
||||
m_pPrimary = NULL;
|
||||
}
|
||||
|
||||
if (m_pDDObject) {
|
||||
|
||||
m_pDDObject->SetCooperativeLevel(m_hwndApp, DDSCL_NORMAL) ;
|
||||
m_pDDObject->Release();
|
||||
m_pDDObject = NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: DDrawSupport.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Prototype of DDrawObject that provides basic DDraw functionality
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#ifndef DDRAWSUPPORT_HEADER
|
||||
#define DDRAWSUPPORT_HEADER
|
||||
|
||||
#ifndef __RELEASE_DEFINED
|
||||
#define __RELEASE_DEFINED
|
||||
|
||||
template<typename T>
|
||||
__inline void RELEASE( T* &p )
|
||||
{
|
||||
if( p ) {
|
||||
p->Release();
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_HR
|
||||
#define CHECK_HR(expr) if (FAILED(expr)) {\
|
||||
DbgLog((LOG_ERROR, 0, \
|
||||
TEXT("FAILED: %s\nat Line:%d of %s"), \
|
||||
TEXT(#expr), __LINE__, TEXT(__FILE__) ));__leave; } else
|
||||
#endif
|
||||
|
||||
|
||||
#define SCRN_WIDTH 640
|
||||
#define SCRN_HEIGHT 480
|
||||
#define SCRN_BITDEPTH 32
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// CDDrawObject
|
||||
//
|
||||
// Class provides basic DDraw functionality
|
||||
//----------------------------------------------------------------------------
|
||||
class CDDrawObject {
|
||||
|
||||
public:
|
||||
CDDrawObject() :
|
||||
m_hwndApp(NULL),
|
||||
m_pDDObject(NULL),
|
||||
m_pPrimary(NULL),
|
||||
m_pBackBuff(NULL)
|
||||
{
|
||||
ZeroMemory(&m_RectScrn, sizeof(m_RectScrn));
|
||||
}
|
||||
|
||||
HRESULT Initialize(HWND hwndApp);
|
||||
HRESULT Terminate();
|
||||
LPDIRECTDRAW7 GetDDObj() {return m_pDDObject;};
|
||||
LPDIRECTDRAWSURFACE7 GetFB() {return m_pPrimary;};
|
||||
LPDIRECTDRAWSURFACE7 GetBB() {return m_pBackBuff;};
|
||||
|
||||
private:
|
||||
HWND m_hwndApp;
|
||||
RECT m_RectScrn;
|
||||
LPDIRECTDRAW7 m_pDDObject;
|
||||
LPDIRECTDRAWSURFACE7 m_pPrimary;
|
||||
LPDIRECTDRAWSURFACE7 m_pBackBuff;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
Windows XP DirectShow Sample -- VMRXCL
|
||||
--------------------------------------
|
||||
|
||||
Description: This application shows capabilities of the new
|
||||
video mixing renderer (VMR) that is the default video
|
||||
renderer in Windows XP. In particular, it demonstrates
|
||||
how to use the VMR in exclusive DirectDraw mode and
|
||||
how to implement a user-provided (customized) Allocator-Presenter
|
||||
for the VMR. Also, it contains useful utilities to manage
|
||||
bitmaps (as textures) and TrueType fonts for text over video.
|
||||
|
||||
Usage:
|
||||
Upon initialization, VMRXCL asks you to specify a video file.
|
||||
The application switches to DirectDraw exclusive mode, after setting
|
||||
the display mode to 640 x 480 x 32bpp. A bitmap-based menu on the
|
||||
left side of the screen provides interactivity.
|
||||
(From top to bottom, the menu items are:
|
||||
- Show statistics
|
||||
- Pause
|
||||
- Run
|
||||
- Rotate in XY plane
|
||||
- Rotate in YX plane
|
||||
- 'Twist' non-linear effect
|
||||
- Exit
|
||||
|
||||
Right click over the menu button to activate its text hint.
|
||||
Left click to hide text hints.
|
||||
|
||||
Troubleshooting:
|
||||
Depending on the capabilities of your video driver, text may be disabled.
|
||||
You may also experience glitches with bitmaps applied over the video.
|
||||
|
||||
NOTE: The speed of the 3D animation is directly related to the frame rate of
|
||||
the video file being played.
|
||||
|
||||
@@ -0,0 +1,561 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: Utils.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// External (global) utilities specific for VMRXcl app
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
#include "project.h"
|
||||
#include "utils.h"
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Function: hresultNameLookup
|
||||
// Purpose: returns a string value for the given hresult
|
||||
// Arguments: HRESULT that needs verifying
|
||||
// Returns: string
|
||||
//-----------------------------------------------------------------------------------------*/
|
||||
const char * hresultNameLookup(HRESULT hres)
|
||||
{
|
||||
switch(hres)
|
||||
{
|
||||
case VFW_E_CANNOT_RENDER:
|
||||
return "VFW_E_CANNOT_RENDER";
|
||||
break;
|
||||
case VFW_E_INVALID_FILE_FORMAT:
|
||||
return "VFW_E_INVALID_FILE_FORMAT";
|
||||
break;
|
||||
case VFW_E_NOT_FOUND:
|
||||
return "VFW_E_NOT_FOUND";
|
||||
break;
|
||||
case VFW_E_NOT_IN_GRAPH:
|
||||
return "VFW_E_NOT_IN_GRAPH";
|
||||
break;
|
||||
case VFW_E_UNKNOWN_FILE_TYPE:
|
||||
return "VFW_E_UNKNOWN_FILE_TYPE";
|
||||
break;
|
||||
case VFW_E_UNSUPPORTED_STREAM:
|
||||
return "VFW_E_UNSUPPORTED_STREAM";
|
||||
break;
|
||||
case VFW_E_CANNOT_CONNECT:
|
||||
return "VFW_E_CANNOT_CONNECT";
|
||||
break;
|
||||
case VFW_E_CANNOT_LOAD_SOURCE_FILTER:
|
||||
return "VFW_E_CANNOT_LOAD_SOURCE_FILTER";
|
||||
break;
|
||||
case VFW_S_PARTIAL_RENDER:
|
||||
return "VFW_S_PARTIAL_RENDER";
|
||||
break;
|
||||
case VFW_S_VIDEO_NOT_RENDERED:
|
||||
return "VFW_S_VIDEO_NOT_RENDERED";
|
||||
break;
|
||||
case VFW_S_AUDIO_NOT_RENDERED:
|
||||
return "VFW_S_AUDIO_NOT_RENDERED";
|
||||
break;
|
||||
case VFW_S_DUPLICATE_NAME:
|
||||
return "VFW_S_DUPLICATE_NAME";
|
||||
break;
|
||||
case VFW_S_MEDIA_TYPE_IGNORED:
|
||||
return "VFW_S_MEDIA_TYPE_IGNORED";
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
return "E_INVALIDARG";
|
||||
break;
|
||||
case DDERR_INCOMPATIBLEPRIMARY:
|
||||
return "DDERR_INCOMPATIBLEPRIMARY";
|
||||
break;
|
||||
case DDERR_INVALIDCAPS:
|
||||
return "DDERR_INVALIDCAPS";
|
||||
break;
|
||||
case DDERR_INVALIDOBJECT :
|
||||
return "DDERR_INVALIDOBJECT";
|
||||
break;
|
||||
case DDERR_INVALIDPIXELFORMAT:
|
||||
return "DDERR_INVALIDPIXELFORMAT";
|
||||
break;
|
||||
case DDERR_NOALPHAHW :
|
||||
return "DDERR_NOALPHAHW";
|
||||
break;
|
||||
case DDERR_NOCOOPERATIVELEVELSET :
|
||||
return "DDERR_NOCOOPERATIVELEVELSET";
|
||||
break;
|
||||
case DDERR_NODIRECTDRAWHW :
|
||||
return "DDERR_NODIRECTDRAWHW";
|
||||
break;
|
||||
case DDERR_NOEMULATION :
|
||||
return "DDERR_NOEMULATION";
|
||||
break;
|
||||
case VFW_E_BUFFERS_OUTSTANDING:
|
||||
return "VFW_E_BUFFERS_OUTSTANDING";
|
||||
break;
|
||||
case DDERR_NOEXCLUSIVEMODE :
|
||||
return "DDERR_NOEXCLUSIVEMODE ";
|
||||
break;
|
||||
case DDERR_NOFLIPHW:
|
||||
return "DDERR_NOFLIPHW";
|
||||
break;
|
||||
case DDERR_NOMIPMAPHW:
|
||||
return "DDERR_NOMIPMAPHW";
|
||||
break;
|
||||
case DDERR_NOOVERLAYHW :
|
||||
return "DDERR_NOOVERLAYHW ";
|
||||
break;
|
||||
case E_OUTOFMEMORY:
|
||||
return "E_OUTOFMEMORY";
|
||||
break;
|
||||
case VFW_E_NO_DISPLAY_PALETTE:
|
||||
return "VFW_E_NO_DISPLAY_PALETTE";
|
||||
break;
|
||||
case VFW_E_NO_COLOR_KEY_FOUND:
|
||||
return "VFW_E_NO_COLOR_KEY_FOUND";
|
||||
break;
|
||||
case VFW_E_PALETTE_SET:
|
||||
return "VFW_E_PALETTE_SET";
|
||||
break;
|
||||
case DDERR_NOZBUFFERHW :
|
||||
return "DDERR_NOZBUFFERHW ";
|
||||
break;
|
||||
case DDERR_OUTOFVIDEOMEMORY :
|
||||
return "DDERR_OUTOFVIDEOMEMORY";
|
||||
break;
|
||||
case DDERR_PRIMARYSURFACEALREADYEXISTS:
|
||||
return "DDERR_PRIMARYSURFACEALREADYEXISTS ";
|
||||
break;
|
||||
case DDERR_UNSUPPORTEDMODE:
|
||||
return "DDERR_UNSUPPORTEDMODE";
|
||||
break;
|
||||
case VFW_E_NO_ADVISE_SET:
|
||||
return "VFW_E_NO_ADVISE_SET";
|
||||
break;
|
||||
case S_OK:
|
||||
return "S_OK";
|
||||
break;
|
||||
case S_FALSE:
|
||||
return "S_FALSE";
|
||||
break;
|
||||
case VFW_S_CONNECTIONS_DEFERRED:
|
||||
return "VFW_S_CONNECTIONS_DEFERRED";
|
||||
break;
|
||||
case 0x80040154:
|
||||
return "Class not registered";
|
||||
break;
|
||||
case E_FAIL:
|
||||
return "E_FAIL";
|
||||
break;
|
||||
case VFW_E_DVD_OPERATION_INHIBITED:
|
||||
return "VFW_E_DVD_OPERATION_INHIBITED";
|
||||
break;
|
||||
case VFW_E_DVD_INVALIDDOMAIN:
|
||||
return "VFW_E_DVD_INVALIDDOMAIN";
|
||||
break;
|
||||
case E_NOTIMPL:
|
||||
return "E_NOTIMPL";
|
||||
break;
|
||||
case VFW_E_WRONG_STATE:
|
||||
return "VFW_E_WRONG_STATE";
|
||||
break;
|
||||
case E_PROP_SET_UNSUPPORTED:
|
||||
return "E_PROP_SET_UNSUPPORTED";
|
||||
break;
|
||||
case VFW_E_NO_PALETTE_AVAILABLE:
|
||||
return "VFW_E_NO_PALETTE_AVAILABLE";
|
||||
break;
|
||||
case E_UNEXPECTED:
|
||||
return "E_UNEXPECTED";
|
||||
break;
|
||||
case VFW_E_DVD_NO_BUTTON:
|
||||
return "VFW_E_DVD_NO_BUTTON";
|
||||
break;
|
||||
case VFW_E_DVD_GRAPHNOTREADY:
|
||||
return "VFW_E_DVD_GRAPHNOTREADY";
|
||||
break;
|
||||
case VFW_E_NOT_OVERLAY_CONNECTION:
|
||||
return "VFW_E_NOT_OVERLAY_CONNECTION";
|
||||
break;
|
||||
case VFW_E_DVD_RENDERFAIL:
|
||||
return "VFW_E_DVD_RENDERFAIL";
|
||||
break;
|
||||
case VFW_E_NOT_CONNECTED:
|
||||
return "VFW_E_NOT_CONNECTED";
|
||||
break;
|
||||
case E_NOINTERFACE:
|
||||
return "E_NOINTERFACE";
|
||||
break;
|
||||
case VFW_E_NO_COLOR_KEY_SET :
|
||||
return "VFW_E_NO_COLOR_KEY_SET ";
|
||||
break;
|
||||
case VFW_E_NO_INTERFACE:
|
||||
return "VFW_E_NO_INTERFACE";
|
||||
break;
|
||||
case 0x8004020c:
|
||||
return "VFW_E_BUFFER_NOTSET";
|
||||
break;
|
||||
case 0x80040225:
|
||||
return "VFW_E_NOT_PAUSED";
|
||||
case 0x80070002:
|
||||
return "System cannot find the file specified";
|
||||
break;
|
||||
case 0x80070003:
|
||||
return "System cannot find the path specified";
|
||||
break;
|
||||
case VFW_E_DVD_DECNOTENOUGH:
|
||||
return "VFW_E_DVD_DECNOTENOUGH";
|
||||
break;
|
||||
case VFW_E_ADVISE_ALREADY_SET:
|
||||
return "VFW_E_ADVISE_ALREADY_SET";
|
||||
break;
|
||||
case VFW_E_DVD_CMD_CANCELLED:
|
||||
return "VFW_E_DVD_CMD_CANCELLED";
|
||||
break;
|
||||
case VFW_E_DVD_MENU_DOES_NOT_EXIST:
|
||||
return "VFW_E_DVD_MENU_DOES_NOT_EXIST";
|
||||
break;
|
||||
case VFW_E_DVD_WRONG_SPEED:
|
||||
return "VFW_E_DVD_WRONG_SPEED";
|
||||
break;
|
||||
case VFW_S_DVD_NON_ONE_SEQUENTIAL:
|
||||
return "VFW_S_DVD_NON_ONE_SEQUENTIAL";
|
||||
break;
|
||||
case E_POINTER:
|
||||
return "E_POINTER";
|
||||
break;
|
||||
case VFW_E_DVD_NOT_IN_KARAOKE_MODE:
|
||||
return "VFW_E_DVD_NOT_IN_KARAOKE_MODE";
|
||||
break;
|
||||
case VFW_E_DVD_INVALID_DISC:
|
||||
return "VFW_E_DVD_INVALID_DISC";
|
||||
break;
|
||||
case VFW_E_DVD_STREAM_DISABLED:
|
||||
return "VFW_E_DVD_STREAM_DISABLED";
|
||||
break;
|
||||
case VFW_E_NOT_STOPPED:
|
||||
return "VFW_E_NOT_STOPPED";
|
||||
break;
|
||||
default:
|
||||
return "Unrecognized";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------------
|
||||
| Function: MySleep
|
||||
| Purpose: if the application is in automated mode, then sleep func is turned off
|
||||
| Arguments: checks m_bAutomatedStatus to see if the func is in automation
|
||||
| Returns: true if automated, false otherwist
|
||||
\-----------------------------------------------------------------------------------------*/
|
||||
|
||||
bool MySleep(DWORD dwTime)
|
||||
{
|
||||
HANDLE hNeverHappensEvent;
|
||||
hNeverHappensEvent = CreateEvent(NULL, FALSE, FALSE, "EVENTTHATNEVERHAPPENS");
|
||||
WaitForSingleObject( hNeverHappensEvent, dwTime);
|
||||
return false;
|
||||
|
||||
} // end of checkHResult method
|
||||
|
||||
|
||||
void ReportDDrawSurfDesc( DDSURFACEDESC2 ddsd)
|
||||
{
|
||||
char szFlags[4096];
|
||||
char szMsg[4096];
|
||||
|
||||
OutputDebugString("*** Surface description ***\n");
|
||||
|
||||
SurfaceDescHelper( ddsd.dwFlags, szFlags);
|
||||
OutputDebugString(szFlags);
|
||||
|
||||
sprintf( szMsg, " dwWidth x dwHeight: %ld x %ld\n", ddsd.dwWidth, ddsd.dwHeight);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
sprintf( szMsg, " lPitch: %ld\n", ddsd.lPitch);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwLinearSize)\n");
|
||||
|
||||
sprintf( szMsg, " dwBackBufferCount: %ld\n", ddsd.dwBackBufferCount);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
sprintf( szMsg, " dwMipMapCount: %ld\n", ddsd.dwMipMapCount);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwRefreshRate)");
|
||||
|
||||
sprintf( szMsg, " dwAlphaBitDepth: %ld\n", (LONG)ddsd.dwAlphaBitDepth);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
sprintf( szMsg, " lpSurface: %x\n", (LONG_PTR)(ddsd.lpSurface));
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
ReportPixelFormat( ddsd.ddpfPixelFormat );
|
||||
ReportDDSCAPS2( ddsd.ddsCaps );
|
||||
|
||||
sprintf( szMsg, " dwTextureStage: %ld\n", ddsd.dwTextureStage);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
OutputDebugString("***************************\n");
|
||||
}
|
||||
|
||||
void ReportDDSCAPS2( DDSCAPS2 ddscaps )
|
||||
{
|
||||
char sz[4096];
|
||||
|
||||
strcpy( sz, " DDSCAPS2::dwCaps: ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_3DDEVICE ) strcat( sz, "DDSCAPS_3DDEVICE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_ALLOCONLOAD ) strcat( sz, "DDSCAPS_ALLOCONLOAD, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_ALPHA ) strcat( sz, "DDSCAPS_ALPHA, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_BACKBUFFER ) strcat( sz, "DDSCAPS_BACKBUFFER, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_COMPLEX ) strcat( sz, "DDSCAPS_COMPLEX, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_FLIP ) strcat( sz, "DDSCAPS_FLIP, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_FRONTBUFFER ) strcat( sz, "DDSCAPS_FRONTBUFFER, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_HWCODEC ) strcat( sz, "DDSCAPS_HWCODEC, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_LIVEVIDEO ) strcat( sz, "DDSCAPS_LIVEVIDEO, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_LOCALVIDMEM ) strcat( sz, "DDSCAPS_LOCALVIDMEM, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_MIPMAP ) strcat( sz, "DDSCAPS_MIPMAP, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_MODEX ) strcat( sz, "DDSCAPS_MODEX, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_NONLOCALVIDMEM ) strcat( sz, "DDSCAPS_NONLOCALVIDMEM, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_OFFSCREENPLAIN ) strcat( sz, "DDSCAPS_OFFSCREENPLAIN, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_OPTIMIZED ) strcat( sz, "DDSCAPS_OPTIMIZED, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_OVERLAY ) strcat( sz, "DDSCAPS_OVERLAY, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_OWNDC ) strcat( sz, "DDSCAPS_OWNDC, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_PALETTE ) strcat( sz, "DDSCAPS_PALETTE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_PRIMARYSURFACE ) strcat( sz, "DDSCAPS_PRIMARYSURFACE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_STANDARDVGAMODE ) strcat( sz, "DDSCAPS_STANDARDVGAMODE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_SYSTEMMEMORY ) strcat( sz, "DDSCAPS_SYSTEMMEMORY, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_TEXTURE ) strcat( sz, "DDSCAPS_TEXTURE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY ) strcat( sz, "DDSCAPS_VIDEOMEMORY, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_VIDEOPORT ) strcat( sz, "DDSCAPS_VIDEOPORT, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_VISIBLE ) strcat( sz, "DDSCAPS_VISIBLE, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_WRITEONLY ) strcat( sz, "DDSCAPS_WRITEONLY, ");
|
||||
if( ddscaps.dwCaps & DDSCAPS_ZBUFFER ) strcat( sz, "DDSCAPS_ZBUFFER, ");
|
||||
|
||||
strcat( sz, "\n");
|
||||
OutputDebugString(sz);
|
||||
strcpy( sz, " DDSCAPS2::dwCaps2: ");
|
||||
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP ) strcat( sz, "DDSCAPS2_CUBEMAP, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) strcat( sz, "DDSCAPS2_CUBEMAP_POSITIVEX, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) strcat( sz, "DDSCAPS2_CUBEMAP_NEGATIVEX, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) strcat( sz, "DDSCAPS2_CUBEMAP_POSITIVEY, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) strcat( sz, "DDSCAPS2_CUBEMAP_NEGATIVEY, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) strcat( sz, "DDSCAPS2_CUBEMAP_POSITIVEZ, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ ) strcat( sz, "DDSCAPS2_CUBEMAP_NEGATIVEZ, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES ) strcat( sz, "DDSCAPS2_CUBEMAP_ALLFACES, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_D3DTEXTUREMANAGE ) strcat( sz, "DDSCAPS2_D3DTEXTUREMANAGE, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_DONOTPERSIST ) strcat( sz, "DDSCAPS2_DONOTPERSIST, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_HARDWAREDEINTERLACE ) strcat( sz, "DDSCAPS2_HARDWAREDEINTERLACE, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_HINTANTIALIASING ) strcat( sz, "DDSCAPS2_HINTANTIALIASING, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_HINTDYNAMIC ) strcat( sz, "DDSCAPS2_HINTDYNAMIC, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_HINTSTATIC ) strcat( sz, "DDSCAPS2_HINTSTATIC, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ) strcat( sz, "DDSCAPS2_MIPMAPSUBLEVEL, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_OPAQUE ) strcat( sz, "DDSCAPS2_OPAQUE, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT ) strcat( sz, "DDSCAPS2_STEREOSURFACELEFT, ");
|
||||
if( ddscaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE ) strcat( sz, "DDSCAPS2_TEXTUREMANAGE, ");
|
||||
|
||||
strcat( sz, "\n");
|
||||
OutputDebugString(sz);
|
||||
}
|
||||
|
||||
|
||||
void ReportPixelFormat( DDPIXELFORMAT ddpf)
|
||||
{
|
||||
char szFlags[4096];
|
||||
char szMsg[MAX_PATH];
|
||||
|
||||
PixelFormatHelper( ddpf.dwFlags, szFlags);
|
||||
|
||||
OutputDebugString(szFlags);
|
||||
|
||||
sprintf( szMsg, " dwFourCC: %ld\n", ddpf.dwFourCC);
|
||||
OutputDebugString(szMsg);
|
||||
|
||||
sprintf( szMsg, " dwRGBBitCount: %ld\n", ddpf.dwRGBBitCount);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwYUVBitCount, dwZBufferBitDepth, dwAlphaBitDepth, dwLuminanceBitCount, dwBumpBitCount)\n");
|
||||
|
||||
sprintf( szMsg, " dwRBitMask: %ld\n", ddpf.dwRBitMask);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwYBitMask, dwStencilBitDepth, dwLuminanceBitMask, dwBumpDuBitMask)\n");
|
||||
|
||||
sprintf( szMsg, " dwGBitMask: %ld\n", ddpf.dwGBitMask);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwUBitMask, dwZBitMask, dwBumpDvBitMask)\n");
|
||||
|
||||
sprintf( szMsg, " dwBBitMask: %ld\n", ddpf.dwBBitMask);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwVBitMask, dwStencilBitMask, dwBumpLuminanceBitMask)\n");
|
||||
|
||||
sprintf( szMsg, " dwRGBAlphaBitMask: %ld\n", ddpf.dwRGBAlphaBitMask);
|
||||
OutputDebugString(szMsg);
|
||||
OutputDebugString(" (dwYUVAlphaBitMask, dwLuminanceAlphaBitMask, dwRGBZBitMask, dwYUVZBitMask)\n");
|
||||
}
|
||||
|
||||
void SurfaceDescHelper( DWORD dwFlags, char * pszFlags )
|
||||
{
|
||||
if( !pszFlags )
|
||||
{
|
||||
return;
|
||||
}
|
||||
strcpy( pszFlags, " dwFlags: ");
|
||||
|
||||
if( dwFlags & DDSD_ALL )
|
||||
strcat( pszFlags, "DDSD_ALL\n");
|
||||
|
||||
if( dwFlags & DDSD_ALPHABITDEPTH )
|
||||
strcat( pszFlags, "DDSD_ALPHABITDEPTH\n");
|
||||
|
||||
if( dwFlags & DDSD_BACKBUFFERCOUNT )
|
||||
strcat( pszFlags, "DDSD_BACKBUFFERCOUNT\n");
|
||||
|
||||
if( dwFlags & DDSD_CAPS )
|
||||
strcat( pszFlags, "DDSD_CAPS\n");
|
||||
|
||||
if( dwFlags & DDSD_CKDESTBLT )
|
||||
strcat( pszFlags, "DDSD_CKDESTBLT\n");
|
||||
|
||||
if( dwFlags & DDSD_CKDESTOVERLAY )
|
||||
strcat( pszFlags, "DDSD_CKDESTOVERLAY\n");
|
||||
|
||||
if( dwFlags & DDSD_CKSRCBLT )
|
||||
strcat( pszFlags, "DDSD_CKSRCBLT\n");
|
||||
|
||||
if( dwFlags & DDSD_CKSRCOVERLAY )
|
||||
strcat( pszFlags, "DDSD_CKSRCOVERLAY\n");
|
||||
|
||||
if( dwFlags & DDSD_HEIGHT )
|
||||
strcat( pszFlags, "DDSD_HEIGHT\n");
|
||||
|
||||
if( dwFlags & DDSD_LINEARSIZE )
|
||||
strcat( pszFlags, "DDSD_LINEARSIZE\n");
|
||||
|
||||
if( dwFlags & DDSD_LPSURFACE )
|
||||
strcat( pszFlags, "DDSD_LPSURFACE\n");
|
||||
|
||||
if( dwFlags & DDSD_MIPMAPCOUNT )
|
||||
strcat( pszFlags, "DDSD_MIPMAPCOUNT\n");
|
||||
|
||||
if( dwFlags & DDSD_PITCH )
|
||||
strcat( pszFlags, "DDSD_PITCH\n");
|
||||
|
||||
if( dwFlags & DDSD_PIXELFORMAT )
|
||||
strcat( pszFlags, "DDSD_PIXELFORMAT\n");
|
||||
|
||||
if( dwFlags & DDSD_REFRESHRATE )
|
||||
strcat( pszFlags, "DDSD_REFRESHRATE\n");
|
||||
|
||||
if( dwFlags & DDSD_TEXTURESTAGE )
|
||||
strcat( pszFlags, "DDSD_TEXTURESTAGE\n");
|
||||
|
||||
if( dwFlags & DDSD_WIDTH )
|
||||
strcat( pszFlags, "DDSD_WIDTH\n");
|
||||
|
||||
strcat(pszFlags, "\n");
|
||||
}
|
||||
|
||||
|
||||
void PixelFormatHelper( DWORD dwFlags, char * pszFlags)
|
||||
{
|
||||
if( !pszFlags )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy( pszFlags, " dwFlags: ");
|
||||
|
||||
if( dwFlags & DDPF_ALPHA )
|
||||
strcat( pszFlags, "DDPF_ALPHA, ");
|
||||
|
||||
if( dwFlags & DDPF_ALPHAPIXELS )
|
||||
strcat( pszFlags, "DDPF_ALPHAPIXELS, ");
|
||||
|
||||
if( dwFlags & DDPF_ALPHAPREMULT )
|
||||
strcat( pszFlags, "DDPF_ALPHAPREMULT, ");
|
||||
|
||||
if( dwFlags & DDPF_BUMPLUMINANCE )
|
||||
strcat( pszFlags, "DDPF_BUMPLUMINANCE, ");
|
||||
|
||||
if( dwFlags & DDPF_BUMPDUDV )
|
||||
strcat( pszFlags, "DDPF_BUMPDUDV, ");
|
||||
|
||||
if( dwFlags & DDPF_COMPRESSED )
|
||||
strcat( pszFlags, "DDPF_COMPRESSED, ");
|
||||
|
||||
if( dwFlags & DDPF_FOURCC )
|
||||
strcat( pszFlags, "DDPF_FOURCC, ");
|
||||
|
||||
if( dwFlags & DDPF_LUMINANCE )
|
||||
strcat( pszFlags, "DDPF_LUMINANCE, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXED1 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXED1, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXED2 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXED2, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXED4 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXED4, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXED8 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXED8, ");
|
||||
|
||||
if( dwFlags & DDPF_PALETTEINDEXEDTO8 )
|
||||
strcat( pszFlags, "DDPF_PALETTEINDEXEDTO8, ");
|
||||
|
||||
if( dwFlags & DDPF_RGB )
|
||||
strcat( pszFlags, "DDPF_RGB, ");
|
||||
|
||||
if( dwFlags & DDPF_RGBTOYUV )
|
||||
strcat( pszFlags, "DDPF_RGBTOYUV, ");
|
||||
|
||||
if( dwFlags & DDPF_STENCILBUFFER )
|
||||
strcat( pszFlags, "DDPF_STENCILBUFFER, ");
|
||||
|
||||
if( dwFlags & DDPF_YUV )
|
||||
strcat( pszFlags, "DDPF_YUV, ");
|
||||
|
||||
if( dwFlags & DDPF_ZBUFFER )
|
||||
strcat( pszFlags, "DDPF_ZBUFFER, ");
|
||||
|
||||
if( dwFlags & DDPF_ZPIXELS )
|
||||
strcat( pszFlags, "DDPF_ZPIXELS, ");
|
||||
|
||||
strcat( pszFlags, "\n");
|
||||
}
|
||||
|
||||
|
||||
/*****************************Private*Routine******************************\
|
||||
* VerifyVMR
|
||||
*
|
||||
\**************************************************************************/
|
||||
BOOL VerifyVMR(void)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
// Verify that the VMR exists on this system
|
||||
IBaseFilter* pBF = NULL;
|
||||
hres = CoCreateInstance(CLSID_VideoMixingRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IBaseFilter,
|
||||
(LPVOID *)&pBF);
|
||||
if(SUCCEEDED(hres))
|
||||
{
|
||||
pBF->Release();
|
||||
CoUninitialize();
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(hwndApp,
|
||||
TEXT("This application requires the Video Mixing Renderer, which is present\r\n")
|
||||
TEXT("only on Windows XP.\r\n\r\n")
|
||||
TEXT("The Video Mixing Renderer (VMR) is also not enabled when viewing a \r\n")
|
||||
TEXT("remote Windows XP machine through a Remote Desktop session.\r\n")
|
||||
TEXT("You can run VMR-enabled applications only on your local machine.")
|
||||
TEXT("\r\n\r\nThis sample will now exit."),
|
||||
TEXT("Video Mixing Renderer capabilities are required"), MB_OK);
|
||||
|
||||
CoUninitialize();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: Utils.h
|
||||
//
|
||||
// Desc: DirectShow sample code
|
||||
// Prototypes for external (global) utilities
|
||||
// specific for VMRXcl app
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// global headers
|
||||
#if !defined(UTILS_H)
|
||||
#define UTILS_H
|
||||
|
||||
// helper function prototypes
|
||||
|
||||
DWORD MyMessage(char *sQuestion, char *sTitle);
|
||||
const char * hresultNameLookup(HRESULT hres);
|
||||
bool MySleep(DWORD dwTime = 2500);
|
||||
|
||||
void ReportPixelFormat( DDPIXELFORMAT ddpf);
|
||||
void ReportDDSCAPS2( DDSCAPS2 ddscaps );
|
||||
void ReportDDrawSurfDesc( DDSURFACEDESC2 ddsd);
|
||||
void PixelFormatHelper( DWORD dwFlags, char * pszFlags);
|
||||
void SurfaceDescHelper( DWORD dwFlags, char * pszFlags );
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SceneSettings
|
||||
//
|
||||
// This structure defines demonstration settings
|
||||
//----------------------------------------------------------------------------
|
||||
struct SceneSettings
|
||||
{
|
||||
bool bRotateZ; // rotate around Z axis if true
|
||||
int nGradZ; // angle of rotation around Z axis, in grades
|
||||
// this is a 'time' variable for Z-rotation effect
|
||||
bool bRotateY; // rotate around Y axis if true
|
||||
int nGradY; // angle of rotation around Y axis, in grades
|
||||
// this is a 'time' variable for Y-rotation effect
|
||||
bool bShowStatistics; // show FPS in the upper right corner if true
|
||||
bool bShowTwist; // show "twist" effect if true; THIS STATE OVERRIDES bRotateZ AND bRotateY
|
||||
int nDy; // vertical offset for the twist effect
|
||||
// this is a 'time' variable for "twist" effect
|
||||
bool bShowHelp; // show text help hints if true (it is activated by right click on the control)
|
||||
int nXHelp; // coordinates for text help hint
|
||||
int nYHelp;
|
||||
TCHAR achHelp[MAX_PATH]; // help hint text
|
||||
TCHAR achFPS[MAX_PATH]; // string representation of FramesPerSecons
|
||||
// (when bShowStatistics is on)
|
||||
|
||||
SceneSettings() // constructor: no effects by default
|
||||
{
|
||||
bRotateZ = false;
|
||||
nGradZ = 0;
|
||||
bRotateY = false;
|
||||
nGradY = 0;
|
||||
bShowStatistics = false;
|
||||
bShowTwist = false;
|
||||
nDy = 0;
|
||||
bShowHelp = 0;
|
||||
nXHelp = 0;
|
||||
nYHelp = 0;
|
||||
lstrcpy(achHelp, TEXT(""));
|
||||
};
|
||||
|
||||
~SceneSettings()
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,196 @@
|
||||
# Microsoft Developer Studio Project File - Name="VMRXcl" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=VMRXcl - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "VMRXcl.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "VMRXcl.mak" CFG="VMRXcl - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "VMRXcl - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "VMRXcl - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "VMRXcl - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /O2 /I "..\..\BaseClasses" /I "..\..\..\DirectShow\BaseClasses" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 d3dx.lib ..\..\..\DirectShow\baseclasses\release\strmbase.lib strmiids.lib comctl32.lib winmm.lib gdi32.lib ddraw.lib comdlg32.lib /nologo /subsystem:windows /pdb:none /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "VMRXcl - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\..\..\DirectShow\BaseClasses" /D "DEBUG" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D WINVER=0x501 /YX"project.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 d3dx.lib ..\..\..\DirectShow\baseclasses\debug\strmbasd.lib strmiids.lib comctl32.lib winmm.lib gdi32.lib ddraw.lib comdlg32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcmtd" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /map
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "VMRXcl - Win32 Release"
|
||||
# Name "VMRXcl - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AllocPresenter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\commands.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dfont.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dtextr.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dutil.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DDrawSupport.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ReadMe.txt
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Utils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\app.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BltAlpha.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dfont.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dtextr.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\d3dutil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DDrawSupport.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\project.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Utils.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vcdplyer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRXcl.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRXcl.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\VMRxclMenu.bmp
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "VMRXCL"=.\VMRXCL.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||