Compartir a través de


Obtención de funcionalidades de formato a través de IWMDMDevice3

IWMDMDevice3::GetFormatCapability es el método preferido para preguntar a un dispositivo qué formato admite. En los pasos siguientes se muestra cómo usar este método para consultar un dispositivo para sus funcionalidades de formato:

  1. La aplicación debe determinar qué formatos admite un dispositivo y cuáles son de interés. Para ello, la aplicación puede solicitar una lista de formatos admitidos por el dispositivo llamando a IWMDMDevice3::GetProperty.
  2. La aplicación recorre en bucle todos los formatos admitidos y solicita las funcionalidades de formato de un dispositivo para un formato específico (como WMA o WMV) llamando a IWMDMDevice3::GetFormatCapability y especificando un formato mediante la enumeración WMDM_FORMATCODE . Este método recupera una estructura WMDM_FORMAT_CAPABILITY .
  3. Recorra en bucle todas las estructuras WMDM_PROP_CONFIG de la estructura de WMDM_FORMAT_CAPABILITY recuperada. Cada estructura de WMDM_PROP_CONFIG contiene un grupo de propiedades con valores admitidos, que representa una configuración para ese formato. Cada configuración tiene un número de preferencia, donde un número menor indica una preferencia mayor por parte del dispositivo.
  4. Recorra en bucle todas las estructuras de WMDM_PROP_DESC del WMDM_PROP_CONFIG recuperado. Cada WMDM_PROP_DESC contiene una lista de pares de propiedades y valores admitidos.
  5. Recupere los nombres y valores de propiedad de la estructura WMDM_PROP_DESC . Las propiedades incluyen velocidad de bits, códec y tamaño de fotograma. Los nombres de propiedad se definen en el archivo de encabezado mswmdm.h; Una lista de la mayoría de estas constantes se da en Constantes de metadatos. Se pueden realizar tres tipos de valores de propiedad:
    • Valor único, WMDM_ENUM_PROP_VALID_VALUES_ANY, que indica la compatibilidad con los valores de esta propiedad.
    • Intervalo de valores, definido por un valor máximo, un valor mínimo e intervalo.
    • Lista de valores discretos.
  6. Borre los valores almacenados. Windows Media Administrador de dispositivos asigna memoria para estos valores; el dispositivo es responsable de liberar la memoria. Cómo hacerlo se describe al final de este tema.

Al responder a GetFormatCapability, un dispositivo puede notificar WMDM_ENUM_PROP_VALID_VALUES_ANY para WMDM_FORMAT_CAPABILITY. WMDM_PROP_CONFIG. WMDM_PROP_DESC. ValidValuesForm para reclamar compatibilidad con los valores de velocidad de bits, canales, etc. Sin embargo, debe tratar esta notificación con precaución, ya que los dispositivos a veces pueden notificar compatibilidad con los valores cuando, de hecho, no admiten todas las velocidades de bits ni los tamaños de imagen. Es posible que considere la posibilidad de que la aplicación transcodifique archivos de velocidad de bits extremadamente grandes o de alta velocidad de bits a versiones más pequeñas o con menos uso intensivo de memoria y de CPU al enviarlos a dispositivos que están diseñados para reproducir estos archivos.

La siguiente función de C++ muestra cómo solicitar compatibilidad con el formato de dispositivo para un 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;
}

Borrar la memoria asignada

Después de recuperar las funcionalidades de formato de un dispositivo, la aplicación debe liberar la memoria asignada para contener la descripción. GetFormatSupport y GetFormatSupport2 tienen matrices de estructuras simples que se pueden borrar simplemente llamando a CoTaskMemFree con la matriz. Sin embargo, GetFormatCapability tiene una estructura de datos más compleja con memoria asignada dinámicamente que se debe borrar mediante el bucle de todos los elementos y liberarlos individualmente.

El siguiente código de C++ muestra cómo una aplicación puede liberar la memoria asignada para una estructura 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;
}

Consulta de todos los formatos admitidos

Normalmente, una aplicación consulta un dispositivo para un formato específico, ya que está interesado en enviar un archivo específico al dispositivo. Sin embargo, si desea consultar una aplicación para todos sus formatos admitidos, puede llamar a IWMDMDevice3::GetProperty y pasar g_wszWMDMFormatsSupported para recuperar una lista completa.

Si un dispositivo solo devuelve un elemento, WMDM_FORMATCODE_UNDEFINED, esto suele significar que el dispositivo no admite códigos de formato. Llamar a GetFormatCapability con WMDM_FORMATCODE_UNDEFINED podría recuperar funcionalidades, pero estas propiedades podrían ser bastante genéricas (como nombre, tamaño de archivo, fecha de última modificación, etc.).

En los pasos siguientes se muestra cómo consultar una lista de todos los formatos admitidos:

  1. Solicite una lista de todos los códigos de formato admitidos llamando a IWMDMDevice3::GetProperty y pasando g_wszWMDMFormatsSupported. Esto devuelve un PROPVARIANT que contiene un SAFEARRAY de formatos admitidos.
  2. Recorra los elementos mediante una llamada a SafeArrayGetElement. Cada elemento es una enumeración WMDM_FORMATCODE .
  3. Solicite las funcionalidades de cada formato, liberando la memoria de cada elemento WMDM_FORMAT_CAPABILITY una vez hecho con él.
  4. Borre el PROPVARIANT recuperado en el paso 1 llamando a PropVariantClear.

El siguiente código de ejemplo de C++ recupera una lista de formatos admitidos para un 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;
}

Detección de funcionalidades de formato de dispositivo