陆老师,请教视频叠加filter的问题,若主视频fps很小,比如=5,此时叠加视频播放不流畅。

cx0928 2006-03-23 04:31:24
比如fps=5,此时主视频就相当于一个静止的画面,画面内容变化得很缓慢。
原因我已经分析出来了:由于是在视频叠加filter的transform()中调用控制类的DoMixing()进行实际的叠加的,而transform()的调用次数和主视频的fps是一致的,即主视频的fps越小,叠加的次数就越少,从而导致叠加视频不流畅。
---------------------------------------------
现在可以这样处理:将主视频的一个sample和叠加视频的多个sample进行合成,但是由于transform()是由filter自动调用的,在这种情况下如何多次调用transform()实现呢?

请指教!多谢!
...全文
364 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
cx0928 2006-03-27
  • 打赏
  • 举报
回复
to happydeer(新奇军) :
-----------------------------
我参照sdk中的Contrast 例子,在其基础上进行修改。
重载了CTransformFilter::Receive函数,代码如下:

HRESULT CContrast::Receive(IMediaSample *pSample)
{
HRESULT hr=0;
REFERENCE_TIME rtTime1;
REFERENCE_TIME rtTime2;
hr=pSample->GetTime(&rtTime1,&rtTime2);
float fFrameRate=(float)(UNITS/(rtTime2-rtTime1));
int nAdjustCount=(int)(m_FrameRate/fFrameRate);//nAdjustCount>=1
//m_FrameRate为设定的视频帧率,类型:float默认值:24.
if(fFrameRate>=20.0)
{
hr=CTransformFilter::Receive(pSample);
}
else
{
for(int i=0;i<nAdjustCount;i++)
{
rtTime1=((nAdjustCount-i)*rtTime1+i*rtTime2)/nAdjustCount;
rtTime2=((nAdjustCount-i-1)*rtTime1+(i+1)*rtTime2)/nAdjustCount;

hr=pSample->SetTime(&rtTime1,&rtTime2);
hr=CTransformFilter::Receive(pSample);
}
}
return hr;
}

并对其它函数进行相应修改。
------------------------
在graph中加入此filter后,播放的过程中观察VMR属性页中的平均帧率,刚开始时确实提高到了设定值m_FrameRate,但慢慢的会往下降,直到与m_FrameRate相差很远。

请陆老师帮忙看看,方案错误和此处代码中的错误之处,谢谢!
cx0928 2006-03-24
  • 打赏
  • 举报
回复
to: happydeer(新奇军)

比如5fps到15fps,经过frame rate adjuster调整后的sample流应该是s1 s1 s1 s2 s2 s2 s3 s3 s3 s4 s4 s4 s5 s5 s5...

这样一来,需要缓存sample,而IMediaSample对象好像不能直接存储,只能调用IMediaSample::GetPointer,存储实际的图像数据,还需另外存储sample的时间戳,不过IMediaSample对象好像没有这样的接口函数可以由一个图像数据和时间戳构造出一个IMediaSample对象,请指教!
cx0928 2006-03-24
  • 打赏
  • 举报
回复
感谢 lserlohn()

对调Input Pin和Branch Pin 的内容,这样理论上也可以解决问题,不过由于一般情况下,叠加视频的图像大小比主视频小,对调后,input pin和output pin的媒体类型不一致了,这样对于一个已成形的项目来说,需要修改的地方太多,不利于扩展。
Thank you all the same!
-------------------------------------
感谢happydeer的指点,这个主意不错。
happydeer 2006-03-24
  • 打赏
  • 举报
回复
5fps->16fps也没有问题的,要根据input pin上收到的sample时间戳来决定是否要重复发送当前的sample。

如果开发这样一个frame rate adjuster,就把所有的改动转移到这个filter,应用程序需要改动的,只是要加上接入这个filter的代码。另外,这是一个通用的filter,可以重用到其他需要调整frame rate的应用程序中。

to cx0928(阳光): 一般是重写input pin的Receive函数.如果filter的父类是CTransformFilter,重写CTransformFilter::Receive也可以。
cx0928 2006-03-24
  • 打赏
  • 举报
回复
to: happydeer(新奇军)
只要将每个sample deliver 3次就可以了
----------------------------
可是Transform函数是由filter自动调用的,Transform函数返回后,若不用缓存的话,就无从得到当前sample了。
你的意思是否是:
由于CTransformFilter::Receive函数内部调用了CTransformFilter::Transform,重载CTransformFilter::Receive,在其内部多次调用CTransformFilter::Transform
还是其他?
lserlohn 2006-03-24
  • 打赏
  • 举报
回复
其实直接在Branch Pin上的Receive中,进行pSample->AddRef()会不会更简单一些?

然后等待Main Pin中的Sample,然后DoMix,每用完一次之后要释放。

这样不需要修改Sample的时间戳,因为每次发生叠加的时间是由主视频流的时间决定的。

还有一个问题就是,如果是5fps->16fps 该怎么办呢?

其实我觉得这两种方法开发起来,复杂度差不多,这个方法需要修改的地方并不少。
happydeer 2006-03-24
  • 打赏
  • 举报
回复
根本就不要缓冲。5fps -> 15fps,只要将每个sample deliver 3次就可以了,当然,每次sample上的时间戳都要修改。
cx0928 2006-03-24
  • 打赏
  • 举报
回复
5fps到15fps调整时,另外有一个缓存元素个数的问题:
调整s1时,需要缓存的sample为:s1、s2 元素个数=2
调整s2时,需要缓存的sample为:s2、s3、s4、s5 元素个数=4
调整s3时,需要缓存的sample为:s3、s4、s5、s6、s7、s8 元素个数=6
调整s4时,需要缓存的sample为:s4、s5、s6、s7、s8、s9、s10、s11 元素个数=8
...
以此类推:
调整sn时,需要缓存的sample为:sn、s(n+1)、s(n+2)、...、s(3n-2)、s(3n-1) 元素个数=2n
特殊情况:n为最后一帧时,需要缓存的sample只有sn
请教一下陆老师,这样的缓冲队列该如何构建,合适一些?


happydeer 2006-03-23
  • 打赏
  • 举报
回复
可以另外再写一个调整frame rate的filter,插入到主视频的链路,将主视频的frame rate调整到跟叠加视频一样,也是15fps。

---(主视频流)---〉frame rate adjuster -> mixer
(叠加视频流) ->

frame rate adjuster的实现主要还是看Input Pin上接收到的sample的时间戳,以及目标frame rate,来决定是否要丢帧(高frame rate到低frame rate的转换)或重复当前帧(低frame rate到高frame rate的转换)。比如5fps到15fps,经过frame rate adjuster调整后的sample流应该是s1 s1 s1 s2 s2 s2 s3 s3 s3 s4 s4 s4 s5 s5 s5...
lserlohn 2006-03-23
  • 打赏
  • 举报
回复
算法修改就是搞清“谁去叠加谁”,在原来的基础上修改应该不难。
lserlohn 2006-03-23
  • 打赏
  • 举报
回复
一个可行的办法就是把Input Pin和Branch Pin 的内容对调,也就是说,主输入Pin中流入的是叠加的视频,而Branch Pin中流入的是背景图的视频。这样,CFrameList中缓冲的是背景视频,而主视频是叠加的视频,这样fps也就随着叠加视频走了。

叠加算法需要修改,别的,可能需要改改吧。

2,543

社区成员

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

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