Поделиться через


Получение возможностей форматирования с помощью IWMDMDevice3

IWMDMDevice3::GetFormatCapability — это предпочтительный метод для запроса устройств, какие форматы оно поддерживает. Ниже показано, как использовать этот метод для запроса устройств на наличие возможностей форматирования.

  1. Приложение должно определить, какие форматы поддерживает устройство, а какие представляют интерес. Для этого приложение может запросить список форматов, поддерживаемых устройством, вызвав IWMDMDevice3::GetProperty.
  2. Приложение перебирает все поддерживаемые форматы и запрашивает возможности формата устройства для определенного формата (например, WMA или WMV), вызывая IWMDMDevice3::GetFormatCapability и указывая формат с помощью перечисления WMDM_FORMATCODE . Этот метод извлекает структуру WMDM_FORMAT_CAPABILITY .
  3. Просмотрите все WMDM_PROP_CONFIG структуры в полученной WMDM_FORMAT_CAPABILITY структуре. Каждая структура WMDM_PROP_CONFIG содержит группу свойств с поддерживаемыми значениями, представляющих одну конфигурацию для этого формата. Каждая конфигурация имеет номер предпочтения, где меньшее число указывает на большее предпочтение устройства.
  4. Циклическое перебирает все WMDM_PROP_DESC структуры в полученном WMDM_PROP_CONFIG. Каждый 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 для утверждения поддержки любых значений скорости, каналов и т. д. Однако к этому утверждению следует относиться с осторожностью, так как устройства иногда могут сообщать о поддержке любых значений, если на самом деле они не поддерживают все скорости передачи данных или размеры изображений. При отправке приложений на устройства, предназначенные для воспроизведения этих файлов, может потребоваться перекодировать очень большие или высокоскоростные файлы в небольшие версии или менее ресурсоемкие версии памяти и ЦП.

В следующей функции 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;
}

Очистка выделенной памяти

После получения возможностей форматирования с устройства приложение должно освободить память, выделенную для хранения описания. GetFormatSupport и GetFormatSupport2 имеют массивы простых структур, которые можно очистить, просто вызвав 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, это обычно означает, что устройство не поддерживает коды форматирования. Вызов GetFormatCapability с WMDM_FORMATCODE_UNDEFINED может получить возможности, но эти свойства могут быть довольно универсальными (например, имя, размер файла, дата последнего изменения и т. д.).

Ниже показано, как запросить список всех поддерживаемых форматов.

  1. Запросите список всех поддерживаемых кодов формата, вызвав IWMDMDevice3::GetProperty и передав g_wszWMDMFormatsSupported. При этом возвращается объект PROPVARIANT , содержащий SAFEARRAY поддерживаемых форматов.
  2. Циклическое перебор элементов путем вызова SafeArrayGetElement. Каждый элемент является перечислением WMDM_FORMATCODE .
  3. Запросите возможности для каждого формата, освободив память для каждого WMDM_FORMAT_CAPABILITY элемента после завершения работы с ним.
  4. Очистите файл PROPVARIANT , полученный на шаге 1, вызвав PropVariantClear.

В следующем примере кода 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;
}

Обнаружение возможностей формата устройства