Share via


透過 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 結構都會保存一組具有支援值的屬性,代表該格式的一個組態。 每個設定都有喜好設定編號,其中較低的數位表示裝置的喜好設定較大。
  4. 迴圈查看所擷取WMDM_PROP_CONFIG中的所有WMDM_PROP_DESC結構。 每個 WMDM_PROP_DESC 都包含支援的屬性/值組清單。
  5. WMDM_PROP_DESC 結構擷取屬性名稱和值。 屬性包括位元速率、編解碼器和框架大小。 屬性名稱定義于 mswmdm.h 標頭檔中;中繼資料 常數中會提供其中大部分常數的清單。 可能有三種類型的屬性值:
    • 單一值WMDM_ENUM_PROP_VALID_VALUES_ANY,表示支援此屬性的任何值。
    • 值範圍,由最大值、最小值和間隔所定義。
    • 離散值的清單。
  6. 清除預存的值。 Windows Media 裝置管理員會配置這些值的記憶體;您的裝置負責釋放記憶體。 本主題結尾會說明如何執行這項操作。

回應 GetFormatCapability時,裝置可以回報 WMDM_ENUM_PROP_VALID_VALUES_ANY WMDM_FORMAT_CAPABILITY。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 以擷取完整清單。

如果裝置只傳回一個專案,WMDM_FORMATCODE_UNDEFINED,這通常表示裝置不支援格式代碼。 使用WMDM_FORMATCODE_UNDEFINED呼叫 GetFormatCapability 可能會擷取功能,但這些屬性可能是相當泛型的 (,例如名稱、檔案大小、上次修改日期等) 。

下列步驟示範如何查詢所有支援格式的清單:

  1. 呼叫 IWMDMDevice3::GetProperty 並傳入 g_wszWMDMFormatsSupported,以要求支援的所有格式代碼清單。 這會傳回 PROPVARIANT ,其中包含支援格式的 SAFEARRAY
  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;
}

探索裝置格式功能