下面的代码我下载的一个源代码的片段,源程序目的是从视频中提取一帧,下面代码片段创建了IGraphBuilder和ISampleGrabber接口的实例,利用ISampleGrabber实现帧的抓取。源程序我已经在 Windows XP + Visual C++ 6.0 + DirectX 9.0b SDK 下编译通过,可是实际运行,却无法抓取视频的帧,调试后,发现错误在下面代码片段的末尾 pMediaControl->Run() 这句话上,他的返回值是1,而不是调用成功了以后的0,我很奇怪,检查自己电脑的DirectX版本为9.0b,我将编译后的执行文件又分别放到了DX版本分别为8.1和6.4的另外两台电脑上,结果DX版本为8.1的电脑可以正常运行程序并成功将视频帧提取出来,而DX版本为6.4的电脑和我那DX版本为9的电脑一样无法实现程序功能,请问是什么原因造成的?如何解决?PS:我所使用的视频采用MPEG-1标准压缩。// Create graph builder
CComPtr<IGraphBuilder> pGraphBuilder;
HRESULT hr = ::CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
(void**)&pGraphBuilder);
if (FAILED(hr)) return hr;
ASSERT(pGraphBuilder != NULL);// Create Grabber filter
CComPtr<IBaseFilter> pGrabberBaseFilter;
CComPtr<ISampleGrabber> pSampleGrabber;
AM_MEDIA_TYPE mt;
hr = ::CoCreateInstance(CLSID_SampleGrabber, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(LPVOID *)&pGrabberBaseFilter);
if (FAILED(hr)) return hr;
pGrabberBaseFilter->QueryInterface(IID_ISampleGrabber,
(void**)&pSampleGrabber);
if (pSampleGrabber == NULL) return E_NOINTERFACE;
hr = pGraphBuilder->AddFilter(pGrabberBaseFilter,L"Grabber");
if (FAILED(hr)) return hr;// Set media type
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
mt.formattype = FORMAT_VideoInfo;
hr = pSampleGrabber->SetMediaType(&mt);
if (FAILED(hr)) return hr; hr = pGraphBuilder->RenderFile(wFile,NULL);
if (FAILED(hr)) return hr;
CComPtr<IMediaControl> pMediaControl;
CComPtr<IMediaEvent> pMediaEventEx;
// QueryInterface for some basic interfaces
pGraphBuilder->QueryInterface(IID_IMediaControl,
(void **)&pMediaControl);
pGraphBuilder->QueryInterface(IID_IMediaEvent,
(void **)&pMediaEventEx); if (pMediaControl == NULL || pMediaEventEx == NULL)
return E_NOINTERFACE;// Set up one-shot mode.
hr = pSampleGrabber->SetBufferSamples(TRUE);
if (FAILED(hr)) return hr; hr = pSampleGrabber->SetOneShot(TRUE);
if (FAILED(hr)) return hr; CComQIPtr<IMediaSeeking> pSeek = pMediaControl;
if (pSeek == NULL)
return E_NOINTERFACE;
LONGLONG Duration;
hr = pSeek->GetDuration(&Duration);
if (FAILED(hr)) return hr;
int NumSecs = int(Duration/10000000); REFERENCE_TIME rtStart = 1 * 10000000;
if (NumSecs < 1)
rtStart = 0;
REFERENCE_TIME rtStop = rtStart;
hr = pSeek->SetPositions(&rtStart, AM_SEEKING_AbsolutePositioning,
&rtStop, AM_SEEKING_AbsolutePositioning);
if (FAILED(hr)) return hr; CComQIPtr<IVideoWindow> pVideoWindow = pGraphBuilder; hr = pVideoWindow->put_AutoShow(OAFALSE);
if (FAILED(hr)) return hr;// Run the graph and wait for completion.
hr = pMediaControl->Run();
if (FAILED(hr)) return hr;
CComPtr<IGraphBuilder> pGraphBuilder;
HRESULT hr = ::CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
(void**)&pGraphBuilder);
if (FAILED(hr)) return hr;
ASSERT(pGraphBuilder != NULL);// Create Grabber filter
CComPtr<IBaseFilter> pGrabberBaseFilter;
CComPtr<ISampleGrabber> pSampleGrabber;
AM_MEDIA_TYPE mt;
hr = ::CoCreateInstance(CLSID_SampleGrabber, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(LPVOID *)&pGrabberBaseFilter);
if (FAILED(hr)) return hr;
pGrabberBaseFilter->QueryInterface(IID_ISampleGrabber,
(void**)&pSampleGrabber);
if (pSampleGrabber == NULL) return E_NOINTERFACE;
hr = pGraphBuilder->AddFilter(pGrabberBaseFilter,L"Grabber");
if (FAILED(hr)) return hr;// Set media type
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
mt.formattype = FORMAT_VideoInfo;
hr = pSampleGrabber->SetMediaType(&mt);
if (FAILED(hr)) return hr; hr = pGraphBuilder->RenderFile(wFile,NULL);
if (FAILED(hr)) return hr;
CComPtr<IMediaControl> pMediaControl;
CComPtr<IMediaEvent> pMediaEventEx;
// QueryInterface for some basic interfaces
pGraphBuilder->QueryInterface(IID_IMediaControl,
(void **)&pMediaControl);
pGraphBuilder->QueryInterface(IID_IMediaEvent,
(void **)&pMediaEventEx); if (pMediaControl == NULL || pMediaEventEx == NULL)
return E_NOINTERFACE;// Set up one-shot mode.
hr = pSampleGrabber->SetBufferSamples(TRUE);
if (FAILED(hr)) return hr; hr = pSampleGrabber->SetOneShot(TRUE);
if (FAILED(hr)) return hr; CComQIPtr<IMediaSeeking> pSeek = pMediaControl;
if (pSeek == NULL)
return E_NOINTERFACE;
LONGLONG Duration;
hr = pSeek->GetDuration(&Duration);
if (FAILED(hr)) return hr;
int NumSecs = int(Duration/10000000); REFERENCE_TIME rtStart = 1 * 10000000;
if (NumSecs < 1)
rtStart = 0;
REFERENCE_TIME rtStop = rtStart;
hr = pSeek->SetPositions(&rtStart, AM_SEEKING_AbsolutePositioning,
&rtStop, AM_SEEKING_AbsolutePositioning);
if (FAILED(hr)) return hr; CComQIPtr<IVideoWindow> pVideoWindow = pGraphBuilder; hr = pVideoWindow->put_AutoShow(OAFALSE);
if (FAILED(hr)) return hr;// Run the graph and wait for completion.
hr = pMediaControl->Run();
if (FAILED(hr)) return hr;
pMediaControl->Run()操作成功,但是剪辑没有播放,估计是驱动程序的问题,即机子没有装那种视频解压缩驱动,但我认为如果这样应该返回错误值,而不是S_FALSE。所以也可能是说剪辑一播放就立刻停止了,即长度很短。由于对DirectShow不清楚,我只是想告诉楼主1代表S_FALSE,表示成功执行操作,但操作的结果是不播放或播放停止,希望对楼主能有启示。