Freigeben über


Abrufen von Formatfunktionen über IWMDMDevice3

IWMDMDevice3::GetFormatCapability ist die bevorzugte Methode, um ein Gerät zu fragen, welche Formate es unterstützt. Die folgenden Schritte zeigen, wie Sie diese Methode verwenden, um ein Gerät nach seinen Formatfunktionen abzufragen:

  1. Die Anwendung muss bestimmen, welche Formate ein Gerät unterstützt und welche von Interesse sind. Dazu kann die Anwendung eine Liste der vom Gerät unterstützten Formate anfordern, indem sie IWMDMDevice3::GetProperty aufruft.
  2. Die Anwendung durchläuft alle unterstützten Formate und fordert die Formatfunktionen eines Geräts für ein bestimmtes Format (z. B. WMA oder WMV) an, indem IWMDMDevice3::GetFormatCapability aufgerufen und ein Format mithilfe der WMDM_FORMATCODE-Enumeration angegeben wird. Diese Methode ruft eine WMDM_FORMAT_CAPABILITY-Struktur ab.
  3. Durchlaufen Sie alle WMDM_PROP_CONFIG-Strukturen in der abgerufenen WMDM_FORMAT_CAPABILITY-Struktur . Jede WMDM_PROP_CONFIG-Struktur enthält eine Gruppe von Eigenschaften mit unterstützten Werten, die eine Konfiguration für dieses Format darstellen. Jede Konfiguration verfügt über eine Einstellungsnummer, wobei eine niedrigere Zahl auf eine größere Präferenz durch das Gerät hinweist.
  4. Durchlaufen Sie alle WMDM_PROP_DESC Strukturen im abgerufenen WMDM_PROP_CONFIG. Jede WMDM_PROP_DESC enthält eine Liste der unterstützten Eigenschafts-Wert-Paare.
  5. Rufen Sie die Eigenschaftennamen und -werte aus der WMDM_PROP_DESC-Struktur ab. Zu den Eigenschaften gehören Bitrate, Codec und Framegröße. Eigenschaftennamen werden in der Headerdatei mswmdm.h definiert. Eine Liste der meisten dieser Konstanten wird unter Metadatenkonstanten angegeben. Drei Arten von Eigenschaftswerten sind möglich:
    • Ein einzelner Wert WMDM_ENUM_PROP_VALID_VALUES_ANY, der die Unterstützung für beliebige Werte für diese Eigenschaft angibt.
    • Ein Wertebereich, der durch einen Maximalwert, einen Minimalwert und ein Intervall definiert ist.
    • Eine Liste diskreter Werte.
  6. Löschen Sie die gespeicherten Werte. Der Arbeitsspeicher für diese Werte wird von Windows Media Geräte-Manager zugewiesen. Ihr Gerät ist für die Freigabe des Arbeitsspeichers verantwortlich. Dies wird am Ende dieses Themas beschrieben.

Bei der Reaktion auf GetFormatCapability kann ein Gerät WMDM_ENUM_PROP_VALID_VALUES_ANY für WMDM_FORMAT_CAPABILITY melden. WMDM_PROP_CONFIG. WMDM_PROP_DESC. ValidValuesForm , um Unterstützung für alle Werte für Bitrate, Kanäle usw. anzufordern. Sie sollten diesen Anspruch jedoch mit Vorsicht behandeln, da Geräte manchmal Unterstützung für alle Werte melden können, wenn sie tatsächlich nicht alle Bitraten oder Bildgrößen unterstützen. Beim Senden an Geräte, die diese Dateien wiedergeben sollen, können Sie in Betracht ziehen, dass Ihre Anwendung extrem große Dateien oder dateien mit hoher Bitrate in kleinere Versionen oder weniger speicherintensive und CPU-intensive Versionen transcodieren soll.

Die folgende C++-Funktion zeigt, wie Sie die Unterstützung des Geräteformats für ein bestimmtes Format anfordern.

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;
}

Löschen des zugeordneten Arbeitsspeichers

Nach dem Abrufen von Formatfunktionen von einem Gerät muss die Anwendung den für die Beschreibung zugeordneten Arbeitsspeicher freigeben. GetFormatSupport und GetFormatSupport2 verfügen über Arrays einfacher Strukturen, die durch einfaches Aufrufen von CoTaskMemFree mit dem Array gelöscht werden können. GetFormatCapability verfügt jedoch über eine komplexere Datenstruktur mit dynamisch zugeordnetem Arbeitsspeicher, der gelöscht werden muss, indem alle Elemente durchlaufen und einzeln freigegeben werden.

Der folgende C++-Code zeigt, wie eine Anwendung den für eine WMDM_FORMAT_CAPABILITY-Struktur zugewiesenen Arbeitsspeicher freigeben kann.

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;
}

Abfragen aller unterstützten Formate

In der Regel fragt eine Anwendung ein Gerät nach einem bestimmten Format ab, da sie daran interessiert ist, eine bestimmte Datei an das Gerät zu senden. Wenn Sie jedoch eine Anwendung nach allen unterstützten Formaten abfragen möchten, können Sie IWMDMDevice3::GetProperty aufrufen und g_wszWMDMFormatsSupported übergeben, um eine vollständige Liste abzurufen.

Wenn ein Gerät nur ein Element zurückgibt, WMDM_FORMATCODE_UNDEFINED, bedeutet dies in der Regel, dass das Gerät keine Formatcodes unterstützt. Das Aufrufen von GetFormatCapability mit WMDM_FORMATCODE_UNDEFINED möglicherweise Funktionen abrufen, aber diese Eigenschaften können ziemlich generisch sein (z. B. Name, Dateigröße, Datum der letzten Änderung usw.).

Die folgenden Schritte zeigen, wie Sie eine Liste aller unterstützten Formate abfragen:

  1. Fordern Sie eine Liste aller Unterstützten Formatcodes an, indem Sie IWMDMDevice3::GetProperty aufrufen und g_wszWMDMFormatsSupported übergeben. Dadurch wird eine PROPVARIANT zurückgegeben, die ein SAFEARRAY mit unterstützten Formaten enthält.
  2. Durchlaufen Sie die Elemente, indem Sie SafeArrayGetElement aufrufen. Jedes Element ist eine WMDM_FORMATCODE-Enumeration .
  3. Fordern Sie die Funktionen für jedes Format an, und geben Sie den Arbeitsspeicher für jedes WMDM_FORMAT_CAPABILITY Element frei, nachdem sie damit fertig sind.
  4. Löschen Sie den propvariant , der in Schritt 1 durch Aufrufen von PropVariantClear abgerufen wurde.

Der folgende C++-Beispielcode ruft eine Liste der unterstützten Formate für ein Gerät ab.

// 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;
}

Ermitteln von Geräteformatfunktionen