다음을 통해 공유


인코더에서 데이터 처리

인코더의 미디어 형식 협상에 설명된 대로 인코더 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 인코더