Получение возможностей формата с помощью IWMDMDevice3
IWMDMDevice3::GetFormatCapability — это предпочтительный метод для запроса устройства о поддерживаемых форматах. В следующем показано, как использовать этот метод для запроса устройства о его возможностях формата.
- Приложение должно определить форматы, поддерживаемые устройством и которые являются интересующими. Для этого приложение может запросить список форматов, поддерживаемых устройством, вызвав IWMDMDevice3::GetProperty.
- Приложение выполняет циклы по всем поддерживаемым форматам и запрашивает возможности формата устройства для определенного формата (например, WMA или WMV), вызывая IWMDMDevice3::GetFormatCapability и указывая формат с помощью перечисления WMDM_FORMATCODE. Этот метод извлекает WMDM_FORMAT_CAPABILITY структуру.
- Прокрутите все структуры WMDM_PROP_CONFIG в полученной WMDM_FORMAT_CAPABILITY структуре. Каждая WMDM_PROP_CONFIG структура содержит группу свойств с поддерживаемыми значениями, представляющую одну конфигурацию для этого формата. Каждая конфигурация имеет номер предпочтения, где меньшее число указывает на большее предпочтение устройства.
- Прокрутить все WMDM_PROP_DESC структуры в полученном WMDM_PROP_CONFIG. Каждый WMDM_PROP_DESC содержит список поддерживаемых пар свойств и значений.
- Извлеките имена и значения свойств из структуры WMDM_PROP_DESC. Свойства включают скорость, кодек и размер кадра. Имена свойств определяются в файле заголовка mswmdm.h; список большинства этих констант приводится в разделе Константы метаданных. Возможны три типа значений свойств:
- Одно значение, WMDM_ENUM_PROP_VALID_VALUES_ANY, указывающее поддержку любых значений этого свойства.
- Диапазон значений, определенный максимальным значением, минимальным значением и интервалом.
- Список дискретных значений.
- Снимите сохраненные значения. Память для этих значений выделяется диспетчером устройств 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 может вернуть возможности, но эти свойства все же могут быть довольно общими (например, имя, размер файла, дата последнего изменения и т. д.).
Ниже показано, как запросить список всех поддерживаемых форматов:
- Запросите список всех кодов формата, поддерживаемых вызовом IWMDMDevice3::GetProperty и передав g_wszWMDMFormatsSupported. Это возвращает PROPVARIANT, содержащий SAFEARRAY поддерживаемых форматов.
- Выполните цикл по элементам, вызвав SafeArrayGetElement. Каждый элемент является перечислением WMDM_FORMATCODE.
- Запросите возможности для каждого формата, освобождая память для каждого элемента WMDM_FORMAT_CAPABILITY после завершения работы с ним.
- Очистите 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;
}
Связанные разделы