现在的位置: 首页 > 综合 > 正文

利用DirectShow实现对视频文件H264编码与解码基类 3

2012年01月22日 ⁄ 综合 ⁄ 共 8448字 ⁄ 字号 评论关闭

bool CEncode::_HasDecodeFilter(CString strFileName)
{
IGraphBuilder * pGraph = NULL;
IBaseFilter * pSrc = NULL;
HRESULT hr = E_FAIL;
bool bHas = false;
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);
if(SUCCEEDED(hr))
{
  int nlen = MultiByteToWideChar(CP_ACP, 0, strFileName, -1, NULL, NULL);
  LPWSTR  pstrFile = new WCHAR[nlen];
  MultiByteToWideChar(CP_ACP, 0, strFileName, -1, pstrFile, nlen);
  hr = pGraph->RenderFile(pstrFile, NULL);
  delete pstrFile;
  if(SUCCEEDED(hr))
  {
   bHas = true;
   hr = pGraph->FindFilterByName(pstrFile, &pSrc);
   if(pSrc)
   {
    _NukeDownstream(pGraph, pSrc);
    pGraph->RemoveFilter(pSrc);
    pSrc->Release();
   }
  }
  else
   bHas = false;
  pGraph->Release();
}
  return bHas;
}

int CEncode::_HasH264Filter(bool bFlag )
{
HRESULT hr=E_FAIL;
int iResult = -1;

/**************创建系统枚举器并获得ICreateDevEnum接口*****************/
ICreateDevEnum * pEnumHardware=NULL;//定义一个指向ICreateDevEnum接口的指针
    hr=CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_ALL, IID_ICreateDevEnum, (void**)&pEnumHardware);
if(FAILED(hr))//创建失败返回
  return iResult;

/**************创建类型目录枚举器并获得IEnumMoniker接口*****************/
    CString strTempName = bFlag? "DT264 Compress Filter":"DT264 Decompress Filter";
REFCLSID CLSID_TempCategory = bFlag? CLSID_VideoCompressorCategory : CLSID_LegacyAmFilterCategory;
IBaseFilter * pTempFilter = NULL;
IEnumMoniker * pEnumMoniker=NULL;//定义一个指向IEnumMoniker接口的指针
hr=pEnumHardware->CreateClassEnumerator(CLSID_TempCategory, &pEnumMoniker ,0);
if(pEnumMoniker)//创建类型目录枚举器成功且IEnumMoniker接口不为空
{
  pEnumMoniker->Reset();//重置枚举序列到初始状态
  ULONG fetched=0;
  IMoniker * pMoniker=NULL;
  //当查询IMoniker接口成功且未成功创建设备filter时,做for循环
  while(SUCCEEDED(pEnumMoniker->Next(1, &pMoniker, &fetched))&&fetched)
  {
   if(pMoniker)//查询IMoniker接口成功
   {
    IPropertyBag * pPropertyBag=NULL;
    hr=pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropertyBag);
    if(FAILED(hr))
    {
                    iResult = -1;
     continue;
    }
    VARIANT  name;
    name.vt=VT_BSTR;
    hr=pPropertyBag->Read(L"FriendlyName", &name , NULL);//获得设备的友好名
    if (SUCCEEDED(hr))//获取设备的友好名成功
    {
     char friendlyName[256];
     friendlyName[0]=0;
     WideCharToMultiByte(CP_ACP, 0, name.bstrVal, -1, friendlyName, 256, NULL, NULL);
     if(strcmp(friendlyName, (LPSTR)(LPCTSTR)strTempName)==0)
     { 
      iResult = 1;
      hr=pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pTempFilter);//创建设备filter
      if(FAILED(hr))//创建设备filter成功
           AfxMessageBox("/r对该文件进行编解码,需要H264编解码器,请下载并安装相应的插件。/rCreate H264 Filter Failed!");
      else
       bFlag? (m_nEncodeFilter.H264Encode = pTempFilter):(m_nDecodeFilter.H264Decode = pTempFilter);
      break;

}
     else
      iResult = 0;
    }    
             pPropertyBag->Release();//propertyBag不为空时,释放其内存空间
    pMoniker->Release();
   }
  }
  pEnumMoniker->Release();
}
pEnumHardware->Release();
return iResult;
}

