共用方式為


在編碼器中處理數據

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

將數據傳送至編碼器進行處理之前,您必須先配置媒體範例,並新增一個包含需要編碼之媒體數據的媒體緩衝區。 呼叫 IMFTransform::ProcessInput,並將指標傳遞至已配置的媒體樣本。 除了媒體範例之外,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 Media Encoders