编写source filter的问题

email_zixuan 2010-01-26 11:57:21
我刚接触directshow不久,用ATL写了一个source filter,但是在graphedit中连接时总是弹出“未找到可用于建立连接的的介质筛选器组合”的对话框。

为了找到原因我把上面写的那个source filter的代码一点一点的替换掉directx 例子中的Async的代码,
包括class factory和
DllMain
DllGetClassObject
DllCanUnloadNow
DllRegisterServer
DllUnregisterServer
这些函数的代码都换成我自己的了,但是问题就出来了,

Async一直都可以连接上,而我原来的那个一直都连接不上,代码替换前后一直就是这样,具体表现就是,Async的IPin接口的Connect
方法会被调用,但是我原来那个的Connect方法就总是不被调用。

有好心人遇到过这类情况吗?我现在真是没办法了,能替换的函数都替换了,基本都是我写的代码了。
...全文
244 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
ID大头哈哈 2011-07-27
  • 打赏
  • 举报
回复
mark
email_zixuan 2010-01-29
  • 打赏
  • 举报
回复
我终于找到原因了,
是com组件的线程模型必须是Both,我一般都用free,估计都是当作单线程对象加载的,
不过还是要十分感谢大家的帮助,
就我分少点,
否则就给大家多分点,
找这个问题2个星期了,
重复写了好几个source filter,
就这一点没有注意,
真是没想到呀,
microsoft还出这种问题,
这怎么让人猜的出来呀
瓶盒 2010-01-29
  • 打赏
  • 举报
回复
楼主的问题估计还是在自已写的IPin接口类及BaseFilter类上。
我用ATL建了一个小球的Filter实例运行还正常,基类用的还是DShow的。
感觉用ATL 写Filter最大的优势还是在写属性页上,用ATL建个属性页确实很方便。
lovestudyeveryday 2010-01-28
  • 打赏
  • 举报
回复
学习
瓶盒 2010-01-28
  • 打赏
  • 举报
回复
能否把你的Sample发来学习一下?
我的邮箱是:zuanhu@163.com
chg 2010-01-28
  • 打赏
  • 举报
回复
给我感觉你声明filter的类型不正确。
可以查看一下AMOVIESETUP_MEDIATYPE,AMOVIESETUP_FILTER 相关结构
另外可以查看一下你的Outpin中的 CheckMediaType 是定义的格式范围过窄?
email_zixuan 2010-01-28
  • 打赏
  • 举报
回复
这是总的头文件:
#ifndef __HEAD_H__
#define __HEAD_H__






#include <stdio.h>
#include <tchar.h>

#include <atlbase.h>
#include <atlstr.h>

#include <windows.h>
#include <olectl.h>
#include <Dshow.h>




#define _FUN_ENTRY { OutputDebugStringA(__FUNCDNAME__"\n"); }
#define VfyWRptr(ptr) { if( IsBadWritePtr(ptr,sizeof(*ptr)) == TRUE || IsBadReadPtr(ptr,sizeof(*ptr)) == TRUE ) return E_POINTER; }




#include "common_syn.h"

#include "enumtype.h"
#include "output_pin.h"

class CAsyncFilter;

#include "enumerate_pins.h"
#include "asyncflt.h"

#include "factory.h"



#endif //__HEAD_H__
email_zixuan 2010-01-28
  • 打赏
  • 举报
回复
这是调用IBaseFilter-》EnumPins是返回的枚举类的头文件,我用一个类写的,为了方便,
class _PINS_ENUMERATER_: public IEnumPins
{

//reference
long ref;
_CMUTEX syn;

//member
CAsyncFilter* parent;
int enum_counter; // Construct to zero.

public:
_PINS_ENUMERATER_( CAsyncFilter* PARENT );

~_PINS_ENUMERATER_();

public:
HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid,void **ppvObject);
ULONG STDMETHODCALLTYPE AddRef( void);
ULONG STDMETHODCALLTYPE Release( void);

HRESULT STDMETHODCALLTYPE Next( ULONG cPins,IPin **ppPins,ULONG *pcFetched);
HRESULT STDMETHODCALLTYPE Skip( ULONG cPins);
HRESULT STDMETHODCALLTYPE Reset( void);
HRESULT STDMETHODCALLTYPE Clone( IEnumPins **ppEnum);
};

这是pin的头文件:
class _OUTPUT_PINS_:
public IPin,
public IAsyncReader
//public IAMAsyncReaderTimestampScaling
{
long ref;
_CMUTEX syn;

IUnknown* parent;

wchar_t pinid[100];

IPin* target; // Construct to NULL;
AM_MEDIA_TYPE targetpintype;

BOOL time_stamp;

public:
_OUTPUT_PINS_( IUnknown* PARENT );
~_OUTPUT_PINS_();

//-------------------------------------------------------------------
// IUnknown
//-------------------------------------------------------------------

public:
HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void **ppvObject);

