windows-nt/Source/XPSP1/NT/multimedia/dshow/streams/test/teststrm.cpp
2020-09-26 16:20:57 +08:00

295 lines
8.6 KiB
C++

/* Test AM streams stuff */
#include <windows.h>
#include <uuids.h>
#include <ddraw.h>
#include <atlbase.h>
CComModule _Module;
#include <atlcom.h>
#include <atlimpl.cpp>
#include <initguid.h>
#include <amstream.h>
#include <mmstream.h>
#include <ddstream.h>
#include <austream.h>
#include <wave.h>
#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<ICreateDevEnum> pCreateDevEnum;
HRESULT hr = CoCreateInstance(
CLSID_SystemDeviceEnum,
NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,
(void**)&pCreateDevEnum);
if (hr != NOERROR)
return FALSE;
CComPtr<IEnumMoniker> 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<IMoniker> 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<IDirectDraw> 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<IMediaStream> pMediaStream;
_ASSERTE(S_OK == pMMStream->GetMediaStream(MSPID_PrimaryAudio, &pMediaStream));
// Get the audio interface and create our sample
CComPtr<IAudioMediaStream> pAudioStream;
CHECK_RESULT(pMediaStream->QueryInterface(IID_IAudioMediaStream, (void**)&pAudioStream));
WAVEFORMATEX wfx;
CHECK_RESULT(pAudioStream->GetFormat(&wfx));
#define NBUFFERS 1
CComPtr<IAudioData> pAudioData[NBUFFERS];
CComPtr<IAudioStreamSample> 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<IMediaStream> pMediaStream;
HRESULT hr = pMMStream->GetMediaStream(MSPID_PrimaryVideo, &pMediaStream);
if (FAILED(hr)) {
return hr;
}
CComPtr<IDirectDrawMediaStream> 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<IDirectDraw> 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<IDirectDrawSurface> pSurface;
hr = CreateARandomSurface(pDDraw, &ddFormat, &pSurface);
if (FAILED(hr)) {
return hr;
}
CComPtr<IDirectDrawStreamSample> 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<IAMMultiMediaStream> pAMMStream;
// Create an AMStream
HRESULT hr = CreateAMMMStream(&pAMMStream);
// Now try to create a stream
CComPtr<IAMMediaStream> 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<IMultiMediaStream, &IID_IMultiMediaStream> pMMStream(
pAMMStream);
DWORD dwFlags;
STREAM_TYPE Type;
hr = pMMStream->GetInformation(&dwFlags, &Type);
_ASSERTE(Type == STREAMTYPE_READ);
CComPtr<IMediaStream> 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;
}