diff options
Diffstat (limited to 'plugins/pluginWinMF/internals/mf_codec.cxx')
-rwxr-xr-x | plugins/pluginWinMF/internals/mf_codec.cxx | 1161 |
1 files changed, 538 insertions, 623 deletions
diff --git a/plugins/pluginWinMF/internals/mf_codec.cxx b/plugins/pluginWinMF/internals/mf_codec.cxx index e2968f4..27fb903 100755 --- a/plugins/pluginWinMF/internals/mf_codec.cxx +++ b/plugins/pluginWinMF/internals/mf_codec.cxx @@ -1,18 +1,18 @@ /* Copyright (C) 2013 Mamadou DIOP * Copyright (C) 2013 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -40,13 +40,13 @@ #endif // Make sure usable on Win7 SDK targeting Win8 OS -#if !defined(CODECAPI_AVLowLatencyMode) +#if !defined(CODECAPI_AVLowLatencyMode) DEFINE_GUID(CODECAPI_AVLowLatencyMode, - 0x9c27891a, 0xed7a, 0x40e1, 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee); + 0x9c27891a, 0xed7a, 0x40e1, 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee); #endif #if !defined(CODECAPI_AVDecVideoH264ErrorConcealment) DEFINE_GUID(CODECAPI_AVDecVideoH264ErrorConcealment, -0xececace8, 0x3436, 0x462c, 0x92, 0x94, 0xcd, 0x7b, 0xac, 0xd7, 0x58, 0xa9); + 0xececace8, 0x3436, 0x462c, 0x92, 0x94, 0xcd, 0x7b, 0xac, 0xd7, 0x58, 0xa9); #endif // @@ -54,117 +54,105 @@ DEFINE_GUID(CODECAPI_AVDecVideoH264ErrorConcealment, // MFCodec::MFCodec(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/) -: m_nRefCount(1) -, m_eId(eId) -, m_eType(eType) -, m_pMFT(NULL) -, m_pCodecAPI(NULL) -, m_pOutputType(NULL) -, m_pInputType(NULL) -, m_dwInputID(0) -, m_dwOutputID(0) -, m_rtStart(0) -, m_rtDuration(0) -, m_pSampleIn(NULL) -, m_pSampleOut(NULL) -, m_pEventGenerator(NULL) -, m_bIsAsync(FALSE) -, m_bIsFirstFrame(TRUE) -, m_bIsBundled(FALSE) -, m_nMETransformNeedInputCount(0) -, m_nMETransformHaveOutputCount(0) -, m_pSampleQueueAsyncInput(NULL) + : m_nRefCount(1) + , m_eId(eId) + , m_eType(eType) + , m_pMFT(NULL) + , m_pCodecAPI(NULL) + , m_pOutputType(NULL) + , m_pInputType(NULL) + , m_dwInputID(0) + , m_dwOutputID(0) + , m_rtStart(0) + , m_rtDuration(0) + , m_pSampleIn(NULL) + , m_pSampleOut(NULL) + , m_pEventGenerator(NULL) + , m_bIsAsync(FALSE) + , m_bIsFirstFrame(TRUE) + , m_bIsBundled(FALSE) + , m_nMETransformNeedInputCount(0) + , m_nMETransformHaveOutputCount(0) + , m_pSampleQueueAsyncInput(NULL) { - MFUtils::Startup(); - - HRESULT hr = S_OK; - - switch(eId) - { - case MFCodecId_H264Base: - case MFCodecId_H264Main: - { - m_eMediaType = MFCodecMediaType_Video; - m_guidCompressedFormat = MFVideoFormat_H264; - break; - } - case MFCodecId_AAC: - { - m_eMediaType = MFCodecMediaType_Audio; - m_guidCompressedFormat = MFAudioFormat_AAC; - break; - } - default: - { - assert(false); - break; - } - } - CHECK_HR(hr = MFCreateMediaType(&m_pOutputType)); - CHECK_HR(hr = MFCreateMediaType(&m_pInputType)); - if(pMFT) // up to the caller to make sure all parameters are corrrect - { - m_pMFT = pMFT; - m_pMFT->AddRef(); - } - else - { - CHECK_HR(hr = MFUtils::GetBestCodec( - (m_eType == MFCodecType_Encoder) ? TRUE : FALSE, // Encoder ? - (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio, // Media Type - (m_eType == MFCodecType_Encoder) ? kMFCodecUncompressedFormat : m_guidCompressedFormat/*GUID_NULL*/, // Input - (m_eType == MFCodecType_Encoder) ? m_guidCompressedFormat : kMFCodecUncompressedFormat, // Output - &m_pMFT)); - } - hr = m_pMFT->QueryInterface(IID_PPV_ARGS(&m_pCodecAPI)); - if(FAILED(hr) && m_eType == MFCodecType_Encoder) // Required only for Encoders - { - CHECK_HR(hr); - } - - - CHECK_HR(hr = MFUtils::IsAsyncMFT(m_pMFT, &m_bIsAsync)); - if(m_bIsAsync) - { - m_pSampleQueueAsyncInput = new MFSampleQueue(); - if(!m_pSampleQueueAsyncInput) - { - CHECK_HR(hr = E_OUTOFMEMORY); - } - CHECK_HR(hr = MFUtils::UnlockAsyncMFT(m_pMFT)); - CHECK_HR(hr = m_pMFT->QueryInterface(IID_PPV_ARGS(&m_pEventGenerator))); - } + MFUtils::Startup(); + + HRESULT hr = S_OK; + + switch(eId) { + case MFCodecId_H264Base: + case MFCodecId_H264Main: { + m_eMediaType = MFCodecMediaType_Video; + m_guidCompressedFormat = MFVideoFormat_H264; + break; + } + case MFCodecId_AAC: { + m_eMediaType = MFCodecMediaType_Audio; + m_guidCompressedFormat = MFAudioFormat_AAC; + break; + } + default: { + assert(false); + break; + } + } + CHECK_HR(hr = MFCreateMediaType(&m_pOutputType)); + CHECK_HR(hr = MFCreateMediaType(&m_pInputType)); + if(pMFT) { // up to the caller to make sure all parameters are corrrect + m_pMFT = pMFT; + m_pMFT->AddRef(); + } + else { + CHECK_HR(hr = MFUtils::GetBestCodec( + (m_eType == MFCodecType_Encoder) ? TRUE : FALSE, // Encoder ? + (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio, // Media Type + (m_eType == MFCodecType_Encoder) ? kMFCodecUncompressedFormat : m_guidCompressedFormat/*GUID_NULL*/, // Input + (m_eType == MFCodecType_Encoder) ? m_guidCompressedFormat : kMFCodecUncompressedFormat, // Output + &m_pMFT)); + } + hr = m_pMFT->QueryInterface(IID_PPV_ARGS(&m_pCodecAPI)); + if(FAILED(hr) && m_eType == MFCodecType_Encoder) { // Required only for Encoders + CHECK_HR(hr); + } + + + CHECK_HR(hr = MFUtils::IsAsyncMFT(m_pMFT, &m_bIsAsync)); + if(m_bIsAsync) { + m_pSampleQueueAsyncInput = new MFSampleQueue(); + if(!m_pSampleQueueAsyncInput) { + CHECK_HR(hr = E_OUTOFMEMORY); + } + CHECK_HR(hr = MFUtils::UnlockAsyncMFT(m_pMFT)); + CHECK_HR(hr = m_pMFT->QueryInterface(IID_PPV_ARGS(&m_pEventGenerator))); + } bail: - if(FAILED(hr)) - { - SafeRelease(&m_pMFT); - SafeRelease(&m_pCodecAPI); - } - if(!IsValid()) - { - TSK_DEBUG_ERROR("Failed to create codec with id = %d", m_eId); - } -} + if(FAILED(hr)) { + SafeRelease(&m_pMFT); + SafeRelease(&m_pCodecAPI); + } + if(!IsValid()) { + TSK_DEBUG_ERROR("Failed to create codec with id = %d", m_eId); + } +} MFCodec::~MFCodec() { - assert(m_nRefCount == 0); + assert(m_nRefCount == 0); - if(m_bIsAsync && m_pMFT) - { - m_pMFT->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, NULL); - m_pMFT->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, NULL); - } + if(m_bIsAsync && m_pMFT) { + m_pMFT->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, NULL); + m_pMFT->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, NULL); + } - SafeRelease(&m_pMFT); - SafeRelease(&m_pCodecAPI); + SafeRelease(&m_pMFT); + SafeRelease(&m_pCodecAPI); SafeRelease(&m_pOutputType); - SafeRelease(&m_pInputType); - SafeRelease(&m_pSampleIn); - SafeRelease(&m_pSampleOut); - SafeRelease(&m_pEventGenerator); - SafeRelease(&m_pSampleQueueAsyncInput); + SafeRelease(&m_pInputType); + SafeRelease(&m_pSampleIn); + SafeRelease(&m_pSampleOut); + SafeRelease(&m_pEventGenerator); + SafeRelease(&m_pSampleQueueAsyncInput); } ULONG MFCodec::AddRef() @@ -175,8 +163,7 @@ ULONG MFCodec::AddRef() ULONG MFCodec::Release() { ULONG uCount = InterlockedDecrement(&m_nRefCount); - if (uCount == 0) - { + if (uCount == 0) { delete this; } // For thread safety, return a temporary variable. @@ -185,242 +172,210 @@ ULONG MFCodec::Release() HRESULT MFCodec::QueryInterface(REFIID iid, void** ppv) { - if(!IsValid()) - { - return E_FAIL; - } - return m_pMFT->QueryInterface(iid, ppv); + if(!IsValid()) { + return E_FAIL; + } + return m_pMFT->QueryInterface(iid, ppv); } // IMFAsyncCallback STDMETHODIMP MFCodec::GetParameters(DWORD *pdwFlags, DWORD *pdwQueue) { - return E_NOTIMPL; + return E_NOTIMPL; } STDMETHODIMP MFCodec::Invoke(IMFAsyncResult *pAsyncResult) { - HRESULT hr = S_OK, hrStatus = S_OK; + HRESULT hr = S_OK, hrStatus = S_OK; IMFMediaEvent* pEvent = NULL; MediaEventType meType = MEUnknown; - + CHECK_HR(hr = m_pEventGenerator->EndGetEvent(pAsyncResult, &pEvent)); - CHECK_HR(hr = pEvent->GetType(&meType)); + CHECK_HR(hr = pEvent->GetType(&meType)); CHECK_HR(hr = pEvent->GetStatus(&hrStatus)); - if (SUCCEEDED(hrStatus)) - { - switch(meType) - { - case METransformNeedInput: - { - InterlockedIncrement(&m_nMETransformNeedInputCount); - break; - } - - case METransformHaveOutput: - { - InterlockedIncrement(&m_nMETransformHaveOutputCount); - break; - } - } - } - + if (SUCCEEDED(hrStatus)) { + switch(meType) { + case METransformNeedInput: { + InterlockedIncrement(&m_nMETransformNeedInputCount); + break; + } + + case METransformHaveOutput: { + InterlockedIncrement(&m_nMETransformHaveOutputCount); + break; + } + } + } + CHECK_HR(hr = m_pEventGenerator->BeginGetEvent(this, NULL)); bail: - SafeRelease(&pEvent); + SafeRelease(&pEvent); return hr; } HRESULT MFCodec::ProcessInput(IMFSample* pSample) { - assert(IsReady()); - - HRESULT hr = S_OK; - - if(m_bIsFirstFrame) - { - if(m_bIsAsync && !m_bIsBundled) - { - CHECK_HR(hr = m_pMFT->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, NULL)); - CHECK_HR(hr = m_pEventGenerator->BeginGetEvent(this, NULL)); - } - m_bIsFirstFrame = FALSE; - } - - if(m_bIsAsync) - { - if(m_nMETransformNeedInputCount == 1 && m_pSampleQueueAsyncInput->IsEmpty()) - { - InterlockedDecrement(&m_nMETransformNeedInputCount); - return m_pMFT->ProcessInput(m_dwInputID, pSample, 0); - } - - if(m_pSampleQueueAsyncInput->Count() > kMFCodecQueuedFramesMax) - { - m_pSampleQueueAsyncInput->Clear(); - CHECK_HR(hr = E_UNEXPECTED); - } - - // Input sample holds shared memory (also used by other samples) - IMFSample *pSampleCopy = NULL; - IMFMediaBuffer *pMediaBuffer = NULL, *pMediaBufferCopy = NULL; - BYTE *pBufferPtr = NULL, *pBufferPtrCopy = NULL; - DWORD dwDataLength = 0; - BOOL bMediaBufferLocked = FALSE, bMediaBufferLockedCopy = FALSE; - - CHECK_HR(hr = pSample->GetBufferByIndex(0, &pMediaBuffer)); - hr = pMediaBuffer->GetCurrentLength(&dwDataLength); - if(FAILED(hr)) - { - goto endofcopy; - } - hr = pMediaBuffer->Lock(&pBufferPtr, NULL, NULL); - if(FAILED(hr)) - { - goto endofcopy; - } - bMediaBufferLocked = TRUE; - - hr = MFUtils::CreateMediaSample(dwDataLength, &pSampleCopy); - if(FAILED(hr)) - { - goto endofcopy; - } - hr = pSampleCopy->GetBufferByIndex(0, &pMediaBufferCopy); - if(FAILED(hr)) - { - goto endofcopy; - } - hr = pMediaBufferCopy->Lock(&pBufferPtrCopy, NULL, NULL); - if(FAILED(hr)) - { - goto endofcopy; - } - bMediaBufferLockedCopy = TRUE; - - memcpy(pBufferPtrCopy, pBufferPtr, dwDataLength); - hr = pMediaBufferCopy->SetCurrentLength(dwDataLength); - if(FAILED(hr)) - { - goto endofcopy; - } - - LONGLONG hnsSampleTime = 0; - LONGLONG hnsSampleDuration = 0; - hr = pSample->GetSampleTime(&hnsSampleTime); - if(SUCCEEDED(hr)) - { - hr = pSampleCopy->SetSampleTime(hnsSampleTime); - } - hr = pSample->GetSampleDuration(&hnsSampleDuration); - if(SUCCEEDED(hr)) - { - hr = pSampleCopy->SetSampleDuration(hnsSampleDuration); - } - - // EnQueue - hr = m_pSampleQueueAsyncInput->Queue(pSampleCopy); + assert(IsReady()); + + HRESULT hr = S_OK; + + if(m_bIsFirstFrame) { + if(m_bIsAsync && !m_bIsBundled) { + CHECK_HR(hr = m_pMFT->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, NULL)); + CHECK_HR(hr = m_pEventGenerator->BeginGetEvent(this, NULL)); + } + m_bIsFirstFrame = FALSE; + } + + if(m_bIsAsync) { + if(m_nMETransformNeedInputCount == 1 && m_pSampleQueueAsyncInput->IsEmpty()) { + InterlockedDecrement(&m_nMETransformNeedInputCount); + return m_pMFT->ProcessInput(m_dwInputID, pSample, 0); + } + + if(m_pSampleQueueAsyncInput->Count() > kMFCodecQueuedFramesMax) { + m_pSampleQueueAsyncInput->Clear(); + CHECK_HR(hr = E_UNEXPECTED); + } + + // Input sample holds shared memory (also used by other samples) + IMFSample *pSampleCopy = NULL; + IMFMediaBuffer *pMediaBuffer = NULL, *pMediaBufferCopy = NULL; + BYTE *pBufferPtr = NULL, *pBufferPtrCopy = NULL; + DWORD dwDataLength = 0; + BOOL bMediaBufferLocked = FALSE, bMediaBufferLockedCopy = FALSE; + + CHECK_HR(hr = pSample->GetBufferByIndex(0, &pMediaBuffer)); + hr = pMediaBuffer->GetCurrentLength(&dwDataLength); + if(FAILED(hr)) { + goto endofcopy; + } + hr = pMediaBuffer->Lock(&pBufferPtr, NULL, NULL); + if(FAILED(hr)) { + goto endofcopy; + } + bMediaBufferLocked = TRUE; + + hr = MFUtils::CreateMediaSample(dwDataLength, &pSampleCopy); + if(FAILED(hr)) { + goto endofcopy; + } + hr = pSampleCopy->GetBufferByIndex(0, &pMediaBufferCopy); + if(FAILED(hr)) { + goto endofcopy; + } + hr = pMediaBufferCopy->Lock(&pBufferPtrCopy, NULL, NULL); + if(FAILED(hr)) { + goto endofcopy; + } + bMediaBufferLockedCopy = TRUE; + + memcpy(pBufferPtrCopy, pBufferPtr, dwDataLength); + hr = pMediaBufferCopy->SetCurrentLength(dwDataLength); + if(FAILED(hr)) { + goto endofcopy; + } + + LONGLONG hnsSampleTime = 0; + LONGLONG hnsSampleDuration = 0; + hr = pSample->GetSampleTime(&hnsSampleTime); + if(SUCCEEDED(hr)) { + hr = pSampleCopy->SetSampleTime(hnsSampleTime); + } + hr = pSample->GetSampleDuration(&hnsSampleDuration); + if(SUCCEEDED(hr)) { + hr = pSampleCopy->SetSampleDuration(hnsSampleDuration); + } + + // EnQueue + hr = m_pSampleQueueAsyncInput->Queue(pSampleCopy); endofcopy: - if(pMediaBuffer && bMediaBufferLocked) - { - pMediaBuffer->Unlock(); - } - if(pMediaBufferCopy && bMediaBufferLockedCopy) - { - pMediaBufferCopy->Unlock(); - } - SafeRelease(&pSampleCopy); - SafeRelease(&pMediaBuffer); - CHECK_HR(hr); - - while(m_nMETransformNeedInputCount > 0) - { - if(m_pSampleQueueAsyncInput->IsEmpty()) - { - break; - } - IMFSample *_pSample = NULL; - hr = m_pSampleQueueAsyncInput->Dequeue(&_pSample); - if(SUCCEEDED(hr)) - { - InterlockedDecrement(&m_nMETransformNeedInputCount); - hr = m_pMFT->ProcessInput(m_dwInputID, _pSample, 0); - } - SafeRelease(&_pSample); - CHECK_HR(hr); - } - } - else - { - CHECK_HR(hr = m_pMFT->ProcessInput(m_dwInputID, pSample, 0)); - } + if(pMediaBuffer && bMediaBufferLocked) { + pMediaBuffer->Unlock(); + } + if(pMediaBufferCopy && bMediaBufferLockedCopy) { + pMediaBufferCopy->Unlock(); + } + SafeRelease(&pSampleCopy); + SafeRelease(&pMediaBuffer); + CHECK_HR(hr); + + while(m_nMETransformNeedInputCount > 0) { + if(m_pSampleQueueAsyncInput->IsEmpty()) { + break; + } + IMFSample *_pSample = NULL; + hr = m_pSampleQueueAsyncInput->Dequeue(&_pSample); + if(SUCCEEDED(hr)) { + InterlockedDecrement(&m_nMETransformNeedInputCount); + hr = m_pMFT->ProcessInput(m_dwInputID, _pSample, 0); + } + SafeRelease(&_pSample); + CHECK_HR(hr); + } + } + else { + CHECK_HR(hr = m_pMFT->ProcessInput(m_dwInputID, pSample, 0)); + } bail: - return hr; + return hr; } HRESULT MFCodec::ProcessOutput(IMFSample **ppSample) { - assert(IsReady()); + assert(IsReady()); - if(m_bIsAsync) - { - if(m_nMETransformHaveOutputCount == 0) - { - return S_OK; - } - InterlockedDecrement(&m_nMETransformHaveOutputCount); - } + if(m_bIsAsync) { + if(m_nMETransformHaveOutputCount == 0) { + return S_OK; + } + InterlockedDecrement(&m_nMETransformHaveOutputCount); + } - *ppSample = NULL; + *ppSample = NULL; IMFMediaBuffer* pBufferOut = NULL; DWORD dwStatus; - HRESULT hr = S_OK; - + HRESULT hr = S_OK; + MFT_OUTPUT_STREAM_INFO mftStreamInfo = { 0 }; MFT_OUTPUT_DATA_BUFFER mftOutputData = { 0 }; - CHECK_HR(hr = m_pMFT->GetOutputStreamInfo(m_dwOutputID, &mftStreamInfo)); - - BOOL bOutputStreamProvidesSamples = (mftStreamInfo.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) == MFT_OUTPUT_STREAM_PROVIDES_SAMPLES; - - if(!bOutputStreamProvidesSamples) - { - if(!m_pSampleOut) - { - CHECK_HR(hr = MFUtils::CreateMediaSample(mftStreamInfo.cbSize, &m_pSampleOut)); - hr = m_pSampleOut->GetBufferByIndex(0, &pBufferOut); - if(FAILED(hr)) - { - SafeRelease(&m_pSampleOut); - CHECK_HR(hr); - } - } - else - { - DWORD dwMaxLength = 0; - CHECK_HR(hr = m_pSampleOut->GetBufferByIndex(0, &pBufferOut)); - CHECK_HR(hr = pBufferOut->GetMaxLength(&dwMaxLength)); - if(dwMaxLength < mftStreamInfo.cbSize) - { - CHECK_HR(hr = m_pSampleOut->RemoveAllBuffers()); - SafeRelease(&pBufferOut); - CHECK_HR(hr = MFCreateMemoryBuffer(mftStreamInfo.cbSize, &pBufferOut)); - CHECK_HR(hr = m_pSampleOut->AddBuffer(pBufferOut)); - } - } - } - - if(pBufferOut) - { - CHECK_HR(hr = pBufferOut->SetCurrentLength(0)); - } - + CHECK_HR(hr = m_pMFT->GetOutputStreamInfo(m_dwOutputID, &mftStreamInfo)); + + BOOL bOutputStreamProvidesSamples = (mftStreamInfo.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) == MFT_OUTPUT_STREAM_PROVIDES_SAMPLES; + + if(!bOutputStreamProvidesSamples) { + if(!m_pSampleOut) { + CHECK_HR(hr = MFUtils::CreateMediaSample(mftStreamInfo.cbSize, &m_pSampleOut)); + hr = m_pSampleOut->GetBufferByIndex(0, &pBufferOut); + if(FAILED(hr)) { + SafeRelease(&m_pSampleOut); + CHECK_HR(hr); + } + } + else { + DWORD dwMaxLength = 0; + CHECK_HR(hr = m_pSampleOut->GetBufferByIndex(0, &pBufferOut)); + CHECK_HR(hr = pBufferOut->GetMaxLength(&dwMaxLength)); + if(dwMaxLength < mftStreamInfo.cbSize) { + CHECK_HR(hr = m_pSampleOut->RemoveAllBuffers()); + SafeRelease(&pBufferOut); + CHECK_HR(hr = MFCreateMemoryBuffer(mftStreamInfo.cbSize, &pBufferOut)); + CHECK_HR(hr = m_pSampleOut->AddBuffer(pBufferOut)); + } + } + } + + if(pBufferOut) { + CHECK_HR(hr = pBufferOut->SetCurrentLength(0)); + } + //Set the output sample mftOutputData.pSample = bOutputStreamProvidesSamples ? NULL : m_pSampleOut; //Set the output id @@ -428,167 +383,145 @@ HRESULT MFCodec::ProcessOutput(IMFSample **ppSample) //Generate the output sample hr = m_pMFT->ProcessOutput(0, 1, &mftOutputData, &dwStatus); - if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) - { + if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { hr = S_OK; goto bail; } - if (FAILED(hr)) - { + if (FAILED(hr)) { goto bail; } *ppSample = mftOutputData.pSample; - if(*ppSample) - { - (*ppSample)->AddRef(); - } + if(*ppSample) { + (*ppSample)->AddRef(); + } bail: - if(bOutputStreamProvidesSamples) - { - SafeRelease(&mftOutputData.pSample); - } + if(bOutputStreamProvidesSamples) { + SafeRelease(&mftOutputData.pSample); + } SafeRelease(&pBufferOut); return hr; } bool MFCodec::IsValid() { - return (m_pMFT && (m_eType == MFCodecType_Decoder || m_pCodecAPI)); + return (m_pMFT && (m_eType == MFCodecType_Decoder || m_pCodecAPI)); } bool MFCodec::IsReady() { - return (IsValid() && m_pOutputType && m_pInputType); + return (IsValid() && m_pOutputType && m_pInputType); } HRESULT MFCodec::Process(const void* pcInputPtr, UINT32 nInputSize, IMFSample **ppSampleOut) { - if(!pcInputPtr || !nInputSize || !ppSampleOut) - { - TSK_DEBUG_ERROR("Invalid parameter"); - return E_INVALIDARG; - } - - *ppSampleOut = NULL; - - HRESULT hr = S_OK; - - IMFMediaBuffer* pBufferIn = NULL; - BYTE* pBufferPtr = NULL; - BOOL bMediaChangeHandled = FALSE; // Endless loop guard - - if(!m_pSampleIn) - { - CHECK_HR(hr = MFUtils::CreateMediaSample(nInputSize, &m_pSampleIn)); - hr = m_pSampleIn->GetBufferByIndex(0, &pBufferIn); - if(FAILED(hr)) - { - SafeRelease(&m_pSampleIn); - CHECK_HR(hr); - } - } - else - { - DWORD dwMaxLength = 0; - CHECK_HR(hr = m_pSampleIn->GetBufferByIndex(0, &pBufferIn)); - CHECK_HR(hr = pBufferIn->GetMaxLength(&dwMaxLength)); - if(dwMaxLength < nInputSize) - { - CHECK_HR(hr = m_pSampleIn->RemoveAllBuffers()); - SafeRelease(&pBufferIn); - CHECK_HR(hr = MFCreateMemoryBuffer(nInputSize, &pBufferIn)); - CHECK_HR(hr = m_pSampleIn->AddBuffer(pBufferIn)); - } - } - - CHECK_HR(hr = pBufferIn->Lock(&pBufferPtr, NULL, NULL)); - memcpy(pBufferPtr, pcInputPtr, nInputSize); - CHECK_HR(hr = pBufferIn->Unlock()); - CHECK_HR(hr = pBufferIn->SetCurrentLength(nInputSize)); - - if(m_eType == MFCodecType_Encoder) - { - CHECK_HR(hr = m_pSampleIn->SetSampleDuration(m_rtDuration)); - CHECK_HR(hr = m_pSampleIn->SetSampleTime(m_rtStart)); // FIXME: use clock(), Same for custom source - } + if(!pcInputPtr || !nInputSize || !ppSampleOut) { + TSK_DEBUG_ERROR("Invalid parameter"); + return E_INVALIDARG; + } + + *ppSampleOut = NULL; + + HRESULT hr = S_OK; + + IMFMediaBuffer* pBufferIn = NULL; + BYTE* pBufferPtr = NULL; + BOOL bMediaChangeHandled = FALSE; // Endless loop guard + + if(!m_pSampleIn) { + CHECK_HR(hr = MFUtils::CreateMediaSample(nInputSize, &m_pSampleIn)); + hr = m_pSampleIn->GetBufferByIndex(0, &pBufferIn); + if(FAILED(hr)) { + SafeRelease(&m_pSampleIn); + CHECK_HR(hr); + } + } + else { + DWORD dwMaxLength = 0; + CHECK_HR(hr = m_pSampleIn->GetBufferByIndex(0, &pBufferIn)); + CHECK_HR(hr = pBufferIn->GetMaxLength(&dwMaxLength)); + if(dwMaxLength < nInputSize) { + CHECK_HR(hr = m_pSampleIn->RemoveAllBuffers()); + SafeRelease(&pBufferIn); + CHECK_HR(hr = MFCreateMemoryBuffer(nInputSize, &pBufferIn)); + CHECK_HR(hr = m_pSampleIn->AddBuffer(pBufferIn)); + } + } + + CHECK_HR(hr = pBufferIn->Lock(&pBufferPtr, NULL, NULL)); + memcpy(pBufferPtr, pcInputPtr, nInputSize); + CHECK_HR(hr = pBufferIn->Unlock()); + CHECK_HR(hr = pBufferIn->SetCurrentLength(nInputSize)); + + if(m_eType == MFCodecType_Encoder) { + CHECK_HR(hr = m_pSampleIn->SetSampleDuration(m_rtDuration)); + CHECK_HR(hr = m_pSampleIn->SetSampleTime(m_rtStart)); // FIXME: use clock(), Same for custom source + } Label_ProcessInput: - hr = ProcessInput(m_pSampleIn); - while(hr == MF_E_NOTACCEPTING) - { - TSK_DEBUG_INFO("MF_E_NOTACCEPTING"); - IMFSample* pSample = NULL; - hr = ProcessOutput(&pSample); - if(SUCCEEDED(hr) && pSample) - { - SafeRelease(ppSampleOut); - *ppSampleOut = pSample, pSample = NULL; - - hr = m_pSampleIn->SetUINT32(MFSampleExtension_Discontinuity, TRUE); - hr = ProcessInput(m_pSampleIn); - } - } - if(!*ppSampleOut) - { - hr = ProcessOutput(ppSampleOut); - if(hr == MF_E_TRANSFORM_STREAM_CHANGE) /* Handling Stream Changes: http://msdn.microsoft.com/en-us/library/windows/desktop/ee663587(v=vs.85).aspx */ - { - TSK_DEBUG_INFO("[MF Codec] Stream changed"); - if(m_eType == MFCodecType_Decoder) - { - IMFMediaType *pTypeOut = NULL; - hr = m_pMFT->GetOutputAvailableType(m_dwOutputID, 0, &pTypeOut); - if(SUCCEEDED(hr)) - { - UINT32 uWidth = 0, uHeight = 0; - hr = MFGetAttributeSize(pTypeOut, MF_MT_FRAME_SIZE, &uWidth, &uHeight); - if(SUCCEEDED(hr)) - { - TSK_DEBUG_INFO("[MF Decoder] New size: width=%u, height=%u", uWidth, uHeight); - hr = m_pMFT->SetOutputType(m_dwOutputID, pTypeOut, 0); - if(SUCCEEDED(hr)) - { - SafeRelease(&m_pOutputType); - pTypeOut->AddRef(); - m_pOutputType = pTypeOut; - if(m_eMediaType == MFCodecMediaType_Video) - { - dynamic_cast<MFCodecVideo*>(this)->m_nWidth = uWidth; - dynamic_cast<MFCodecVideo*>(this)->m_nHeight = uHeight; - } - } - } - } - SafeRelease(&pTypeOut); - if(SUCCEEDED(hr)) - { - if(!bMediaChangeHandled) - { - bMediaChangeHandled = TRUE; - goto Label_ProcessInput; - } - } - } - } - } - - m_rtStart += m_rtDuration; - + hr = ProcessInput(m_pSampleIn); + while(hr == MF_E_NOTACCEPTING) { + TSK_DEBUG_INFO("MF_E_NOTACCEPTING"); + IMFSample* pSample = NULL; + hr = ProcessOutput(&pSample); + if(SUCCEEDED(hr) && pSample) { + SafeRelease(ppSampleOut); + *ppSampleOut = pSample, pSample = NULL; + + hr = m_pSampleIn->SetUINT32(MFSampleExtension_Discontinuity, TRUE); + hr = ProcessInput(m_pSampleIn); + } + } + if(!*ppSampleOut) { + hr = ProcessOutput(ppSampleOut); + if(hr == MF_E_TRANSFORM_STREAM_CHANGE) { /* Handling Stream Changes: http://msdn.microsoft.com/en-us/library/windows/desktop/ee663587(v=vs.85).aspx */ + TSK_DEBUG_INFO("[MF Codec] Stream changed"); + if(m_eType == MFCodecType_Decoder) { + IMFMediaType *pTypeOut = NULL; + hr = m_pMFT->GetOutputAvailableType(m_dwOutputID, 0, &pTypeOut); + if(SUCCEEDED(hr)) { + UINT32 uWidth = 0, uHeight = 0; + hr = MFGetAttributeSize(pTypeOut, MF_MT_FRAME_SIZE, &uWidth, &uHeight); + if(SUCCEEDED(hr)) { + TSK_DEBUG_INFO("[MF Decoder] New size: width=%u, height=%u", uWidth, uHeight); + hr = m_pMFT->SetOutputType(m_dwOutputID, pTypeOut, 0); + if(SUCCEEDED(hr)) { + SafeRelease(&m_pOutputType); + pTypeOut->AddRef(); + m_pOutputType = pTypeOut; + if(m_eMediaType == MFCodecMediaType_Video) { + dynamic_cast<MFCodecVideo*>(this)->m_nWidth = uWidth; + dynamic_cast<MFCodecVideo*>(this)->m_nHeight = uHeight; + } + } + } + } + SafeRelease(&pTypeOut); + if(SUCCEEDED(hr)) { + if(!bMediaChangeHandled) { + bMediaChangeHandled = TRUE; + goto Label_ProcessInput; + } + } + } + } + } + + m_rtStart += m_rtDuration; + bail: - SafeRelease(&pBufferIn); - return hr; + SafeRelease(&pBufferIn); + return hr; } enum tmedia_chroma_e MFCodec::GetUncompressedChroma() { - if(kMFCodecUncompressedFormat == MFVideoFormat_NV12) - { - return tmedia_chroma_nv12; - } - assert(false); - return tmedia_chroma_none; + if(kMFCodecUncompressedFormat == MFVideoFormat_NV12) { + return tmedia_chroma_nv12; + } + assert(false); + return tmedia_chroma_none; } // @@ -596,12 +529,12 @@ enum tmedia_chroma_e MFCodec::GetUncompressedChroma() // MFCodecVideo::MFCodecVideo(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/) -: MFCodec(eId, eType, pMFT) -, m_nFrameRate(0) -, m_nWidth(0) -, m_nHeight(0) + : MFCodec(eId, eType, pMFT) + , m_nFrameRate(0) + , m_nWidth(0) + , m_nHeight(0) { - assert(m_eMediaType == MFCodecMediaType_Video); + assert(m_eMediaType == MFCodecMediaType_Video); } MFCodecVideo::~MFCodecVideo() @@ -610,279 +543,261 @@ MFCodecVideo::~MFCodecVideo() } HRESULT MFCodecVideo::Initialize( - UINT32 nFrameRate, - UINT32 nWidth, - UINT32 nHeight, - UINT32 nOutputBitRateInBps /*= 0*/ - ) + UINT32 nFrameRate, + UINT32 nWidth, + UINT32 nHeight, + UINT32 nOutputBitRateInBps /*= 0*/ +) { - assert(IsValid()); - - HRESULT hr = S_OK; + assert(IsValid()); - VARIANT var = {0}; + HRESULT hr = S_OK; - // make sure identifiers are zero-based (other layouts not supported yet) - hr = m_pMFT->GetStreamIDs(1, &m_dwInputID, 1, &m_dwOutputID); - if (hr == E_NOTIMPL) - { + VARIANT var = {0}; + + // make sure identifiers are zero-based (other layouts not supported yet) + hr = m_pMFT->GetStreamIDs(1, &m_dwInputID, 1, &m_dwOutputID); + if (hr == E_NOTIMPL) { m_dwInputID = 0; m_dwOutputID = 0; hr = S_OK; } - else if (FAILED(hr)) - { - TSK_DEBUG_ERROR("The stream identifiers are not zero-based"); + else if (FAILED(hr)) { + TSK_DEBUG_ERROR("The stream identifiers are not zero-based"); return hr; } - m_rtStart = 0; - CHECK_HR(hr = MFFrameRateToAverageTimePerFrame(nFrameRate, 1, &m_rtDuration)); + m_rtStart = 0; + CHECK_HR(hr = MFFrameRateToAverageTimePerFrame(nFrameRate, 1, &m_rtDuration)); + + CHECK_HR(hr = m_pOutputType->SetGUID(MF_MT_MAJOR_TYPE, (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio)); + CHECK_HR(hr = m_pInputType->SetGUID(MF_MT_MAJOR_TYPE, (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio)); - CHECK_HR(hr = m_pOutputType->SetGUID(MF_MT_MAJOR_TYPE, (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio)); - CHECK_HR(hr = m_pInputType->SetGUID(MF_MT_MAJOR_TYPE, (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio)); + CHECK_HR(hr = m_pOutputType->SetGUID(MF_MT_SUBTYPE, (m_eType == MFCodecType_Encoder) ? m_guidCompressedFormat : kMFCodecUncompressedFormat)); + CHECK_HR(hr = m_pInputType->SetGUID(MF_MT_SUBTYPE, (m_eType == MFCodecType_Encoder) ? kMFCodecUncompressedFormat : m_guidCompressedFormat)); - CHECK_HR(hr = m_pOutputType->SetGUID(MF_MT_SUBTYPE, (m_eType == MFCodecType_Encoder) ? m_guidCompressedFormat : kMFCodecUncompressedFormat)); - CHECK_HR(hr = m_pInputType->SetGUID(MF_MT_SUBTYPE, (m_eType == MFCodecType_Encoder) ? kMFCodecUncompressedFormat : m_guidCompressedFormat)); - - CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, (m_eType == MFCodecType_Encoder) ? FALSE : TRUE)); - CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, (m_eType == MFCodecType_Encoder) ? TRUE : FALSE)); + CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, (m_eType == MFCodecType_Encoder) ? FALSE : TRUE)); + CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, (m_eType == MFCodecType_Encoder) ? TRUE : FALSE)); + + CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, (m_eType == MFCodecType_Encoder) ? FALSE : TRUE)); + CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, (m_eType == MFCodecType_Encoder) ? TRUE : FALSE)); + + // Set bitrate + // Set (MF_MT_AVG_BITRATE) for MediaType + // Set (CODECAPI_AVEncCommonMeanBitRate) for H.264 + hr = SetBitRate(nOutputBitRateInBps); - CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, (m_eType == MFCodecType_Encoder) ? FALSE : TRUE)); - CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, (m_eType == MFCodecType_Encoder) ? TRUE : FALSE)); - - // Set bitrate - // Set (MF_MT_AVG_BITRATE) for MediaType - // Set (CODECAPI_AVEncCommonMeanBitRate) for H.264 - hr = SetBitRate(nOutputBitRateInBps); - CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive)); - CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive)); + CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive)); CHECK_HR(hr = MFSetAttributeSize(m_pOutputType, MF_MT_FRAME_SIZE, nWidth, nHeight)); - CHECK_HR(hr = MFSetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, nWidth, nHeight)); + CHECK_HR(hr = MFSetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, nWidth, nHeight)); CHECK_HR(hr = MFSetAttributeRatio(m_pOutputType, MF_MT_FRAME_RATE, nFrameRate, 1)); - CHECK_HR(hr = MFSetAttributeRatio(m_pInputType, MF_MT_FRAME_RATE, nFrameRate, 1)); + CHECK_HR(hr = MFSetAttributeRatio(m_pInputType, MF_MT_FRAME_RATE, nFrameRate, 1)); CHECK_HR(hr = MFSetAttributeRatio(m_pOutputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1)); - CHECK_HR(hr = MFSetAttributeRatio(m_pInputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1)); - - // Encoder: Output format must be set before input - // Decoder: Input format must be set before output - if(m_eType == MFCodecType_Encoder) - { - CHECK_HR(hr = m_pMFT->SetOutputType(m_dwOutputID, m_pOutputType, 0)); - CHECK_HR(hr = m_pMFT->SetInputType(m_dwInputID, m_pInputType, 0)); - } - else - { - CHECK_HR(hr = m_pMFT->SetInputType(m_dwInputID, m_pInputType, 0)); - CHECK_HR(hr = m_pMFT->SetOutputType(m_dwOutputID, m_pOutputType, 0)); - } - - if(m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main) - { - if(m_eType == MFCodecType_Decoder) - { - // Only decoder support GetAttributes() - IMFAttributes* pAttributes = NULL; - hr = m_pMFT->GetAttributes(&pAttributes); - if(SUCCEEDED(hr)) - { - // FIXME: Very strange that "CODECAPI_AVLowLatencyMode" only works with "IMFAttributes->" and not "ICodecAPI->SetValue()" - hr = pAttributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); - } - SafeRelease(&pAttributes); - } - else - { - var.vt = VT_BOOL; - var.boolVal = VARIANT_TRUE; - hr = m_pCodecAPI->SetValue(&CODECAPI_AVLowLatencyMode, &var); - - var.vt = VT_BOOL; - var.boolVal = VARIANT_TRUE; - hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonLowLatency, &var); // Correct for the decoder - - // Disable B-Frames - var.vt = VT_UI4; - var.ulVal = 0; - hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncMPVDefaultBPictureCount, &var); - - // Constant bitrate (updated using RTCP) - var.vt = VT_UI4; - var.ulVal = eAVEncCommonRateControlMode_CBR; - hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); - } - - hr = S_OK; // Not mandatory features - } + CHECK_HR(hr = MFSetAttributeRatio(m_pInputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1)); + + // Encoder: Output format must be set before input + // Decoder: Input format must be set before output + if(m_eType == MFCodecType_Encoder) { + CHECK_HR(hr = m_pMFT->SetOutputType(m_dwOutputID, m_pOutputType, 0)); + CHECK_HR(hr = m_pMFT->SetInputType(m_dwInputID, m_pInputType, 0)); + } + else { + CHECK_HR(hr = m_pMFT->SetInputType(m_dwInputID, m_pInputType, 0)); + CHECK_HR(hr = m_pMFT->SetOutputType(m_dwOutputID, m_pOutputType, 0)); + } + + if(m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main) { + if(m_eType == MFCodecType_Decoder) { + // Only decoder support GetAttributes() + IMFAttributes* pAttributes = NULL; + hr = m_pMFT->GetAttributes(&pAttributes); + if(SUCCEEDED(hr)) { + // FIXME: Very strange that "CODECAPI_AVLowLatencyMode" only works with "IMFAttributes->" and not "ICodecAPI->SetValue()" + hr = pAttributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); + } + SafeRelease(&pAttributes); + } + else { + var.vt = VT_BOOL; + var.boolVal = VARIANT_TRUE; + hr = m_pCodecAPI->SetValue(&CODECAPI_AVLowLatencyMode, &var); + + var.vt = VT_BOOL; + var.boolVal = VARIANT_TRUE; + hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonLowLatency, &var); // Correct for the decoder + + // Disable B-Frames + var.vt = VT_UI4; + var.ulVal = 0; + hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncMPVDefaultBPictureCount, &var); + + // Constant bitrate (updated using RTCP) + var.vt = VT_UI4; + var.ulVal = eAVEncCommonRateControlMode_CBR; + hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var); + } + + hr = S_OK; // Not mandatory features + } bail: - if(SUCCEEDED(hr)) - { - m_nFrameRate = nFrameRate; - m_nWidth = nWidth; - m_nHeight = nHeight; - } + if(SUCCEEDED(hr)) { + m_nFrameRate = nFrameRate; + m_nWidth = nWidth; + m_nHeight = nHeight; + } - return hr; + return hr; } HRESULT MFCodecVideo::SetGOPSize(UINT32 nFramesCount) { - assert(IsValid()); + assert(IsValid()); - HRESULT hr = S_OK; + HRESULT hr = S_OK; - if(m_eType == MFCodecType_Encoder && (m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) - { - VARIANT var = {0}; - var.vt = VT_UI4; - var.ullVal = nFramesCount; - CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncMPVGOPSize, &var)); - } + if(m_eType == MFCodecType_Encoder && (m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) { + VARIANT var = {0}; + var.vt = VT_UI4; + var.ullVal = nFramesCount; + CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncMPVGOPSize, &var)); + } bail: - return hr; + return hr; } HRESULT MFCodecVideo::SetBitRate(UINT32 nBitRateInBps) { - assert(IsValid()); + assert(IsValid()); - HRESULT hr = S_OK; + HRESULT hr = S_OK; - if(nBitRateInBps > 0 && m_eType == MFCodecType_Encoder) - { - CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_AVG_BITRATE, nBitRateInBps)); + if(nBitRateInBps > 0 && m_eType == MFCodecType_Encoder) { + CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_AVG_BITRATE, nBitRateInBps)); - if((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) - { - VARIANT var = {0}; + if((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) { + VARIANT var = {0}; - // Set BitRate - var.vt = VT_UI4; - var.ullVal = nBitRateInBps; - CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var)); - } - } + // Set BitRate + var.vt = VT_UI4; + var.ullVal = nBitRateInBps; + CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var)); + } + } bail: - return hr; + return hr; } HRESULT MFCodecVideo::IsSetSliceMaxSizeInBytesSupported(BOOL &supported) { - HRESULT hr = S_OK; - supported = FALSE; + HRESULT hr = S_OK; + supported = FALSE; - if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) - { + if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) { #if defined(CODECAPI_AVEncSliceControlMode) && defined(CODECAPI_AVEncSliceControlSize) - if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlMode) == S_OK && m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlSize) == S_OK) { - supported = TRUE; - } + if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlMode) == S_OK && m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlSize) == S_OK) { + supported = TRUE; + } #endif - } - return hr; + } + return hr; } HRESULT MFCodecVideo::SetSliceMaxSizeInBytes(UINT32 nSliceMaxSizeInBytes) { - assert(IsValid() && nSliceMaxSizeInBytes > 0); + assert(IsValid() && nSliceMaxSizeInBytes > 0); - HRESULT hr = S_OK; + HRESULT hr = S_OK; - if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) - { + if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) { #if defined(CODECAPI_AVEncSliceControlMode) && defined(CODECAPI_AVEncSliceControlSize) - if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlMode) == S_OK && m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlSize) == S_OK) { - VARIANT var = { 0 }; - var.vt = VT_UI4; + if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlMode) == S_OK && m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlSize) == S_OK) { + VARIANT var = { 0 }; + var.vt = VT_UI4; - var.ulVal = 1; // Bits - CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncSliceControlMode, &var)); + var.ulVal = 1; // Bits + CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncSliceControlMode, &var)); - var.ulVal = (nSliceMaxSizeInBytes << 3); // From Bytes to Bits - CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncSliceControlSize, &var)); - } + var.ulVal = (nSliceMaxSizeInBytes << 3); // From Bytes to Bits + CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncSliceControlSize, &var)); + } #else - CHECK_HR(hr = S_OK); + CHECK_HR(hr = S_OK); #endif - } + } bail: - return hr; + return hr; } HRESULT MFCodecVideo::RequestKeyFrame() { - assert(IsValid()); - - HRESULT hr = S_OK; + assert(IsValid()); + + HRESULT hr = S_OK; - if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) - { + if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) { #if defined(CODECAPI_AVEncVideoForceKeyFrame) - if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncVideoForceKeyFrame) == S_OK) { - VARIANT var = { 0 }; + if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncVideoForceKeyFrame) == S_OK) { + VARIANT var = { 0 }; - var.vt = VT_UI4; - var.ulVal = 1; - CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncVideoForceKeyFrame, &var)); - } + var.vt = VT_UI4; + var.ulVal = 1; + CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncVideoForceKeyFrame, &var)); + } #else - CHECK_HR(hr = S_OK); + CHECK_HR(hr = S_OK); #endif - } + } bail: - return hr; + return hr; } // // MFCodecVideo // MFCodecVideoH264::MFCodecVideoH264(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/) -: MFCodecVideo(eId, eType, pMFT) + : MFCodecVideo(eId, eType, pMFT) { - assert(eId == MFCodecId_H264Base || eId == MFCodecId_H264Main); - - HRESULT hr = S_OK; + assert(eId == MFCodecId_H264Base || eId == MFCodecId_H264Main); - if(m_pOutputType) - { - CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_MPEG2_PROFILE, (m_eId == MFCodecId_H264Base) ? eAVEncH264VProfile_Base : eAVEncH264VProfile_Main)); - } + HRESULT hr = S_OK; + + if(m_pOutputType) { + CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_MPEG2_PROFILE, (m_eId == MFCodecId_H264Base) ? eAVEncH264VProfile_Base : eAVEncH264VProfile_Main)); + } bail: - assert(SUCCEEDED(hr)); + assert(SUCCEEDED(hr)); } MFCodecVideoH264::~MFCodecVideoH264() { - + } MFCodecVideoH264* MFCodecVideoH264::CreateCodecH264Base(MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/) { - MFCodecVideoH264* pCodec = new MFCodecVideoH264(MFCodecId_H264Base, eType, pMFT); - if(pCodec && !pCodec->IsValid()) - { - SafeRelease(&pCodec); - } - return pCodec; + MFCodecVideoH264* pCodec = new MFCodecVideoH264(MFCodecId_H264Base, eType, pMFT); + if(pCodec && !pCodec->IsValid()) { + SafeRelease(&pCodec); + } + return pCodec; } MFCodecVideoH264* MFCodecVideoH264::CreateCodecH264Main(MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/) { - MFCodecVideoH264* pCodec = new MFCodecVideoH264(MFCodecId_H264Main, eType, pMFT); - if(pCodec && !pCodec->IsValid()) - { - SafeRelease(&pCodec); - } - return pCodec; + MFCodecVideoH264* pCodec = new MFCodecVideoH264(MFCodecId_H264Main, eType, pMFT); + if(pCodec && !pCodec->IsValid()) { + SafeRelease(&pCodec); + } + return pCodec; } |