다음을 통해 공유


IWMDMDevice3을 통해 형식 기능 가져오기

IWMDMDevice3::GetFormatCapability 는 디바이스에서 지원하는 형식을 묻는 기본 방법입니다. 다음 단계에서는 이 메서드를 사용하여 해당 형식 기능에 대해 디바이스를 쿼리하는 방법을 보여줍니다.

  1. 애플리케이션은 디바이스가 지원하는 형식과 관심 있는 형식을 결정해야 합니다. 이를 위해 애플리케이션은 IWMDMDevice3::GetProperty를 호출하여 디바이스에서 지원하는 형식 목록을 요청할 수 있습니다.
  2. 애플리케이션은 지원되는 모든 형식을 반복하고 IWMDMDevice3::GetFormatCapability 를 호출하고 WMDM_FORMATCODE 열거형을 사용하여 형식을 지정하여 특정 형식(예: WMA 또는 WMV)에 대한 디바이스의 형식 기능을 요청합니다. 이 메서드는 WMDM_FORMAT_CAPABILITY 구조를 검색합니다.
  3. 검색된 WMDM_FORMAT_CAPABILITY 구조체의 모든 WMDM_PROP_CONFIG 구조를 반복합니다. 각 WMDM_PROP_CONFIG 구조체에는 해당 형식에 대한 하나의 구성을 나타내는 지원되는 값이 있는 속성 그룹이 있습니다. 각 구성에는 기본 설정 번호가 있습니다. 여기서 낮은 숫자는 디바이스에서 더 큰 기본 설정을 나타냅니다.
  4. 검색된 WMDM_PROP_CONFIG 모든 WMDM_PROP_DESC 구조를 반복합니다. 각 WMDM_PROP_DESC 지원되는 속성/값 쌍의 목록을 포함합니다.
  5. WMDM_PROP_DESC 구조체에서 속성 이름 및 값을 검색합니다. 속성에는 비트 속도, 코덱 및 프레임 크기가 포함됩니다. 속성 이름은 mswmdm.h 헤더 파일에 정의됩니다. 이러한 상수의 대부분은 메타데이터 상수에 제공됩니다. 다음과 같은 세 가지 유형의 속성 값이 가능합니다.
    • 이 속성에 대한 모든 값에 대한 지원을 나타내는 단일 값인 WMDM_ENUM_PROP_VALID_VALUES_ANY.
    • 최대값, 최소값 및 간격으로 정의된 값 범위입니다.
    • 불연속 값 목록입니다.
  6. 저장된 값을 지웁 수 있습니다. 이러한 값에 대한 메모리는 Windows Media 장치 관리자 할당됩니다. 디바이스는 메모리를 해제해야 합니다. 이 작업을 수행하는 방법은 이 항목의 끝에 설명되어 있습니다.

GetFormatCapability에 응답할 때 디바이스는 WMDM_FORMAT_CAPABILITY 대한 WMDM_ENUM_PROP_VALID_VALUES_ANY 보고할 수 있습니다. WMDM_PROP_CONFIG. WMDM_PROP_DESC. ValidValuesForm은 비트 전송률, 채널 등에 대한 모든 값에 대한 지원을 요청합니다. 그러나 디바이스가 실제로 모든 비트 전송률 또는 이미지 크기를 지원하지 않는 경우 경우에 따라 모든 값에 대한 지원을 보고할 수 있으므로 이 클레임을 주의해서 처리해야 합니다. 이러한 파일을 재생하기 위한 디바이스로 보낼 때 애플리케이션이 매우 크거나 높은 비트 전송률 파일을 더 작은 버전으로 변환하거나 메모리 집약적이고 CPU 집약적인 버전으로 변환하도록 고려할 수 있습니다.

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

할당된 메모리 지우기

디바이스에서 형식 기능을 검색한 후 애플리케이션은 할당된 메모리를 해제하여 설명을 보관해야 합니다. GetFormatSupportGetFormatSupport2 에는 단순히 배열을 사용하여 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 하나의 요소만 반환하는 경우 이는 일반적으로 디바이스가 형식 코드를 지원하지 않음을 의미합니다. WMDM_FORMATCODE_UNDEFINED 사용하여 GetFormatCapability 를 호출하면 기능을 검색할 수 있지만 이러한 속성은 상당히 일반적일 수 있습니다(예: 이름, 파일 크기, 마지막으로 수정한 날짜 등).

다음 단계에서는 지원되는 모든 형식 목록을 쿼리하는 방법을 보여 줍니다.

  1. IWMDMDevice3::GetProperty를 호출하고 g_wszWMDMFormatsSupported 전달하여 지원되는 모든 형식 코드 목록을 요청합니다. 지원되는 형식의 SAFEARRAY를 포함하는 PROPVARIANT를 반환합니다.
  2. SafeArrayGetElement를 호출하여 요소를 반복합니다. 각 요소는 WMDM_FORMATCODE 열거형입니다.
  3. 각 형식에 대한 기능을 요청하여 각 WMDM_FORMAT_CAPABILITY 요소에 대한 메모리를 해제합니다.
  4. PropVariantClear를 호출하여 1단계에서 검색된 PROPVARIANT를 지웁합니다.

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

디바이스 형식 기능 검색