本文系YoYo Chan原创,转载请保留版权信息和注明出处! 一般做将Mplayer移植到嵌入式设备都是通过直接写Framebuffer来显示视频,因为这样是最快的。但是某些情况我们需要视频只在特定的窗口播放,而非全屏,这是直接用Framebuffer来实现就很困难。这里提供了一种方法,通过SDL+Microwindows(Nano-X)+Mplayer实现窗口播放视频。其实SDL也支持直接写Framebuffer,但是我们需要SDL通过Nano-X提供的绘图函数来绘制视频图片。SDL的最新版本已经包含了Nano-X的补丁,下面分别介绍在X11下和直接用Nano-X写Framebuffer的两种编译设置。 X11: 然后根据SDL目录下的README.NanoX文件配置编译SDL share-memory --with-nanox-pixel-type=0888 最后根据网上教程编译Mplayer
FrameBuffer: SDL: direct-fb --enable-nanox-share-memory --with-nanox-pixel-type=0888 如果一切顺利,应该看到Mplayer以全屏显示而非窗口显示,那怎样才能使Mplayer利用Nano-X的窗口播放视频?通过阅读SDL的Nano-X部分的代码,我们发现结构体SDL_PrivateVideoData里有SDL_Window和FSWindow两个GR_WINDOW_ID成员,一个是普通窗口,一个是全屏窗口,通过读取环境变量SDL_WINDOWID来决定使用指定的窗口还是创建一个全屏窗口。因此我们只要设置SDL_WINDOWID,将Nano-X里的一个窗口ID 付给SDL_WINDOWID就可以了,如:
但你可能会发现视频很慢,丢帧很严重。这是由于SDL驱动没有硬件减速器,在播放视频时通过软件实现缩放。而且你还会发现,视频大小跟Nano-X的根窗口大小有关,而与你指定的窗口无关,即假如你指定的窗口小于跟窗口,那只会显示视频的一部分。 在阅读Mplayer的源代码时我们发现,在libvo\vo_sdl.c里有config函数,播放时视频显示大小就是从这里设置的。我们发现无论怎样在播放时都是全屏模式,因为其中一个判断:
并没有SDL的驱动,所以最终这个函数会调用set_fullmode(priv->fullmode)根据Nano-X根窗口大小(即Nano-X屏幕)来设置视频大小。因此只要加入 ||(strcmp(priv->driver, "nanox") == 0), 就可以进入窗口模式,而我们可以通过启动Mplayer时设置视频大小,即 最后介绍一下SDL+Nano-X播放Mplayer视频的原理,SDL原本可以直接写屏,即Blit一段图像指针到Framebuffer,Mplayer会将每一帧图像的指针传给SDL。采用Nano-X后,如果没开启Framebuffer,就会采用GrArea来更新视频图像,而开启Framebuffer后其实还是直接Blit写屏。 (chenzhuoyou) |