Compartir a través de


Procesamiento de datos en el codificador

Después de haber negociado el tipo de entrada y el tipo de salida para el codificador MFT, como se describe en Negociación de tipos de medios en el codificador, puede empezar a procesar muestras de datos multimedia. Los datos se pasan en forma de muestras de medios (interfaz IMFSample ) y también se reciben de la salida como muestras de medios.

Antes de enviar datos al codificador para su procesamiento, debe asignar un ejemplo multimedia y agregar uno de más búferes multimedia que contienen datos multimedia que deben codificarse. Llame a IMFTransform::P rocessInput y pase un puntero a la muestra de medios asignada. Además del ejemplo multimedia, ProcessInput también necesita el identificador de flujo de entrada. Para obtener el identificador de flujo, llame a IMFTransform::GetStreamIDs. Dado que un codificador está diseñado para tener solo una y una salida, estos identificadores de secuencia siempre tienen el valor 0.

Para obtener datos del codificador, llame a IMFTransform::P rocessOutput. Antes de llamar a ProcessOutput, debe averiguar si el codificador asigna los ejemplos de medios de salida o debe hacerlo explícitamente. Para ello, llame a IMFTransform::GetOutputStreamInfo. Esto devuelve información de ejemplo de medios de salida en la estructura MFT_OUTPUT_STREAM_INFO . Si el codificador asigna muestras multimedia, devuelve la marca MFT_OUTPUT_STREAM_PROVIDES_SAMPLES en el miembro dwFlags y el miembro cbSize contiene cero. Si el codificador espera que asigne el búfer de salida, cree el ejemplo de medios de salida y el búfer multimedia asociado en función del tamaño devuelto en cbSize. Al llamar a ProcessSample, pase un puntero al ejemplo de medios recién creado. Durante la sesión de codificación, el codificador rellena los búferes multimedia, señalados por el ejemplo de medios de salida, con los datos codificados.

Para iniciar la sesión de codificación, pase el ejemplo de medios de entrada al codificador mediante una llamada a ProcessInput. El codificador inicia el procesamiento y los datos y genera uno o varios ejemplos de medios de salida que ProcessOutput debe recuperar, siempre y cuando devuelva MF_E_TRANSFORM_NEED_MORE_INPUT. Si llama a ProcessInput para pasar más entradas siempre y cuando haya datos de salida que se van a recuperar, ProcessInput produce un error MF_E_NOTACCEPTING. El codificador no acepta ninguna entrada más hasta que el cliente llama a ProcessOutput al menos una vez.

Debe establecer marcas de tiempo y duraciones precisas para todas las muestras de entrada pasadas. Las marcas de tiempo no son estrictamente necesarias, pero ayudan a mantener la sincronización de audio/vídeo. Si no tiene las marcas de tiempo para las muestras, es mejor dejarlos fuera que usar valores no seguros.

Ejemplo de procesamiento del codificador

En el código de ejemplo siguiente se muestra cómo llamar a IMFTransform::P rocessOutput para obtener un ejemplo codificado. Para obtener el contexto completo de este ejemplo, consulte Código de ejemplo del 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

Creación de instancias de un codificador MFT

Codificadores de Windows Media