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);
}