首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

再问filter的mediatype动态改变的有关问题

2013-08-27 
再问filter的mediatype动态改变的问题。我的问题和这个帖子里面的“动态改变视频分辨率的问题?”(http://topi

再问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用的广的话,你还会遇到各种各样的情况,总之就是很麻烦。

热点排行