ULONG STDMETHODCALLTYPE AddRef( void);

ULONG STDMETHODCALLTYPE Release( void);


//-------------------------------------------------------------------
//IPin
//-------------------------------------------------------------------

public:
HRESULT STDMETHODCALLTYPE Connect(
/* [in] */ IPin *pReceivePin,
/* [annotation][in] */
__in_opt const AM_MEDIA_TYPE *pmt);

HRESULT STDMETHODCALLTYPE ReceiveConnection(
/* [in] */ IPin *pConnector,
/* [in] */ const AM_MEDIA_TYPE *pmt);

HRESULT STDMETHODCALLTYPE Disconnect( void);

HRESULT STDMETHODCALLTYPE ConnectedTo(
/* [annotation][out] */
__out IPin **pPin);

HRESULT STDMETHODCALLTYPE ConnectionMediaType(
/* [annotation][out] */
__out AM_MEDIA_TYPE *pmt);

HRESULT STDMETHODCALLTYPE QueryPinInfo(
/* [annotation][out] */
__out PIN_INFO *pInfo);

HRESULT STDMETHODCALLTYPE QueryDirection(
/* [annotation][out] */
__out PIN_DIRECTION *pPinDir);

HRESULT STDMETHODCALLTYPE QueryId(
/* [annotation][out] */
__out LPWSTR *Id);

HRESULT STDMETHODCALLTYPE QueryAccept(
/* [in] */ const AM_MEDIA_TYPE *pmt);

HRESULT STDMETHODCALLTYPE EnumMediaTypes( IEnumMediaTypes **ppEnum );

HRESULT STDMETHODCALLTYPE QueryInternalConnections(
/* [annotation][out] */
__out_ecount_part_opt(*nPin, *nPin) IPin **apPin,
/* [out][in] */ ULONG *nPin);

HRESULT STDMETHODCALLTYPE EndOfStream( void);

HRESULT STDMETHODCALLTYPE BeginFlush( void);

HRESULT STDMETHODCALLTYPE EndFlush( void);

HRESULT STDMETHODCALLTYPE NewSegment(
/* [in] */ REFERENCE_TIME tStart,
/* [in] */ REFERENCE_TIME tStop,
/* [in] */ double dRate);


//-------------------------------------------------------------------
//IAsyncReader
//-------------------------------------------------------------------

public:
HRESULT STDMETHODCALLTYPE RequestAllocator(
/* [in] */ IMemAllocator *pPreferred,
/* [annotation][in] */
__in ALLOCATOR_PROPERTIES *pProps,
/* [annotation][out] */
__out IMemAllocator **ppActual);

HRESULT STDMETHODCALLTYPE Request(
/* [in] */ IMediaSample *pSample,
/* [in] */ DWORD_PTR dwUser);

HRESULT STDMETHODCALLTYPE WaitForNext(
/* [in] */ DWORD dwTimeout,
/* [annotation][out] */
__out_opt IMediaSample **ppSample,
/* [annotation][out] */
__out DWORD_PTR *pdwUser);

HRESULT STDMETHODCALLTYPE SyncReadAligned(
/* [in] */ IMediaSample *pSample);

HRESULT STDMETHODCALLTYPE SyncRead(
/* [in] */ LONGLONG llPosition,
/* [in] */ LONG lLength,
/* [annotation][size_is][out] */
__out_bcount(lLength) BYTE *pBuffer);

HRESULT STDMETHODCALLTYPE Length(
/* [annotation][out] */
__out LONGLONG *pTotal,
/* [annotation][out] */
__out LONGLONG *pAvailable);

//----------------------------------------------------------
// IAMAsyncReaderTimestampScaling
//----------------------------------------------------------

HRESULT STDMETHODCALLTYPE GetTimestampMode( BOOL *pfRaw );

HRESULT STDMETHODCALLTYPE SetTimestampMode( BOOL fRaw );


public:

};

这是pin中枚举的头文件:
//================================================================================================
// IEnumMediaTypes
//================================================================================================
class _IEnumMediaTypes_: public IEnumMediaTypes
{
long ref;
long enum_count;
AM_MEDIA_TYPE type;
AM_MEDIA_TYPE type2;
public:
_IEnumMediaTypes_();
~_IEnumMediaTypes_();

HRESULT STDMETHODCALLTYPE QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject);

ULONG STDMETHODCALLTYPE AddRef( void);

ULONG STDMETHODCALLTYPE Release( void);

