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?
我正在使用 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?