示例#1
0
文件: dshow.c 项目: 3688/FFmpeg
/**
 * Cycle through available devices using the device enumerator devenum,
 * retrieve the device with type specified by devtype and return the
 * pointer to the object found in *pfilter.
 * If pfilter is NULL, list all device names.
 */
static int
dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
                    enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype, IBaseFilter **pfilter)
{
    struct dshow_ctx *ctx = avctx->priv_data;
    IBaseFilter *device_filter = NULL;
    IEnumMoniker *classenum = NULL;
    IMoniker *m = NULL;
    const char *device_name = ctx->device_name[devtype];
    int skip = (devtype == VideoDevice) ? ctx->video_device_number
                                        : ctx->audio_device_number;
    int r;

    const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
                                   &CLSID_AudioInputDeviceCategory };
    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only";
    const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio";

    r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[sourcetype],
                                             (IEnumMoniker **) &classenum, 0);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices (or none found).\n",
               devtypename);
        return AVERROR(EIO);
    }

    while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
        IPropertyBag *bag = NULL;
        char *friendly_name = NULL;
        char *unique_name = NULL;
        VARIANT var;
        IBindCtx *bind_ctx = NULL;
        LPOLESTR olestr = NULL;
        LPMALLOC co_malloc = NULL;
        int i;

        r = CoGetMalloc(1, &co_malloc);
        if (r != S_OK)
            goto fail1;
        r = CreateBindCtx(0, &bind_ctx);
        if (r != S_OK)
            goto fail1;
        /* GetDisplayname works for both video and audio, DevicePath doesn't */
        r = IMoniker_GetDisplayName(m, bind_ctx, NULL, &olestr);
        if (r != S_OK)
            goto fail1;
        unique_name = dup_wchar_to_utf8(olestr);
        /* replace ':' with '_' since we use : to delineate between sources */
        for (i = 0; i < strlen(unique_name); i++) {
            if (unique_name[i] == ':')
                unique_name[i] = '_';
        }

        r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
        if (r != S_OK)
            goto fail1;

        var.vt = VT_BSTR;
        r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
        if (r != S_OK)
            goto fail1;
        friendly_name = dup_wchar_to_utf8(var.bstrVal);

        if (pfilter) {
            if (strcmp(device_name, friendly_name) && strcmp(device_name, unique_name))
                goto fail1;

            if (!skip--) {
                r = IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
                if (r != S_OK) {
                    av_log(avctx, AV_LOG_ERROR, "Unable to BindToObject for %s\n", device_name);
                    goto fail1;
                }
            }
        } else {
            av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
            av_log(avctx, AV_LOG_INFO, "    Alternative name \"%s\"\n", unique_name);
        }

fail1:
        if (olestr && co_malloc)
            IMalloc_Free(co_malloc, olestr);
        if (bind_ctx)
            IBindCtx_Release(bind_ctx);
        av_free(friendly_name);
        av_free(unique_name);
        if (bag)
            IPropertyBag_Release(bag);
        IMoniker_Release(m);
    }

    IEnumMoniker_Release(classenum);

    if (pfilter) {
        if (!device_filter) {
            av_log(avctx, AV_LOG_ERROR, "Could not find %s device with name [%s] among source devices of type %s.\n",
                   devtypename, device_name, sourcetypename);
            return AVERROR(EIO);
        }
        *pfilter = device_filter;
    }

    return 0;
}
示例#2
0
/**
 * Cycle through available devices using the device enumerator devenum,
 * retrieve the device with type specified by devtype and return the
 * pointer to the object found in *pfilter.
 * If pfilter is NULL, list all device names.
 */
static int
dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
                    enum dshowDeviceType devtype, IBaseFilter **pfilter)
{
    struct dshow_ctx *ctx = avctx->priv_data;
    IBaseFilter *device_filter = NULL;
    IEnumMoniker *classenum = NULL;
    IMoniker *m = NULL;
    const char *device_name = ctx->device_name[devtype];
    int skip = (devtype == VideoDevice) ? ctx->video_device_number
                                        : ctx->audio_device_number;
    int r;

