再问filter的mediatype动态改变的问题。

hegu 2011-04-12 10:38:13
我的问题和这个帖子里面的“动态改变视频分辨率的问题?”(http://topic.csdn.net/u/20101210/20/94c2ea0e-1603-4f4d-94ae-30efd093fdc4.html)里面的基本一样,都是Live Source->MPEG2 Demultiplexer->mpeg decode->my filter->video render

上述连路未启动的时候从MPEG2 Demultiplexer输出的分辨率是320*240,而run后,视频实际的分辨率为1280*720,而这时候我的my filter还依然运行在320*240,所以render显示的图像就是320*240,但是如果去掉我的filter,就能正常的动态显示为1280*720的。

我现在在我的filter的input pin的QueryAccept调用tufaqing
贴过的output pin的一个"ChangeMediaType"函数,但是总是在
hr = CompleteConnect(m_Connected);返回失败,返回的hr是0x80040227,
然后render显示的大小没有改变,而系统在不停地调用QueryAccept和ReceiveConnection.

我尝试过载input pin的ReceiveConnection里面调用ChangeMediaType,效果也是一样的。

把我的代码贴上一下,大家有空帮我看看,诶?
这里还不能添加附件呀?
我的代码的下载地址:http://www.qqhelper.info/NullNull.rar

谢谢了。
...全文
298 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Havy 2013-08-18
  • 打赏
  • 举报
回复
同求啊,为什么都没有人分享解决的方法呢?
mlhy20060406 2011-04-23
  • 打赏
  • 举报
回复
做个记号,曾经遇到过一直没有解决
huiyan0828 2011-04-21
  • 打赏
  • 举报
回复
请问,这个文件解决了吗?我也遇到了同样的问题,找不到例子可以借鉴,看到说明看的有点晕~
hegu 2011-04-14
  • 打赏
  • 举报
回复
你说inplace自动支持动态调整mediatype?
但是dshow例子里面的nullnull好像不行。

[Quote=引用 15 楼 rageliu 的回复:]
“ReceiveConnection里可以不用调ChangeMediaType,应该是可以自动重连outputpin”
这个是根据你的框架说的,你注意看inplace的框架,由于是inplace,所以他的输入和输出是同一个alloc,所以它一定要求输入和输出的媒体格式完全一样。所以它在完成函数里做了判断,如果不相同,会自动重连。
我这里说的不需要,主要是考虑到框架里已经有这个功能了。具体还要你……
[/Quote]
rageliu 2011-04-13
  • 打赏
  • 举报
回复
有时间整理个关于格式改变的比较全面的文档,估计会对很多人有帮助。
rageliu 2011-04-13
  • 打赏
  • 举报
回复
“ReceiveConnection里可以不用调ChangeMediaType,应该是可以自动重连outputpin”
这个是根据你的框架说的,你注意看inplace的框架,由于是inplace,所以他的输入和输出是同一个alloc,所以它一定要求输入和输出的媒体格式完全一样。所以它在完成函数里做了判断,如果不相同,会自动重连。
我这里说的不需要,主要是考虑到框架里已经有这个功能了。具体还要你看代码确定下。

再有,如果你要实时处理数据的话,inplace是很不适合的一个框架,一是ms这个例子本身有几个地方代码有bug,二是它可能会用到render提供的显存,这样速度就会非常慢了。

对于DShow框架来说,觉得最难的地方就是媒体格式的改变这块,关于这部分,文档里描述也不是很多,例子代码的话,一个也没有。我写中间虑镜的时候,也是边调边写,如果你的trans用的广的话,你还会遇到各种各样的情况,总之就是很麻烦。
hegu 2011-04-13
  • 打赏
  • 举报
回复
对了,rageliu,你知道有什么可以动态改变mediatype的例子吗?
感觉要是有个例子,应该就会好多了。
hegu 2011-04-13
  • 打赏
  • 举报
回复
首先谢谢指点。:)
我还没有注意 CompleteConnect是在哪里出错了。等下调试一下看看。

请问这话“ReceiveConnection里可以不用调ChangeMediaType,应该是可以自动重连outputpin”是具体什么意思呀?在ReceiveConnection里面什么也不用做?只要CMediaType mt = *pmt;hr = etMediaType(&mt);吗?



谢谢了。


[Quote=引用 12 楼 rageliu 的回复:]
首先:
//0x80040227
hr = CompleteConnect(m_Connected);
既然这个函数返回错误,跟进去啊,看看具体是哪步失败。

