下面的代码我下载的一个源代码的片段,源程序目的是从视频中提取一帧,下面代码片段创建了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;

解决方案 »

  1.   

    对DirectShow不清楚,不过返回值为1代表是S_FALSE。它的意思是成功,但是不是,也就是说
    pMediaControl->Run()操作成功,但是剪辑没有播放,估计是驱动程序的问题,即机子没有装那种视频解压缩驱动,但我认为如果这样应该返回错误值,而不是S_FALSE。所以也可能是说剪辑一播放就立刻停止了,即长度很短。由于对DirectShow不清楚,我只是想告诉楼主1代表S_FALSE,表示成功执行操作,但操作的结果是不播放或播放停止,希望对楼主能有启示。