The following sample program renders a file named Test.avi inside an application window. For brevity, it omits the following functionality:
- It does not resize the video window when the parent window is resized. To accomplish this, call IVideoWindow::SetWindowPosition again in response to a WM_SIZE message on the parent window.
- It performs no error checking.
- It stretches the video window without regard to the aspect ratio of the source. To determine the aspect ratio, use the IBasicVideo interface.
- It does not handle end-of-stream events. For information on how to do this, see Responding to Events.
NoteTo make the following code example easier to read, error checking is not included. Do not use this code example in a release configuration unless it you have modified it to include secure error handling.
#include <windows.h>
#include <streams.h>
#define CLASSNAME "VideoWindow"
IGraphBuilder *pGraph = NULL;
IMediaControl *pMediaControl = NULL;
IVideoWindow *pVidWin = NULL;
HWND g_hwnd;
void PlayFile(void)
{
// Create the filter graph manager.
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **)&pGraph);
pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);
// Build the graph.
pGraph->RenderFile(L"Test.avi", NULL);
//Set the video window.
//Attach the video playback window to the desired parent window.
//call the IVideoWindow::put_Owner method and pass it a handle to the owner window.
pVidWin->put_Owner((OAHWND)g_hwnd);
pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS); RECT grc; GetClientRect(g_hwnd, &grc); pVidWin->SetWindowPosition(0, 0, grc.right, grc.bottom); // Run the graph. pMediaControl->Run(); } void CleanUp(void) {
//Before the application exits, it is important that
//you set the visibility of the video window to false.
// Otherwise, a video image remains on the screen
//and the user cannot get rid of it. Then, reset the owner to NULL;
//otherwise, messages are sent to the wrong window, likely causing errors.
pVidWin->put_Visible(OAFALSE); pVidWin->put_Owner(NULL); pMediaControl->Release(); pVidWin->Release(); pGraph->Release(); } // Message handler. long FAR PASCAL WindowProc( HWND hwnd, UINT msg, UINT wParam, LONG lParam) { switch (msg) { case WM_DESTROY: CleanUp(); PostQuitMessage(0); break; default: return (DefWindowProc(hwnd, msg, wParam, lParam)); } return(NULL); } // Main. int PASCAL WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow ) { MSG msg; WNDCLASS wc; CoInitialize(NULL); ZeroMemory(&wc, sizeof wc); wc.lpfnWndProc = WindowProc; wc.hInstance = hInst; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); wc.lpszMenuName = NULL; wc.lpszClassName = CLASSNAME; RegisterClass( &wc ); g_hwnd = CreateWindow( CLASSNAME, "DirectShow Sample", (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX), CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); ShowWindow( g_hwnd, nCmdShow ); UpdateWindow( g_hwnd ); PlayFile(); while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } CoUninitialize(); return msg.wParam; }
本文提供了一个使用DirectShow在Windows环境下播放视频的示例程序。该程序加载并播放名为Test.avi的文件,展示了如何创建过滤器图、设置视频窗口的位置及大小,并运行播放图。注意,示例代码未包含错误检查及视频宽高比调整。
538

被折叠的 条评论
为什么被折叠?



