Condividi tramite


Elaborazione dei dati nel codificatore

Dopo aver negoziato il tipo di input e il tipo di output per il codificatore MFT, come descritto in Negoziazione tipo di supporto nel codificatore, è possibile avviare l'elaborazione di esempi di dati multimediali. I dati vengono passati sotto forma di campioni multimediali (interfaccia FMSample ) e ricevuti anche dall'output come campioni multimediali.

Prima di inviare dati al codificatore per l'elaborazione, è necessario allocare un esempio multimediale e aggiungere uno di più buffer multimediali contenenti dati multimediali che devono essere codificati. Chiamare FMTransform::P rocessInput e passare un puntatore all'esempio di supporto allocato. Oltre all'esempio multimediale, ProcessInput richiede anche l'identificatore del flusso di input. Per ottenere l'identificatore di flusso, chiamare FMTransform::GetStreamIDs. Poiché un codificatore è progettato per avere solo uno e un output, questi identificatori di flusso hanno sempre il valore 0.

Per ottenere dati dal codificatore, chiamare FMTransform::P rocessOutput. Prima di chiamare ProcessOutput, è necessario scoprire se il codificatore alloca gli esempi di supporti di output o è necessario farlo in modo esplicito. A tale scopo, chiamare FMTransform::GetOutputStreamInfo. In questo modo vengono restituite informazioni di esempio di supporto di output nella struttura MFT_OUTPUT_STREAM_INFO . Se il codificatore alloca esempi multimediali, restituisce il flag MFT_OUTPUT_STREAM_PROVIDES_SAMPLES nel membro dwFlags e il membro cbSize contiene zero. Se il codificatore prevede di allocare il buffer di output, creare l'esempio di supporto di output e il buffer multimediale associato in base alle dimensioni restituite in cbSize. Quando si chiama ProcessSample, passare un puntatore all'esempio di supporto appena creato. Durante la sessione di codifica, il codificatore riempie i buffer multimediali, puntati dall'esempio di supporto di output, con i dati codificati.

Per avviare la sessione di codifica, passare l'esempio di supporto di input al codificatore chiamando ProcessInput. Il codificatore avvia l'elaborazione e i dati e genera uno o più esempi di supporti di output che devono essere recuperati da ProcessOutput , purché restituisca MF_E_TRANSFORM_NEED_MORE_INPUT. Se si chiama ProcessInput per passare più input, purché siano presenti dati di output da recuperare, ProcessInput ha esito negativo con MF_E_NOTACCEPTING. Il codificatore non accetta più input finché il client chiama ProcessOutput almeno una volta.

È necessario impostare timestamp e durate accurati per tutti gli esempi di input passati. I timestamp non sono strettamente necessari, ma consentono di mantenere la sincronizzazione audio/video. Se non si hanno i timestamp per gli esempi, è preferibile lasciarli fuori che usare valori incerti.

Esempio di elaborazione del codificatore

Il codice di esempio seguente illustra come chiamare FMTransform::P rocessOutput per ottenere un esempio codificato. Per il contesto completo di questo esempio, vedere Codice di esempio del codificatore.

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

ASF Multiplexer

Creazione di un'istanza di un codificatore MFT

Codificatori di Windows Media