Para localizar formatos de áudio
[O recurso associado a esta página, Windows Media Format 11 SDK, é um recurso herdado. Ele foi substituído por Leitor de Origem e Gravador de Coletor. O Leitor de Origem e o Gravador do Coletor foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use o Leitor de Origem e o Gravador do Coletor em vez do SDK do Windows Media Format 11, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]
O código de exemplo a seguir demonstra como encontrar um formato de áudio que corresponda aos critérios especificados. A função FindAudioFormat aceita um ponteiro para uma estrutura WAVEFORMATEX que contém o número de canais, bits por amostra e taxa de exemplo que você deseja usar. A função localiza o formato que corresponde a esses requisitos e tem a taxa de bits mais alta que não excede o parâmetro dwMaxRate . Se você definir fAVSync como TRUE, a função validará apenas formatos que podem ser sincronizados com vídeo. Para simplificar, essa função só funciona com formatos CBR de 1 passagem.
// This constant is used to determine if an index was found.
#define INVALID_INDEX 0xFFFF
// The FindAudioFormat function finds a compressed audio format that
// matches the criteria defined by the input parameters.
HRESULT FindAudioFormat(GUID SubType,
WAVEFORMATEX* pWaveLimits,
DWORD dwMaxRate,
BOOL fAVSync,
IWMStreamConfig** ppStreamConfig)
{
HRESULT hr = S_OK;
IWMProfileManager* pProfileMgr = NULL;
IWMCodecInfo3* pCodecInfo = NULL;
IWMStreamConfig* pStreamConfig = NULL;
IWMStreamConfig* pBestMatch = NULL;
IWMMediaProps* pProps = NULL;
WM_MEDIA_TYPE* pType = NULL;
DWORD cbType = 0;
WAVEFORMATEX* pWave = NULL;
DWORD index = 0;
DWORD cEntries = 0;
DWORD dwBestRate = 0;
DWORD PacketsPerSecond = 0;
// This value is beyond the codec indexes
// and will be used to verify success.
DWORD CodecIndex = INVALID_INDEX;
// Instantiate a profile manager object.
hr = WMCreateProfileManager(&pProfileMgr);
GOTO_EXIT_IF_FAILED(hr);
// Get the codec information interface.
hr = pProfileMgr->QueryInterface(IID_IWMCodecInfo3, (void**)&pCodecInfo);
GOTO_EXIT_IF_FAILED(hr);
// Get the number of audio codecs for which there is information.
hr = pCodecInfo->GetCodecInfoCount(WMMEDIATYPE_Audio, &cEntries);
GOTO_EXIT_IF_FAILED(hr);
// Find the index of the codec corresponding to the requested subytpe.
for(index = 0; index < cEntries; index++)
{
// Get the first format for each codec.
hr = pCodecInfo->GetCodecFormat(WMMEDIATYPE_Audio, index, 0, &pStreamConfig);
GOTO_EXIT_IF_FAILED(hr);
// Get the media properties interface.
hr = pStreamConfig->QueryInterface(IID_IWMMediaProps, (void**)&pProps);
GOTO_EXIT_IF_FAILED(hr);
// Get the size required for the media type structure.
hr = pProps->GetMediaType(NULL, &cbType);
GOTO_EXIT_IF_FAILED(hr);
// Allocate memory for the media type structure.
pType = (WM_MEDIA_TYPE*) new BYTE[cbType];
if(pType == NULL)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Get the media type structure.
hr = pProps->GetMediaType(pType, &cbType);
GOTO_EXIT_IF_FAILED(hr);
// Check this codec against the one requested.
if(pType->subtype == SubType)
CodecIndex = index;
// The subtypes did not match. Clean up for next iteration.
SAFE_RELEASE(pStreamConfig);
SAFE_RELEASE(pProps);
SAFE_ARRAY_DELETE(pType);
// Break now if needed. Placing the break here avoids having to
// release or delete both inside and outside of the loop.
if(CodecIndex != INVALID_INDEX)
break;
} // for index
// The subtype is invalid if no codec was found that matches it.
if(CodecIndex == INVALID_INDEX)
{
hr = E_INVALIDARG;
goto Exit;
}
// Get the number of formats supported for the codec.
hr = pCodecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio,
CodecIndex,
&cEntries);
GOTO_EXIT_IF_FAILED(hr);
// Loop through the formats for the codec, looking for matches.
for(index = 0; index < cEntries; index++)
{
// Get the next format.
hr = pCodecInfo->GetCodecFormat(WMMEDIATYPE_Audio,
CodecIndex,
index,
&pStreamConfig);
GOTO_EXIT_IF_FAILED(hr);
// Get the media properties interface.
hr = pStreamConfig->QueryInterface(IID_IWMMediaProps, (void**)&pProps);
GOTO_EXIT_IF_FAILED(hr);
// Get the size required for the media type structure.
hr = pProps->GetMediaType(NULL, &cbType);
GOTO_EXIT_IF_FAILED(hr);
// Allocate memory for the media type structure.
pType = (WM_MEDIA_TYPE*) new BYTE[cbType];
if(pType == NULL)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Get the media type structure.
hr = pProps->GetMediaType(pType, &cbType);
GOTO_EXIT_IF_FAILED(hr);
// Check that the format data is present.
if(pType->cbFormat >= sizeof(WAVEFORMATEX))
pWave = (WAVEFORMATEX*)pType->pbFormat;
else
{
// The returned media type should always have an attached
// WAVEFORMATEX structure.
hr = E_UNEXPECTED;
goto Exit;
}
// Start checking data.
// Do not check particulars unless the bit rate is in range.
if((pWave->nAvgBytesPerSec * 8) > dwBestRate &&
(pWave->nAvgBytesPerSec * 8) <= dwMaxRate)
{
// Check the limits.
if((pWave->nChannels == pWaveLimits->nChannels) &&
(pWave->wBitsPerSample == pWaveLimits->wBitsPerSample) &&
(pWave->nSamplesPerSec == pWaveLimits->nSamplesPerSec))
{
// If audio/video synchronization requested, check the number
// of packets per second (Bps / BlockAlign). The bit rate is
// greater than 3200 bps, this value must be 5.
// Otherwise this value is 3.
// This is an ASF requirement.
if(fAVSync)
{
if((pWave->nAvgBytesPerSec / pWave->nBlockAlign) >=
((pWave->nAvgBytesPerSec >= 4000) ? 5.0 : 3.0))
{
// Release the previous best match.
SAFE_RELEASE(pBestMatch);
// Set this stream configuration as the new best match.
pBestMatch = pStreamConfig;
pStreamConfig->AddRef();
// Set the best bit rate.
dwBestRate = (pWave->nAvgBytesPerSec * 8);
}
} // if fAVSync
else
{
// Release the previous best match.
SAFE_RELEASE(pBestMatch);
// Set this stream configuration as the new best match.
pBestMatch = pStreamConfig;
pStreamConfig->AddRef();
// Set the best bit rate.
dwBestRate = (pWave->nAvgBytesPerSec * 8);
} // else
} // if matching limits
} // if valid bit rate
// Clean up for next iteration.
SAFE_RELEASE(pStreamConfig);
SAFE_RELEASE(pProps);
pWave = NULL;
SAFE_ARRAY_DELETE(pType);
} // for index
// If no match was found, the arguments were not valid for the codec.
if(pBestMatch == NULL)
{
hr = E_INVALIDARG;
goto Exit;
}
// Set the pointer to the stream configuration.
*ppStreamConfig = pBestMatch;
pBestMatch = NULL;
Exit:
SAFE_RELEASE(pProfileMgr);
SAFE_RELEASE(pCodecInfo);
SAFE_RELEASE(pStreamConfig);
SAFE_RELEASE(pBestMatch);
SAFE_RELEASE(pProps);
SAFE_ARRAY_DELETE(pType);
return hr;
}
Tópicos relacionados