HRESULT STDMETHODCALLTYPE Next(
/* [in] */ ULONG cMediaTypes,
/* [annotation][size_is][out] */
__out_ecount_part(cMediaTypes, *pcFetched) AM_MEDIA_TYPE **ppMediaTypes,
/* [annotation][out] */
__out_opt ULONG *pcFetched);

HRESULT STDMETHODCALLTYPE Skip(
/* [in] */ ULONG cMediaTypes);

HRESULT STDMETHODCALLTYPE Reset( void);

HRESULT STDMETHODCALLTYPE Clone(
/* [annotation][out] */
__out IEnumMediaTypes **ppEnum);
};
email_zixuan 2010-01-28
  • 打赏
  • 举报
回复
我把头文件的代码发上来,实现现在还有问题,而且也很简单,就是照着说明写的,
这是Async例子中原来的source filter类,我改成我自己的了,除了名字没改:
//------------------------------------------------------------------------------
// File: AsyncFlt.h
//
// Desc: DirectShow sample code - header file for async filter.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------



// c553f2c0-1529-11d0-b4d1-00805f6cbbea
DEFINE_GUID(CLSID_AsyncSample,
0xc553f2c0, 0x1529, 0x11d0, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea);

class CAsyncFilter : public IBaseFilter,
public IFileSourceFilter
{
public:
CAsyncFilter(LPUNKNOWN pUnk, HRESULT *phr)
{
ref = 1;

IUnknown* p;
this->QueryInterface( IID_IUnknown , (void**)&p );
output_pin = new _OUTPUT_PINS_(p);

state = State_Stopped;

clock = NULL;

related_graph = NULL;
}

~CAsyncFilter()
{
delete [] m_pbData;
delete [] m_pFileName;
}

STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( riid == IID_IUnknown || riid == IID_IBaseFilter )
{
*ppv = this;
AddRef();
return S_OK;
}
else if( riid == IID_IFileSourceFilter )
{
*ppv = static_cast<IFileSourceFilter*>(this);
AddRef();
return S_OK;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
};
STDMETHODIMP_(ULONG) AddRef() {
//return GetOwner()->AddRef();
ref++;
return ref;
};
STDMETHODIMP_(ULONG) Release() {
//return GetOwner()->Release();
ref--;
if( ref == 0 )
{
delete this;
return 0;
}
return ref;
};

// Load a (new) file
STDMETHODIMP Load(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt)
{
_FUN_ENTRY
wcscpy_s( file , sizeof(file)/sizeof(file[0]) , pszFileName );
if( pmt != NULL )
{
filemt = *pmt;
}
else
{
ZeroMemory( &filemt , sizeof(filemt) );
filemt.majortype = MEDIATYPE_Stream;
filemt.subtype = GUID_NULL/*MEDIASUBTYPE_Avi*/;
filemt.formattype = GUID_NULL;
filemt.bFixedSizeSamples = TRUE;
filemt.lSampleSize = 1;
}
return S_OK;
}

// Modeled on IPersistFile::Load
// Caller needs to CoTaskMemFree or equivalent.

STDMETHODIMP GetCurFile(LPOLESTR * ppszFileName, AM_MEDIA_TYPE *pmt)
{
_FUN_ENTRY
*ppszFileName = (LPOLESTR)CoTaskMemAlloc( ( wcsnlen(file,1024) + 1 ) * sizeof(file[0]) );
wcscpy_s( *ppszFileName , wcsnlen(file,1024) + 1 , file );
if( pmt != NULL )
{
*pmt = filemt;
}
return S_OK;
}

//==========================================================================================
// IPersist
//==========================================================================================
public:
HRESULT STDMETHODCALLTYPE GetClassID( CLSID *pClassID);


//==========================================================================================
// IMediaFilter
//==========================================================================================
public:
HRESULT STDMETHODCALLTYPE Stop( void);

HRESULT STDMETHODCALLTYPE Pause( void);

HRESULT STDMETHODCALLTYPE Run( REFERENCE_TIME tStart);

HRESULT STDMETHODCALLTYPE GetState( DWORD dwMilliSecsTimeout,FILTER_STATE *State);

HRESULT STDMETHODCALLTYPE SetSyncSource( IReferenceClock *pClock);

HRESULT STDMETHODCALLTYPE GetSyncSource( IReferenceClock **pClock);

//==========================================================================================
// IBaseFilter
//==========================================================================================
HRESULT STDMETHODCALLTYPE EnumPins( IEnumPins **ppEnum );

HRESULT STDMETHODCALLTYPE FindPin( LPCWSTR Id,IPin **ppPin);

HRESULT STDMETHODCALLTYPE QueryFilterInfo( FILTER_INFO *pInfo);

HRESULT STDMETHODCALLTYPE JoinFilterGraph( IFilterGraph *pGraph,LPCWSTR pName);

HRESULT STDMETHODCALLTYPE QueryVendorInfo( LPWSTR *pVendorInfo);

//==========================================================================================
// end
//==========================================================================================

private:

private:
LPWSTR m_pFileName;
LONGLONG m_llSize;
PBYTE m_pbData;

wchar_t file[1024];
AM_MEDIA_TYPE filemt;

FILTER_STATE state;

IReferenceClock* clock;

wchar_t filter_name[MAX_FILTER_NAME];

static const wchar_t vendor_info[100];

IFilterGraph* related_graph;

long ref;

public:
_OUTPUT_PINS_ *output_pin;
};
email_zixuan 2010-01-27
  • 打赏
  • 举报
