Processando dados no codificador
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, você pode começar a processar exemplos 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 exemplos de mídia.
Antes de enviar dados ao codificador para processamento, você deve alocar um exemplo de mídia e adicionar mais um dos buffers de mídia que contêm dados de mídia que precisam ser codificados. Chame IMFTransform::P rocessInput e passe um ponteiro para a amostra de mídia alocada. Além do exemplo de mídia, ProcessInput também precisa do identificador de fluxo de entrada. Para obter o identificador de fluxo, chame IMFTransform::GetStreamIDs. Como um codificador foi projetado para ter apenas uma e uma saída, esses identificadores de fluxo sempre têm o valor de 0.
Para obter dados do codificador, chame IMFTransform::P rocessOutput. Antes de chamar ProcessOutput, você precisa descobrir se o codificador aloca os exemplos de mídia de saída ou se você deve fazê-lo explicitamente. Para fazer isso, chame IMFTransform::GetOutputStreamInfo. Isso retorna informações de exemplo de mídia de saída na estrutura MFT_OUTPUT_STREAM_INFO . Se o codificador alocar amostras de mídia, ele retornará o sinalizador MFT_OUTPUT_STREAM_PROVIDES_SAMPLES no membro dwFlags e o membro cbSize conterá zero. Se o codificador espera que você aloque o buffer de saída, crie o exemplo de mídia de saída e o buffer de mídia associado com base no tamanho retornado em cbSize. Ao chamar 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 pelo exemplo 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 um ou mais exemplos de mídia de saída que devem ser recuperados pelo ProcessOutput , desde que retorne MF_E_TRANSFORM_NEED_MORE_INPUT. Se você chamar ProcessInput para passar mais entrada, desde que haja dados de saída a 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 todos os exemplos de entrada passados. 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 uma amostra codificada. Para obter o contexto completo deste exemplo, consulte Código de exemplo 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