Partilhar via


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;
};

Multiplexador ASF

Instanciando um codificador MFT

Codificadores do Windows Media