注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

mie

 
 
 

日志

 
 

COM引用计数带来的进程崩溃问题  

2010-07-29 19:41:49|  分类: 多媒体开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

        之前的代码使用的是CComPtr<>这个智能指针,但是,因为自己使用Directshow实现的一个Filter存在问题,导致程序总是出问题。我把原因归咎于智能指针,于是,消除了所有的CComPtr智能指针,改用普通指针代替。

        在我解决了自己的Filter的BUG之后,发现一个更严重的问题,程序总是崩溃!仔细查了一下,发现引用计数存在问题,刚好少计算了一个!

        包括Smart Tee这些系统自带的Filter在内,所有的Filter都少计数了一次。在我自己的Filter里面,我这样处理:在构造函数里面将引用计数设为一,从而,我自己的Filter在Release回收时正常,但是其他的系统Filter在Release回收时还是存在问题!

        于是,我将普通指针再次改为智能指针,问题依旧!

 

解决!原因是,我在不该释放Pin的地方,释放了Pin。这段代码是抄网络上的,然后我做了一些小改动,也记不清是原先的代码有问题,还是我改错了,把正确的代码帖出来,免得又被骂。


HRESULT CDirectshowCommonApi::ConnectFilter(
 IGraphBuilder * pGraph,
 IPin * pOut,        
 IBaseFilter * pDest
 )   
{
 if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))
 {
  ATLTRACE("CDirectshowCommonApi::ConnectFilter(), pGraph == NULL) || (pOut == NULL) || (pDest == NULL, err=[%d]<%s * .\n", GetLastError(), g_FormatErrorStringA());

  return E_POINTER;
 }

#ifdef _DEBUG
 PIN_DIRECTION PinDir;
 pOut-> QueryDirection(&PinDir);
 _ASSERTE(PinDir == PINDIR_OUTPUT);
#endif

 IPin *pIn = 0;
 HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
 if (FAILED(hr))
 {
  ATLTRACE("CDirectshowCommonApi::ConnectFilter(), GetUnconnectedPin, err=[%d]<%s * .\n", GetLastError(), g_FormatErrorStringA());

  return hr;
 }

 hr = pGraph-> Connect(pOut, pIn);

 if (FAILED(hr))
 {
  ATLTRACE("CDirectshowCommonApi::ConnectFilter(), Connect, err=[%d]<%s * .\n", GetLastError(), g_FormatErrorStringA());
 }

//   pIn->Release();//删除的代码

 return hr;
}

HRESULT CDirectshowCommonApi::ConnectFilter(
 IGraphBuilder * pGraph,
 IBaseFilter * pSrc,
 IBaseFilter * pDest
 )
{
 if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
 {
  return E_POINTER;
 }

 IPin * pOut = 0;
 HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);
 if (FAILED(hr))
 {
  ATLTRACE("CDirectshowCommonApi::ConnectFilter()2, GetUnconnectedPin, err=[%d]<%s * .\n", GetLastError(), g_FormatErrorStringA());

  return hr;
 }

 hr = ConnectFilter(pGraph, pOut, pDest);

//   pOut->Release();//删除的代码

 return hr;
}

IPin * CDirectshowCommonApi::GetSmartTeeCapturePin(IBaseFilter * pSmartTee)
{
 if(pSmartTee)
 {
  IPin * pPin;
  HRESULT hr = pSmartTee-> FindPin(L"Capture",&pPin);
  if(SUCCEEDED(hr))
  {
   ATLTRACE("CDirectshowCommonApi::GetSmartTeeCapturePin(), FindPin, err=[%d]<%s * .\n", GetLastError(), g_FormatErrorStringA());

//   pPin->Release();//删除的代码  

 return pPin;
  }
 }

 return NULL;

}

IPin * CDirectshowCommonApi::GetSmartTeePreviewPin(IBaseFilter * pSmartTee)
{
 if(pSmartTee)
 {
  IPin * pPin;
  HRESULT hr = pSmartTee-> FindPin(L"Preview",&pPin);
  if(SUCCEEDED(hr))
  {
   ATLTRACE("CDirectshowCommonApi::GetSmartTeePreviewPin(), FindPin, err=[%d]<%s * .\n", GetLastError(), g_FormatErrorStringA());

//   pPin->Release();//删除的代码

return pPin;
  }
 }

 return NULL;
}

加粗的地方就是导致引用计数混乱的代码。

 

By:zhanyonhu

  评论这张
 
阅读(911)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016