Supporting Rendering Profiles
An audio or video device may support specific rendering profiles. For example, an audio streaming device may stream a particular type of content at a specific bitrate over multiple channels. The content type, streaming bitrate, and channel count are referred to as a rendering profile.
WPD applications will often retrieve a rendering profile from the driver. For more information about how an application retrieves a rendering profile, see the Retrieving the Rendering Capabilities Supported by a Device topic in the WPD SDK.
This topic describes how the WpdWudfSampleDriver driver implements support for audio streaming in the Helpers.cpp module.
When an application requests a rendering profile, the driver receives a WPD_COMMAND_OBJECT_PROPERTIES_GET command with a command category of WPD_CATEGORY_OBJECT_PROPERTIES and a WPD_PROPERTY_OBJECT_PROPERTIES_OBJECT_ID of RenderingInformation. In the sample driver, the receipt of this command triggers a call to the SetRenderingProfile function in the Helpers.cpp module.
HRESULT SetRenderingProfiles(
IPortableDeviceValues* pValues)
{
HRESULT hr = S_OK;
CComPtr<IPortableDeviceValues> pPreferredProfile;
CComPtr<IPortableDeviceValues> pProfile2;
CComPtr<IPortableDeviceValuesCollection> pProfiles;
if(pValues == NULL)
{
hr = E_POINTER;
CHECK_HR(hr, ("Cannot have NULL parameter"));
return hr;
}
// Create the collection to hold the profiles
if (hr == S_OK)
{
hr = CoCreateInstance(CLSID_PortableDeviceValuesCollection,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPortableDeviceValuesCollection,
(VOID**) &pProfiles);
CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDeviceValuesCollection");
}
// Get the preferred audio profile
if (hr == S_OK)
{
hr = GetPreferredAudioProfile(&pPreferredProfile);
CHECK_HR(hr, "Failed to get preferred audio profile properties");
}
// Add the profile
if (hr == S_OK)
{
hr = pProfiles->Add(pPreferredProfile);
CHECK_HR(hr, "Failed to add preferred audio profile to profile collection");
}
// Get the second audio profile
if (hr == S_OK)
{
hr = GetAudioProfile2(&pProfile2);
CHECK_HR(hr, "Failed to get second audio profile properties");
}
// Add the profile
if (hr == S_OK)
{
hr = pProfiles->Add(pProfile2);
CHECK_HR(hr, "Failed to add second audio profile to profile collection");
}
// Set the WPD_RENDERING_INFORMATION_PROFILES
if (hr == S_OK)
{
hr = pValues->SetIPortableDeviceValuesCollectionValue(WPD_RENDERING_INFORMATION_PROFILES, pProfiles);
CHECK_HR(hr, "Failed to set WPD_RENDERING_INFORMATION_PROFILES");
}
return hr;
}
The SetRenderingProfiles function, in turn, calls the GetPreferredAudioProfile helper function, which returns the actual profile information in an IPortableDeviceValues object.
HRESULT GetPreferredAudioProfile(
IPortableDeviceValues** ppProfile)
{
HRESULT hr = S_OK;
CComPtr<IPortableDeviceValues> pProfile;
if(ppProfile == NULL)
{
hr = E_POINTER;
CHECK_HR(hr, ("Cannot have NULL parameter"));
return hr;
}
if (hr == S_OK)
{
hr = CoCreateInstance(CLSID_PortableDeviceValues,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPortableDeviceValues,
(VOID**) &pProfile);
CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDeviceValues");
}
// Set the value for WPD_OBJECT_FORMAT to indicate this profile applies to WMA objects
if (hr == S_OK)
{
hr = pProfile->SetGuidValue(WPD_OBJECT_FORMAT, WPD_OBJECT_FORMAT_WMA);
CHECK_HR(hr, "Failed to set WPD_OBJECT_FORMAT");
}
// Set the preferred value for WPD_MEDIA_TOTAL_BITRATE
if (hr == S_OK)
{
hr = pProfile->SetUnsignedIntegerValue(WPD_MEDIA_TOTAL_BITRATE, 192000);
CHECK_HR(hr, "Failed to set WPD_MEDIA_TOTAL_BITRATE");
}
// Set the preferred value for WPD_AUDIO_CHANNEL_COUNT
if (hr == S_OK)
{
hr = pProfile->SetUnsignedIntegerValue(WPD_AUDIO_CHANNEL_COUNT, 2);
CHECK_HR(hr, "Failed to set WPD_AUDIO_CHANNEL_COUNT");
}
// Set the preferred value for WPD_AUDIO_FORMAT_CODE
if (hr == S_OK)
{
hr = pProfile->SetUnsignedIntegerValue(WPD_AUDIO_FORMAT_CODE, WAVE_FORMAT_MSAUDIO3);
CHECK_HR(hr, "Failed to set WPD_AUDIO_FORMAT_CODE");
}
// Set the output result
if (hr == S_OK)
{
hr = pProfile->QueryInterface(IID_PPV_ARGS(ppProfile));
CHECK_HR(hr, "Failed to QI for IPortableDeviceValues");
}
return hr;
}
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for