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了。
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了。
相关文章推荐
- ffmpeg如何转化YUV420p格式为其它视频格式
- ffmpeg如何转化YUV420p格式为其它视频格式
- ffmpeg如何转化YUV420p格式为其它视频格式
- YUV视频格式到RGB32格式转换的速度优化 上篇
- 视频与图像RGB/YUV格式详解
- 视频与图像RGB/YUV格式详解
- 图像视频编码和FFmpeg(2)-----YUV格式介绍和应用
- YUV视频格式到RGB32格式转换的速度优化 中篇
- YUV视频格式到RGB32格式转换的速度优化 上篇
- 视频与图像RGB/YUV格式详解
- 【视频处理】YUV格式说明
- 如何选择视频输出格式的浅见
- android 解码出来的视频frame数据,是如何一步步的传递到显示端的(使用hwc composer online 合成)
- FFmpeg 视频格式转换,avi 转 yuv
- YUV RGB 常见视频格式解析
- android 解码出来的视频frame数据,是如何一步步的传递到显示端的(使用 GPU offline 合成)
- YUV视频格式详解(翻译自微软文档)
- 视频与图像RGB/YUV格式详解
- YUV格式 及 davinci视频采集格式
- 如何使用DirectDraw直接显示YUV视频数据