回复
是把ATL建立的代码放到async里然后又把class factory和dll的导出函数全部重写。

[Quote=引用 12 楼 email_zixuan 的回复:]
是用ATL建立的,后来又把里面的class factory和dll的那些导出函数重写了。

引用 10 楼 bottlebox 的回复:
楼主在家里能使用的是哪个代码?用ATL建立的项目吗?
用ATL写Filter很麻烦,我以前试过一下,放弃了。


[/Quote]
email_zixuan 2010-01-27
  • 打赏
  • 举报
回复
是用ATL建立的,后来又把里面的class factory和dll的那些导出函数重写了。

[Quote=引用 10 楼 bottlebox 的回复:]
楼主在家里能使用的是哪个代码?用ATL建立的项目吗?
用ATL写Filter很麻烦,我以前试过一下,放弃了。

[/Quote]
绝代坏坏 2010-01-27
  • 打赏
  • 举报
回复
学习了。
瓶盒 2010-01-27
  • 打赏
  • 举报
回复
楼主在家里能使用的是哪个代码?用ATL建立的项目吗?
用ATL写Filter很麻烦,我以前试过一下,放弃了。
email_zixuan 2010-01-26
  • 打赏
  • 举报
回复
谢谢楼上的各位大侠,我把修改后的代码放到家里的计算机中,编译,注册,
居然还能使用,看来基本排除注册表的问题了,
剩下的就是我原来的那个为什么不能用了,
因为毕竟两份代码是一样的,
第一次遇到这种情况,
rageliu 2010-01-26
  • 打赏
  • 举报
回复
刚开始不就看pull的Async啊,建议开始看ball那个例子,我觉得比较适合
blackmash 2010-01-26
  • 打赏
  • 举报
回复
“ Async一直都可以连接上,而我原来的那个一直都连接不上,代码替换前后一直就是这样,具体表现就是,Async的IPin接口的Connect
方法会被调用,但是我原来那个的Connect方法就总是不被调用。 ”

可以一级一级的查上去,看调用connect方法的函数有没有被调用,然后继续往上查。直到找到元凶。
blackmash 2010-01-26
  • 打赏
  • 举报
回复
我觉得可以这样调试:
1. 将你的代码加到async sample code中,看看整个过程的flow
2. 用你自己的code,将上面的flow经过的函数都设一下断点,看看具体是在哪里失败的。
yinfuyong 2010-01-26
  • 打赏
  • 举报
回复
注册只需要个GUID即可注册,还是编译器调试环境的问题,

相同的程序在VS2005或是VC6.0就有能运行,有的不能

就是SDK里面自带的例子,在你安装的路径下也许可以编译成功

但是你把它拷到其他地方再编译说不定就不行了

你说的那些函数都不是主要的,应该不是什么问题

email_zixuan 2010-01-26
  • 打赏
  • 举报
回复
我是说async编译完成后,我在重写里面全部的代码,从dll入口处开始,没有使用任何类库,全是自己写的,重新编译,仍然保留原来的dll名称,也没有反注册开始编译的那个,目前是可以用的,但是相同的代码在我开始写的那个里却使不了,我猜想可能是注册表哪里是不是还需要一些额外的信息,但我真的在sdk的文档中没有找的,sdk中建立连接的流程的文档中好像也没有相关资料。
email_zixuan 2010-01-26
  • 打赏
  • 举报
回复
终于有人说话了,
谢谢楼上的,有一点我没说清楚,
我没有使用基类,所有的代码都是自己写的,我按照文档实现的接口,全部是自己写的代码,
现在的问题是我开始写的那个连接不上,
但是用相同的代码替换到async例子中,然后重新编译,却可以使用,async在替换前编译过,重新编译前也没有进行反注册。
不知道是不是在注册表中需要一些额外的配置信息还是怎么回事,
谢谢楼上的,要是总没人搭理我看来这些分都是你的了
加载更多回复(2)

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