#define VFW_E_NOT_COMMITTED ((HRESULT)0x80040211L) 引起的連鎖反應

來源:互聯網
上載者:User

#define E_POINTER                        _HRESULT_TYPEDEF_(0x80004003L)

#define E_INVALIDARG                     _HRESULT_TYPEDEF_(0x80000003L)

#define E_NOTIMPL                        _HRESULT_TYPEDEF_(0x80004001L)

                 2147746321

#define CO_E_FAILEDTOGETWINDIR           _HRESULT_TYPEDEF_(0x80040211L)
#define VFW_E_SIZENOTSET                 ((HRESULT)0x80040212L)
#define S_FALSE                                ((HRESULT)0x00000001L)

在line 4841

【HRESULT
CBaseAllocator::Alloc(void)
{
    /* Error if he hasn't set the size yet */
    if (m_lCount <= 0 || m_lSize <= 0 || m_lAlignment <= 0) {
        return VFW_E_SIZENOTSET;
    }】

CBaseOutputPin::GetDeliveryBuffer   的時候怎麼會出現這錯誤   CO_E_FAILEDTOGETWINDIR  
   
  //  
  //   MessageId:   CO_E_FAILEDTOGETWINDIR  
  //  
  //   MessageText:  
  //  
  //     Unable   to   obtain   the   Windows   directory  
  //  
 
   
   
  這是由什麼引起的啊

#define VFW_E_NOT_COMMITTED              ((HRESULT)0x80040211L)

剛開始我被CO_E_FAILEDTOGETWINDIR 這個錯誤迷惑了 但後來我讀了GetDeliveryBuffer函數涉及到的源碼我終於發現了
其實這個錯誤是在CBaseAllocator::GetBuffer()中由於
if (!m_bCommitted) {
return VFW_E_NOT_COMMITTED;
注意: #define   CO_E_FAILEDTOGETWINDIR                       _HRESULT_TYPEDEF_(0x80040211L)  
和上面的錯誤值相同 而且在代碼雷根本沒有返回 CO_E_FAILEDTOGETWINDIR 的地方
後來我又跟蹤m_bCommitted 為什麼沒有被置為1(true)
這裡說明一下 如果你的輸出Pin 是基於CBaseOutPin 的話 那麼
填充sample 必須遵循如下步驟

1 首先調用CBaseAllocator::SetProperties 方法來指定記憶體的要求,包括記憶體的數量和大小
2 調用CBaseAllocator::Commit 類分配記憶體 在這個函數中調用 Alloc()將m_bCommitted 置為1
3 通過CBaseAllocator::GetBuffer 得到media samples,這個方法一直阻塞直到另一塊sample
  可用,
4 當你使用完sample 以後,記得調用sample 上的IUnknown::Release 來減少sample 的引用計
  數,當一個sample 的引用計數到了0 時,sample 並不是被刪除,而是返回到allocator 記憶體池
  中,供其他的客戶使用。
5 當你使用完allocator 以後,記得要調用CBaseAllocator::Decommit 來釋放記憶體。

後來我發現由於CBaseAllocator::Commit調用CBaseAllocator::Alloc()
進行檢查
CBaseAllocator::Alloc(void)
{
    /* Error if he hasn't set the size yet */
    if (m_lCount <= 0 || m_lSize <= 0 || m_lAlignment <= 0) {
        return VFW_E_SIZENOTSET;
    而這些值是在
    CBaseAllocator::SetProperties()被賦值的
    如下:
    pActual->cbBuffer = m_lSize = pRequest->cbBuffer;
    pActual->cBuffers = m_lCount = pRequest->cBuffers;
    pActual->cbAlign = m_lAlignment = pRequest->cbAlign;
    pActual->cbPrefix = m_lPrefix = pRequest->cbPrefix; 
   
    而我在
    CRecvOutPutPin::DecideBufferSize內部調用  SetProperties()pRequest->cbBuffer
    賦值為0 所以造成了如上錯誤
    但是我也弄明白了 填充sample的流程。
    CRecvOutPutPin::DecideBufferSize 這個函數是在Pin串連時自動調用。
   
       
       
HRESULT CBaseAllocator::GetBuffer(IMediaSample **ppBuffer,
                                  REFERENCE_TIME *pStartTime,
                                  REFERENCE_TIME *pEndTime,
                                  DWORD dwFlags
                                  )
{
    UNREFERENCED_PARAMETER(pStartTime);
    UNREFERENCED_PARAMETER(pEndTime);
    UNREFERENCED_PARAMETER(dwFlags);
    CMediaSample *pSample;

    *ppBuffer = NULL;
    for (;;)
    {
        {  // scope for lock
            CAutoLock cObjectLock(this);

            /* Check we are committed */
            if (!m_bCommitted) {
                return VFW_E_NOT_COMMITTED;
            }
            pSample = (CMediaSample *) m_lFree.RemoveHead();
            if (pSample == NULL) {
                SetWaiting();
            }
        }

        /* If we didn't get a sample then wait for the list to signal */

        if (pSample) {
            break;
        }
        if (dwFlags & AM_GBF_NOWAIT) {
            return VFW_E_TIMEOUT;
        }
        ASSERT(m_hSem != NULL);
        WaitForSingleObject(m_hSem, INFINITE);
    }

    /* Addref the buffer up to one. On release
       back to zero instead of being deleted, it will requeue itself by
       calling the ReleaseBuffer member function. NOTE the owner of a
       media sample must always be derived from CBaseAllocator */

    ASSERT(pSample->m_cRef == 0);
    pSample->m_cRef = 1;
    *ppBuffer = pSample;

    return NOERROR;
}

 

///當filter 出於stop 狀態時

STDMETHODIMP
CNetworkReceiverFilter::Stop (
    )
{
    LockFilter () ;

    //  synchronous call to stop the receiver (leaves the multicast group
    //  and terminates the thread)
    m_pNetReceiver -> Stop () ;

    //  if we have an output pin (we should) stop it
    if (m_pOutput) {
        //重載CBasePin::Inactive() 調用IMemAllocator::Decommit method  decommit the memory allocator
      m_pOutput -> Inactive () ;
    }

    m_State = State_Stopped ;

    UnlockFilter () ;

    return S_OK ;
}

//filter  處於 pause 狀態

STDMETHODIMP
CNetworkReceiverFilter::Pause (
    )
{
    HRESULT hr ;

    LockFilter ();

    if (m_ulIP == UNDEFINED ||
        m_ulNIC == UNDEFINED)
 {

        hr = E_FAIL ;
    }
    else if  (m_State == State_Stopped)
 {

        //  --------------------------------------------------------------------
        //  stopped -> pause transition; get the filter up and running

        //  activate the receiver; joins the multicast group and starts the
        //  thread
//重載 the CBasePin::Active method. 調用 IMemAllocator::Commit method on the allocator, to allocate memory for buffers.
        hr = m_pNetReceiver -> Activate (m_ulIP, m_usPort, m_ulNIC) ;//

        if (SUCCEEDED (hr))
  {
            m_State = State_Paused ;

            if (m_pOutput &&
                m_pOutput -> IsConnected ())
   {
                m_pOutput -> Active ();
            }
        }
    }
    else
 {
        //  --------------------------------------------------------------------
        //  run -> pause transition; do nothing but set the state

        m_State = State_Paused ;

        hr = S_OK ;
    }

    UnlockFilter () ;

    return hr ;
}

InitAllocator 是自動調用的

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.