Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Depois de negociar o tipo de entrada e o tipo de saída para o codificador MFT, conforme descrito em Negociação de tipo de mídia no codificador, pode começar a processar amostras de dados de mídia. Os dados são passados na forma de amostras de mídia (interface IMFSample) e também recebidos da saída como amostras de mídia.
Antes de enviar dados para o codificador para processamento, você deve alocar uma amostra de mídia e adicionar um ou mais buffers de mídia contendo dados de mídia que precisam ser codificados. Chame IMFTransform::ProcessInput e passe um ponteiro para a amostra de mídia alocada. Além da amostra de mídia, o ProcessInput também precisa do identificador do fluxo de entrada. Para obter o identificador de fluxo, chame IMFTransform::GetStreamIDs. Como um codificador é projetado para ter apenas uma saída, esses identificadores de fluxo sempre têm o valor de 0.
Para obter dados do encoder, chame IMFTransform::ProcessOutput. Antes de chamar ProcessOutput, você precisa descobrir se o codificador aloca as amostras de mídia de saída ou se você deve fazê-lo explicitamente. Para fazer isso, chame IMFTransform::GetOutputStreamInfo. Isto retorna informações sobre o exemplo de mídia de saída na estrutura MFT_OUTPUT_STREAM_INFO. Se o codificador alocar amostras de dados multimédia, ele retorna o sinalizador MFT_OUTPUT_STREAM_PROVIDES_SAMPLES no membro dwFlags e o membro cbSize contém zero. Se o codificador espera que você aloque o buffer de saída, crie a amostra de mídia de saída e o buffer de mídia associado com base no tamanho retornado em cbSize. Quando você chama ProcessSample, passe um ponteiro para o exemplo de mídia recém-criado. Durante a sessão de codificação, o codificador preenche os buffers de mídia, apontados pela amostra de mídia de saída, com os dados codificados.
Para iniciar a sessão de codificação, passe o exemplo de mídia de entrada para o codificador chamando ProcessInput. O codificador inicia o processamento e os dados e produz uma ou mais amostras de mídia de saída que devem ser recuperadas por ProcessOutput, desde que ele retorne MF_E_TRANSFORM_NEED_MORE_INPUT. Se chamar ProcessInput para passar mais entrada enquanto houver dados de saída para serem recuperados, ProcessInput falhará com MF_E_NOTACCEPTING. O codificador não aceita mais nenhuma entrada até que o cliente chame ProcessOutput pelo menos uma vez.
Você deve definir carimbos de data/hora e durações precisos para todas as amostras de entrada passadas. Os carimbos de data/hora não são estritamente necessários, mas ajudam a manter a sincronização de áudio/vídeo. Se você não tiver os carimbos de data/hora para suas amostras, é melhor deixá-los de fora do que usar valores incertos.
Exemplo de processamento do codificador
O código de exemplo a seguir mostra como chamar IMFTransform::P rocessOutput para obter um exemplo codificado. Para obter o contexto completo deste exemplo, consulte o exemplo de código do codificador .
HRESULT CWmaEncoder::ProcessOutput(IMFSample **ppSample)
{
if (m_pMFT == NULL)
{
return MF_E_NOT_INITIALIZED;
}
*ppSample = NULL;
IMFMediaBuffer* pBufferOut = NULL;
IMFSample* pSampleOut = NULL;
DWORD dwStatus;
MFT_OUTPUT_STREAM_INFO mftStreamInfo = { 0 };
MFT_OUTPUT_DATA_BUFFER mftOutputData = { 0 };
HRESULT hr = m_pMFT->GetOutputStreamInfo(m_dwOutputID, &mftStreamInfo);
if (FAILED(hr))
{
goto done;
}
//create a buffer for the output sample
hr = MFCreateMemoryBuffer(mftStreamInfo.cbSize, &pBufferOut);
if (FAILED(hr))
{
goto done;
}
//Create the output sample
hr = MFCreateSample(&pSampleOut);
if (FAILED(hr))
{
goto done;
}
//Add the output buffer
hr = pSampleOut->AddBuffer(pBufferOut);
if (FAILED(hr))
{
goto done;
}
//Set the output sample
mftOutputData.pSample = pSampleOut;
//Set the output id
mftOutputData.dwStreamID = m_dwOutputID;
//Generate the output sample
hr = m_pMFT->ProcessOutput(0, 1, &mftOutputData, &dwStatus);
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
{
hr = S_OK;
goto done;
}
// TODO: Handle MF_E_TRANSFORM_STREAM_CHANGE
if (FAILED(hr))
{
goto done;
}
*ppSample = pSampleOut;
(*ppSample)->AddRef();
done:
SafeRelease(&pBufferOut);
SafeRelease(&pSampleOut);
return hr;
};
Tópicos relacionados