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

时间:2015-04-03 11:58:13

标签: c++ video format directshow samplegrabber

我正在使用Media Foundation处理Windows的音频/视频捕获库。但是,我在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!
   } 
}

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

提前致谢!

1 个答案:

答案 0 :(得分:1)

示例Grabber回调将始终返回“正确”大小,以匹配实际数据大小和流式传输管道中使用的格式。

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

另见: