다음을 통해 공유


인코더에서 데이터 처리

인코더 미디어 형식 협상에 설명된 대로 인코더 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 멤버에는 0이 포함됩니다. 인코더에서 출력 버퍼를 할당해야 하는 경우 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 인코더