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

IMediaSample returned by Sample Grabber has unexpected buffer size

本文关键字:缓冲区 意外 Grabber 返回 IMediaSample Sample      更新时间:2023-10-16

我正在使用Media Foundation为Windows开发音频/视频捕获库。然而,我在这篇文章中为Windows8.1上的一些网络摄像头描述了这个问题。因此,我决定使用Directshow在我的应用程序中支持驱动程序尚未更新的网络摄像头。

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

例如,我遇到的情况是,格式集的子类型为MEDIASBTYPE_RGB24(每像素3个字节),帧大小为640x480。biSizeImage(来自BITMAPINFOHEADER)在应用该格式时为640*480*3=921600。IAMStreamConfig::SetFormat()方法成功应用了该格式。

hr = pStreamConfig->SetFormat(pmt);

我还将采样采集器接口的格式设置如下:

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,这意味着,根据GetMediaType方法的文档,媒体类型没有更改(所以我想,它仍然是我使用IAMStreamConfig::SetFormat()函数成功应用的媒体类型)。

HRESULT hr = pSample->GetMediaType(&pType);
if(SUCCEEDED(hr)) {
   if(pType==NULL) {
     //it enters here => the media type has not changed!
   } 
}

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

提前感谢!

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

如果你看到不匹配,这意味着你的过滤图拓扑结构与你期望的不同。你需要查看该图(尤其是使用GraphEdit的远程连接),检查媒体类型,并检查其构建错误的原因。例如,您可能在连接引脚后应用您感兴趣的格式,但为时已晚。

另请参阅:

  • 如何对DirectShow图形进行反向工程