不注册ffdshow.ax,怎么在自己的代码使用它?
网上查询了,基本上说的都是类似这个方法http://blog.csdn.net/mjh1021/article/details/5468150
但不知道为什么,我的代码里总是Addfilter失败,难道是我下载的ffdshow.ax有问题。
还有个问题,ffdshow一般都包括了video和audio解码,我怎么去区分使用它(如果需要手动连接就需要区分是什么filter了),难道我只要成功Addfilter了就可以了吗?
用了动态加载是不是不能使用智能连接(RenderFile),还是只能使用手动链接他?
[解决办法]
1)在FFDShow的配置里把自己的程序加进去。
2)如果只需要ffdshow的vdieo、audio解码器,成功Addfilter是第1步,剩下的就是用ICaptureGraphBuilder2把各个Filter成功连接起来。
3)用了动态加载,一般就不用智能连接了,而且智能连接在性能上比手动链接要差些。
[解决办法]
刚才回另一个帖子了,你也试试:
BOOL SafeRegisterFilter(char* pchControlFilePath)
{
BOOL bRegOK = FALSE;
HINSTANCE hInst = LoadLibrary(pchControlFilePath);
if (hInst)
{
typedef HRESULT (*DLLREGISTERSERVER)();
DLLREGISTERSERVER DllRegisterServer = (DLLREGISTERSERVER)GetProcAddress(hInst, "DllRegisterServer");
if (DllRegisterServer)
{
DllRegisterServer();
bRegOK = TRUE;
}
FreeLibrary(hInst);
}
return bRegOK;
}
SafeRegisterFilter("aaa.ax");
试一下这个函数行不行。
再或者,在程序里调用 regsvr32("aaa.ax")。
[解决办法]
"有个问题啊,机子在安装了FFDSHOW之后才会弹出属性设置页,"
你没看到 XunLei 里面有 FFdshow 的东西吗?人家没安装啊,
#ifndef COMUtility_H#define COMUtility_H//////////////////////////////////////////////////////////////////////////#include <Windows.h>//////////////////////////////////////////////////////////////////////////// define the prototype of the class factory entry point in a COM dlltypedef HRESULT (STDAPICALLTYPE *DllGetClassObjectT)(REFCLSID clsid, REFIID iid, LPVOID *ppv);//////////////////////////////////////////////////////////////////////////template <DWORD dwUnique>class COMUtilityT{public: static HRESULT CreateObjectFromPath(REFCLSID clsid, IUnknown **ppUnk, LPCSTR lpszPath) { // load the target DLL directly HMODULE hModule = LoadLibraryA(lpszPath); if (hModule == NULL) { return HRESULT_FROM_WIN32(GetLastError()); } return CreateObjectFromPath(hModule, clsid, ppUnk); } static HRESULT CreateObjectFromPath(REFCLSID clsid, IUnknown **ppUnk, LPCWSTR lpszPath) { // load the target DLL directly HMODULE hModule = LoadLibraryW(lpszPath); if (hModule == NULL) { return HRESULT_FROM_WIN32(GetLastError()); } return CreateObjectFromPath(hModule, clsid, ppUnk); }private: static HRESULT CreateObjectFromPath(HMODULE hModule, REFCLSID clsid, IUnknown **ppUnk) { if (hModule == NULL) { return HRESULT_FROM_WIN32(GetLastError()); } // the entry point is an exported function DllGetClassObjectT fn = (DllGetClassObjectT) GetProcAddress(hModule, "DllGetClassObject"); if (fn == NULL) { return HRESULT_FROM_WIN32(GetLastError()); } // create a class factory CComPtr<IUnknown> pUnknown; HRESULT hr = fn(clsid, IID_IUnknown, (LPVOID *) &pUnknown); if (SUCCEEDED(hr)) { CComQIPtr<IClassFactory> pClassFactory(pUnknown); if (pClassFactory == NULL) { hr = E_NOINTERFACE; } else { // ask the class factory to create the object hr = pClassFactory->CreateInstance(NULL, IID_IUnknown, (LPVOID *) ppUnk); } } return hr; }};//////////////////////////////////////////////////////////////////////////typedef COMUtilityT<0> COMUtility;//////////////////////////////////////////////////////////////////////////#endif
------解决方案--------------------
自己修改ffdshow.ax源代码,将读取注册表的部分改为读取自己的位置(注册表中都是一些ffdshow的设置项),然后自己安装一个ffdshow的源代码同期版本的安装盘,将它的注册表部分保存下来同时修改里面的注册位置,然后把该注册表文件同你的程序放到一起,使用前必须要注册一下,然后直接在自己的程序中加载.ax,得到他的DllGetClassObject接口,后面就是得到各个解码接口直接使用了.
如果不想用注册表的话,那就只有改动更多代码进行默认值的设置,我没做过,可能工作量很大,不知道有人有好方法没。
DWORD err = 0;
std::string SiboPath = ModulePath;
SiboPath += "codec\\ffdshow\\ffdshow.ax";
m_hInst = LoadLibrary(SiboPath.c_str());
if(m_hInst != NULL)
{
m_ffdshow_fun = (pFFDShow_DllGetClassObject)GetProcAddress(m_hInst, "DllGetClassObject");
}