windows-nt/Source/XPSP1/NT/multimedia/dshow/streams/foxbear/vidsrc.c
2020-09-26 16:20:57 +08:00

164 lines
4.5 KiB
C

/* Copyright (c) 1997 Microsoft Corporation. All Rights Reserved. */
#include "foxbear.h"
BOOL bMovie;
BOOL bCamera;
WCHAR wszMovie[100];
#define RELEASE(x) if ((x) != NULL) (x)->lpVtbl->Release(x);
#ifdef DEBUG
HRESULT __inline check_error(HRESULT hr, LPSTR psz)
{
if (FAILED(hr)) {
char sz[200];
wsprintf(sz, "%s failed code 0x%8.8X\n", psz, hr);
OutputDebugString(sz);
}
return hr;
}
#else
HRESULT __inline check_error(HRESULT hr, LPSTR psz)
{
UNREFERENCED_PARAMETER(psz);
return hr;
}
#endif
#define CHECK_ERROR(x) if (FAILED(hr = check_error(x, #x))) goto Exit;
HRESULT FindCaptureDevice(IMoniker **ppMoniker)
{
ICreateDevEnum *pCreateDevEnum;
IEnumMoniker *pEm;
ULONG cFetched;
HRESULT hr = CoCreateInstance(
&CLSID_SystemDeviceEnum,
NULL,
CLSCTX_INPROC_SERVER,
&IID_ICreateDevEnum,
(void**)&pCreateDevEnum);
if (FAILED(hr))
return hr;
hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum,
&CLSID_CVidCapClassManager,
&pEm,
0);
ICreateDevEnum_Release(pCreateDevEnum);
if (FAILED(hr)) {
return hr;
}
hr = IEnumMoniker_Next(pEm, 1, ppMoniker, &cFetched);
IEnumMoniker_Release(pEm);
return S_OK == hr ? hr : E_FAIL;
}
BOOL CreateVideoSource(IDirectDrawStreamSample **ppVideoSource, WCHAR * szFileName)
{
HRESULT hr;
IAMMultiMediaStream *pAMStream = NULL;
IMediaStream *pVideoStream = NULL;
IDirectDrawMediaStream *pDDVideoStream = NULL;
IDirectDrawSurface *pSurface = NULL;
IMoniker *pMoniker = NULL;
IDirectDrawPalette *pPalette = NULL;
IBindCtx *pCtx = NULL;
DDSURFACEDESC ddsd;
CHECK_ERROR(CoCreateInstance(&CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER,
&IID_IAMMultiMediaStream, (void **)&pAMStream));
CHECK_ERROR(IAMMultiMediaStream_Initialize(pAMStream, STREAMTYPE_READ, 0, NULL));
CHECK_ERROR(IAMMultiMediaStream_AddMediaStream(pAMStream, (IUnknown*)lpDD, &MSPID_PrimaryVideo, 0, &pVideoStream));
CHECK_ERROR(IAMMultiMediaStream_AddMediaStream(pAMStream, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL));
if (bCamera) {
CreateBindCtx(0, &pCtx);
CHECK_ERROR(FindCaptureDevice(&pMoniker));
CHECK_ERROR(IAMMultiMediaStream_OpenMoniker(
pAMStream, pCtx, pMoniker, AMMSF_RENDERTOEXISTING));
} else {
CHECK_ERROR(IAMMultiMediaStream_OpenFile(
pAMStream, bMovie ? wszMovie : szFileName, AMMSF_RENDERTOEXISTING));
}
CHECK_ERROR(IMediaStream_QueryInterface(pVideoStream, &IID_IDirectDrawMediaStream, (void **)&pDDVideoStream));
ddsd.dwSize = sizeof(ddsd);
CHECK_ERROR(IDirectDrawMediaStream_GetFormat(pDDVideoStream, &ddsd, NULL, NULL, NULL));
pSurface = DDCreateSurface(ddsd.dwWidth, ddsd.dwHeight, FALSE, TRUE);
hr = IDirectDrawSurface_GetPalette(lpFrontBuffer, &pPalette);
if (SUCCEEDED(hr)) {
CHECK_ERROR(IDirectDrawSurface_SetPalette(pSurface, pPalette));
}
CHECK_ERROR(IDirectDrawMediaStream_CreateSample(pDDVideoStream, pSurface, NULL, DDSFF_PROGRESSIVERENDER, ppVideoSource));
CHECK_ERROR(IAMMultiMediaStream_SetState(pAMStream, STREAMSTATE_RUN));
CHECK_ERROR(IDirectDrawStreamSample_Update(*ppVideoSource, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0));
Exit:
RELEASE(pAMStream);
RELEASE(pVideoStream);
RELEASE(pDDVideoStream);
RELEASE(pSurface);
RELEASE(pMoniker);
RELEASE(pPalette);
RELEASE(pCtx);
return hr == S_OK ? TRUE : FALSE;
}
BOOL DisplayVideoSource(IDirectDrawStreamSample *pVideoSource)
{
if (pVideoSource) {
RECT rc;
IDirectDrawSurface *pSurface;
HRESULT CompStatus = IDirectDrawStreamSample_CompletionStatus(pVideoSource, COMPSTAT_NOUPDATEOK | COMPSTAT_WAIT, INFINITE);
if (SUCCEEDED(CompStatus)) {
HRESULT hr = IDirectDrawStreamSample_GetSurface(pVideoSource, &pSurface, &rc);
if (hr == S_OK) {
IDirectDrawSurface_BltFast(lpBackBuffer, 240, 180,
pSurface, &rc, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);
IDirectDrawSurface_Release(pSurface);
}
}
if (CompStatus == MS_S_ENDOFSTREAM) {
IMediaStream *pStream;
IMultiMediaStream *pMMStream;
IDirectDrawStreamSample_GetMediaStream(pVideoSource, &pStream);
IMediaStream_GetMultiMediaStream(pStream, &pMMStream);
IMultiMediaStream_Seek(pMMStream, 0);
IMediaStream_Release(pStream);
IMultiMediaStream_Release(pMMStream);
}
IDirectDrawStreamSample_Update(pVideoSource, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
return TRUE;
} else {
return FALSE;
}
}