简体   繁体   English

如何通过UVC支持硬件编码H264

[英]How to support hardware encoded H264 though UVC

I am using Logitech C930e webcam in a videochat application, created with DirectShow. 我在使用DirectShow创建的视频应用程序中使用Logitech C930e网络摄像头。 So far I was able to use raw stream in YUY2 or mJPEG. 到目前为止,我能够在YUY2或mJPEG中使用原始流。 Anyway, I have discovered that the webcam supports hardware H264 encoding though a UVC interface. 无论如何,我发现网络摄像头通过UVC接口支持硬件H264编码。

Right now I using standart methods to fetch possible webcam capture pin configurations, but there is no H264 pin there. 现在我使用标准方法来获取可能的网络摄像头捕获引脚配置,但那里没有H264引脚。

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();
}

_cameras is a vector of Camera, defined as follows: _cameras是Camera的矢量,定义如下:

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;

_pCapture is a pointer to the created capture filter. _pCapture是指向创建的捕获过滤器的指针。 CameraConfig is defined as follows: CameraConfig定义如下:

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;

How do one implement a support for UVC devices? 如何实现对UVC设备的支持? Which parameters of hardware encoder can be controlled? 可以控制哪些硬件编码器参数?

Thanks. 谢谢。

The only way I was able to get that stream under Windows 8.x was by NOT USING LOGITECH DRIVERS. 我能够在Windows 8.x下获得该流的唯一方法是不使用LOGITECH驱动程序。 This is a UVC 1.5 compatible camera and it will be configured automatically by the OS. 这是兼容UVC 1.5的相机,它将由操作系统自动配置。 With that driver (from Microsoft), use pin 1 (not 0) and you will get a ton of H264 formats. 使用该驱动程序(来自Microsoft),使用引脚1(而不是0),您将获得大量的H264格式。

I think that under Windows 7, some drivers from Logitech give also a number of H264 formats. 我认为在Windows 7下,Logitech的一些驱动程序也提供了许多H264格式。

In the case you are using Windows 8.x and you already have the Logitech driver installed you must remove that. 如果您使用的是Windows 8.x并且已经安装了Logitech驱动程序,则必须将其删除。 And it is quite hard. 这很难。 I usually do it by writing constructs like this (run as admin): 我通常通过编写这样的结构(以管理员身份运行)来实现:

BOOL res;
res = SetupUninstallOEMInf(TEXT("oem131.inf"), SUOI_FORCEDELETE, nullptr );

As to what inf you delete this is simple: go to Windows\\Inf folder and search for Logitech. 至于你删除的内容很简单:转到Windows \\ Inf文件夹并搜索Logitech。 Then check each file o see what exactly is (you might have a mouse or something else you want to keep). 然后检查每个文件o看看究竟是什么(你可能有一个鼠标或其他你想保留的东西)。 Usually it is more than one. 通常它不止一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM