|
本帖最后由 ancientcc 于 2020-1-30 21:02 编辑
通过dxdiag,exe,出问题电脑的系统型号:macbookpro15,2
问题描述。运行Win10自带的“相机”可以正常打开摄像头。运行AMCap,无法打开摄像头。运行GraphEdit.exe,用NV12时可以打开摄像头,但YUY2时,不论1280x720还是640x480,都不能看到摄像头图像。运行自写的基于webrtc app,也是摄像头不正常,具体是Run成功了,但没有收到图像。
分析原因。该摄像头支持两种颜色空间:NV12和YUY2。NV12正常(但不完全符合规范,像AMCap换成NV12还是不正常),YUY2不正常,不正常的原因极可能出在摄像头硬件,因为我看这个驱动程序装载的相关软件就是标准的UVC驱动须要的文件。
如何解决。试着把2017年MacBook Pro上的摄像头驱动移植过来,但发现这两摄像头架构不一样,2019年的可能是UVC,全用了Win10自带驱动。而2015年的不是。于是深入webrtc代码,发现在windows平台,webrtc是没考虑支持NV12,于是做以下修改。
- <webrtc>/modules/video_capture/windows/device_info_ds.cc
- ---DeviceInfoDS::CreateCapabilityMap(const char* deviceUniqueIdUTF8)
- 增加
- else if (pmt->subtype == MEDIASUBTYPE_NV12) {
- capability.videoType = VideoType::kNV12;
- }
- <webrtc>/modules/video_capture/windows/sink_filter_ds.cc
- ---CaptureInputPin::GetMediaType(IN int iPosition, OUT CMediaType* pmt)
- case 5: {
- pvi->bmiHeader.biCompression = MAKEFOURCC('N', 'V', '1', '2');
- pvi->bmiHeader.biBitCount = 12; // bit per pixel
- pvi->bmiHeader.biWidth = _requestedCapability.width;
- pvi->bmiHeader.biHeight = _requestedCapability.height;
- pvi->bmiHeader.biSizeImage = 3 * _requestedCapability.height * _requestedCapability.width / 2;
- pmt->SetSubtype(&MEDIASUBTYPE_NV12);
- } break;
- ---CaptureInputPin::CheckMediaType(IN const CMediaType* pMediaType)
- 两处,*formatType == FORMAT_VideoInfo和*formatType == FORMAT_VideoInfo2都要增加。
- if (*SubType == MEDIASUBTYPE_NV12 && pvi->bmiHeader.biCompression == MAKEFOURCC('N', 'V', '1', '2')) {
- _resultingCapability.videoType = VideoType::kNV12;
- return S_OK; // This format is acceptable.
- }
- <webrtc>/modules/video_capture/device_info_impl.cc
- ---int32_t VideoCaptureDS::SetCameraOutput
- hr = _graphBuilder->ConnectDirect(_outputCapturePin, _inputSendPin, NULL);
- 改为在NV12时需要显示提供AM_MEDIA_TYPE。
- AM_MEDIA_TYPE mt;
- AM_MEDIA_TYPE* pmt = NULL;
- memset(&mt, 0, sizeof(mt));
- mt.majortype = MEDIATYPE_Video;
- if (_requestedCapability.videoType == VideoType::kNV12) {
- mt.subtype = MEDIASUBTYPE_NV12;
- pmt = &mt;
- }
- hr = _graphBuilder->ConnectDirect(_outputCapturePin, _inputSendPin, pmt);
复制代码
经过以上修改,640x480是可以了,但1280x720还是不行。另外VideoCaptureDS::SetCameraOutput中,_dsInfo.GetBestMatchedCapability得到的capability其实是kYUY2,不是应该的kNV12!但不影响结果,不对DeviceInfoImpl::GetBestMatchedCapability做修改了。
这问题或许得等win10有升级或使用了新版本webrtc源码。对win10升级,可用AMCap是否正常了进行判断。对webrtc源码,判断方法是看win10上是否支持NV12,一种快速方法是看<webrtc>/modules/video_capture/windows/device_info_ds.cc中的DeviceInfoDS::CreateCapabilityMap是否有了MEDIASUBTYPE_NV12判断入口。 |
|