    const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
                                   &CLSID_AudioInputDeviceCategory };
    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";

    r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
                                             (IEnumMoniker **) &classenum, 0);
    if (r != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n",
               devtypename);
        return AVERROR(EIO);
    }

    while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
        IPropertyBag *bag = NULL;
        char *buf = NULL;
        VARIANT var;

        r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
        if (r != S_OK)
            goto fail1;

        var.vt = VT_BSTR;
        r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
        if (r != S_OK)
            goto fail1;

        buf = dup_wchar_to_utf8(var.bstrVal);

        if (pfilter) {
            if (strcmp(device_name, buf))
                goto fail1;

            if (!skip--)
                IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
        } else {
            av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf);
        }

fail1:
        if (buf)
            av_free(buf);
        if (bag)
            IPropertyBag_Release(bag);
        IMoniker_Release(m);
    }

    IEnumMoniker_Release(classenum);

    if (pfilter) {
        if (!device_filter) {
            av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n",
                   devtypename);
            return AVERROR(EIO);
        }
        *pfilter = device_filter;
    }

    return 0;
}
示例#3
0
static HRESULT DXDiag_InitDXDiagDirectShowFiltersContainer(IDxDiagContainer* pSubCont) {
    HRESULT hr = S_OK;
    static const WCHAR szName[] = {'s','z','N','a','m','e',0};
    static const WCHAR szCatName[] = {'s','z','C','a','t','N','a','m','e',0};
    static const WCHAR szClsidCat[] = {'s','z','C','l','s','i','d','C','a','t',0};
    static const WCHAR szClsidFilter[] = {'s','z','C','l','s','i','d','F','i','l','t','e','r',0};
    static const WCHAR dwInputs[] = {'d','w','I','n','p','u','t','s',0};
    static const WCHAR dwOutputs[] = {'d','w','O','u','t','p','u','t','s',0};
    static const WCHAR dwMerit[] = {'d','w','M','e','r','i','t',0};
    /*
    static const WCHAR szFileName[] = {'s','z','F','i','l','e','N','a','m','e',0};
    static const WCHAR szFileVersion[] = {'s','z','F','i','l','e','V','e','r','s','i','o','n',0};
    */
    VARIANT v;

    static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
    static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
    static const WCHAR wszFilterDataName[] = {'F','i','l','t','e','r','D','a','t','a',0};
    /*static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};*/

    ICreateDevEnum* pCreateDevEnum = NULL;
    IEnumMoniker* pEmCat = NULL;
    IMoniker* pMCat = NULL;
    /** */
    hr = CoCreateInstance(&CLSID_SystemDeviceEnum,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          &IID_ICreateDevEnum,
                          (void**) &pCreateDevEnum);
    if (FAILED(hr)) return hr;

    hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &CLSID_ActiveMovieCategories, &pEmCat, 0);
    if (FAILED(hr)) goto out_show_filters;

    VariantInit(&v);

    while (S_OK == IEnumMoniker_Next(pEmCat, 1, &pMCat, NULL)) {
        IPropertyBag* pPropBag = NULL;
        CLSID clsidCat;
        hr = IMoniker_BindToStorage(pMCat, NULL, NULL, &IID_IPropertyBag, (void**) &pPropBag);
        if (SUCCEEDED(hr)) {
            WCHAR* wszCatName = NULL;
            WCHAR* wszCatClsid = NULL;

            hr = IPropertyBag_Read(pPropBag, wszFriendlyName, &v, 0);
            wszCatName = SysAllocString(V_BSTR(&v));
            VariantClear(&v);

            hr = IPropertyBag_Read(pPropBag, wszClsidName, &v, 0);
            wszCatClsid = SysAllocString(V_BSTR(&v));
            hr = CLSIDFromString(V_UNION(&v, bstrVal), &clsidCat);
            VariantClear(&v);

            /*
            hr = IPropertyBag_Read(pPropBag, wszMeritName, &v, 0);
            hr = IDxDiagContainerImpl_AddProp(pSubCont, dwMerit, &v);
            VariantClear(&v);
            */

            if (SUCCEEDED(hr)) {
                IEnumMoniker* pEnum = NULL;
                IMoniker* pMoniker = NULL;
                hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &clsidCat, &pEnum, 0);
                FIXME("\tClassEnumerator for clsid(%s) pEnum(%p)\n", debugstr_guid(&clsidCat), pEnum);
                if (FAILED(hr) || pEnum == NULL) {
                    goto class_enum_failed;
                }
                while (NULL != pEnum && S_OK == IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL)) {
                    IPropertyBag* pPropFilterBag = NULL;
                    FIXME("\tIEnumMoniker_Next(%p, 1, %p)\n", pEnum, pMoniker);
                    hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (void**) &pPropFilterBag);
                    if (SUCCEEDED(hr)) {
                        LPBYTE pData = NULL;
                        LPBYTE pCurrent = NULL;
                        struct REG_RF* prrf = NULL;
                        VARIANT v_data;
                        DWORD it;
                        DWORD dwNOutputs = 0;
                        DWORD dwNInputs = 0;

                        V_VT(&v) = VT_BSTR;
                        V_BSTR(&v) = SysAllocString(wszCatName);
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szCatName, &v);
                        VariantClear(&v);

                        V_VT(&v) = VT_BSTR;
                        V_BSTR(&v) = SysAllocString(wszCatClsid);
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szClsidCat, &v);
                        VariantClear(&v);

                        hr = IPropertyBag_Read(pPropFilterBag, wszFriendlyName, &v, 0);
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szName, &v);
                        FIXME("\tName:%s\n", debugstr_w(V_BSTR(&v)));
                        VariantClear(&v);

                        hr = IPropertyBag_Read(pPropFilterBag, wszClsidName, &v, 0);
                        FIXME("\tClsid:%s\n", debugstr_w(V_BSTR(&v)));
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szClsidFilter, &v);
                        VariantClear(&v);

                        hr = IPropertyBag_Read(pPropFilterBag, wszFilterDataName, &v, NULL);
                        hr = SafeArrayAccessData(V_UNION(&v, parray), (LPVOID*) &pData);
                        prrf = (struct REG_RF*) pData;
                        pCurrent = pData;

                        VariantInit(&v_data);
                        V_VT(&v_data) = VT_UI4;
                        V_UI4(&v_data) = prrf->dwVersion;
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szName, &v_data);
                        VariantClear(&v_data);
                        V_VT(&v_data) = VT_UI4;
                        V_UI4(&v_data) = prrf->dwMerit;
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, dwMerit, &v_data);
                        VariantClear(&v_data);

                        pCurrent += sizeof(struct REG_RF);
                        for (it = 0; it < prrf->dwPins; ++it) {
                            struct REG_RFP* prrfp = (struct REG_RFP*) pCurrent;
                            UINT j;

                            if (prrfp->dwFlags & REG_PINFLAG_B_OUTPUT) ++dwNOutputs;
                            else ++dwNInputs;

                            pCurrent += sizeof(struct REG_RFP);
                            if (prrfp->bCategory) {
                                pCurrent += sizeof(DWORD);
                            }
                            for (j = 0; j < prrfp->dwMediaTypes; ++j) {
                                struct REG_TYPE* prt = (struct REG_TYPE *)pCurrent;
                                pCurrent += sizeof(*prt);
                            }
                            for (j = 0; j < prrfp->dwMediums; ++j) {
                                DWORD dwOffset = *(DWORD*) pCurrent;
                                pCurrent += sizeof(dwOffset);
                            }
                        }

                        V_VT(&v_data) = VT_UI4;
                        V_UI4(&v_data) = dwNInputs;
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, dwInputs, &v_data);
                        VariantClear(&v_data);
                        V_VT(&v_data) = VT_UI4;
                        V_UI4(&v_data) = dwNOutputs;
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, dwOutputs, &v_data);
                        VariantClear(&v_data);

                        SafeArrayUnaccessData(V_UNION(&v, parray));
                        VariantClear(&v);
                    }
                    IPropertyBag_Release(pPropFilterBag);
                    pPropFilterBag = NULL;
                }
                IEnumMoniker_Release(pEnum);
                pEnum = NULL;
            }
