Obtendo recursos de formato por meio de IWMDMDevice3
IWMDMDevice3::GetFormatCapability é o método preferencial para perguntar a um dispositivo quais formatos ele dá suporte. As etapas a seguir mostram como usar esse método para consultar um dispositivo para seus recursos de formato:
- O aplicativo deve determinar quais formatos um dispositivo dá suporte e quais são de interesse. Para fazer isso, o aplicativo pode solicitar uma lista de formatos compatíveis com o dispositivo chamando IWMDMDevice3::GetProperty.
- O aplicativo percorre todos os formatos com suporte e solicita os recursos de formato de um dispositivo para um formato específico (como WMA ou WMV) chamando IWMDMDevice3::GetFormatCapability e especificando um formato usando a enumeração WMDM_FORMATCODE . Esse método recupera uma estrutura de WMDM_FORMAT_CAPABILITY .
- Passe o loop por todas as estruturas de WMDM_PROP_CONFIG na estrutura de WMDM_FORMAT_CAPABILITY recuperada. Cada estrutura WMDM_PROP_CONFIG contém um grupo de propriedades com valores com suporte, representando uma configuração para esse formato. Cada configuração tem um número de preferência, em que um número menor indica uma preferência maior pelo dispositivo.
- Passe o loop por todas as estruturas de WMDM_PROP_DESC no WMDM_PROP_CONFIG recuperado. Cada WMDM_PROP_DESC contém uma lista de pares de propriedade/valor com suporte.
- Recupere os nomes de propriedade e os valores da estrutura WMDM_PROP_DESC . As propriedades incluem taxa de bits, codec e tamanho do quadro. Os nomes de propriedade são definidos no arquivo de cabeçalho mswmdm.h; uma lista da maioria dessas constantes é fornecida em Constantes de Metadados. Três tipos de valores de propriedade são possíveis:
- Um único valor, WMDM_ENUM_PROP_VALID_VALUES_ANY, indicando suporte para quaisquer valores para essa propriedade.
- Um intervalo de valores, definido por um valor máximo, um valor mínimo e um intervalo.
- Uma lista de valores discretos.
- Limpe os valores armazenados. A memória para esses valores é alocada pelo Windows Media Gerenciador de Dispositivos; seu dispositivo é responsável por liberar a memória. Como fazer isso é descrito no final deste tópico.
Ao responder a GetFormatCapability, um dispositivo pode relatar WMDM_ENUM_PROP_VALID_VALUES_ANY para WMDM_FORMAT_CAPABILITY. WMDM_PROP_CONFIG. WMDM_PROP_DESC. ValidValuesForm para solicitar suporte para quaisquer valores para taxa de bits, canais e assim por diante. No entanto, você deve tratar essa declaração com cuidado, pois os dispositivos às vezes podem relatar suporte para quaisquer valores quando, na verdade, eles não dão suporte a todas as taxas de bits ou tamanhos de imagem. Você pode considerar que seu aplicativo transcodifica arquivos extremamente grandes ou de alta taxa de bits para versões menores ou versões menos intensivas em memória e com uso intensivo de CPU ao enviá-los para dispositivos destinados a reproduzir esses arquivos.
A função C++ a seguir mostra como solicitar suporte ao formato de dispositivo para um formato específico.
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;
}
Limpar memória alocada
Depois de recuperar recursos de formato de um dispositivo, o aplicativo deve liberar a memória alocada para manter a descrição. GetFormatSupport e GetFormatSupport2 têm matrizes de estruturas simples que podem ser desmarcadas simplesmente chamando CoTaskMemFree com a matriz . No entanto, GetFormatCapability tem uma estrutura de dados mais complexa com memória alocada dinamicamente que deve ser limpa por loop de todos os elementos e liberando-os individualmente.
O código C++ a seguir mostra como um aplicativo pode liberar a memória alocada para uma estrutura de 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;
}
Consultando todos os formatos com suporte
Normalmente, um aplicativo consulta um dispositivo para um formato específico, pois ele está interessado em enviar um arquivo específico para o dispositivo. No entanto, se você quiser consultar um aplicativo para todos os seus formatos com suporte, poderá chamar IWMDMDevice3::GetProperty e passar g_wszWMDMFormatsSupported para recuperar uma lista completa.
Se um dispositivo retornar apenas um elemento, WMDM_FORMATCODE_UNDEFINED, isso geralmente significa que o dispositivo não dá suporte a códigos de formato. Chamar GetFormatCapability com WMDM_FORMATCODE_UNDEFINED pode recuperar recursos, mas essas propriedades podem ser bastante genéricas (como nome, tamanho do arquivo, data da última modificação e assim por diante).
As etapas a seguir mostram como consultar uma lista de todos os formatos com suporte:
- Solicite uma lista de todos os códigos de formato com suporte chamando IWMDMDevice3::GetProperty e passando g_wszWMDMFormatsSupported. Isso retorna um PROPVARIANT que contém um SAFEARRAY de formatos com suporte.
- Faça loop pelos elementos chamando SafeArrayGetElement. Cada elemento é uma enumeração WMDM_FORMATCODE .
- Solicite os recursos para cada formato, liberando a memória de cada elemento WMDM_FORMAT_CAPABILITY uma vez feito com ele.
- Limpe o PROPVARIANT recuperado na etapa 1 chamando PropVariantClear.
O código de exemplo C++ a seguir recupera uma lista de formatos com suporte para um dispositivo.
// 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;
}
Tópicos relacionados