// Encode.h: interface for the CEncode class.//
#if !defined(AFX_ENCODE_H__F6B1A672_0A17_4011_87DA_F97CA0B0E52E__INCLUDED_)#define AFX_ENCODE_H__F6B1A672_0A17_4011_87DA_F97CA0B0E52E__INCLUDED_
#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "streams.h"#include "afxpriv.h"# define SafeRelease(s) {if(s) {(s)->Release(); (s) = NULL;}}# define WM_ENCODE_NOTIFY (WM_USER + 1200)# define WM_DECODE_NOTIFY (WM_USER + 1201)class CEncode {public: CEncode(); virtual ~CEncode();
private: struct _CODE_GRAPH { IGraphBuilder * pGraph; IMediaControl * pControl; IMediaEventEx * pEvent; IMediaSeeking * pSeek; IMediaFilter * pMedia; ICaptureGraphBuilder2 * pBuilder; }m_nEncode, m_nDecode; //Filter Graph Manager变量
struct _ENCODE_FILTER { IBaseFilter * pSrc; IBaseFilter * pAviDecode; IBaseFilter * pFileWrite; IBaseFilter * pAviMux; IBaseFilter * H264Encode; IFileSinkFilter2 * pSink; }m_nEncodeFilter; //Encode Graph变量
struct _DECODE_FILTER { IBaseFilter * pSrc; IBaseFilter * pEncode; IBaseFilter * pFileWrite; IBaseFilter * pAviMux; IBaseFilter * H264Decode; IFileSinkFilter2 * pSink; }m_nDecodeFilter; //Decode Graph变量
struct _CONTROL_STATE { int iProgress; //进度值(0 - 100) bool bStop; //ture - 终止编码 false - 不终止编码 bool bStopFlag; //终止标志 bool bCompleted; //数据传输完成标志 }m_nEncodeCtl, m_nDecodeCtl; //Graph控制变量
public: /********************功能函数*******************/ int CompressFile( CString strSourcePathName, CString strDestPathName); //实现视频文件的H264编码 int UnCompressFile( CString strSourcePathName, CString strDestPathName, CString strCompressorName); //对H264编码的视频文件用其它的编码器重新编码 int GetProgress(bool bFlag=true); //获得视频编码完成的进度 bool TerminiateProgress(bool bFlag=true); //终止视频编码 bool SetNotifyWindow(HWND inWindow, bool bFlag); //设置消息处理窗口 void OnCodecNotify(WPARAM inWParam, LPARAM inLParam, bool bFlags); //编码/解码消息处理
private: /****************编码条件的检测*****************/ bool _IsFileOpenedCorrectly(CString strFileName); bool _IsSuitedFileType(CString strFileName); bool _HasDecodeFilter(CString strFileName); int _IsH264Encoded(CString strFileName); //返回值:1 - 成功, 0 - 失败, -1 - 其它情况 int _HasH264Filter(bool bFlag); //返回值:1 - 成功 ,0 - 失败, -1 - 其它情况 /**************Filter Graph的创建与销毁************/ HRESULT _CreateFilterGraph(IGraphBuilder ** inGraph, ICaptureGraphBuilder2** inBuilder); void _DestroyFilterGraph(IGraphBuilder * inGraph, ICaptureGraphBuilder2* inBuilder); void _DestroyEncodeGraph(); void _DestroyDecodeGraph();
/*******************辅助功能函数*******************/ bool _CreateCompressDevice( CString strDevice , IBaseFilter ** pCompressorFilter ) ; //创建设备 bool _FindPins(IBaseFilter * pInFilter, bool bFlag, IPin ** pOutPin); //true - 输入pin, false - 输出pin void _NukeDownstream(IGraphBuilder* inGraph, IBaseFilter * inFilter); //删除下游链路};
#endif // !defined(AFX_ENCODE_H__F6B1A672_0A17_4011_87DA_F97CA0B0E52E__INCLUDED_)
// Encode.cpp: implementation of the CEncode class.////
#include "stdafx.h"#include "EncodeDemo.h"#include "Encode.h"
#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif
//// Construction/Destruction//
CEncode::CEncode(){ /*********Encode Graph中变量***********/ m_nEncode.pGraph = NULL; m_nEncode.pBuilder = NULL; m_nEncode.pControl = NULL; m_nEncode.pEvent = NULL; m_nEncode.pSeek = NULL; m_nEncode.pMedia = NULL; m_nEncodeFilter.H264Encode = NULL; m_nEncodeFilter.pAviDecode = NULL; m_nEncodeFilter.pAviMux = NULL; m_nEncodeFilter.pFileWrite = NULL; m_nEncodeFilter.pSink = NULL; m_nEncodeFilter.pSrc = NULL;
/*********Decode Graph中变量***********/ m_nDecode.pGraph = NULL; m_nDecode.pBuilder = NULL; m_nDecode.pControl = NULL; m_nDecode.pEvent = NULL; m_nDecode.pSeek = NULL; m_nDecode.pMedia = NULL; m_nDecodeFilter.H264Decode = NULL; m_nDecodeFilter.pAviMux = NULL; m_nDecodeFilter.pEncode = NULL; m_nDecodeFilter.pFileWrite = NULL; m_nDecodeFilter.pSink = NULL; m_nDecodeFilter.pSrc = NULL;
/*****Graph控制变量及状态变量*****/ m_nEncodeCtl.iProgress = 0; m_nDecodeCtl.iProgress = 0; m_nEncodeCtl.bStop = false; m_nDecodeCtl.bStop = false; m_nEncodeCtl.bStopFlag = false; m_nDecodeCtl.bStopFlag = false; m_nEncodeCtl.bCompleted = false; m_nDecodeCtl.bCompleted = false;}
CEncode::~CEncode(){ /********异常退出资源释放*******/// _DestroyEncodeGraph();// _DestroyDecodeGraph();}
int CEncode::CompressFile( CString strSourcePathName, CString strDestPathName){ /****************编码条件的检测*****************/ if(!_IsFileOpenedCorrectly(strSourcePathName)) return -3; if(1 == _IsH264Encoded(strSourcePathName)) return -5; if(!_HasDecodeFilter(strSourcePathName)) return -1; if(0==_HasH264Filter(true)) return -2;
/*******************编码Graph创建的检测**************/ if (m_nEncode.pGraph&&m_nEncodeFilter.pSrc) //Filter Graph Manager已经创建 { if(m_nEncode.pControl) m_nEncode.pControl->Stop();//停止压缩 _NukeDownstream(m_nEncode.pGraph, m_nEncodeFilter.pSrc); //销毁下游链路 m_nEncode.pGraph->RemoveFilter(m_nEncodeFilter.pSrc); SafeRelease(m_nEncode.pSeek); SafeRelease(m_nEncode.pControl); SafeRelease(m_nEncode.pEvent); SafeRelease(m_nEncodeFilter.pSink); SafeRelease(m_nEncodeFilter.pSrc); _DestroyFilterGraph(m_nEncode.pGraph, m_nEncode.pBuilder); }
/**************编码Graph的创建*************/ HRESULT hr = E_FAIL; hr = _CreateFilterGraph(&m_nEncode.pGraph, &m_nEncode.pBuilder); if(FAILED(hr)) { AfxMessageBox("Uninitialize COM Library!"); return 0; } int iResult = 0; do { /***************************查询接口***************************/ hr = m_nEncode.pGraph->QueryInterface(IID_IMediaControl, (void**)&m_nEncode.pControl); if (FAILED(hr))//查询失败 break ; hr = m_nEncode.pGraph->QueryInterface(IID_IMediaEventEx, (void**)&m_nEncode.pEvent); if (FAILED(hr))//查询失败 break ; hr = m_nEncode.pGraph->QueryInterface(IID_IMediaSeeking, (void**)&m_nEncode.pSeek); if (FAILED(hr))//查询失败 break ; hr = m_nEncode.pGraph->QueryInterface(IID_IMediaFilter, (void**)&m_nEncode.pMedia); if (FAILED(hr))//查询失败 break ; /*************************辅助Filter的创建*********************/ hr = m_nEncode.pGraph->AddSourceFilter(strSourcePathName.AllocSysString(), L"Source Filter", &m_nEncodeFilter.pSrc); if(FAILED(hr))//添加失败 break ; hr = CoCreateInstance(CLSID_AVIDec, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&m_nEncodeFilter.pAviDecode); if (FAILED(hr))//创建失败 break ; hr = CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&m_nEncodeFilter.pAviMux); if (FAILED(hr)) //创建失败 break; hr = m_nEncodeFilter.pAviMux->QueryInterface(IID_IMediaSeeking, (void**)&m_nEncode.pSeek); if (FAILED(hr))//查询失败 break ; hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC, IID_IFileSinkFilter2, (void**)&m_nEncodeFilter.pSink); if (FAILED(hr)) //创建失败 break ; hr = m_nEncodeFilter.pSink->QueryInterface(IID_IBaseFilter, (void**)&m_nEncodeFilter.pFileWrite); if(FAILED(hr)) //创建失败 break ; /* if(!_CreateCompressDevice("DT264 Compress Filter", &m_nEncodeFilter.H264Encode)) //创建压缩设备失败 break ; */ if (!m_nEncodeFilter.H264Encode) //H264Encode Filter 未被创建 break; hr = m_nEncode.pGraph->AddFilter(m_nEncodeFilter.pAviDecode, L"AVI Decompressor"); hr = m_nEncode.pGraph->AddFilter(m_nEncodeFilter.H264Encode, L"H264 Compress Filter");
/*******************Filter Graph链路的创建*******************/ hr = m_nEncode.pBuilder->RenderStream(NULL, NULL, m_nEncodeFilter.pSrc, m_nEncodeFilter.pAviDecode, m_nEncodeFilter.H264Encode); if (FAILED(hr)) //创建链路失败 { AfxMessageBox("/r该编解码器不支持所选的媒体类型,请下载相应的插件。/rCreate pSrc->pAviDecompress->pCompressFilter Failed!"); break; } hr = m_nEncode.pGraph->AddFilter(m_nEncodeFilter.pAviMux, L"AVI Dest Filter"); hr = m_nEncode.pGraph->AddFilter((IBaseFilter *)m_nEncodeFilter.pFileWrite, L"File Write Filter"); hr = m_nEncodeFilter.pSink->SetMode(AM_FILE_OVERWRITE); hr = m_nEncodeFilter.pSink->SetFileName(strDestPathName.AllocSysString() , NULL); if(FAILED(hr)) { iResult = -4; break; } hr = m_nEncode.pBuilder->RenderStream(NULL, NULL, m_nEncodeFilter.H264Encode, m_nEncodeFilter.pAviMux, m_nEncodeFilter.pFileWrite); if (FAILED(hr)) { AfxMessageBox("/r该编解码器不支持所选的媒体类型,请下载相应的插件。/rCreate H264 Compress Filter->---->File Write Filter Failed!"); break; } hr=m_nEncode.pMedia->SetSyncSource(NULL);
hr = m_nEncode.pControl->Run(); //运行filter graph if(SUCCEEDED(hr)) { iResult = 1; m_nEncodeCtl.bStopFlag = true; }
}while(false);
return iResult;}
int CEncode::UnCompressFile( CString strSourcePathName, CString strDestPathName, CString strCompressorName){ /****************编码条件的检测*****************/ if(!_IsFileOpenedCorrectly(strSourcePathName)) return -4; if(!_IsSuitedFileType(strSourcePathName)) return -2; if(0 == _IsH264Encoded(strSourcePathName)) return -1; if(0==_HasH264Filter(false)) return -6;
/*******************编码Graph创建的检测**************/ if (m_nDecode.pGraph&&m_nDecodeFilter.pSrc) //Filter Graph Manager已经创建 { if(m_nDecode.pControl) m_nDecode.pControl->Stop();//停止压缩 _NukeDownstream(m_nDecode.pGraph, m_nDecodeFilter.pSrc); //销毁下游链路 m_nDecode.pGraph->RemoveFilter(m_nDecodeFilter.pSrc); SafeRelease(m_nDecode.pSeek); SafeRelease(m_nDecode.pControl); SafeRelease(m_nDecode.pEvent); SafeRelease(m_nDecodeFilter.pSink); SafeRelease(m_nDecodeFilter.pSrc); _DestroyFilterGraph(m_nDecode.pGraph, m_nDecode.pBuilder); }
/**************编码Graph的创建*************/ HRESULT hr = E_FAIL; hr = _CreateFilterGraph(&m_nDecode.pGraph, &m_nDecode.pBuilder); if(FAILED(hr)) { AfxMessageBox("Uninitialize COM Library!"); return -7; } int iResult = -7; do { /***************************查询接口***************************/ hr = m_nDecode.pGraph->QueryInterface(IID_IMediaControl, (void**)&m_nDecode.pControl); if (FAILED(hr))//查询失败 break ; hr = m_nDecode.pGraph->QueryInterface(IID_IMediaEventEx, (void**)&m_nDecode.pEvent); if (FAILED(hr))//查询失败 break ; hr = m_nDecode.pGraph->QueryInterface(IID_IMediaSeeking, (void**)&m_nDecode.pSeek); if (FAILED(hr))//查询失败 break ; hr = m_nDecode.pGraph->QueryInterface(IID_IMediaFilter, (void**)&m_nDecode.pMedia); if (FAILED(hr))//查询失败 break ; /*************************辅助Filter的创建*********************/ hr = m_nDecode.pGraph->AddSourceFilter(strSourcePathName.AllocSysString(), L"Source Filter", &m_nDecodeFilter.pSrc); if(FAILED(hr))//添加失败 break ; hr = CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&m_nDecodeFilter.pAviMux); if (FAILED(hr)) //创建失败 break; hr = m_nDecodeFilter.pAviMux->QueryInterface(IID_IMediaSeeking, (void**)&m_nDecode.pSeek); if (FAILED(hr))//查询失败 break ; hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC, IID_IFileSinkFilter2, (void**)&m_nDecodeFilter.pSink); if (FAILED(hr)) //创建失败 break ; hr = m_nDecodeFilter.pSink->QueryInterface(IID_IBaseFilter, (void**)&m_nDecodeFilter.pFileWrite); if(FAILED(hr)) //创建失败 break ; if (!m_nDecodeFilter.H264Decode) //H264Encode Filter 未被创建 break; hr = m_nDecode.pGraph->AddFilter(m_nDecodeFilter.H264Decode, L"H264 UnCompress Filter");
/*********************创建Graph中的上游链路(H264Decode)*****************/ hr = m_nDecode.pBuilder->RenderStream(NULL, NULL, m_nDecodeFilter.pSrc, NULL, m_nDecodeFilter.H264Decode); if (FAILED(hr)) //创建链路失败 { AfxMessageBox("/r该编解码器不支持所选的媒体类型,请下载相应的插件。/rCreate pSrc->pAviSplitter->H264UnCompressFilter Failed!"); break; }
/**********************第三方编码器的检测********************/ if(strCompressorName.IsEmpty()) //压缩设备名为空 m_nDecodeFilter.pEncode = NULL; else if(!_CreateCompressDevice(strCompressorName, &m_nDecodeFilter.pEncode)) //创建压缩设备失败 { iResult = -3; break ; }
/************************添加Filter到Graph中********************/ if(m_nDecodeFilter.pEncode) { hr = m_nDecode.pGraph->AddFilter(m_nDecodeFilter.pEncode, L"Compress Filter"); if(FAILED(hr)) break; } hr = m_nDecode.pGraph->AddFilter(m_nDecodeFilter.pAviMux, L"AVI Dest Filter"); if(FAILED(hr)) break; hr = m_nDecode.pGraph->AddFilter((IBaseFilter *)m_nDecodeFilter.pFileWrite, L"File Write Filter"); if(FAILED(hr)) break; hr = m_nDecodeFilter.pSink->SetMode(AM_FILE_OVERWRITE); if(FAILED(hr)) break; hr = m_nDecodeFilter.pSink->SetFileName(strDestPathName.AllocSysString() , NULL); if(FAILED(hr)) { iResult = -5; break; }
/*********************创建Graph中的下游链路(H264Decode)*****************/ hr = m_nDecode.pBuilder->RenderStream(NULL, NULL, m_nDecodeFilter.H264Decode, m_nDecodeFilter.pEncode, m_nDecodeFilter.pFileWrite); if (FAILED(hr)) { AfxMessageBox("/r该编解码器不支持所选的媒体类型,请下载相应的插件。/rCreate H264 Filter->---->File Write Filter Failed!"); break; } hr=m_nDecode.pMedia->SetSyncSource(NULL);
hr = m_nDecode.pControl->Run(); //运行filter graph if(SUCCEEDED(hr)) { iResult = 1; m_nDecodeCtl.bStopFlag = true; } }while(false); return iResult;}
int CEncode::GetProgress(bool bFlag){ HRESULT hr = E_FAIL; if(bFlag) //压缩状态 { if(m_nEncodeCtl.bCompleted) //数据传输完成 { m_nEncodeCtl.bCompleted = false; return 100; } } else //解压状态 { if(m_nDecodeCtl.bCompleted) //数据传输完成 { m_nDecodeCtl.bCompleted = false; return 100; }
}
/********************获得数据传输的当前状态*********************/ IMediaSeeking * pSeek = bFlag? m_nEncode.pSeek : m_nDecode.pSeek; LONGLONG lDuration = 1; if(pSeek == NULL) return -1; hr = pSeek->GetDuration(&lDuration); if(SUCCEEDED(hr)) //得到总的持续时间成功 { LONGLONG Start = 0; hr = pSeek->GetCurrentPosition(&Start); //得到当前的位置 if(SUCCEEDED(hr)) //获得当前的位置成功 { int iProgress = (int)(100*(Start/((double)lDuration))); if (bFlag) //压缩状态 { m_nEncodeCtl.iProgress = iProgress; return m_nEncodeCtl.iProgress; } else //解缩状态 { m_nDecodeCtl.iProgress = iProgress; return m_nDecodeCtl.iProgress; } } return -1; } else return -1;}
bool CEncode::TerminiateProgress(bool bFlag){ HRESULT hr = E_FAIL; if(bFlag) { /*********************终止编码*******************/ if(m_nEncode.pControl!=NULL&&m_nEncodeCtl.bStopFlag) { OAFilterState state = State_Stopped; if (SUCCEEDED(m_nEncode.pControl->GetState(15, &state)/*得到当前状态*/)) { if(state != State_Stopped) hr = m_nEncode.pControl->Stop(); //停止filter graph } _DestroyEncodeGraph(); } return SUCCEEDED(hr); } else { /*********************终止解码*******************/ if(m_nDecode.pControl!=NULL&&m_nDecodeCtl.bStopFlag) { OAFilterState state = State_Stopped; if (SUCCEEDED(m_nDecode.pControl->GetState(15, &state)/*得到当前状态*/)) { if(state != State_Stopped) hr = m_nDecode.pControl->Stop(); //停止filter graph } _DestroyDecodeGraph(); } return SUCCEEDED(hr); }}
bool CEncode::SetNotifyWindow(HWND inWindow, bool bFlag){ HRESULT hr = E_FAIL; if (bFlag) //压缩过程 { if(m_nEncode.pEvent) { hr = m_nEncode.pEvent->SetNotifyWindow((OAHWND)inWindow, WM_ENCODE_NOTIFY, 0); return SUCCEEDED(hr); } } else //解压过程 if(m_nDecode.pEvent) { hr = m_nDecode.pEvent->SetNotifyWindow((OAHWND)inWindow, WM_DECODE_NOTIFY, 0); return SUCCEEDED(hr); } return false;}
void CEncode::OnCodecNotify(WPARAM inWParam, LPARAM inLParam, bool bFlags){ IMediaEventEx * pEvent = bFlags? m_nEncode.pEvent:m_nDecode.pEvent; if (pEvent) { LONG eventCode = 0, eventParam1 = 0, eventParam2 = 0; while (SUCCEEDED(pEvent->GetEvent(&eventCode, &eventParam1, &eventParam2, 0))) { switch (eventCode) { case EC_COMPLETE: //数据传输完毕 TerminiateProgress(bFlags); bFlags? (m_nEncodeCtl.bCompleted = true) : (m_nDecodeCtl.bCompleted = true); break; case EC_USERABORT: //运行出错 case EC_ERRORABORT: TerminiateProgress(bFlags); bFlags? (m_nEncodeCtl.bCompleted = true) : (m_nDecodeCtl.bCompleted = true); break; default: break; } pEvent->FreeEventParams(eventCode, eventParam1, eventParam2); } } }
int CEncode::_IsH264Encoded(CString strFileName){ IGraphBuilder * pGraph = NULL; IBaseFilter * pSrc = NULL; IBaseFilter * pAviSplitter = NULL; HRESULT hr = E_FAIL; int nResult = -1; do { /******************创建Filter Graph Manager******************/ hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph); if(FAILED(hr)) //创建Filter Graph Manager失败 { AfxMessageBox("Create Filter Graph Manager Failed!"); return nResult; } int nlen = MultiByteToWideChar(CP_ACP, 0, strFileName, -1, NULL, NULL); LPWSTR pstrFile = new WCHAR[nlen]; MultiByteToWideChar(CP_ACP, 0, strFileName, -1, pstrFile, nlen); /***************创建Source Filter与AVI Splitter Filter***************/ hr = pGraph->AddSourceFilter(pstrFile, L"Source Filter", &pSrc); if(pstrFile) delete pstrFile; //释放资源 if(FAILED(hr))//添加Source Filter失败 { AfxMessageBox("Create Source Filter Failed!"); return nResult; } hr = CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAviSplitter); if(FAILED(hr))//创建Avi Splitter Filter 失败 { AfxMessageBox("Add Avi Splitter Filer Failed!"); return nResult; } pGraph->AddFilter(pAviSplitter, L"AVI Splitter");
/****************链接Source Filter 与AVI Splitter Filter**************/ IPin * pSrcOutPin = NULL; IPin * pAviInPin = NULL; IPin * pAviOutPin = NULL; if(_FindPins(pSrc, false, &pSrcOutPin)&&_FindPins(pAviSplitter, true, &pAviInPin)) { hr = pGraph->Connect(pSrcOutPin, pAviInPin); if(FAILED(hr)) //连接失败 { pSrcOutPin->Release(); pAviInPin->Release(); AfxMessageBox("Connect Source Filter to Avi Splitter Failed!"); break; } else //连接成功 { if(_FindPins(pAviSplitter, false, &pAviOutPin)) { IEnumMediaTypes * pEnumType = NULL; hr = pAviOutPin->EnumMediaTypes(&pEnumType); if(FAILED(hr))//枚举pin的媒体类型失败 { pAviOutPin->Release(); AfxMessageBox("Enum MediaTypes Failed!"); break; } else //枚举pin的媒体类型成功 { AM_MEDIA_TYPE * mediaType; ULONG nfeched = 0; pEnumType->Reset(); while(SUCCEEDED(pEnumType->Next(1, &mediaType, &nfeched))&&nfeched)//枚举媒体类型 { static const GUID MEDIASUBTYPE_DT264= {0x52445444, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}}; if(mediaType->subtype == MEDIASUBTYPE_DT264) //为H264编码文件 { nResult = 1; DeleteMediaType(mediaType); break; } else 不为H264编码文件 nResult = 0; DeleteMediaType(mediaType); } pEnumType->Release(); } pAviOutPin->Release(); } pGraph->Disconnect(pSrcOutPin); pGraph->Disconnect(pAviInPin); pSrcOutPin->Release(); pAviInPin->Release(); } } else //查找Source Filter的输出pin或Avi Splitter Filter的输入pin失败 return nResult; }while(false);
/********************释放资源*********************/ if(pAviSplitter) { pGraph->RemoveFilter(pAviSplitter); SafeRelease(pAviSplitter); } if(pSrc) { pGraph->RemoveFilter(pSrc); SafeRelease(pSrc); } SafeRelease(pGraph); return nResult;}
bool CEncode::_IsFileOpenedCorrectly(CString strFileName){ bool bOpened = false; char * pFileName = (LPSTR)(LPCTSTR)strFileName; try { CFile f(pFileName, CFile::modeRead|CFile::shareDenyNone); bOpened = true; f.Close(); } catch(CFileException e) { bOpened = false; throw; } return bOpened;}
bool CEncode::_IsSuitedFileType(CString strFileName){ if(strFileName.IsEmpty()) return false; if (strFileName.GetLength()<5) //文件名长度小于5 return false; else //文件名长度大于5 { if ((strFileName.Right(4)).Compare(".avi")!=0) //文件名后四位不为.avi return false; } return true;}
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);}