我曾经有过一个想法,就是做一个万能的图片处理装置,今天我无意中将JPG的图片拖到了Media Player的里面,突然在Media Player的窗口里出现了JPG图片,于是我想到了用DShow显示图片的想法。可是普通的用HWND挂钩的方法根本就不行,怎么办呢?于是我察看MSDN的DShow函数库,发现了一个与DirectDraw习习相关的东西----------IDirectDrawMediaStream。
大家用百度或者在Gameres的网站里面搜索一下IDirectDrawMediaStream,就有一篇文章,这里给出地址: http://www.gameres.com/articles/Program/Visual/Other/VCuseDS.htm 大家可以看一下,这篇文章就是本文章的前篇,对于新手们还有一个问题,《在VC中调用DirectShow全屏播放视频》的方法中利用了DirectDraw 和 DirectDrawSurface ,而不是最流行的DirectDraw7 和 DirectDrawSurface7,MSDN说了这一句:
Use QueryInterface to obtain the IDirectDrawSurface interface from an IDirectDrawSurface7 interface.
我想到了QueryInterface。
QueryInterface通俗的讲就是COM模型的“强制转换”,呵呵,或许你已经知道我要怎么做了,没错,用一个临时的DirectDraw 和 DirectDrawSurface 。
代码如下: //------------------------------------------------------------------------------------------------
#include <stdio.h> #include <ddraw.h> // DirectDraw interfaces #pragma comment(lib,"ddraw.lib") #pragma comment(lib,"dxguid.lib") #include "mmstream.h" // multimedia stream interfaces #include "amstream.h" // DirectShow multimedia stream interfaces #include "ddstream.h" // DirectDraw multimedia stream interfaces #pragma comment(lib,"strmiids.lib")
HRESULT RenderStreamToSurface(IDirectDrawSurface *pSurface, IMultiMediaStream *pMMStream) { IMediaStream *pPrimaryVidStream; IDirectDrawMediaStream *pDDStream; IDirectDrawStreamSample *pSample; RECT rect; DDSURFACEDESC ddsd;
HRESULT hr; hr = pMMStream->GetMediaStream(MSPID_PrimaryVideo, &pPrimaryVidStream); if (FAILED(hr)) { return hr; } pPrimaryVidStream->QueryInterface(IID_IDirectDrawMediaStream, (void **)&pDDStream);
ddsd.dwSize = sizeof(ddsd); hr = pDDStream->GetFormat(&ddsd, NULL, NULL, NULL); if (SUCCEEDED(hr)) { rect.top = rect.left = 0; rect.bottom = ddsd.dwHeight; rect.right = ddsd.dwWidth; hr = pDDStream->CreateSample(pSurface, &rect, 0, &pSample); if (SUCCEEDED(hr)) { pMMStream->SetState(STREAMSTATE_RUN); while (pSample->Update(0, NULL, NULL, NULL) == S_OK) { // Empty loop. } pMMStream->SetState(STREAMSTATE_STOP); pSample->Release(); } } pDDStream->Release(); pPrimaryVidStream->Release(); return hr; }
HRESULT RenderFileToMMStream( const char * szFileName, IMultiMediaStream **ppMMStream, IDirectDraw *pDD) { if (strlen(szFileName) > MAX_PATH) { return E_INVALIDARG; }
IAMMultiMediaStream *pAMStream; HRESULT hr = CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream, (void **)&pAMStream); if (FAILED(hr)) { return hr; }
WCHAR wPath[MAX_PATH + 1]; MultiByteToWideChar(CP_ACP, 0, szFileName, -1, wPath, MAX_PATH + 1);
pAMStream->Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, NULL); pAMStream->AddMediaStream(pDD, &MSPID_PrimaryVideo, 0, NULL); pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL); hr = pAMStream->OpenFile(wPath, 0); if (SUCCEEDED(hr)) { hr = pAMStream->QueryInterface(IID_IMultiMediaStream, (void**)ppMMStream); } pAMStream->Release(); return hr; }
int __cdecl main(int argc, char *argv[]) { if (argc < 2) { printf("Usage : showstrm movie.ext\n"); exit(0); }
DDSURFACEDESC2 ddsd; LPDIRECTDRAW7 pDD; LPDIRECTDRAWSURFACE7 pPrimarySurface; IMultiMediaStream *pMMStream;
CoInitialize(NULL); DirectDrawCreateEx (NULL, (void **)&pDD, IID_IDirectDraw7, NULL); pDD->SetCooperativeLevel(GetDesktopWindow(), DDSCL_NORMAL); ZeroMemory(&ddsd, sizeof(ddsd));//设置页面内存大小 ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; pDD->CreateSurface(&ddsd, &pPrimarySurface, NULL); LPDIRECTDRAW pDD1; LPDIRECTDRAWSURFACE pPrimarySurface1; pPrimarySurface->QueryInterface(IID_IDirectDrawSurface,(LPVOID*)&pPrimarySurface1); pPrimarySurface->Release(); pDD->QueryInterface(IID_IDirectDraw,(LPVOID*)&pDD1); pDD->Release();
HRESULT hr = RenderFileToMMStream(argv[1], &pMMStream,pDD1);
if (SUCCEEDED(hr)) { RenderStreamToSurface(pPrimarySurface1, pMMStream); pMMStream->Release(); } pPrimarySurface1->Release(); pDD1->Release(); CoUninitialize(); return 0; } |