再有:
前面我说过,inplace框架特殊,注意看明白CompleteConnect,我觉得ReceiveConnection里可以不用调ChangeMediaType,应该是可以自动重连outputpin
[/Quote]
rageliu 2011-04-13
  • 打赏
  • 举报
回复
首先:
//0x80040227
hr = CompleteConnect(m_Connected);
既然这个函数返回错误,跟进去啊,看看具体是哪步失败。

再有:
前面我说过,inplace框架特殊,注意看明白CompleteConnect,我觉得ReceiveConnection里可以不用调ChangeMediaType,应该是可以自动重连outputpin
hegu 2011-04-13
  • 打赏
  • 举报
回复
我用inplace,就是因为这个简单,只需要考虑加上兼容动态改变就行。其他的可以先不考虑。

我调试了一下,在CBaseFilter::ReconnectPin函数里面返回失败了。
具体可以见下面的图。


[Quote=引用 15 楼 rageliu 的回复:]
“ReceiveConnection里可以不用调ChangeMediaType,应该是可以自动重连outputpin”
这个是根据你的框架说的,你注意看inplace的框架,由于是inplace,所以他的输入和输出是同一个alloc,所以它一定要求输入和输出的媒体格式完全一样。所以它在完成函数里做了判断,如果不相同,会自动重连。
我这里说的不需要,主要是考虑到框架里已经有这个功能了。具体还要你……
[/Quote]
hegu 2011-04-13
  • 打赏
  • 举报
回复
嗯,顶。
看论坛里面不少人问这个问题。
一直没有合适的答案。

[Quote=引用 16 楼 rageliu 的回复:]
有时间整理个关于格式改变的比较全面的文档,估计会对很多人有帮助。
[/Quote]
hegu 2011-04-12
  • 打赏
  • 举报
回复
看这个帖子里面的“动态改变视频分辨率的问题?”(http://topic.csdn.net/u/20101210/20/94c2ea0e-1603-4f4d-94ae-30efd093fdc4.html)里面说:

问题已解决,成功设置了新的格式后解码器会重新分配输出缓冲区长度,然后输出的就是正确的数据了.

不知道这个具体是怎么做的。
hegu 2011-04-12
  • 打赏
  • 举报
回复
这是整个新代码:

#include <streams.h> // DirectShow (includes windows.h)
#include <initguid.h> // declares DEFINE_GUID to declare an EXTERN_C const.
#include <stdio.h>
#include <DvdMedia.h>

// The CLSID used by the minimal, in-place, null filter
// DO NOT REUSE IT. Run uuidgen.exe to create a new one.
// {08af6540-4f21-11cf-aacb-0020af0b99a3}
DEFINE_GUID(CLSID_NullNull,
0x08af6540, 0x4f21, 0x11cf, 0xaa, 0xcb, 0x00, 0x20, 0xaf, 0x0b, 0x99, 0xa3);


// setup data - allows the self-registration to work.

const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_NULL // clsMajorType
, &MEDIASUBTYPE_NULL // clsMinorType
};

const AMOVIESETUP_PIN psudPins[] =
{ { L"Input" // strName
, FALSE // bRendered
, FALSE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"" // strConnectsToPin
, 1 // nTypes
, &sudPinTypes // lpTypes
}
, { L"Output" // strName
, FALSE // bRendered
, TRUE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"" // strConnectsToPin
, 1 // nTypes
, &sudPinTypes // lpTypes
}
};

const AMOVIESETUP_FILTER sudNullNull =
{
&CLSID_NullNull // clsID
, L"Minimal Null" // strName
, MERIT_DO_NOT_USE // dwMerit
, 2 // nPins
, psudPins // lpPin
};

class CMyInputPin : public CTransInPlaceInputPin
{
public:
CMyInputPin::CMyInputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName);

~CMyInputPin() { };
STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);
STDMETHODIMP ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt);

BOOL mReConnet;
};

CMyInputPin::CMyInputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName) : CTransInPlaceInputPin(pObjectName,pFilter,phr,pName)
,mReConnet(FALSE)
{ };

class CMyOutputPin : public CTransInPlaceOutputPin
{
public:
CMyOutputPin::CMyOutputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,LPCWSTR pName);

~CMyOutputPin() { };
STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);
STDMETHODIMP ChangeMediaType(const AM_MEDIA_TYPE *pmt);
};

CMyOutputPin::CMyOutputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName) : CTransInPlaceOutputPin(pObjectName,pFilter,phr,pName)
{ };

