北京理工大学 20981 陈罡
注意,本文章和后续关于mplayer往a1200上移植技术的文章均采用mplayer的svn版本为24118。
首先就是svn了,最好采用TortoiseSVN,这个软件在win32下面用起来非常方便
(安装后可能需要重启一下电脑)。
第一步,得到mplayer的代码
在cygwin的home/xxxx/moto/目录下面建立一个目录(这里我只写出我自己的做法),
然后,进入该目录,单击鼠标右键,选择“svn checkout...”,然后输入如下uri:
svn://svn.mplayerhq.hu/mplayer/trunk
下面的checkout directory中,选择home/xxxxx/moto目录,
然后在Revision单选框里面不选择“HEAD revision”,呵呵,mplayer的开发和更新是非常
迅速的,在这里向mplayer的开发者致敬;应该选择“Revision”,然后在它后面的文本框里
面填入:24118,这个版本没什么特别的,只是跟我开始做实验的时候版本一致而已。
svn设置抓图如下:
然后就是漫长的svn导出过程,最后会告诉你导出成功。到了这一步,代表你的mplayer已经
下载到你的机器上了。
第二步,修改configure文件
这里感谢一下e680播霸的作者xinhua666,他提醒我要把编译参数改为-O2而不是缺省的-O4。
需要将configure里面所有的-O4改为-O2,如果用早期mplayer编译的话,需要将config.mak
文件中的-O4改为-O2。
然后就是编译之前的设置:
./configure --host-cc=gcc --cc=arm-linux-gcc --target=arm-linux --enable-static --disable-dvdread --enable-fbdev --disable-x11 --disable-sdl --disable-mencoder
第三步,开始编译
成功以后,就是例牌的make,也是一个漫长的过程,当然不会是一帆风顺。
会出现如下错误:
这里先修改源文件,再用下面命令行手工编译:
其中,dsputil.c中有一个地方
/* DECLARE_ALIGNED_8 (uint64_t, aligned_bak[stride]); */
uint64_t aligned_bak[stride] ; /* 改成这样就可以编译过去 */
DCTELEM * const temp= (DCTELEM*)aligned_temp;
uint8_t * const bak= (uint8_t*)aligned_bak;
DECLARE_ALIGNED_8宏定义在dsputil.h文件中定义似乎有问题,不知道取消了这个align,
解码的时候会不会有问题。
arm-linux-gcc -I../libswscale -I../libavcodec -DHAVE_AV_CONFIG_H -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_ISOC9X_SOURCE -I.. -I.. -I../libavutil -Wdisabled-optimization -I. -I.. -I../libavutil -Wall -Wno-switch -Wpointer-arith -Wredundant-decls -O1 -pipe -ffast-math -fomit-frame-pointer -D_REENTRANT -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DHAVE_CONFIG_H -I/usr/X11R6/include -c -o dsputil.o dsputil.c
然后是下面这个文件出现问题,使用如下命令行不需要修改,手工编译即可:
arm-linux-gcc -DHAVE_AV_CONFIG_H -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_ISOC9X_SOURCE -I.. -I.. -I../libavutil -Wdisabled-optimization -I. -I.. -I../libavutil -Wall -Wno-switch -Wpointer-arith -Wredundant-decls -O1 -pipe -ffast-math -fomit-frame-pointer -D_REENTRANT -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DHAVE_CONFIG_H -I/usr/X11R6/include -c -o intfloat_readwrite.o intfloat_readwrite.c
最后成功生成mplayer的警告如下(但愿不会有什么问题):
/home/wayne/moto/ezx-crosstool-0.5/gcc-arm-iwmmxt/gcc-3.3.6-glibc-2.3.2/arm-linux/lib/gcc-lib/arm-linux/3.3.6/
../../../../arm-linux/lib/libm.a(e_expf.o)(.text+0xb4): In function '__ieee754_expf':
: warning: warning: feholdexcept is not implemented and will always fail
/home/wayne/moto/ezx-crosstool-0.5/gcc-arm-iwmmxt/gcc-3.3.6-glibc-2.3.2/arm-linux/lib/gcc-lib/arm-linux/3.3.6/
../../../../arm-linux/lib/libm.a(e_expf.o)(.text+0x24c): In function `__ieee754_expf':
: warning: warning: fesetenv is not implemented and will always fail
看上去似乎是libm数学库的浮点数出了问题,不管了,先能跑起来再说。
第三步,可以拷贝到真机上测试了。
e680系列的手机,framebuffer是支持16bpp的,刚刚好里面符合mpalyer的标准配置,因此,
通过这种方法编译出来的mplayer是可以直接在e680系列上面使用的。
这里先列出基本的使用方法:
(1)啰嗦一下视频编码方法,采用mencoder。(可以手工在mingw上编译一个,或者网上下载一个)
mencoder a.asf -o a.avi -ovc lavc -oac lavc
这里的-ovc是指output video codec,-oac是指output audio codec,具体都支持什么参数
可以利用mencoder -ovc help或者mencoder -oac help来得到。
(2)手机上测试方法,mplayer拷贝到内存卡,然后利用如下命令测试:
./mplayer -vf rotate=2:scale=240:320 a.avi
这里的-vf rotate=2指视频逆时针旋转90度,适合手机屏幕全屏观看。
到此为止,e680系列的手机应该没问题了,文件有6M多,我就不传上来了,blog空间有限啊:~(。
第四步,开始a1200上面的摸索工作
按照第三步的在手机上的测试方法,同样的视频,在a1200上面无法播放,得到的错误如下:
FATAL:Could not initialize video filters (-vf) or video output (-vo)
看来是由于moto的18bpp引起的,开始从这个错误入手吧。
查找/dev/fb0,结果在libvo中找到了vo_fbdev.c和vo_fbdev2.c。
接着,确定a1200在播放视频之前初始化的时候到底用到了那个函数,经过跟踪,原来是
vo_fbdev.c中的framebuffer初始化fb_preinit()函数。
mplayer.c文件总体上看了一下,总体上是一个大的while循环,在循环里面:
while(!视频文件末端) {
播放视频中的音频部分代码段;
播放视频中的视频部分代码段;
}
代表性代码如下:
/*========================== PLAY AUDIO ============================*/
if (mpctx->sh_audio)
if (!fill_audio_out_buffers())
// at eof, all audio at least written to ao
if (!mpctx->sh_video)
mpctx->eof = PT_NEXT_ENTRY;
if(!mpctx->sh_video) {
// handle audio-only case:
double a_pos=0;
if(!quiet || end_at.type == END_AT_TIME )
a_pos = playing_audio_pts(mpctx->sh_audio, mpctx->d_audio, mpctx->audio_out);
if(!quiet)
print_status(a_pos, 0, 0);
if(end_at.type == END_AT_TIME && end_at.pos < a_pos)
mpctx->eof = PT_NEXT_ENTRY;
update_osd_msg();
} else {
/*========================== PLAY VIDEO ============================*/
vo_pts=mpctx->sh_video->timer*90000.0;
vo_fps=mpctx->sh_video->fps;
if (!mpctx->num_buffered_frames) {
double frame_time = update_video(&blit_frame);
mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"*** ftime=%5.3f ***\n",frame_time);
if (mpctx->sh_video->vf_inited < 0) {
mp_msg(MSGT_CPLAYER,MSGL_FATAL, MSGTR_NotInitializeVOPorVO);
mpctx->eof = 1; goto goto_next_file;
}
if (frame_time < 0)
mpctx->eof = 1;
else {
// might return with !eof && !blit_frame if !correct_pts
mpctx->num_buffered_frames += blit_frame;
time_frame += frame_time / playback_speed; // for nosound
}
}
可以基本肯定,就是这个大循环出了问题。下一步就是一步步慢慢调试了。
呼呼,mplayer到底是经典之作啊,里面真复杂。
今天先这样了,剩下的摸索明天再发。谢谢大家对我的业余爱好的支持。
阅读(7958) | 评论(27) | 转发(0) |