SDL+Nano-X实现Mplayer窗口播放

 转贴 http://hi.baidu.com/chenzhuoyou/blog/item/d83d6827c5a4c506918f9dcc.html

关键字:SDL Microwindows Nano-X Mplayer

一般做将Mplayer移植到嵌入式设备都是通过直接写Framebuffer来显示视频,因为这样是最快的。但是某些情况我们需要视频只在特定的窗口播放,而非全屏,这是直接用Framebuffer来实现就很困难。这里提供了一种方法,通过SDL+Microwindows(Nano-X)+Mplayer实现窗口播放视频。其实SDL也支持直接写Framebuffer,但是我们需要SDL通过Nano-X提供的绘图函数来绘制视频图片。SDL的最新版本已经包含了Nano-X的补丁,下面分别介绍在X11下和直接用Nano-X写Framebuffer的两种编译设置。

X11:
首先要将Nano-X编译成X11模式,并开启共享内存减少传输,提高性能。即编辑microwin/src下的config文件,修改下面参数
SCREEN_PIXTYPE = MWPF_TRUECOLOR0888
HAVE_SHAREDMEM_SUPPORT = Y

 

然后根据SDL目录下的README.NanoX文件配置编译SDL
./configure --disable-video-x11 --disable-video-fbcon /
            --enable-video-nanox --enable-nanox-share-memory /
            --with-nanox-pixel-type=0888

 

注意:如果仅仅根据上述配置的话,在X11下运行,调试会发现在fblin32.c中的linear32_drawpixel  linear32_drawhorzline  linear32_drawvertline 的assert (c < psd->ncolors) 中的psd->ncolors居然是1<<24得来的(是在x11_scr.c中计算的)。当你运行SDL/src/test中的例程的时候,会发现无法运行,因为背景的c颜色值太大了,好像超过了2G,所以无法成功,想了其他办法,

如修改

SCREEN_PIXTYPE = MWPF_TRUECOLOR8888
和WMtypes.h

typedef unsigned int MWPIXELVAL;

均失败。

所以只能屏蔽这些assert (c < psd->ncolors) ,为出错,可以运行。具体原因还要详细分析。


 

 

最后根据网上教程编译Mplayer


FrameBuffer:
将Nano-X编译成Framebuffer模式,同样开启共享内存支持,具体编译过程请参考网上例子。

SDL:
./configure --disable-video-x11 --disable-video-fbcon /

                 --enable-video-nanox --enable-nanox-direct-fb /

                 --enable-nanox-share-memory

                 --with-nanox-pixel-type=0888
注意--with-nanox-pixel-type应与你的LCD屏的类型对应!


编译完后先启动Nano-X服务器,然后在调用Mplayer播放程序
mplayer -vo sdl filename

如果一切顺利,应该看到Mplayer以全屏显示而非窗口显示,那怎样才能使Mplayer利用Nano-X的窗口播放视频?通过阅读SDL的Nano-X部分的代码,我们发现结构体SDL_PrivateVideoData里有SDL_Window和FSWindow两个GR_WINDOW_ID成员,一个是普通窗口,一个是全屏窗口,通过读取环境变量SDL_WINDOWID来决定使用指定的窗口还是创建一个全屏窗口。因此我们只要设置SDL_WINDOWID,将Nano-X里的一个窗口ID

付给SDL_WINDOWID就可以了,如:
export SDL_WINDOWID=1


在同一终端再次启动Mplayer,视频就会只显示在窗口里。


但你可能会发现视频很慢,丢帧很严重。这是由于SDL驱动没有硬件减速器,在播放视频时通过软件实现缩放。而且你还会发现,视频大小跟Nano-X的根窗口大小有关,而与你指定的窗口无关,即假如你指定的窗口小于跟窗口,那只会显示视频的一部分。

在阅读Mplayer的源代码时我们发现,在libvo/vo_sdl.c里有config函数,播放时视频显示大小就是从这里设置的。我们发现无论怎样在播放时都是全屏模式,因为其中一个判断:

        else {
                  if((strcmp(priv->driver, "x11") == 0)
                  ||(strcmp(priv->driver, "windib") == 0)
                ||(strcmp(priv->driver, "directx") == 0)
                ||(strcmp(priv->driver, "Quartz") == 0)
                  ||(strcmp(priv->driver, "cgx") == 0)
                  ||(strcmp(priv->driver, "os4video") == 0)
                  ||((strcmp(priv->driver, "aalib") == 0) && priv->X)){
               if( mp_msg_test(MSGT_VO,MSGL_V) ) {
                     mp_msg(MSGT_VO,MSGL_V, "SDL: setting windowed mode/n"); }
                set_video_mode(priv->dstwidth, priv->dstheight, priv->bpp, priv->sdlflags);
   }

并没有SDL的驱动,所以最终这个函数会调用set_fullmode(priv->fullmode)根据Nano-X根窗口大小(即Nano-X屏幕)来设置视频大小。因此只要加入 ||(strcmp(priv->driver, "nanox") == 0), 就可以进入窗口模式,而我们可以通过启动Mplayer时设置视频大小,即
Mplayer -vo sdl -x 320 -y 240 filename

最后介绍一下SDL+Nano-X播放Mplayer视频的原理,SDL原本可以直接写屏,即Blit一段图像指针到Framebuffer,Mplayer会将每一帧图像的指针传给SDL。采用Nano-X后,如果没开启Framebuffer,就会采用GrArea来更新视频图像,而开启Framebuffer后其实还是直接Blit写屏。

 

 
FAQ
Microwindows可以编译运行demos文件夹下的例子;SDL可以编译运行test文件夹下的例子;MPlayer似乎也可以运行。但是我在执行mplayer -vo sdl filename这句的时候,MPlayer报Error opening/initializing the selected video_out(-vo) device,然后MPlayer就自己运行了一遍filename但是没有画面。请教怎么解决这个问题!!!
Microwindows版本是0.90 SDL版本是1.2.13 MPlayer版本是1.0rc2 LINUX环境是Redhat9.0 用的是X11界面,对了FrameBuffer也试了一次,结果一样的。我感觉是SDL哪边没配对...
 
Answer:
检查一下你在编译Mplayer时有没有开SDL支持,配置编译Mplayer时 ./configure --enable-sdl ,估计是你Mplayer编译时没开SDL支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值