bool CEncode::_FindPins(IBaseFilter * pInFilter, bool bFlag, IPin ** pOutPin)
{
ASSERT(pInFilter);
HRESULT hr = E_FAIL;
bool bReturned = false;
IEnumPins  * pEnumPins;
hr = pInFilter->EnumPins(&pEnumPins);
if(FAILED(hr))
  return bReturned;
IPin * pPin = NULL;
ULONG nfetched = 0;
pEnumPins->Reset();
while(SUCCEEDED(pEnumPins->Next(1, &pPin, &nfetched))&&nfetched)
{
  if(pPin)//查询pin成功
  {
   PIN_DIRECTION pinDir;
   PIN_DIRECTION pinDirection = bFlag? PINDIR_INPUT : PINDIR_OUTPUT;
   hr = pPin->QueryDirection(&pinDir);
   if(FAILED(hr)) //查询pin的方向失败
   {
    pPin->Release();
    continue;
   }
   else //查询pin的方向成功
   {
    if(pinDir == pinDirection)
    {
     IPin * pConnectedPin = NULL;
     hr = pPin->ConnectedTo(&pConnectedPin);
        if(FAILED(hr))//该pin已被连接
     {
                        * pOutPin = pPin;
      bReturned = true;
     }
     else//该pin未被连接
     {
      pPin->Release();
      pConnectedPin->Release();
      continue;
     }
    }
   }
  }
}
pEnumPins->Release();
return bReturned;
}

void  CEncode::_NukeDownstream(IGraphBuilder* inGraph, IBaseFilter * inFilter) 
{
if (!inGraph || !inFilter)
  return ;
IEnumPins * pinEnum = NULL;
if (SUCCEEDED(inFilter->EnumPins(&pinEnum))) //枚举所有的pin成功
{
  pinEnum->Reset();
  IPin * pin     = NULL;
  ULONG  fetched = 0;
  while (SUCCEEDED(pinEnum->Next(1, &pin, &fetched)) && fetched)//查询pin成功
  {
   if (pin)
   {
    IPin * connectedPin = NULL;
    pin->ConnectedTo(&connectedPin);//得到与该pin相连的pin
    if (connectedPin) //与查询pin相连的pin不为空
    {
     PIN_INFO pininfo;
     if (SUCCEEDED(connectedPin->QueryPinInfo(&pininfo)))//查询pin的方向成功
     {
      if (pininfo.dir == PINDIR_INPUT) //连接的pin为输入pin
      {
       _NukeDownstream(inGraph, pininfo.pFilter);//递归调用
       inGraph->Disconnect(connectedPin);
       inGraph->Disconnect(pin);
       inGraph->RemoveFilter(pininfo.pFilter);//从Filter Graph中移除
      }    
                        pininfo.pFilter->Release();
     }
     connectedPin->Release();
    }
    pin->Release();
    pin = NULL;
   }
  }
  pinEnum->Release();
}
}

bool CEncode::_CreateCompressDevice( CString strDevice , IBaseFilter ** pCompressorFilter) 
{
HRESULT hr=S_OK;
bool bCreated = false;
IBaseFilter * pTempFilter = NULL;
ICreateDevEnum * enumHardware=NULL;//定义一个指向ICreateDevEnum接口的指针
    hr=CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_ALL, IID_ICreateDevEnum,  (void**)&enumHardware);//创建一个系统设备枚举器并获得ICreateDevEnum接口
if(FAILED(hr))//创建失败返回
  return false;
IEnumMoniker * enumMoniker=NULL;//定义一个指向IEnumMoniker接口的指针
hr=enumHardware->CreateClassEnumerator(CLSID_VideoCompressorCategory, &enumMoniker ,0);//创建一个类型目录枚举器并获得IEnumMoniker接口

