流氓兔子的嵌入式生活

---------------------------文档库 Making everything simple

用户操作
[即时聊天] [发私信] [加为好友]
ID:hubu01
15755次访问,排名7509(-7)好友0人,关注者1
hubu01的文章
原创 29 篇
翻译 0 篇
转载 12 篇
评论 2 篇
hubu01的公告
Just do it !
最近评论
vvukqr:wow power leveling
ets2008:很好
文章分类
收藏
    相册
    嵌入式圈(精)
    CSDN专家门诊
    daishengs专栏
    device driver
    embedded linux
    Peter lee
    陈志新blog
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 mplayer在ARM9(s3c2410)上的移植收藏

    新一篇: 贪吃蛇游戏 | 旧一篇: 内核论坛的利用

           在S3C2410 嵌入式开发平台上移植了几款linux媒体播放器,感觉播放效果不是很理想,320x240分辨率下的视频播放也不是很流畅,难道200M主频的速度就只能这样了?我开始有点失望了。上个月,当mplayer摘取了年度Linux world 博览会“新媒体”大奖的消息传来,激发了我再次移植mplayer 到2410的决心,尽管前几次移植的结果都不是很成功。

    以前我刚开始在linux下做桌面开发时,就听说mplayer号称linux史上功能最强的媒体播放器,它在桌面上安装起来很方便,简单的configure,make一下,就装好了,和QT的GUI配合,界面还是蛮友好的。Mplayer对媒体格式的广泛支持,以及丰富的后期处理滤镜给我留下深刻印象,最新的版本更支持DIVX,H.264,MPEG4等最新的流媒体格式,可以实时在线播放视频流,这么优秀的播放软件把它移植到嵌入式设备上该多好啊!

    公司里有一块2410的开发板,CPU是三星的S3C2410,arm9的内核,板子做工很精细,以前一直都用它来做开发,买的时候配的是10。4寸的sharp大屏,640X480的分辨率,不错,这样就可以测试在640X480分辨率下的视频播放速度了。硬件平台的问题解决了,下一步下载最新的mplayer源代码包,毕竟最新的源代码包才有最新的功能,当然了BUG估计也是不少的。打开mplayer的官方网站http://www.mplayerhq.hu的主页,可以看到“download”这个链接,点击一下,进入下载页面,在该页面里可以看到“daily CVS snapshot source”的下载部分,这部分链接都指向了每天提交到CVS服务器里最新的mplayer源代码包,鼠标点击一下开始下载!

    1. 开始编译

    下载下来的源代码一般都叫MPlayer-current.tar.bz2的名字,好,开始解包,在命令行下敲以下的命令

    bunzip2 MPlayer-current.tar.bz2 | tar xv –

    查看解包出来的README和INSTALL文件,看看有没有安装时特别声明的东西,这是我的习惯,因为同一个软件的不同版本,安装的方法有时并不一样。然后输入./configure --help看看有没有多出或减少什么选项,还好,没什么变化,于是把以前配置mplayer的命令拿出来,复制,粘贴在命令行上:

    ./configure --cc=arm-linux-gcc --target=arm-armv4-linux --enable-static --prefix=/tmp /mplayer --disable-win32 --disable-dvdread --enable-fbdev --disable-mencoder --disable-live --disable-mp3lib --enable-mad --enable-libavcodec --language=zh_CN

    配置完毕,开始跨平台编译: make

    眼睛盯着编译器反馈的每一个信息,老是担心在哪出错,mplayer的源代码太庞大了,

    又使用到不少第三方的库,谁能保证编译不出问题呢.果然,没编译几下,就停下来了,说什么codec- cfg无法运行,产生不了某某头文件。检查了一下,发现codec-cfg这个可执行文件是最先编译产生的一个文件,这个文件是存在的啊,怎么会执行不了呢?于是手动执行了一下,系统提示“cannot execute binary file”,突然想起来,codec-cfg是按跨平台方式编译的啊,产生的是arm的代码,当然不能在x86上执行了,那就先用不用跨平台编译的方式,先把mplayer编译成x86的代码,于是重新配置,简单的 ./configure, make,然后将生成的

    codec-cfg改名为codec-cfg.x86。然后再按跨平台方式配置,编译,等编译器出现错误停止编译时,将codec-cfg.x86该名为codec-cfg,再make,OK,编译就可以继续进行了。

    在编译期间,还出现了几处错误,都是头文件引用的问题,特别提醒大家的是,在libmpcodecs和libavcodec这两个目录下,有一个疏漏,就是这两个目录的源文件都以

    #incude “config.h” 的方式引用头文件“config.h”,但是在这两个目录下并不存在该头文件“config.h”,这些源文件实际是期望引用mplayer安装包根目录下的“config.h”头文件,

    因此我们需要在libmpcodecs和libavcodec这两个目录下手动建立一个名为config.h的链接并指向mplayer安装包根目录下的“config.h”头文件,建立方法

    $> cd libmpcodecs

    $> ln –s ../config.h config.h

    $> cd ../

    $> cd libavcodec

    $> ln –s ../config.h config.h

    经过几次的编辑修改,终于成功完成对mplayer的编译链接,一看mplayer文件的大小,10M,z这也太太夸张了吧,我还没编译成debug的呢。到目前为止这算是成功的第一步了。

    2.开始调试

    编译出来的代码能正常的在2410上跑吗?心中还是有许多疑问。给板子上电,然后用自己编写的一个网络传输工具将代码传到板子的ramdisk,接着再传上一个10M左右的视频,好了,先不带参数运行mplayer,不错,中文的帮助信息弹出来了,说明程序基本编译对了,这时输入命令 ./mplayer matrix.mpg , 眼睛直盯着屏幕,期待着画面的出现,可惜,在出现了一些视频剪辑的反馈信息后,程序再也不动了,没办法,按CTRL+C结束程序,然后就提示出现段错误。以前听说有linux嵌入式的爱好者移植时也出现这样的错误,但是如果不播放声音时,图像可以出现,于是输入命令 ./mplayer -nosound matrix.mpg,这时画面出来了,这个320x240大小的从网上下载的视频,播放起来相当流畅,好像比平时看的影碟机解码速度还快,那当然了,毕竟是320x240大小,又没声音解码的。

    声音这块不解决,当然是不能说移植成功的,因为mplayer还支持那么多格式的音频解码。但是问题究竟出在哪里呢?用排除法吧!找一个未经任何音频压缩的WAV音频文件,其时就是PCM文件,上传到ramdisk,然后用mplayer播放,还是出现一样的问题,程序死了。好了,这就说明问题并非出现在音频解码部分,极有可能出现在音频流的播放部分。现在市面上大多数的嵌入式开发板的音频驱动是oss规范的驱动,以前自己做过oss的编程,对这块还是比较熟悉。于是开始查看mpalyer,c源文件,看看它是如何实现音频流播放的,

    在音频播放部分它使用到了libao2库的音频播放/控制模块,通过进一步查看ao_oss.c源代码进一步获知mplayer是如何与音频的linux驱动工作的。这一步弄清楚后,重新编译mplayer,打开debug选项,打开调试字符串输出,并在音频播放处设置多处断点,并加上printf语句输出一些变量内容,最终发现在调用ao_oss.c的play()函数时出现除零出错,

    这个问题产生的根源最终追溯到音频的驱动部分。现在大部分的嵌入式板子都使用菲利普uda1341音频芯片,因而也都使用了相同一个音频驱动,即MIZI公司拥有版权的linux uda1341音频驱动,这个驱动基本上符合了oss的规范,但是当使用到多段DMA音频数据传输时,出现了一个问题,即DMA缓冲的建立发生在第一次调用write()函数将音频数据传送到设备描述符的时候,然而oss驱动的调用者通常要在打开音频设备描述时候,就期望获取DMA缓冲的信息,然而因为缓冲尚未建立,因而返回缓冲大小为0这个结果。

    解决的办法是在音频驱动源码的smdk2410_audio_open()函数体,加上如下一段代码,

    if (!output_stream .buffers && audio_setup_buf(&output_stream))

    return -ENOMEM;

    添加的位置具体见以下代码的粗体部分:

    static int smdk2410_audio_open(struct inode *inode, struct file *file)

    {

    int cold = !audio_active;

    DPRINTK("audio_openn");

    if ((file->f_flags & O_ACCMODE) == O_RDONLY) {

    if (audio_rd_refcount || audio_wr_refcount)

    return -EBUSY;

    audio_rd_refcount++;

    } else if ((file->f_flags & O_ACCMODE) == O_WRONLY) {

    if (audio_wr_refcount)

    return -EBUSY;

    audio_wr_refcount++;

    } else if ((file->f_flags & O_ACCMODE) == O_RDWR) {

    if (audio_rd_refcount || audio_wr_refcount)

    return -EBUSY;

    audio_rd_refcount++;

    audio_wr_refcount++;

    } else

    return -EINVAL;

    if (cold) {

    audio_rate = AUDIO_RATE_DEFAULT;

    audio_channels = AUDIO_CHANNELS_DEFAULT;

    audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;

    audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;

    if ((file->f_mode & FMODE_WRITE)){

    init_s3c2410_iis_bus_tx();

    audio_clear_buf(&output_stream);

    // 加上以下这行代码

    if (!output_stream .buffers && audio_setup_buf(&output_stream))

    return -ENOMEM;

    }

    if ((file->f_mode & FMODE_READ)){

    init_s3c2410_iis_bus_rx();

    audio_clear_buf(&input_stream);

    }

    }

    MOD_INC_USE_COUNT;

    return 0;

    }

    改完驱动后,重新编译内核。

    3结论

    mplayer因为直接使用缓冲帧,或者使用别的什么优化的算法,使得在ARM S3C2410视频播放速度得到显著提高,至少在320x240大小,解压mpeg1或2标准的视频时速度是相当流畅的,但是mpeg4解码速度仍显不足。Arm s3c2410的cpu属于精简指令,定点计算,

    无MMX,无硬件浮点计算,因而对大尺寸多媒体编解码的能力仍显不足。业界的解决办法是在CPU外增加硬编解码的DSP,或者在SOC内增加协处理器以加强这方面的功能。

    后记

    在得知xscale PXA255面世后,我决定用将移植好的mplayer拿给他们在板子上测试。mpeg4编码,画面大小为320x240的视频播放已经相当流畅,这也许就是那些市面上用PXA255 CPU做的PDA播放DIVX视频的效果吧!

     原文地址 http://smilecn.spaces.live.com/blog/
     

    发表于 @ 2007年05月21日 03:00:00|评论(loading...)|编辑

    新一篇: 贪吃蛇游戏 | 旧一篇: 内核论坛的利用

    评论:没有评论。

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © hubu01