再问filter的mediatype动态改变的问题。
我的问题和这个帖子里面的“动态改变视频分辨率的问题?”(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
谢谢了。
[解决办法]
我再大体说下步骤:
1、对于inputpin的QueryAccept,主要完成两件事,一个是filter本身对媒体格式的检测,这步没通过的话,直接返回错误,这步通过的话,就是第二步了,这步就是对你后面连接的Filter的inputpin的QueryAccept的调用,返回它的返回值。也就是说,你自己要检测,对你的下游filter一样要检测。因为新的格式不但你要能接受,同时需要你的下游filter也接受才行。
2、检测媒体格式,设置新的格式,按新格式重新分配Sample,用新格式重新调用下游inputpin的ReceiveConnection,重新连接你的outputpin。
[解决办法]
几个地方
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;
}
[解决办法]
首先:
//0x80040227
hr = CompleteConnect(m_Connected);
既然这个函数返回错误,跟进去啊,看看具体是哪步失败。
再有:
前面我说过,inplace框架特殊,注意看明白CompleteConnect,我觉得ReceiveConnection里可以不用调ChangeMediaType,应该是可以自动重连outputpin
[解决办法]
“ReceiveConnection里可以不用调ChangeMediaType,应该是可以自动重连outputpin”
这个是根据你的框架说的,你注意看inplace的框架,由于是inplace,所以他的输入和输出是同一个alloc,所以它一定要求输入和输出的媒体格式完全一样。所以它在完成函数里做了判断,如果不相同,会自动重连。
我这里说的不需要,主要是考虑到框架里已经有这个功能了。具体还要你看代码确定下。
再有,如果你要实时处理数据的话,inplace是很不适合的一个框架,一是ms这个例子本身有几个地方代码有bug,二是它可能会用到render提供的显存,这样速度就会非常慢了。
对于DShow框架来说,觉得最难的地方就是媒体格式的改变这块,关于这部分,文档里描述也不是很多,例子代码的话,一个也没有。我写中间虑镜的时候,也是边调边写,如果你的trans用的广的话,你还会遇到各种各样的情况,总之就是很麻烦。