Conversões de tipo de mídia
Ocasionalmente, é necessário converter entre tipos de mídia do Media Foundation e as estruturas de tipo de mídia mais antigas do DirectShow ou do SDK de Formato de Mídia do Windows.
De uma estrutura de formato a um tipo de base de mídia
As funções a seguir inicializam um tipo de mídia do Media Foundation de uma estrutura de formato. Essas funções também serão úteis se um fluxo de dados ou um cabeçalho de arquivo contiver uma estrutura de formato. Por exemplo, o cabeçalho do arquivo para arquivos de áudio WAVE contém uma estrutura deWAVEFORMATEX.
Estrutura a ser convertida | Função |
---|---|
AM_MEDIA_TYPE (DirectShow) DMO_MEDIA_TYPE (objetos de mídia DirectX) WM_MEDIA_TYPE (SDK de Formato de Mídia do Windows) Observação: Essas estruturas são equivalentes. |
MFInitMediaTypeFromAMMediaType |
BITMAPINFOHEADER | MFCreateVideoMediaTypeFromBitMapInfoHeaderEx |
MFVIDEOFORMAT | MFInitMediaTypeFromMFVideoFormat |
MPEG1VIDEOINFO | MFInitMediaTypeFromMPEG1VideoInfo |
MPEG2VIDEOINFO | MFInitMediaTypeFromMPEG2VideoInfo |
VIDEOINFOHEADER2 | MFInitMediaTypeFromVideoInfoHeader2 |
VIDEOINFOHEADER | MFInitMediaTypeFromVideoInfoHeader |
WAVEFORMATEX ouWAVEFORMATEXTENSIBLE | MFInitMediaTypeFromWaveFormatEx |
De um tipo de fundação de mídia a uma estrutura de formato
As funções a seguir criam ou inicializam uma estrutura de formato de um tipo de mídia do Media Foundation.
Função | Estrutura de destino |
---|---|
IMFMediaType::GetRepresentation | AM_MEDIA_TYPE,MFVIDEOFORMAT, VIDEOINFOHEADER ou VIDEOINFOHEADER2 |
MFCreateAMMediaTypeFromMFMediaType | AM_MEDIA_TYPE |
MFCreateMFVideoFormatFromMFMediaType | MFVIDEOFORMAT |
MFCreateWaveFormatExFromMFMediaType | WAVEFORMATEX ouWAVEFORMATEXTENSIBLE |
MFInitAMMediaTypeFromMFMediaType | AM_MEDIA_TYPE |
Mapeamentos de formato
As tabelas a seguir listam os atributos do Media Foundation que correspondem a várias estruturas de formato. Nem todos esses atributos podem ser traduzidos diretamente. Para executar conversões, você deve usar as funções listadas na seção anterior; essas tabelas são fornecidas principalmente para referência.
AM_MEDIA_TYPE
Membro | Atributo |
---|---|
bTemporalCompression | MF_MT_ALL_SAMPLES_INDEPENDENT |
bFixedSizeSamples | MF_MT_FIXED_SIZE_SAMPLES |
lSampleSize | MF_MT_SAMPLE_SIZE |
WAVEFORMATEX, WAVEFORMATEXTENSIBLE
Membro | Atributo |
---|---|
wFormatTag |
MF_MT_SUBTYPE Se wFormatTag for WAVE_FORMAT_EXTENSIBLE, o subtipo será encontrado no membro SubFormat do. |
nChannels | MF_MT_AUDIO_NUM_CHANNELS |
nSamplesPerSec | MF_MT_AUDIO_SAMPLES_PER_SECOND |
nAvgBytesPerSec | MF_MT_AUDIO_AVG_BYTES_PER_SECOND |
nBlockAlign | MF_MT_AUDIO_BLOCK_ALIGNMENT |
wBitsPerSample | MF_MT_AUDIO_BITS_PER_SAMPLE |
wValidBitsPerSample | MF_MT_AUDIO_VALID_BITS_PER_SAMPLE |
wSamplesPerBlock | MF_MT_AUDIO_SAMPLES_PER_BLOCK |
dwChannelMask | MF_MT_AUDIO_CHANNEL_MASK |
subformatação | MF_MT_SUBTYPE |
Dados extras | MF_MT_USER_DATA |
VIDEOINFOHEADER, VIDEOINFOHEADER2
Membro | Atributo |
---|---|
dwBitRate | MF_MT_AVG_BITRATE |
dwBitErrorRate | MF_MT_AVG_BIT_ERROR_RATE |
AvgTimePerFrame | MF_MT_FRAME_RATE; use MFAverageTimePerFrameToFrameRate para calcular esse valor. |
dwInterlaceFlags | MF_MT_INTERLACE_MODE |
dwCopyProtectFlags | Nenhum equivalente definido |
dwPictAspectRatioX, dwPictAspectRatioY | MF_MT_PIXEL_ASPECT_RATIO; deve converter da taxa de proporção da imagem para a taxa de proporção da imagem. |
dwControlFlags | MF_MT_PAD_CONTROL_FLAGS. Se o sinalizador AMCONTROL_COLORINFO_PRESENT estiver presente, defina os atributos de cor estendidos descritos em informações de cor estendidas. |
bmiHeader.biWidth, bmiHeader.biHeight | MF_MT_FRAME_SIZE |
bmiHeader.biBitCount | Implícito no subtipo (MF_MT_SUBTYPE). |
bmiHeader.biCompression | Implícito no subtipo. |
bmiHeader.biSizeImage | MF_MT_SAMPLE_SIZE |
Informações da paleta | MF_MT_PALETTE |
Os atributos a seguir podem ser inferidos do VIDEOINFOHEADER ou VIDEOINFOHEADER2 estrutura, mas também exigem algum conhecimento dos detalhes do formato. Por exemplo, diferentes formatos YUV têm requisitos de passo diferentes.
MPEG1VIDEOINFO
Membro | Atributo |
---|---|
dwStartTimeCode | MF_MT_MPEG_START_TIME_CODE |
bSequenceHeader | MF_MT_MPEG_SEQUENCE_HEADER |
biXPelsPerMeter, biYPelsPerMeter | MF_MT_PIXEL_ASPECT_RATIO |
MPEG2VIDEOINFO
Membro | Atributo |
---|---|
dwStartTimeCode | MF_MT_MPEG_START_TIME_CODE |
dwSequenceHeader | MF_MT_MPEG_SEQUENCE_HEADER |
dwProfile | MF_MT_MPEG2_PROFILE |
dwLevel | MF_MT_MPEG2_LEVEL |
dwFlags | MF_MT_MPEG2_FLAGS |
Exemplos
O código a seguir preenche uma estrutura BITMAPINFOHEADER de um tipo de mídia de vídeo. Observe que essas conversões perdem algumas das informações de formato (interlacing, taxa de quadros, dados de cores estendidas). No entanto, pode ser útil ao salvar um bitmap de um quadro de vídeo, por exemplo.
#include <dshow.h>
#include <dvdmedia.h>
// Converts a video type to a BITMAPINFO structure.
// The caller must free the structure by calling CoTaskMemFree.
// Note that this conversion loses some format information, including
// interlacing, and frame rate.
HRESULT GetBitmapInfoHeaderFromMFMediaType(
IMFMediaType *pType, // Pointer to the media type.
BITMAPINFOHEADER **ppBmih, // Receives a pointer to the structure.
DWORD *pcbSize) // Receives the size of the structure.
{
*ppBmih = NULL;
*pcbSize = 0;
GUID majorType = GUID_NULL;
AM_MEDIA_TYPE *pmt = NULL;
DWORD cbSize = 0;
DWORD cbOffset = 0;
BITMAPINFOHEADER *pBMIH = NULL;
// Verify that this is a video type.
HRESULT hr = pType->GetMajorType(&majorType);
if (FAILED(hr))
{
goto done;
}
if (majorType != MFMediaType_Video)
{
hr = MF_E_INVALIDMEDIATYPE;
goto done;
}
hr = pType->GetRepresentation(AM_MEDIA_TYPE_REPRESENTATION, (void**)&pmt);
if (FAILED(hr))
{
goto done;
}
if (pmt->formattype == FORMAT_VideoInfo)
{
cbOffset = (FIELD_OFFSET(VIDEOINFOHEADER,bmiHeader));
}
else if (pmt->formattype == FORMAT_VideoInfo2)
{
cbOffset = (FIELD_OFFSET(VIDEOINFOHEADER2,bmiHeader));
}
else
{
hr = MF_E_INVALIDMEDIATYPE; // Unsupported format type.
goto done;
}
if (pmt->cbFormat - cbOffset < sizeof(BITMAPINFOHEADER))
{
hr = E_UNEXPECTED; // Bad format size.
goto done;
}
cbSize = pmt->cbFormat - cbOffset;
pBMIH = (BITMAPINFOHEADER*)CoTaskMemAlloc(cbSize);
if (pBMIH == NULL)
{
hr = E_OUTOFMEMORY;
goto done;
}
CopyMemory(pBMIH, pmt->pbFormat + cbOffset, cbSize);
*ppBmih = pBMIH;
*pcbSize = cbSize;
done:
if (pmt)
{
pType->FreeRepresentation(AM_MEDIA_TYPE_REPRESENTATION, pmt);
}
return hr;
}
Tópicos relacionados