您的位置:首页 > 其它

WINCE下YUV格式的视频如何传递给Video Renderer

2009-02-25 18:07 351 查看
Video Renderer是DirectShow中的最后一个Filter,用来将解码出来的视频显示到Display中。为了提高显示的性能,Video Renderer使用了DirectDraw的技术,来加快YUV数据的显示速度。当系统中没有提供DirectDraw的驱动时,它又能调用GDI来显示视频。

WinCE中的Video Renderer和Windows中的目标功能一致,但是会有一些小区别。正是这些小区别让我很郁闷。我为我们公司的芯片开发了DirectDraw的驱动以及H.264的视频解码器。在自己写的Video Renderer下面,这些都能工作的很正常。我的DirectDraw能接受NV12格式的YUV数据,而H.264解码器解码出来的也是NV12的YUV数据。理论上讲,只要解码器正确的将格式传递给Video Renderer,那么Video Renderer就能识别该格式,并调用系统中的DirectDraw让其显示。但是实际的操作过程中,我才发现事实并不如此。

当Video Renderer和我的H.264解码器握手时,会来询问我输出的MediaType,也就是调用CTransformFilter::GetMediaType函数。当我在GetMediaType函数中返回NV12的视频格式时,Video Renderer毫无理由的拒绝了这种格式,无论是何种YUV的格式都无情的拒绝了。只有当我返回RGB565的数据格式时,Video Renderer才明确表示接受该格式(注意:RGB565是我Display的Primary Surface的格式)。不是说Video Renderer能支持YUV的数据吗,而且我的DirectDraw也已经可以接受YUV数据了?该死的微软也没有源代码,对我来讲它完全是一个黑盒子。仔仔细细的将微软的英文文档研究了一下,才发现Decoder filter和Video Renderer握手的时候,Video Renderer确实只能接受你系统中Display的Primary Surface的格式,也就是你的显示器主模式的格式。只有当这个握手成功了,并且调用了MediaControl的Run函数之后,Video Renderer才会重新来协商以哪种格式显示。我跟了Video Renderer的汇编代码,发现是通过CVideoAllocator::FindSpeedyType函数来协商的。CVideoAllocator是Video Renderer中提供的Allocator。在该函数中,它会首先调用up stream的GetMediaType来获得新的Media Type,这个时候我将NV12的格式返回出去,Video Renderer就可以接受了。当Video Renderer发现是YUV的格式后,它会调用DirectDraw的CreateSurface来创建相对应格式的Surface,如果创建成功,则接受该格式,否则继续上面的步骤,直到成功。

另外,Video Renderer可以支持DirectDraw的Overlay或者BLT功能,当Overlay无法支持的时候,Video Renderer就采用BLT的方式。在写DirectDraw驱动的时候要注意,虽然Video Renderer能支持BLT的方式,但是它调用CreateSurface的时候一定会创建Overlay的表面,如果失败,就无法连上DirectDraw了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: