인코더에서 데이터 처리
인코더의 미디어 형식 협상에 설명된 대로 인코더 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;
};
관련 항목