STDMETHODIMP CMyOutputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
return CTransInPlaceOutputPin::QueryAccept(pmt);
}

// CNullNull
//
class CNullNull
: public CTransInPlaceFilter
{

public:

static CUnknown *WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);

STDMETHODIMP ChangeMediaType(const AM_MEDIA_TYPE *pmt);

DECLARE_IUNKNOWN;

private:

// Constructor - just calls the base class constructor
CNullNull(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr)
: CTransInPlaceFilter (tszName, punk, CLSID_NullNull, phr)
{ }

// Overrides the PURE virtual Transform of CTransInPlaceFilter base class.
// This is where the "real work" is done by altering *pSample.
// We do the Null transform by leaving it alone.
HRESULT Transform(IMediaSample *pSample);//{ return NOERROR; }

CBasePin * GetPin(int n);

// We accept any input type. We'd return S_FALSE for any we didn't like.
HRESULT CheckInputType(const CMediaType* mtIn) { return S_OK; }
};

STDMETHODIMP CMyInputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::QueryAccept(pmt);

if (hr == S_OK)
{
mReConnet = TRUE;
}

char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::QueryAccept = %08x\n",hr);
OutputDebugStringA(buffer);

return hr;
}

STDMETHODIMP CMyInputPin::ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::ReceiveConnection(pConnector,pmt);

if (hr == S_OK && mReConnet)
{
hr = ((CNullNull*)m_pTIPFilter)->ChangeMediaType(pmt);
}

char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::ReceiveConnection = %08x\n",hr);
OutputDebugStringA(buffer);
return hr;
}


CBasePin * CNullNull::GetPin(int n)
{
HRESULT hr = S_OK;

if(m_pInput == NULL)
{
//CBasePin *pPin = NULL;
m_pInput = new CMyInputPin(("CMyInputPin"),this,&hr,L"Input");
ASSERT(SUCCEEDED(hr));
}

if (m_pOutput == NULL) {

m_pOutput = new CMyOutputPin(("CMyOutputPin"), this, &hr, L"Output");

ASSERT(SUCCEEDED(hr));
}

// Return the appropriate pin

ASSERT (n>=0 && n<=1);
if (n == 0) {
return m_pInput;
} else if (n==1) {
return m_pOutput;
} else {
return NULL;
}
}

STDMETHODIMP CMyOutputPin::ChangeMediaType(const AM_MEDIA_TYPE *pmt)
{
CheckPointer(m_Connected, E_POINTER);
CheckPointer(pmt, E_POINTER);

HRESULT hr = m_Connected->QueryAccept(pmt);
if(FAILED(hr))
{
return hr;
}

hr = m_Connected->ReceiveConnection(this, pmt);
if(FAILED(hr))
{
return hr;
}

CMediaType mt = *pmt;
hr = SetMediaType(&mt);

hr = m_pAllocator->Decommit();
if(FAILED(hr))
{
return hr;
}

//0x80040227
hr = CompleteConnect(m_Connected);
if(FAILED(hr))
{
return hr;
}

hr = m_pAllocator->Commit();
if(FAILED(hr))
{
return hr;
}
return S_OK;
}

STDMETHODIMP CNullNull::ChangeMediaType(const AM_MEDIA_TYPE *pmt)
{
return ((CMyOutputPin*) m_pOutput)->ChangeMediaType(pmt);
}

HRESULT CNullNull::Transform(IMediaSample *pSample)
{
AM_MEDIA_TYPE *pNewMediaType = NULL;
HRESULT hr_sample = NULL;

AM_MEDIA_TYPE mt = {0};
BITMAPINFOHEADER *pbmi = NULL, *pbmiNew = NULL;

hr_sample = pSample->GetMediaType(&pNewMediaType);

if (hr_sample == S_OK && pNewMediaType && pNewMediaType->formattype == FORMAT_VideoInfo2)
{
((CMyOutputPin*) m_pOutput)->ChangeMediaType(pNewMediaType);
}

return NOERROR;
}

// Class factory template - needed for the CreateInstance mechanism
CFactoryTemplate g_Templates[]=
{ { L"Minimal Null"
, &CLSID_NullNull
, CNullNull::CreateInstance
, NULL
, &sudNullNull }
};

int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);


//
// CreateInstance
//
// Provide the way for COM to create a CNullNull object
CUnknown * WINAPI CNullNull::CreateInstance(LPUNKNOWN punk, HRESULT *phr) {

CheckPointer(phr,NULL);

CNullNull *pNewObject =
new CNullNull(NAME("Minimal, in-place, null filter"), punk, phr );

if (pNewObject == NULL) {
*phr = E_OUTOFMEMORY;
}

return pNewObject;
} // CreateInstance



