次の方法で共有


IWMDMDevice3 を使用したフォーマット機能の取得

IWMDMDevice3::GetFormatCapability は、サポートされている形式をデバイスに問い合わせるための推奨される方法です。 次の手順では、このメソッドを使用して、デバイスの形式機能を照会する方法を示します。

  1. アプリケーションは、デバイスがサポートする形式と、対象となる形式を決定する必要があります。 これを行うために、アプリケーションは IWMDMDevice3::GetProperty を呼び出すことによって、デバイスでサポートされている形式の一覧を要求できます。
  2. アプリケーションは、サポートされているすべての形式をループ処理し、 IWMDMDevice3::GetFormatCapability を呼び出し、 WMDM_FORMATCODE 列挙を使用して形式を指定することで、特定の形式 (WMA や WMV など) のデバイスの形式機能を要求します。 このメソッドは、 WMDM_FORMAT_CAPABILITY 構造体を取得します。
  3. 取得した WMDM_FORMAT_CAPABILITY 構造体内のすべての WMDM_PROP_CONFIG 構造体をループ処理します。 各 WMDM_PROP_CONFIG 構造体は、サポートされている値を持つプロパティのグループを保持し、その形式の 1 つの構成を表します。 各構成にはユーザー設定番号があり、数値が小さい場合はデバイスの優先順位が高くなります。
  4. 取得したWMDM_PROP_CONFIG内のすべてのWMDM_PROP_DESC構造体をループ処理します。 各 WMDM_PROP_DESC には、サポートされているプロパティと値のペアの一覧が含まれています。
  5. WMDM_PROP_DESC構造体からプロパティの名前と値を取得します。 プロパティには、ビット レート、コーデック、フレーム サイズが含まれます。 プロパティ名は mswmdm.h ヘッダー ファイルで定義されます。これらの定数の大部分の一覧は、 メタデータ定数で指定されます。 次の 3 種類のプロパティ値を使用できます。
    • このプロパティの値のサポートを示す 1 つの値 (WMDM_ENUM_PROP_VALID_VALUES_ANY)。
    • 最大値、最小値、間隔によって定義される値の範囲。
    • 不連続値の一覧。
  6. 格納されている値をクリアします。 これらの値のメモリは Windows Media デバイス マネージャーによって割り当てられます。デバイスはメモリの解放を担当します。 これを行う方法については、このトピックの最後で説明します。

GetFormatCapability に応答すると、デバイスはWMDM_FORMAT_CAPABILITYのWMDM_ENUM_PROP_VALID_VALUES_ANYを報告できます。WMDM_PROP_CONFIG。WMDM_PROP_DESC。ValidValuesForm ビット レート、チャネルなどの値のサポートを要求します。 ただし、実際にはすべてのビット レートやイメージ サイズをサポートしていない場合、デバイスが値のサポートを報告する場合があるため、この要求は慎重に扱う必要があります。 これらのファイルを再生することを目的としたデバイスに送信する場合は、アプリケーションで非常に大きいファイルまたは高ビット レートのファイルを、より小さなバージョンにトランスコードするか、メモリを集中的に消費する低いバージョンと CPU 負荷の高いバージョンにトランスコードすることを検討できます。

次の C++ 関数は、特定の形式のデバイス形式のサポートを要求する方法を示しています。

