我必须使用MS DirectShow从相机中捕获视频帧(我只想要原始像素数据)。
我能够构建Graph/Filter网络(捕获设备过滤器和ISampleGrabber),并实现回调(ISampleGrabberCB)。我接收到适当大小的样本。
但是,它们总是颠倒的(垂直翻转,而不是旋转),颜色通道是BGR顺序(而不是RGB)。
我尝试将BITMAPINFOHEADER中的biHeight字段设置为正值和负值,但它没有任何效果。根据MSDN文档,ISampleGrapper::SetMediaType()无论如何都忽略视频数据的格式块。
这是我看到的内容(使用不同的相机录制,而不是DS),以及DirectShow ISampleGrabber给我的内容:所谓的“RGB”实际上是红色,绿色和蓝色。
以下是我正在使用的代码示例,稍微简化:
// Setting the media type...
AM_MEDIA_TYPE* media_type = 0 ;
this->ds.device_streamconfig->GetFormat(&media_type); // The IAMStreamConfig of the capture device
// Find the BMI header in the media type struct
BITMAPINFOHEADER* bmi_header;
if (media_type->formattype != FORMAT_VideoInfo) {
bmi_header = &((VIDEOINFOHEADER*)media_type->pbFormat)->bmiHeader;
} else if (media_type->formattype != FORMAT_VideoInfo2) {
bmi_header = &((VIDEOINFOHEADER2*)media_type->pbFormat)->bmiHeader;
} else {
return false;
}
// Apply changes
media_type->subtype = MEDIASUBTYPE_RGB24;
bmi_header->biWidth = width;
bmi_header->biHeight = height;
// Set format to video device
this->ds.device_streamconfig->SetFormat(media_type);
// Set format for sample grabber
// bmi_header->biHeight = -(height); // tried this for either and both interfaces, no effect
this->ds.sample_grabber->SetMediaType(media_type);
// Connect filter pins
IPin* out_pin= getFilterPin(this->ds.device_filter, OUT, 0); // IBaseFilter interface for the capture device
IPin* in_pin = getFilterPin(this->ds.sample_grabber_filter, IN, 0); // IBaseFilter interface for the sample grabber filter
out_pin->Connect(in_pin, media_type);
// Start capturing by callback
this->ds.sample_grabber->SetBufferSamples(false);
this->ds.sample_grabber->SetOneShot(false);
this->ds.sample_grabber->SetCallback(this, 1);
// start recording
this->ds.media_control->Run(); // IMediaControl interface
我正在检查每个函数的返回类型,没有收到任何错误。
非常感谢您提供的任何提示或想法。
我已经尝试过以下方法:
为捕获设备过滤器或样本抓取器或两者或两者都设置biHeight字段为负值-没有任何效果。
使用IGraphBuilder连接引脚-同样的问题。
在更改媒体类型之前连接引脚-同样的问题。
通过再次查询过滤器来检查媒体类型是否实际应用-但显然已经应用或至少已存储。
将图像解释为完全字节反转(最后一个字节先,第一个字节后)-则会水平翻转。
检查视频摄像头是否存在问题-当我使用VLC(DirectShow捕获)进行测试时,它看起来是正常的。
biHeight
为负值,根据Windows的说法应该会产生效果,但是它并没有起作用。 另外:我仍然困扰于BGR颜色通道翻转,这似乎只发生在我身上。你能想象出任何原因吗? - Makx