Sample Grabber 返回的 IMediaSample 具有意外的缓冲区大小

IMediaSample returned by Sample Grabber has unexpected buffer size

我正在使用 Media Foundation 为 Windows 开发一个 audio/video 捕获库。但是,我在 Windows 8.1 上遇到了某些网络摄像头 in this post 所描述的问题。因此,我决定使用 Directshow 进行另一个实现,以在我的应用程序中支持尚未更新驱动程序的网络摄像头。

该库运行良好,但我注意到一些网络摄像头存在问题,根据启动摄像头之前设置的格式,返回的示例 (IMediaSample) 没有达到预期大小。

例如,我有这样一种情况,其中格式集的子类型为 MEDIASUBTYPE_RGB24(每个像素 3 个字节)并且帧大小为 640x480。应用格式时,biSizeImage(来自 BITMAPINFOHEADER)很好 640*480*3 = 921600。 IAMStreamConfig::SetFormat() 方法成功应用格式。

hr = pStreamConfig->SetFormat(pmt);

我也将格式设置为 Sample Grabber Interface 如下:

hr = pSampleGrabberInterface->SetMediaType(pmt);

我在开始图表之前应用了格式。

但是,在回调 (ISampleGrabberCB::SampleCB) 中,我收到了一个大小为 230400 的样本(这可能是一个大小为 320x240 (320*240*3=230400) 的帧的缓冲区)。

HRESULT MyClass::SampleCB(double sampleTime, IMediaSample *pSample)
{
   unsigned char* pBuffer= 0;
   HRESULT hr = pSample->GetPointer((unsigned char**) &pBuffer);
   if(SUCCEEDED(hr) {
      long bufSize = pSample->GetSize();
      //bufSize = 230400
   }
}

我试图调查使用 IMediaSample::GetMediaType() 方法返回的媒体类型,但是媒体类型为 NULL,这意味着根据 the documentation of the GetMediaType method 媒体类型没有改变(所以我想,它仍然是我使用 IAMStreamConfig::SetFormat() 函数成功应用的媒体类型。

HRESULT hr = pSample->GetMediaType(&pType);

if(SUCCEEDED(hr)) {
   if(pType==NULL) {
     //it enters here => the media type has not changed!
   } 
}

为什么在这种情况下返回的样本缓冲区大小不是预期的大小?我该如何解决这个问题?

提前致谢!

Sample Grabber 回调将始终 return "correct" 大小,以匹配流式传输管道中使用的实际数据大小和格式。

如果您发现不匹配,则表示您的过滤器图拓扑与您预期的不同。您需要查看图表(尤其是 using remote connection by GraphEdit),检查媒体类型并检查构建错误的原因。例如,您可能在连接引脚后应用您感兴趣的格式,但为时已晚。

另请参阅:

  • How can I reverse engineer a DirectShow graph?