#define VFW_E_NOT_COMMITTED ((HRESULT)0x80040211L) 引起的连锁反应

#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 是自动调用的

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值