HRESULT GetFormatCaps(WMDM_FORMATCODE formatCode, IWMDMDevice3* pDevice)
{
    HRESULT hr = S_OK;

    // Get a list of supported configurations for the format.
    WMDM_FORMAT_CAPABILITY formatCapList;
    hr = pDevice->GetFormatCapability(formatCode, &formatCapList);
    if (FAILED(hr)) return E_FAIL;

    // TODO: Display the format name.
    // Loop through the configurations and examine each one.
    for (UINT iConfig = 0; iConfig < formatCapList.nPropConfig; iConfig++)
    {
        WMDM_PROP_CONFIG formatConfig = formatCapList.pConfigs[iConfig];

        // Preference level for this configuration (lower number means more preferred).
        // TODO: Display the preference level for this format configuration.

        // Loop through all properties for this configuration and get supported
        // values for the property. Values can be a single value, a range, 
        // or a list of enumerated values.
        for (UINT iDesc = 0; iDesc < formatConfig.nPropDesc; iDesc++)
        {
            WMDM_PROP_DESC propDesc = formatConfig.pPropDesc[iDesc];
            // TODO: Display the property name.

            // Three ways a value can be represented: any, a range, or a list.
            switch (propDesc.ValidValuesForm)
            {
                case WMDM_ENUM_PROP_VALID_VALUES_ANY:
                    // TODO: Display a message indicating that all values are valid.
                    break;
                case WMDM_ENUM_PROP_VALID_VALUES_RANGE:
                    {
                        // List these in the docs as the propvariants set.
                        WMDM_PROP_VALUES_RANGE rng = 
                            propDesc.ValidValues.ValidValuesRange;
                        // TODO: Display the min, max, and step values.
                    }
                    break;
                case WMDM_ENUM_PROP_VALID_VALUES_ENUM:
                    {
                        // TODO: Display a banner for the list of valid values.
                        WMDM_PROP_VALUES_ENUM list = propDesc.ValidValues.EnumeratedValidValues;
                        PROPVARIANT pVal;
                        for (UINT iValue = 0; iValue < list.cEnumValues; iValue++)
                        {
                            pVal = list.pValues[iValue];
                            // TODO: Display each valid value.
                            PropVariantClear(&pVal);
                            PropVariantInit(&pVal);
                        }
                    }

                    break;
                default:
                    return E_FAIL,
                    break;
            }
        }
    }
    // Now clear the memory used by WMDM_FORMAT_CAPABILITY.
    FreeFormatCapability(formatCapList);
    return hr;
}

割り当てられたメモリのクリア

デバイスからフォーマット機能を取得した後、アプリケーションは、説明を保持するために割り当てられたメモリを解放する必要があります。 GetFormatSupportGetFormatSupport2 には、単純な構造体の配列があり、この配列を使用して CoTaskMemFree を 呼び出すだけでクリアできます。 ただし、 GetFormatCapability には、動的に割り当てられたメモリを持つより複雑なデータ構造があり、すべての要素をループして個別に解放することでクリアする必要があります。

次の C++ コードは、 アプリケーションがWMDM_FORMAT_CAPABILITY 構造体に割り当てられたメモリを解放する方法を示しています。

void CWMDMController::FreeFormatCapability(WMDM_FORMAT_CAPABILITY formatCap)
{
    // Loop through all configurations.
    for (UINT i = 0; i < formatCap.nPropConfig; i++) 
    {
        // Loop through all descriptions of a configuration and delete
        // the values particular to that description type.
        for (UINT j=0; j < formatCap.pConfigs[i].nPropDesc; j++) 
        {
            switch (formatCap.pConfigs[i].pPropDesc[j].ValidValuesForm)
            {
                case WMDM_ENUM_PROP_VALID_VALUES_ENUM:
                    for (UINT k=0; k < formatCap.pConfigs[i].pPropDesc[j].ValidValues.EnumeratedValidValues.cEnumValues; k++)
                    {
                        PropVariantClear (&(formatCap.pConfigs[i].pPropDesc[j].ValidValues.EnumeratedValidValues.pValues[k]));
                    }
                    CoTaskMemFree(formatCap.pConfigs[i].pPropDesc[j].ValidValues.EnumeratedValidValues.pValues);
                    break;
                case WMDM_ENUM_PROP_VALID_VALUES_RANGE:
                    PropVariantClear (&(formatCap.pConfigs[i].pPropDesc[j].ValidValues.ValidValuesRange.rangeMin));
                    PropVariantClear (&(formatCap.pConfigs[i].pPropDesc[j].ValidValues.ValidValuesRange.rangeMax));
                    PropVariantClear (&(formatCap.pConfigs[i].pPropDesc[j].ValidValues.ValidValuesRange.rangeStep));
                    break;
                case WMDM_ENUM_PROP_VALID_VALUES_ANY:
                    // No dynamically allocated memory for this value.
                default:
                    break;
            }

            // Free the memory for the description name.
            CoTaskMemFree(formatCap.pConfigs[i].pPropDesc[j].pwszPropName);
        }
        // Free the memory holding the array of description items for this configuration.
        CoTaskMemFree(formatCap.pConfigs[i].pPropDesc);
    }

    // Free the memory pointing to the array of configurations.
    CoTaskMemFree(formatCap.pConfigs);
    formatCap.nPropConfig = 0;
}

