Sample Grabber返回的IMediaSample具有意外的缓冲区大小
IMediaSample returned by Sample Grabber has unexpected buffer size
我正在使用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图形进行反向工程
- C++字符*缓冲区的大小
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 在C++中对T*类型执行std::move的意外行为
- Xaudio2在更改缓冲区或循环时弹出声音
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 处理除以零会导致<csignal>意外行为
- 多线程双缓冲区
- Android P-9.0.0_r53 Logcat主缓冲区超出定义大小
- vscode下的Arduino代码出现意外编译错误
- 使用++运算符会导致意外的结果
- 套接字读取后,我在缓冲区中看到意外输入
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- Sample Grabber返回的IMediaSample具有意外的缓冲区大小
- 在缓冲区之间移动字节时出现意外结果