//==========================================================================; // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1996 - 1998 Microsoft Corporation. All Rights Reserved. // //--------------------------------------------------------------------------; #include #include #include #include #include "memfile.h" /* Function prototypes */ HRESULT SelectAndRender(CMemReader *pReader, IFilterGraph **pFG); HRESULT PlayFileWait(IFilterGraph *pFG); /* Read a file into memory, play it (or part of it), then exit */ int _CRTAPI1 main(int argc, char *argv[]) { if (argc < 2 || argc > 3) { printf("Usage : memfile foo.bar \n"); return 0; } DWORD dwKBPerSec = argc == 2 ? INFINITE : atoi(argv[2]); CMediaType mt; mt.majortype = MEDIATYPE_Stream; LPTSTR lpType; { /* Find the extension */ int len = lstrlen(argv[1]); if (len >= 4 && argv[1][len - 4] == TEXT('.')) { lpType = argv[1] + len - 3; } else { printf("Invalid file extension\n"); return 1; } } if (lstrcmpi(lpType, TEXT("mpg")) == 0) { mt.subtype = MEDIASUBTYPE_MPEG1System; } else if (lstrcmpi(lpType, TEXT("mpa")) == 0) { mt.subtype = MEDIASUBTYPE_MPEG1Audio; } else if (lstrcmpi(lpType, TEXT("mpv")) == 0) { mt.subtype = MEDIASUBTYPE_MPEG1Video; } else if (lstrcmpi(lpType, TEXT("dat")) == 0) { mt.subtype = MEDIASUBTYPE_MPEG1VideoCD; } else if (lstrcmpi(lpType, TEXT("avi")) == 0) { mt.subtype = MEDIASUBTYPE_Avi; } else if (lstrcmpi(lpType, TEXT("mov")) == 0) { mt.subtype = MEDIASUBTYPE_QTMovie; } else if (lstrcmpi(lpType, TEXT("wav")) == 0) { mt.subtype = MEDIASUBTYPE_WAVE; } else { printf("Unknown file type %s\n", lpType); return 1; } /* Read the file */ HANDLE hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("Could not open %s\n", argv[1]); return 1; } ULARGE_INTEGER uliSize; uliSize.LowPart = GetFileSize(hFile, &uliSize.HighPart); PBYTE pbMem = new BYTE[uliSize.LowPart]; if (pbMem == NULL) { printf("Could not allocate %d bytes\n", uliSize.LowPart); return 1; } DWORD dwBytesRead; if (!ReadFile(hFile, (LPVOID)pbMem, uliSize.LowPart, &dwBytesRead, NULL) || dwBytesRead != uliSize.LowPart) { printf("Could not read file\n"); CloseHandle(hFile); return 1; } CloseHandle(hFile); HRESULT hr = S_OK; CoInitialize(NULL); CMemStream Stream(pbMem, (LONGLONG)uliSize.QuadPart, dwKBPerSec); CMemReader *rdr = new CMemReader(&Stream, &mt, &hr); if (FAILED(hr) || rdr == NULL) { delete rdr; printf("Could not create filter HRESULT 0x%8.8X\n", hr); CoUninitialize(); return 1; } // Make sure we don't accidentally go away! rdr->AddRef(); IFilterGraph *pFG = NULL; hr = SelectAndRender(rdr, &pFG); if (FAILED(hr)) { printf("Failed to create graph and render file HRESULT 0x%8.8X", hr); } else { // Play the file HRESULT hr = PlayFileWait(pFG); if (FAILED(hr)) { printf("Failed to play graph HRESULT 0x%8.8X", hr); } } rdr->Release(); if (pFG) { ULONG ulRelease = pFG->Release(); if (ulRelease != 0) { printf("Filter graph count not 0! was %d", ulRelease); } } CoUninitialize(); return 0; } // Select a filter into a graph and render its output pin, returning // the graph HRESULT SelectAndRender(CMemReader *pReader, IFilterGraph **ppFG) { /* Create filter graph */ HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IFilterGraph, (void**) ppFG); if (FAILED(hr)) { return hr; } /* Get the various interfaces we need */ /* Add our filter */ hr = (*ppFG)->AddFilter(pReader, NULL); if (FAILED(hr)) { return hr; } /* Render our output pin */ IGraphBuilder *pBuilder; hr = (*ppFG)->QueryInterface(IID_IGraphBuilder, (void **)&pBuilder); if (FAILED(hr)) { return hr; } hr = pBuilder->Render(pReader->GetPin(0)); pBuilder->Release(); return hr; } HRESULT PlayFileWait(IFilterGraph *pFG) { IMediaControl *pMC; IMediaEvent *pME; HRESULT hr = pFG->QueryInterface(IID_IMediaControl, (void **)&pMC); if (FAILED(hr)) { return hr; } hr = pFG->QueryInterface(IID_IMediaEvent, (void **)&pME); if (FAILED(hr)) { pMC->Release(); return hr; } OAEVENT oEvent; hr = pME->GetEventHandle(&oEvent); if (SUCCEEDED(hr)) { hr = pMC->Run(); } if (SUCCEEDED(hr)) { LONG levCode; hr = pME->WaitForCompletion(INFINITE, &levCode); } pMC->Release(); pME->Release(); return hr; }