现在的位置: 首页 > 综合 > 正文

与大家讨论一下在视频上叠加透明窗口后闪烁的问题,求指导!

2017年10月20日 ⁄ 综合 ⁄ 共 997字 ⁄ 字号 评论关闭

公司作了限制,代码和图片都发不出来,请大家耐心往下看。
   
  RT,当视频处于播放状态时,在视频上画一些图案,如多边形,矩形等,对画出的图形还要实现拖动操作。所以需要响应BUTTONUP,BUTTONDOWN 消息来画图,MOUSEMOVE消息来进行图像拖动。

  既定的方案是在录像上叠加一个完全透明的窗口,把鼠标画图的操作在内存设备中响应,完了再画到透明窗口上去,透明窗口只画了多边形线框,其余部分都是透明的,可以看到视频。
  功能都实现了,但是透明窗口的闪烁很严重,可以看到明显的跳变。

  这个问题我查了几天了,我觉得是这样的:录像是用DSHOW显示的,录像播放时窗口应该是处于不断重绘的状态,而透明窗口和视频窗口处在同一块区域,录像重绘的时候把透明窗口给画掉了,从而导致透明窗口接着重绘,透明窗口重绘又改变了录像的区域,不停循环,就会出现透明窗口闪烁的情况。

    有几点需要注意的是:

  1. 画图是在透明窗口的OnPaint 中画的,但这不是闪烁的原因。
  2. 录像和透明窗口在完全重叠的,所以录像窗口更新应该会导致透明窗口必然的重绘。

    经过大量的百度之后,发现这个问题应该有很多人遇到过,不过大部分都选择了放弃,解决的例子不多。常见的解释是因为录像是在overlay层播放的,透明窗口是基于gdi层实现的,这两个层面应该是不能叠加的。于是我做了实验,在透明窗口的OnPaint中打印日志,事实证明,透明窗口在闪烁的过程中并没有触发打印日志,也就是说不是窗绘造成的。

  我试过了几种方法,比如设置WS_CLIPSIBLINGS,WS_CLIPCHILDREN属性,把该窗口设置成前台窗口,把整块录像区域用ExcludeClipRect 限制更新,结果是:
  1.设置WS_CLIPSIBLINGS,WS_CLIPCHILDREN属性,把该窗口设置成前台窗口照样闪烁。
  2.用ExcludeClipRect 限制更新,我想要画的图形也不会在窗口上显示了,只能看到录像。
  3.我把透明窗口往上移一点,在录像窗口之外的图形不会闪烁,在录像范围内的不停闪。

  根据上面的第三点我猜想会不会是因为窗口模式的录像窗口和透明窗口在不停地抢占顶层窗口的位置,导致窗口切换造成的闪烁。但是我没做过DSHOW,不懂DSHOW的显示机制,希望了解这块的朋友指出我分析中的不足,谢谢!另外我想要实现的这个效果,大家有好的建议请尽管提。

抱歉!评论已关闭.