C++ 如何通过UVC支持硬件编码的H264
我正在用DirectShow创建的视频聊天应用程序中使用Logitech C930e网络摄像头。到目前为止,我能够使用YUY2或mJPEG中的原始流。无论如何,我发现网络摄像头通过UVC接口支持硬件H264编码 现在我正在使用标准的方法获取可能的网络摄像头捕获pin配置,但那里没有H264 pinC++ 如何通过UVC支持硬件编码的H264,c++,video,directshow,h.264,C++,Video,Directshow,H.264,我正在用DirectShow创建的视频聊天应用程序中使用Logitech C930e网络摄像头。到目前为止,我能够使用YUY2或mJPEG中的原始流。无论如何,我发现网络摄像头通过UVC接口支持硬件H264编码 现在我正在使用标准的方法获取可能的网络摄像头捕获pin配置,但那里没有H264 pin void list_cameras { ICreateDevEnum *pDevEnum = nullptr; IEnumMoniker *pEnum = nullptr;
void list_cameras {
ICreateDevEnum *pDevEnum = nullptr;
IEnumMoniker *pEnum = nullptr;
// Create the System Device Enumerator.
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
reinterpret_cast<void**>(&pDevEnum));
if (SUCCEEDED(hr)) {
// Create an enumerator for the video capture category.
hr = pDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory,
&pEnum, 0);
if (hr == S_FALSE) {
return;
}
}
IMoniker *pMoniker = nullptr; // IMoniker is the device
int index = 0;
// for each device
while (pEnum->Next(1, &pMoniker, nullptr) == S_OK) {
// bind camera to filter to be able to use it
if (cam.device->BindToObject(nullptr, nullptr, IID_IBaseFilter, reinterpret_cast<void**>(&_pCapture)) != S_OK) {
continue;
}
// fetch the configuration interface
IAMStreamConfig *pConfig = nullptr;
HRESULT hr = _capture->FindInterface(
&PIN_CATEGORY_CAPTURE, // Preview pin.
nullptr, // Any media type.
_pCapture, // Pointer to the capture filter.
IID_IAMStreamConfig, reinterpret_cast<void**>(&pConfig));
if (FAILED(hr)) {
continue;
}
// fetch possible configurations
int iCount = 0, iSize = 0;
if (pConfig->GetNumberOfCapabilities(&iCount, &iSize) != S_OK) {
continue;
}
// store each configuration
AM_MEDIA_TYPE *pmtConfig;
for (int iFormat = 0; iFormat < iCount; iFormat++) {
// get config
VIDEO_STREAM_CONFIG_CAPS scc;
if (pConfig->GetStreamCaps(iFormat, &pmtConfig, reinterpret_cast<BYTE*>(&scc)) != S_OK) {
continue;
}
// copy config data
VIDEOINFOHEADER *pVih = new VIDEOINFOHEADER(); // deleted afterwards
*pVih = *reinterpret_cast<VIDEOINFOHEADER *>(pmtConfig->pbFormat);
AM_MEDIA_TYPE mt;
mt = *pmtConfig;
mt.pbFormat = reinterpret_cast<BYTE *>(pVih);
auto fcc = FOURCCMap(pVih->bmiHeader.biCompression);
// wrap it
CameraConfig config = { mt, pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight, 1000 / (static_cast<float>(pVih->AvgTimePerFrame) / 10000), fcc };
// if resolution is bad (or unsupported), skip this configuration
if (config.width == 0 || config.height == 0 ) // bad
continue;
cam.configurations.push_back(config);
}
_cameras.push_back(cam);
pConfig->Release();
_pCapture->Release();
}
pEnum->Release();
pDevEnum->Release();
}
\u pCapture
是指向创建的捕获筛选器的指针。
CameraConfig
的定义如下:
typedef struct {
//! Pointer to DirectShow device.
DSDevice device;
//! Camera name
string name;
//! List of supported configurations.
vector<CameraConfig> configurations; // list of all available configurations
//! Index of selected configuration.
int selected;
} Camera;
typedef struct {
//! Media type.
AM_MEDIA_TYPE _mediaType;
//! Output width.
int width;
//! Outpus height.
int height;
//! Output framerate.
float fps;
//! Compression algoritm. YUY2 and mJPEG are supported for now.
FOURCCMap compression;
} CameraConfig;
如何实现对UVC设备的支持?硬件编码器的哪些参数可以控制
谢谢。我在Windows 8.x下获得该流的唯一方法是不使用LOGITECH驱动程序。这是一款兼容UVC 1.5的相机,将由操作系统自动配置。使用该驱动程序(来自Microsoft),使用pin 1(而不是0),您将获得大量H264格式 我认为在Windows7下,Logitech的一些驱动程序也提供了许多H264格式 如果您使用的是Windows 8.x,并且已经安装了Logitech驱动程序,则必须删除该驱动程序。这很难。我通常通过编写这样的结构(以管理员身份运行):
至于删除什么inf,这很简单:转到Windows\inf文件夹并搜索Logitech。然后检查每个文件,看看到底是什么(你可能有一个鼠标或其他你想保留的东西)。通常不止一个。您通过DirectShow API使用相机。相机可以通过
IAMStreamConfig
等众所周知的方式(您已经知道的方式(YUY2,MJPG)或特定于此特定型号(SDK等)的供应商特定方式进行曝光。谢谢。是否有可靠的信息来源,哪些网络摄像头通过DirectShow API公开硬件编码的H264?如果摄像头以“标准方式”公开H.264 capture,您应该能够通过列举其功能来查看它。查看它的方法之一是通过IAMStreamConfig
界面以编程方式显示您拥有的一切。另一种方法是使用插入的捕获过滤器并遍历pin媒体类型。无论哪种方式,您都应该看到H264
或AVC1
子类型或biCompression
值。顺便说一句,您的代码正在执行IAMStreamConfig
大约正确,但是你没有显示结果,我们对你的相机一无所知……你对通过方法显示pin\u CATEGORY\u CAPTURE
的pin感兴趣。如果有人正在寻找查询和卸载驱动程序的解决方案,我已经开发了一个工具。GitHub上提供的源代码,详细信息如下:
BOOL res;
res = SetupUninstallOEMInf(TEXT("oem131.inf"), SUOI_FORCEDELETE, nullptr );