////////////////////////////////////////////////////////////////////////
//
// Exported entry points for registration and unregistration
// (in this case they only call through to default implementations).
//
////////////////////////////////////////////////////////////////////////

STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2( TRUE );
}

STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2( FALSE );
}


//
// DllEntryPoint
//
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);

BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}


// Microsoft C Compiler will give hundreds of warnings about
// unused inline functions in header files. Try to disable them.
#pragma warning( disable:4514)
hegu 2011-04-12
  • 打赏
  • 举报
回复
我按下面的代码修改了这两个函数,还是不行。

STDMETHODIMP CMyInputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::QueryAccept(pmt);

if (hr == S_OK)
{
mReConnet = TRUE;
}

char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::QueryAccept = %08x\n",hr);
OutputDebugStringA(buffer);

return hr;
}

STDMETHODIMP CMyInputPin::ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::ReceiveConnection(pConnector,pmt);

if (hr == S_OK && mReConnet)
{
hr = ((CNullNull*)m_pTIPFilter)->ChangeMediaType(pmt);
}

char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::ReceiveConnection = %08x\n",hr);
OutputDebugStringA(buffer);
return hr;
}

[Quote=引用 9 楼 hegu 的回复:]
我在ReceiveConnection调用过ChangeMediaType,不行,我就又放到QueryAccept里面试试。
我再按你的建议试试。

谢谢了。


引用 7 楼 rageliu 的回复:
几个地方
STDMETHODIMP CMyInputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTra……
[/Quote]
hegu 2011-04-12
  • 打赏
  • 举报
回复
我在ReceiveConnection调用过ChangeMediaType,不行,我就又放到QueryAccept里面试试。
我再按你的建议试试。

谢谢了。

[Quote=引用 7 楼 rageliu 的回复:]
几个地方
STDMETHODIMP CMyInputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::QueryAccept(pmt);//1、这里最好判断结果先

CMediaType mt = *pmt;
SetMediaType(&mt);//2……
[/Quote]
rageliu 2011-04-12
  • 打赏
  • 举报
回复
补充:

由于是用的inplace的框架,上面说的不一定合适(大体是对的,细节要修改),可能有要修改的地方。因为inplace的complate完成函数里做了一个比较有意思的逻辑,以用来确保输入和输出的格式100%相同。请很注意的看明白那个地方的代码。
rageliu 2011-04-12
  • 打赏
  • 举报
回复
几个地方
STDMETHODIMP CMyInputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::QueryAccept(pmt);//1、这里最好判断结果先

CMediaType mt = *pmt;
SetMediaType(&mt);//2、询问而已,这里不要设置格式

hr = ((CNullNull*)m_pTIPFilter)->ChangeMediaType(pmt);//3、这里只是询问,不是连接,该放到ReceiveConnection里啊,ReceiveConnection才是实际的连接

char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::QueryAccept = %08x\n",hr);
OutputDebugStringA(buffer);

return hr;
}

STDMETHODIMP CMyInputPin::ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::ReceiveConnection(pConnector,pmt);//1、判断结果

//2、hr = ((CNullNull*)m_pTIPFilter)->ChangeMediaType(pmt);这个适合的地方
//3、都成功后,才调SetMediaType(&mt)

if (pmt->formattype == FORMAT_VideoInfo2)
{
VIDEOINFOHEADER2 * pHeader = (VIDEOINFOHEADER2 *) pmt->pbFormat;
int mWidth = pHeader->bmiHeader.biWidth;
int mHeight = pHeader->bmiHeader.biHeight;
}
char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::ReceiveConnection = %08x\n",hr);
OutputDebugStringA(buffer);
return hr;
}
hegu 2011-04-12
  • 打赏
  • 举报
回复
都实现了,见上面的代码。

谢谢了。

[Quote=引用 4 楼 oexpress 的回复:]
系统在不停地调用QueryAccept和ReceiveConnection."

你调用基类的实现了没有,QueryAccept和ReceiveConnection.
[/Quote]
hegu 2011-04-12
  • 打赏
  • 举报
回复
第一步,我应该是做了。
第二步应该在哪里做呀?在Transform?我这个是个CTransInPlaceFilter,现在在Transform里面什么也没做,本想按一个帖子调ChangeMediaType,但是我的这个只是开始连接pin是是一个格式,运行后就一直是一个格式。运行时MediaType没有变化,所以也就没有调上那个ChangeMediaType。