if(enumMoniker)//创建类型目录枚举器成功且IEnumMoniker接口不为空
{
  enumMoniker->Reset();//重置枚举序列到初始状态
  ULONG fetched=0;
  IMoniker * moniker=NULL;
  char friendlyName[256];
  //当查询IMoniker接口成功且未成功创建设备filter时,做for循环
  while(SUCCEEDED(enumMoniker->Next(1, &moniker, &fetched))&&fetched)
  {
   if(moniker)//查询IMoniker接口成功
   {
    IPropertyBag * propertyBag=NULL;
    VARIANT  name;
    friendlyName[0]=0;
    hr=moniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&propertyBag);
    if(SUCCEEDED(hr))
    {
     name.vt=VT_BSTR;
     hr=propertyBag->Read(L"FriendlyName", &name , NULL);//获得设备的友好名
    }
    if (SUCCEEDED(hr))//获取设备的友好名成功
    {   
     WideCharToMultiByte(CP_ACP, 0, name.bstrVal, -1, friendlyName, 256, NULL, NULL);
     if(strcmp(friendlyName, (LPSTR)(LPCTSTR)strDevice)==0)
     {   
      hr=moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pTempFilter);//创建设备filter
      if(SUCCEEDED(hr))//创建设备filter成功
      {
       *pCompressorFilter = pTempFilter;
       bCreated = true;
      }
     }     
    }    
    if(propertyBag)//propertyBag不为空时,释放其内存空间
    {   
     propertyBag->Release();
     propertyBag=NULL;
    }
    moniker->Release();
   }
  }
  enumMoniker->Release();
}
enumHardware->Release();
return bCreated;
}

HRESULT CEncode::_CreateFilterGraph(IGraphBuilder ** inGraph, ICaptureGraphBuilder2 ** inBuilder)
{
HRESULT hr = E_FAIL;
IGraphBuilder * pGraph = NULL;
ICaptureGraphBuilder2 * pBuilder = NULL;
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);
if(SUCCEEDED(hr))//创建Filter Graph Manager成功
{
  *inGraph = pGraph;
  hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuilder);
  if(SUCCEEDED(hr)) //创建辅助组件成功
  {
   hr = pBuilder->SetFiltergraph(pGraph);
   *inBuilder = pBuilder;
  }
  else //创建辅助组件失败
   AfxMessageBox("Create Capture Graph Builder object Failed!");
}
else //创建Filter Graph Manager失败
  AfxMessageBox("Create Filter Graph Manager Failed!");
return hr;
}

void CEncode::_DestroyEncodeGraph()
{
/*************释放资源***************/
SafeRelease(m_nEncode.pSeek);
SafeRelease(m_nEncode.pControl);
SafeRelease(m_nEncode.pEvent);
    SafeRelease(m_nEncodeFilter.pSink);
if (m_nEncode.pGraph&&m_nEncodeFilter.pSrc)
{
  _NukeDownstream(m_nEncode.pGraph, m_nEncodeFilter.pSrc); //销毁下游链路
  m_nEncode.pGraph->RemoveFilter(m_nEncodeFilter.pSrc);
  SafeRelease(m_nEncodeFilter.pSrc);
}
_DestroyFilterGraph(m_nEncode.pGraph, m_nEncode.pBuilder);
}

void CEncode::_DestroyDecodeGraph()
{
/*************释放资源***************/
SafeRelease(m_nDecode.pSeek);
SafeRelease(m_nDecode.pControl);
SafeRelease(m_nDecode.pEvent);
    SafeRelease(m_nDecodeFilter.pSink);
if (m_nDecode.pGraph&&m_nDecodeFilter.pSrc)
{
  _NukeDownstream(m_nDecode.pGraph, m_nDecodeFilter.pSrc); //销毁下游链路
  m_nDecode.pGraph->RemoveFilter(m_nDecodeFilter.pSrc);
  SafeRelease(m_nDecodeFilter.pSrc);
}
_DestroyFilterGraph(m_nDecode.pGraph, m_nDecode.pBuilder);
}

void CEncode::_DestroyFilterGraph(IGraphBuilder * inGraph, ICaptureGraphBuilder2 * inBuilder)
{
SafeRelease(inBuilder);
SafeRelease(inGraph);
}

抱歉!评论已关闭.