在編碼器中處理資料

在您交涉編碼器 MFT 的輸入類型和輸出類型之後,如 編碼器上的媒體類型交涉中所述,您可以開始處理媒體資料範例。 資料會以媒體範例的形式傳遞, (IMFSample 介面) ,也會從輸出收到作為媒體樣本。

將資料傳送至編碼器進行處理之前,您必須配置媒體範例,並新增一個包含需要編碼之媒體資料的多個媒體緩衝區。 呼叫 IMFTransform::P rocessInput ,並將指標傳遞至配置的媒體範例。 除了媒體範例之外, ProcessInput 也需要輸入資料流程識別碼。 若要取得資料流程識別碼,請呼叫 IMFTransform::GetStreamIDs。 因為編碼器的設計只有一個和一個輸出,所以這些資料流程識別碼一律具有 0 的值。

若要從編碼器取得資料,請呼叫 IMFTransform::P rocessOutput。 在呼叫 ProcessOutput之前,您必須瞭解編碼器是否配置輸出媒體範例,或者您必須明確執行此動作。 若要這樣做,請呼叫 IMFTransform::GetOutputStreamInfo。 這會傳回 MFT_OUTPUT_STREAM_INFO 結構中的輸出媒體範例資訊。 如果編碼器配置媒體樣本,它會傳回 dwFlags 成員中的MFT_OUTPUT_STREAM_PROVIDES_SAMPLES旗標, 而 cbSize 成員包含零。 如果編碼器需要您配置輸出緩衝區,請根據 cbSize中傳回的大小建立輸出媒體範例和相關聯的媒體緩衝區。 當您呼叫 ProcessSample時,請將指標傳遞至新建立的媒體範例。 在編碼會話期間,編碼器會以編碼的資料填入輸出媒體範例所指向的媒體緩衝區。

若要啟動編碼會話,請呼叫 ProcessInput,將輸入媒體範例傳遞至編碼器。 編碼器會開始處理和資料,並產生一或多個輸出媒體範例,只要其傳回MF_E_TRANSFORM_NEED_MORE_INPUT, ProcessOutput 就必須擷取這些輸出媒體範例。 如果您呼叫 ProcessInput 以傳遞更多輸入,只要有要擷取的輸出資料, ProcessInput 就會失敗並產生MF_E_NOTACCEPTING。 除非用戶端至少呼叫 ProcessOutput 一次,否則編碼器不會再接受任何輸入。

您應該為所有傳遞的輸入樣本設定精確的時間戳記和持續時間。 時間戳記並非絕對必要,但有助於維護音訊/視訊同步處理。 如果您沒有範例的時間戳記,最好不要使用不確定的值。

編碼器處理範例

下列範例程式碼示範如何呼叫 IMFTransform::P rocessOutput 以取得編碼的範例。 如需此範例的完整內容,請參閱 編碼器範例程式碼

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 多工器

具現化編碼器 MFT

Windows 媒體編碼器