下面把我的代码贴上吧:

#include <streams.h> // DirectShow (includes windows.h)
#include <initguid.h> // declares DEFINE_GUID to declare an EXTERN_C const.
#include <stdio.h>
#include <DvdMedia.h>

// The CLSID used by the minimal, in-place, null filter
// DO NOT REUSE IT. Run uuidgen.exe to create a new one.
// {08af6540-4f21-11cf-aacb-0020af0b99a3}
DEFINE_GUID(CLSID_NullNull,
0x08af6540, 0x4f21, 0x11cf, 0xaa, 0xcb, 0x00, 0x20, 0xaf, 0x0b, 0x99, 0xa3);


// setup data - allows the self-registration to work.

const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_NULL // clsMajorType
, &MEDIASUBTYPE_NULL // clsMinorType
};

const AMOVIESETUP_PIN psudPins[] =
{ { L"Input" // strName
, FALSE // bRendered
, FALSE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"" // strConnectsToPin
, 1 // nTypes
, &sudPinTypes // lpTypes
}
, { L"Output" // strName
, FALSE // bRendered
, TRUE // bOutput
, FALSE // bZero
, FALSE // bMany
, &CLSID_NULL // clsConnectsToFilter
, L"" // strConnectsToPin
, 1 // nTypes
, &sudPinTypes // lpTypes
}
};

const AMOVIESETUP_FILTER sudNullNull =
{
&CLSID_NullNull // clsID
, L"Minimal Null" // strName
, MERIT_DO_NOT_USE // dwMerit
, 2 // nPins
, psudPins // lpPin
};

class CMyInputPin : public CTransInPlaceInputPin
{
public:
CMyInputPin::CMyInputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName);

~CMyInputPin() { };
STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);
STDMETHODIMP ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt);
};

CMyInputPin::CMyInputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName) : CTransInPlaceInputPin(pObjectName,pFilter,phr,pName)
{ };

class CMyOutputPin : public CTransInPlaceOutputPin
{
public:
CMyOutputPin::CMyOutputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,LPCWSTR pName);

~CMyOutputPin() { };
STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);
STDMETHODIMP ChangeMediaType(const AM_MEDIA_TYPE *pmt);
};

CMyOutputPin::CMyOutputPin(TCHAR *pObjectName,CTransInPlaceFilter *pFilter,HRESULT *phr,
LPCWSTR pName) : CTransInPlaceOutputPin(pObjectName,pFilter,phr,pName)
{ };

STDMETHODIMP CMyOutputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
return CTransInPlaceOutputPin::QueryAccept(pmt);
}

// CNullNull
//
class CNullNull
: public CTransInPlaceFilter
{

public:

static CUnknown *WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);

STDMETHODIMP ChangeMediaType(const AM_MEDIA_TYPE *pmt);

DECLARE_IUNKNOWN;

private:

// Constructor - just calls the base class constructor
CNullNull(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr)
: CTransInPlaceFilter (tszName, punk, CLSID_NullNull, phr)
{ }

// Overrides the PURE virtual Transform of CTransInPlaceFilter base class.
// This is where the "real work" is done by altering *pSample.
// We do the Null transform by leaving it alone.
HRESULT Transform(IMediaSample *pSample);//{ return NOERROR; }

CBasePin * GetPin(int n);

// We accept any input type. We'd return S_FALSE for any we didn't like.
HRESULT CheckInputType(const CMediaType* mtIn) { return S_OK; }
};

STDMETHODIMP CMyInputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::QueryAccept(pmt);

CMediaType mt = *pmt;
SetMediaType(&mt);

hr = ((CNullNull*)m_pTIPFilter)->ChangeMediaType(pmt);

char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::QueryAccept = %08x\n",hr);
OutputDebugStringA(buffer);

return hr;
}

STDMETHODIMP CMyInputPin::ReceiveConnection( IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
HRESULT hr = CTransInPlaceInputPin::ReceiveConnection(pConnector,pmt);

if (pmt->formattype == FORMAT_VideoInfo2)
{
VIDEOINFOHEADER2 * pHeader = (VIDEOINFOHEADER2 *) pmt->pbFormat;
int mWidth = pHeader->bmiHeader.biWidth;
int mHeight = pHeader->bmiHeader.biHeight;
}
char buffer[1024];
sprintf(buffer,"CTransInPlaceInputPin::ReceiveConnection = %08x\n",hr);
OutputDebugStringA(buffer);
return hr;
}