サポートされているすべての形式のクエリ

通常、アプリケーションは特定のファイルをデバイスに送信することに関心があるため、特定の形式のデバイスに対してクエリを実行します。 ただし、サポートされているすべての形式のアプリケーションに対してクエリを実行する場合は、 IWMDMDevice3::GetProperty を呼び出し、g_wszWMDMFormatsSupportedを渡して完全なリストを取得できます。

デバイスが 1 つの要素 (WMDM_FORMATCODE_UNDEFINED) のみを返す場合、これは通常、デバイスがフォーマット コードをサポートしていないことを意味します。 WMDM_FORMATCODE_UNDEFINEDを使用して GetFormatCapability を呼び出すと機能が取得される場合がありますが、これらのプロパティはかなり汎用的な場合があります (名前、ファイル サイズ、最終変更日など)。

次の手順では、サポートされているすべての形式の一覧を照会する方法を示します。

  1. IWMDMDevice3::GetProperty を呼び出し、g_wszWMDMFormatsSupported渡すことによってサポートされているすべての書式コードの一覧を要求します。 これにより、サポートされている形式の SAFEARRAY を含む PROPVARIANT が返されます。
  2. SafeArrayGetElement を呼び出して要素をループします。 各要素は 、WMDM_FORMATCODE 列挙体です。
  3. 各形式の機能を要求し、一度実行した 各WMDM_FORMAT_CAPABILITY 要素のメモリを解放します。
  4. PropVariantClear を呼び出して、手順 1 で取得した PROPVARIANT をクリアします。

次の C++ コード例では、デバイスでサポートされている形式の一覧を取得します。

// Query a device for supported configurations for each media or format type. 
HRESULT CWMDMController::GetCaps(IWMDMDevice3* pDevice)
{
    HRESULT hr = S_OK;

    // Request the "formats supported" property to get a list of supported formats.
    PROPVARIANT pvFormatsSupported;
    PropVariantInit(&pvFormatsSupported);
    hr = pDevice->GetProperty(g_wszWMDMFormatsSupported, &pvFormatsSupported);
    HANDLE_HR(hr, "Got a property list in GetCaps", "Couldn't get a property list in GetCaps.");

    // Loop through the retrieved format list.
    // For each format, get a list of format configurations.
    SAFEARRAY* formatList = pvFormatsSupported.parray;
    WMDM_FORMATCODE formatCode = WMDM_FORMATCODE_NOTUSED;
    for (LONG iCap = 0; iCap < formatList->rgsabound[0].cElements; iCap++)
    { 
        // Get a format from the SAFEARRAY of retrieved formats.
        SafeArrayGetElement(formatList, &iCap, &formatCode);

        // Call a custom function to request the format capabilities.
        if (formatCode != WMDM_FORMATCODE_NOTUSED)
            myGetFormatCaps(formatCode, pDevice);
    }

e_Exit:
    // Clear out the memory we used.
    PropVariantClear(&pvFormatsSupported);
    return hr;
}

デバイス形式機能の検出