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

Multiplexador ASF

Instanciando um codificador MFT

Codificadores do Windows Media