CBasePin * CNullNull::GetPin(int n)
{
HRESULT hr = S_OK;

if(m_pInput == NULL)
{
//CBasePin *pPin = NULL;
m_pInput = new CMyInputPin(("CMyInputPin"),this,&hr,L"Input");
ASSERT(SUCCEEDED(hr));
}

if (m_pOutput == NULL) {

m_pOutput = new CMyOutputPin(("CMyOutputPin"), this, &hr, L"Output");

ASSERT(SUCCEEDED(hr));
}

// Return the appropriate pin

ASSERT (n>=0 && n<=1);
if (n == 0) {
return m_pInput;
} else if (n==1) {
return m_pOutput;
} else {
return NULL;
}
}

STDMETHODIMP CMyOutputPin::ChangeMediaType(const AM_MEDIA_TYPE *pmt)
{
CheckPointer(m_Connected, E_POINTER);
CheckPointer(pmt, E_POINTER);

HRESULT hr = m_Connected->QueryAccept(pmt);
if(FAILED(hr))
{
return hr;
}

hr = m_Connected->ReceiveConnection(this, pmt);
if(FAILED(hr))
{
return hr;
}

CMediaType mt = *pmt;
hr = SetMediaType(&mt);

hr = m_pAllocator->Decommit();
if(FAILED(hr))
{
return hr;
}

//0x80040227
hr = CompleteConnect(m_Connected);
if(FAILED(hr))
{
return hr;
}

hr = m_pAllocator->Commit();
if(FAILED(hr))
{
return hr;
}
return S_OK;
}

STDMETHODIMP CNullNull::ChangeMediaType(const AM_MEDIA_TYPE *pmt)
{
return ((CMyOutputPin*) m_pOutput)->ChangeMediaType(pmt);
}

HRESULT CNullNull::Transform(IMediaSample *pSample)
{
AM_MEDIA_TYPE *pNewMediaType = NULL;
HRESULT hr_sample = NULL;

AM_MEDIA_TYPE mt = {0};
BITMAPINFOHEADER *pbmi = NULL, *pbmiNew = NULL;

hr_sample = pSample->GetMediaType(&pNewMediaType);

if (hr_sample == S_OK && pNewMediaType && pNewMediaType->formattype == FORMAT_VideoInfo2)
{
((CMyOutputPin*) m_pOutput)->ChangeMediaType(pNewMediaType);
}

return NOERROR;
}

// Class factory template - needed for the CreateInstance mechanism
CFactoryTemplate g_Templates[]=
{ { L"Minimal Null"
, &CLSID_NullNull
, CNullNull::CreateInstance
, NULL
, &sudNullNull }
};

int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);


//
// CreateInstance
//
// Provide the way for COM to create a CNullNull object
CUnknown * WINAPI CNullNull::CreateInstance(LPUNKNOWN punk, HRESULT *phr) {

CheckPointer(phr,NULL);

CNullNull *pNewObject =
new CNullNull(NAME("Minimal, in-place, null filter"), punk, phr );

if (pNewObject == NULL) {
*phr = E_OUTOFMEMORY;
}

return pNewObject;
} // CreateInstance



////////////////////////////////////////////////////////////////////////
//
// Exported entry points for registration and unregistration
// (in this case they only call through to default implementations).
//
////////////////////////////////////////////////////////////////////////

STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2( TRUE );
}

STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2( FALSE );
}


//
// DllEntryPoint
//
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);

BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}


// Microsoft C Compiler will give hundreds of warnings about
// unused inline functions in header files. Try to disable them.
#pragma warning( disable:4514)


[Quote=引用 3 楼 rageliu 的回复:]
我再大体说下步骤:
1、对于inputpin的QueryAccept,主要完成两件事,一个是filter本身对媒体格式的检测,这步没通过的话,直接返回错误,这步通过的话,就是第二步了,这步就是对你后面连接的Filter的inputpin的QueryAccept的调用,返回它的返回值。也就是说,你自己要检测,对你的下游filter一样要检测。因为新的格式不但你要能接受,同时需要你的下游filter……
[/Quote]
CyberLogix 2011-04-12
  • 打赏
  • 举报
回复
系统在不停地调用QueryAccept和ReceiveConnection."

你调用基类的实现了没有,QueryAccept和ReceiveConnection.
加载更多回复(2)

2,542

社区成员

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

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