描述:
下面的代码我下载的一个源代码的片段,源程序目的是从视频中提取一帧,下面代码片段创建了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;
您可能想查找下面的文章:
- 关于directshow和directmusic部分问题
- 关于使用directshow中的playcap例子改写成ocx中出现的问题
- 用Directshow如何得到视频文件如avi、asf中视频的宽和高?
- 请教用过DIRECTSHOW的各位!急!
- 急。。。。。。。。。。。通过directshow开发多媒体播放器中,如何实现后退功能,以及退回一帧图片功能
- directshow的显示问题
- DirectX里怎么没有DirectShow
- 关于音轨和声道的问题DirectShow?
- directShow编译的问题,小弟在编译一个例子,通不过!请大家帮忙
- 在directshow中如何做一个可以提供一个有序流的renderfitler,一有新数据来就让外面取走