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>
This commit is contained in:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

View File

@@ -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;
}

View 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};

View File

@@ -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;
}

View File

@@ -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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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};

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -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>
{{{
}}}
###############################################################################

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -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

View File

@@ -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

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

View File

@@ -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;
}
}

View File

@@ -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();
}
}
};

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}
};

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

View File

@@ -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

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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};

View File

@@ -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;
}

View File

@@ -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;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -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.
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -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;
}
}

View File

@@ -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;
};

View 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>
{{{
}}}
###############################################################################

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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_)

View File

@@ -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.

View File

@@ -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
}

View File

@@ -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_)

View File

@@ -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"

View File

@@ -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_)

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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_)

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

View File

@@ -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_)

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -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...
/////////////////////////////////////////////////////////////////////////////

View File

@@ -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

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

File diff suppressed because it is too large Load Diff

View File

@@ -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};

View File

@@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -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.
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -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;
}
}

View File

@@ -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;
};

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -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;
}

View File

@@ -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;
}
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

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