class_enum_failed:
            SysFreeString(wszCatName);
            SysFreeString(wszCatClsid);
            IPropertyBag_Release(pPropBag);
            pPropBag = NULL;
        }
        IEnumMoniker_Release(pMCat);
        pMCat = NULL;
    }

out_show_filters:
    if (NULL != pEmCat) {
        IEnumMoniker_Release(pEmCat);
        pEmCat = NULL;
    }
    if (NULL != pCreateDevEnum) {
        ICreateDevEnum_Release(pCreateDevEnum);
        pCreateDevEnum = NULL;
    }
    return hr;
}
示例#4
0
static GValueArray *
gst_dshowaudiosrc_get_device_name_values (GstDshowAudioSrc * src)
{
  GValueArray *array = g_value_array_new (0);
  GValue value = { 0 };
  ICreateDevEnum *devices_enum = NULL;
  IEnumMoniker *moniker_enum = NULL;
  IMoniker *moniker = NULL;
  HRESULT hres = S_FALSE;
  ULONG fetched;

  g_value_init (&value, G_TYPE_STRING);

  hres = CoCreateInstance (&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
      &IID_ICreateDevEnum, (void **) &devices_enum);
  if (hres != S_OK) {
    GST_CAT_ERROR (dshowaudiosrc_debug,
        "Can't create an instance of the system device enumerator (error=%d)",
        hres);
    array = NULL;
    goto clean;
  }

  hres =
      ICreateDevEnum_CreateClassEnumerator (devices_enum,
      &CLSID_AudioInputDeviceCategory, &moniker_enum, 0);
  if (hres != S_OK || !moniker_enum) {
    GST_CAT_ERROR (dshowaudiosrc_debug,
        "Can't get enumeration of audio devices (error=%d)", hres);
    array = NULL;
    goto clean;
  }

  IEnumMoniker_Reset (moniker_enum);

  while (hres = IEnumMoniker_Next (moniker_enum, 1, &moniker, &fetched),
      hres == S_OK) {
    IPropertyBag *property_bag = NULL;

    hres =
        IMoniker_BindToStorage (moniker, NULL, NULL, &IID_IPropertyBag,
        (void **) &property_bag);
    if (SUCCEEDED (hres) && property_bag) {
      VARIANT varFriendlyName;

      VariantInit (&varFriendlyName);
      hres =
          IPropertyBag_Read (property_bag, L"FriendlyName", &varFriendlyName,
          NULL);
      if (hres == S_OK && varFriendlyName.bstrVal) {
        gchar *friendly_name =
            g_utf16_to_utf8 ((const gunichar2 *) varFriendlyName.bstrVal,
            wcslen (varFriendlyName.bstrVal), NULL, NULL, NULL);

        g_value_set_string (&value, friendly_name);
        g_value_array_append (array, &value);
        g_value_unset (&value);
        g_free (friendly_name);
        SysFreeString (varFriendlyName.bstrVal);
      }
      IPropertyBag_Release (property_bag);
    }
    IMoniker_Release (moniker);
  }

clean:
  if (moniker_enum) {
    IEnumMoniker_Release (moniker_enum);
  }

  if (devices_enum) {
    ICreateDevEnum_Release (devices_enum);
  }

  return array;
}
示例#5
0
文件: devenum.c 项目: Barrell/wine
static void test_devenum(IBindCtx *bind_ctx)
{
    HRESULT res;
    ICreateDevEnum* create_devenum;
    IEnumMoniker* enum_moniker = NULL;
    int i;

    res = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                           &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
    if (res != S_OK) {
        skip("Cannot create SystemDeviceEnum object (%x)\n", res);
        return;
    }

    for (i = 0; i < (sizeof(am_categories) / sizeof(struct category)); i++)
    {
        if (winetest_debug > 1)
            trace("%s:\n", am_categories[i].name);

        res = ICreateDevEnum_CreateClassEnumerator(create_devenum, am_categories[i].clsid, &enum_moniker, 0);
        ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
        if (res == S_OK)
        {
            IMoniker* moniker;
            while (IEnumMoniker_Next(enum_moniker, 1, &moniker, NULL) == S_OK)
            {
                IPropertyBag* prop_bag = NULL;
                VARIANT var;
                HRESULT hr;

                VariantInit(&var);
                hr = IMoniker_BindToStorage(moniker, bind_ctx, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
                ok(hr == S_OK, "IMoniker_BindToStorage failed with error %x\n", hr);

                if (SUCCEEDED(hr))
                {
                    hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
                    ok((hr == S_OK) || broken(hr == 0x80070002), "IPropertyBag_Read failed with error %x\n", hr);

                    if (SUCCEEDED(hr))
                    {
                        if (winetest_debug > 1)
                            trace("  %s\n", wine_dbgstr_w(V_UNION(&var, bstrVal)));
                        VariantClear(&var);
                    }
                    else
                    {
                        trace("  ???\n");
                    }
                }

                if (prop_bag)
                    IPropertyBag_Release(prop_bag);
                IMoniker_Release(moniker);
            }
            IEnumMoniker_Release(enum_moniker);
        }
    }

    ICreateDevEnum_Release(create_devenum);
}