Uncompressed Audio Media Types
To create a complete uncompressed audio type, set at least the following attributes on the IMFMediaType interface pointer.
Attribute | Description |
---|---|
MF_MT_MAJOR_TYPE | Major type. Set to MFMediaType_Audio. |
MF_MT_SUBTYPE | Subtype. See Audio Subtype GUIDs. |
MF_MT_AUDIO_NUM_CHANNELS | Number of audio channels. |
MF_MT_AUDIO_SAMPLES_PER_SECOND | Number of audio samples per second. |
MF_MT_AUDIO_BLOCK_ALIGNMENT | Block alignment. |
MF_MT_AUDIO_AVG_BYTES_PER_SECOND | Average number of bytes per second. |
MF_MT_AUDIO_BITS_PER_SAMPLE | Number of bits per audio sample. |
MF_MT_ALL_SAMPLES_INDEPENDENT | Specifies whether each audio sample is independent. Set to TRUE for MFAudioFormat_PCM and MFAudioFormat_Float formats. |
In addition, the following attributes are required for some audio formats.
Attribute | Description |
---|---|
MF_MT_AUDIO_VALID_BITS_PER_SAMPLE | Number of valid bits of audio data in each audio sample. Set this attribute if the audio samples have padding—that is, if the number of valid bits in each audio sample is less than the sample size. |
MF_MT_AUDIO_CHANNEL_MASK | The assignment of audio channels to speaker positions. Set this attribute for multichannel audio streams, such as 5.1. This attribute is not required for mono or stereo audio. |
Example Code
The following code shows how to create a media type for uncompressed PCM audio.
HRESULT CreatePCMAudioType(
UINT32 sampleRate, // Samples per second
UINT32 bitsPerSample, // Bits per sample
UINT32 cChannels, // Number of channels
IMFMediaType **ppType // Receives a pointer to the media type.
)
{
HRESULT hr = S_OK;
IMFMediaType *pType = NULL;
// Calculate derived values.
UINT32 blockAlign = cChannels * (bitsPerSample / 8);
UINT32 bytesPerSecond = blockAlign * sampleRate;
// Create the empty media type.
hr = MFCreateMediaType(&pType);
if (FAILED(hr))
{
goto done;
}
// Set attributes on the type.
hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
if (FAILED(hr))
{
goto done;
}
hr = pType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
if (FAILED(hr))
{
goto done;
}
hr = pType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, cChannels);
if (FAILED(hr))
{
goto done;
}
hr = pType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, sampleRate);
if (FAILED(hr))
{
goto done;
}
hr = pType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, blockAlign);
if (FAILED(hr))
{
goto done;
}
hr = pType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, bytesPerSecond);
if (FAILED(hr))
{
goto done;
}
hr = pType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, bitsPerSample);
if (FAILED(hr))
{
goto done;
}
hr = pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
if (FAILED(hr))
{
goto done;
}
// Return the type to the caller.
*ppType = pType;
(*ppType)->AddRef();
done:
SafeRelease(&pType);
return hr;
}
The next example takes an encoded audio format as input, and creates a matching PCM audio type. This type would be suitable to set on an encoder or decoder, for example.
//-------------------------------------------------------------------
// ConvertAudioTypeToPCM
//
// Given an audio media type (which might describe a compressed audio
// format), returns a media type that describes the equivalent
// uncompressed PCM format.
//-------------------------------------------------------------------
HRESULT ConvertAudioTypeToPCM(
IMFMediaType *pType, // Pointer to an encoded audio type.
IMFMediaType **ppType // Receives a matching PCM audio type.
)
{
HRESULT hr = S_OK;
GUID majortype = { 0 };
GUID subtype = { 0 };
UINT32 cChannels = 0;
UINT32 samplesPerSec = 0;
UINT32 bitsPerSample = 0;
hr = pType->GetMajorType(&majortype);
if (FAILED(hr))
{
return hr;
}
if (majortype != MFMediaType_Audio)
{
return MF_E_INVALIDMEDIATYPE;
}
// Get the audio subtype.
hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype);
if (FAILED(hr))
{
return hr;
}
if (subtype == MFAudioFormat_PCM)
{
// This is already a PCM audio type. Return the same pointer.
*ppType = pType;
(*ppType)->AddRef();
return S_OK;
}
// Get the sample rate and other information from the audio format.
cChannels = MFGetAttributeUINT32(pType, MF_MT_AUDIO_NUM_CHANNELS, 0);
samplesPerSec = MFGetAttributeUINT32(pType, MF_MT_AUDIO_SAMPLES_PER_SECOND, 0);
bitsPerSample = MFGetAttributeUINT32(pType, MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
// Note: Some encoded audio formats do not contain a value for bits/sample.
// In that case, use a default value of 16. Most codecs will accept this value.
if (cChannels == 0 || samplesPerSec == 0)
{
return MF_E_INVALIDTYPE;
}
// Create the corresponding PCM audio type.
hr = CreatePCMAudioType(samplesPerSec, bitsPerSample, cChannels, ppType);
return hr;
}
Related topics