/* Test AM streams stuff */ #include #include #include #include CComModule _Module; #include #include #include #include #include #include #include #include #define CHECK_RESULT(_x_) \ { \ HRESULT hr = check_result(_x_, #_x_); \ if (FAILED(hr)) { \ return hr; \ } \ } inline check_result(HRESULT _x_, LPCTSTR sz) { if (FAILED(_x_)) { AtlTrace(_T("%s failed code %8.8X\n"), sz); } return _x_; } HRESULT FindCaptureDevice(IMoniker **ppMoniker) { CComPtr pCreateDevEnum; HRESULT hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) return FALSE; CComPtr pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_CVidCapClassManager, &pEm, 0); if (hr != NOERROR) return hr; ULONG cFetched; return pEm->Next(1, ppMoniker, &cFetched); } HRESULT LoadCapture(DWORD dwFlags, IAMMultiMediaStream *pMMStream) { CComPtr pMoniker; HRESULT hr = FindCaptureDevice(&pMoniker); AtlTrace(_T("FindCaptureDevice returned %8.8X\n"), hr); if (S_OK != hr) { return E_FAIL; } hr = pMMStream->OpenMoniker( pMoniker, dwFlags ); AtlTrace("OpenMoniker returned 0x%8.8X\n", hr); return hr; } HRESULT LoadFile(LPCSTR lpsz, DWORD dwFlags, IAMMultiMediaStream *pMMStream) { /* Load our file */ WCHAR wsz[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, lpsz, -1, wsz, MAX_PATH); HRESULT hr = pMMStream->OpenFile( wsz, dwFlags ); AtlTrace("OpenFile returned 0x%8.8X\n", hr); return hr; } HRESULT CreateAMMMStream(IAMMultiMediaStream **ppMMStream) { /* Create the mmstream object */ HRESULT hr = CoCreateInstance( CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream, (void **)ppMMStream ); AtlTrace(_T("CreateAMMMStream returned 0x%8.8X\n"), hr); return hr; } HRESULT AddAudioStream(IAMMultiMediaStream *pAMMStream) { return pAMMStream->AddMediaStream( NULL, MSPID_PrimaryAudio, 0, NULL); } HRESULT AddDDStream(IAMMultiMediaStream *pAMMStream) { CComPtr pDDraw; HRESULT hr = DirectDrawCreate(NULL, &pDDraw, NULL); if (FAILED(hr)) { return hr; } hr = pDDraw->SetCooperativeLevel(HWND_DESKTOP, DDSCL_NORMAL); if (FAILED(hr)) { return hr; } return pAMMStream->AddMediaStream( pDDraw, MSPID_PrimaryVideo, 0, NULL); } // Create a random surface HRESULT CreateARandomSurface( IDirectDraw *pDDraw, LPDDSURFACEDESC pDesc, IDirectDrawSurface **ppSurface ) { return pDDraw->CreateSurface(pDesc, ppSurface, NULL); } HRESULT PlayAudio(IMultiMediaStream *pMMStream) { // Find the audio stream CComPtr pMediaStream; _ASSERTE(S_OK == pMMStream->GetMediaStream(MSPID_PrimaryAudio, &pMediaStream)); // Get the audio interface and create our sample CComPtr pAudioStream; CHECK_RESULT(pMediaStream->QueryInterface(IID_IAudioMediaStream, (void**)&pAudioStream)); WAVEFORMATEX wfx; CHECK_RESULT(pAudioStream->GetFormat(&wfx)); #define NBUFFERS 1 CComPtr pAudioData[NBUFFERS]; CComPtr pSample[NBUFFERS]; PBYTE pBuffer[NBUFFERS]; HANDLE hEvent[NBUFFERS]; for (int i = 0; i < NBUFFERS; i++) { #define DATA_SIZE 5000 pBuffer[i] = new BYTE[DATA_SIZE]; CHECK_RESULT(CoCreateInstance(CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, IID_IAudioData, (void**)&pAudioData[i])); CHECK_RESULT(pAudioData[i]->Init(DATA_SIZE, pBuffer[i], 0)); CHECK_RESULT(pAudioData[i]->SetFormat(&wfx)); CHECK_RESULT(pAudioStream->CreateSample( pAudioData[i], 0, &pSample[i])); hEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL); } // Make a player CWaveOut WaveOut(&wfx, 4, 2048); #define MAX_PLAY_TIME 3 for (int Times = 0; Times < 3; Times++) { DWORD dwStart = timeGetTime(); for (; ; ) { HRESULT hr = pSample[0]->Update(0, hEvent[0], NULL, 0); if (FAILED(hr) || hr == MS_S_ENDOFSTREAM) { break; } WaitForSingleObject(hEvent[0], INFINITE); CHECK_RESULT(pSample[0]->CompletionStatus(0, 0)); if ((LONG)(timeGetTime() - dwStart) > MAX_PLAY_TIME * 1000) { break; } DWORD dwLength; CHECK_RESULT(pAudioData[0]->GetInfo(NULL, NULL, &dwLength)); _ASSERTE(dwLength == DATA_SIZE || S_OK != hr); WaveOut.Write(pBuffer[0], dwLength); #if 0 if (S_OK != hr) { _ASSERTE(hr == MS_S_ENDOFSTREAM || hr == S_FALSE); break; } #endif } pMMStream->Seek(0); } WaveOut.Wait(); return S_OK; } // Play a multimedia stream HRESULT PlayVideo(IMultiMediaStream *pMMStream) { // First get the video stream CComPtr pMediaStream; HRESULT hr = pMMStream->GetMediaStream(MSPID_PrimaryVideo, &pMediaStream); if (FAILED(hr)) { return hr; } CComPtr pDDStream; // Get the dd stream hr = pMediaStream->QueryInterface(IID_IDirectDrawMediaStream, (void **)&pDDStream); if (FAILED(hr)) { return hr; } // Now create our surface and play with it CComPtr pDDraw; hr = pDDStream->GetDirectDraw(&pDDraw); if (FAILED(hr)) { return hr; } // Find out the movie size DDSURFACEDESC ddFormat; ddFormat.dwSize = sizeof(ddFormat); hr = pDDStream->GetFormat(&ddFormat, NULL, NULL); if (FAILED(hr)) { return hr; } CComPtr pSurface; hr = CreateARandomSurface(pDDraw, &ddFormat, &pSurface); if (FAILED(hr)) { return hr; } CComPtr pSample; hr = pDDStream->CreateSample(pSurface, NULL, NULL, &pSample); if (FAILED(hr)) { return hr; } for (; ; ) { HRESULT hr = pSample->Update(0, NULL, NULL, 0); if (S_OK != hr) { AtlTrace(_T("Update returned 0x%8.8X\n"), hr); return S_OK; } Sleep(10); hr = pSample->CompletionStatus(COMPSTAT_NOUPDATEOK | COMPSTAT_WAIT, 0); } } void DoTests(LPSTR lpszFileName) { CComPtr pAMMStream; // Create an AMStream HRESULT hr = CreateAMMMStream(&pAMMStream); // Now try to create a stream CComPtr pDDStream; hr = AddAudioStream(pAMMStream); AtlTrace(_T("CreateDDStream returned 0x%8.8X\n"), hr); hr = lpszFileName ? LoadFile(lpszFileName, AMMSF_RENDERTOEXISTING, pAMMStream) : LoadCapture(AMMSF_RENDERTOEXISTING, pAMMStream); if (SUCCEEDED(hr)) { HRESULT hr = pAMMStream->Initialize(STREAMTYPE_READ, NULL); CComQIPtr pMMStream( pAMMStream); DWORD dwFlags; STREAM_TYPE Type; hr = pMMStream->GetInformation(&dwFlags, &Type); _ASSERTE(Type == STREAMTYPE_READ); CComPtr pStream; hr = pMMStream->GetMediaStream(MSPID_PrimaryAudio, &pStream); pStream = NULL; hr = pMMStream->GetMediaStream(MSPID_PrimaryVideo, &pStream); hr = pMMStream->SetState(STREAMSTATE_RUN); AtlTrace(_T("SetState(STREAMSTATE_RUN) returned 0x%8.8X\n"), hr); hr = PlayAudio(pMMStream); Sleep(5000); hr = pMMStream->SetState(STREAMSTATE_STOP); AtlTrace(_T("SetState(STREAMSTATE_STOP) returned 0x%8.8X\n"), hr); } } int _CRTAPI1 main(int argc, char *argv[]) { CoInitialize(NULL); DoTests(argc < 2 ? NULL : argv[1]); CoUninitialize(); return 0; }