网站导航: 首页 > 设计参考 > 正文 文章搜索
mplayer在S3C2410上的移植
 
文章编号:
081228171710
文章分类: 单片机 ARM
点 击:
...
关 键 词: mplayer,S3C2410,移植
文章来源:
网络
摘 要:
在S3C2410嵌入式开发平台上移植了几款linux媒体播放器,感觉播放效果不是很理想,320x240分辨率下的视频播放也不是很流畅,难道200M主频的速度就只能这样了?

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

        以前我刚开始在linux下做桌面开发时,就听说mplayer号称linux史上功能最强的媒体播放器,它在桌面上安装起来很方便,简单的 configure,make一下,就装好了,和QT的GUI配合,界面还是蛮友好的。Mplayer对媒体格式的广泛支持,以及丰富的后期处理滤镜给我留下深刻印象,最新的版本更支持DIVX,H.264,MPEG4等最新的流媒体格式,可以实时在线播放视频流,这么优秀的播放软件把它移植到嵌入式设备上该多好啊! 
  
        公司里有一块FS2410的开发板,深圳优龙的板子,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.开始调试     
        编译出来的代码能正常的在FS2410上跑吗?心中还是有许多疑问。给板子上电,然后用自己编写的一个网络传输工具将代码传到板子的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; 
  
  添加的位置具体见以下代码的粗体部分:    

 
  1. static   int   smdk2410_audio_open(struct   inode   *inode,   struct   file   *file)        
  2.  {        
  3.                int   cold   =   !audio_active;       
  4.      
  5.                DPRINTK("audio_open\n");        
  6.      
  7.                if   ((file->f_flags   &   O_ACCMODE)   ==   O_RDONLY)   {     
  8.      
  9.                              if   (audio_rd_refcount   ||   audio_wr_refcount)     
  10.      
  11.                                            return   -EBUSY;     
  12.      
  13.                              audio_rd_refcount++;     
  14.      
  15.                }   else   if   ((file->f_flags   &   O_ACCMODE)   ==   O_WRONLY)   {     
  16.      
  17.                              if   (audio_wr_refcount)     
  18.      
  19.                                            return   -EBUSY;     
  20.      
  21.                              audio_wr_refcount++;     
  22.      
  23.                }   else   if   ((file->f_flags   &   O_ACCMODE)   ==   O_RDWR)   {     
  24.      
  25.                              if   (audio_rd_refcount   ||   audio_wr_refcount)     
  26.      
  27.                                            return   -EBUSY;     
  28.      
  29.                              audio_rd_refcount++;     
  30.      
  31.                              audio_wr_refcount++;     
  32.      
  33.                }   else     
  34.      
  35.                              return   -EINVAL;        
  36.      
  37.              if   (cold)   {     
  38.      
  39.                              audio_rate   =   AUDIO_RATE_DEFAULT;     
  40.      
  41.                              audio_channels   =   AUDIO_CHANNELS_DEFAULT;     
  42.      
  43.                              audio_fragsize   =   AUDIO_FRAGSIZE_DEFAULT;     
  44.      
  45.                              audio_nbfrags   =   AUDIO_NBFRAGS_DEFAULT;     
  46.      
  47.                              if   ((file->f_mode   &   FMODE_WRITE)){     
  48.      
  49.                                                          init_s3c2410_iis_bus_tx();     
  50.      
  51.                                                          audio_clear_buf(&output_stream);     
  52.      
  53.                                //   加上以下这行代码           
  54.                                if   (!output_stream   .buffers   &&   audio_setup_buf(&output_stream))        
  55.                                      return   -ENOMEM;        
  56.                              }     
  57.      
  58.                              if   ((file->f_mode   &   FMODE_READ)){     
  59.      
  60.                                                          init_s3c2410_iis_bus_rx();     
  61.      
  62.                                                          audio_clear_buf(&input_stream);     
  63.      
  64.                              }     
  65.      
  66.                }        
  67.      
  68.                MOD_INC_USE_COUNT;     
  69.      
  70.                return   0;     
  71.      
  72.  }        

3.   结论     
      mplayer因为直接使用缓冲帧,或者使用别的什么优化的算法,使得在ARM   S3C2410视频播放速度得到显著提高,至少在320x240大小,解压mpeg1或2标准的视频时速度是相当流畅的,但是mpeg4解码速度仍显不足。Arm   s3c2410的cpu属于精简指令,定点计算,无MMX,无硬件浮点计算,因而对大尺寸多媒体编解码的能力仍显不足。业界的解决办法是在CPU外增加硬编解码的DSP,或者在SOC内增加协处理器以加强这方面的功能。  
   
  
后记     
      在得知优龙又有新的开发板-xscale   PXA255面世后,我决定用将移植好的mplayer拿给他们在板子上测试。mpeg4编码,画面大小为320x240的视频播放已经相当流畅,这也许就是那些市面上用PXA255   CPU做的PDA播放DIVX视频的效果吧!

 
相关文章:
s3c2410 Timer工作原理[图]
虚拟SPI时序在TC77与S3C2410通信中的应用[图]
s3c2410 MMU(存储器管理单元)讲解[图]
s3c2410 CACHES,WRITE BUFFER讲解[图]
S3C2410中的脉宽调制定时器(PWM)
S3C2410 中断程序的实现
s3c2410 watchdog详解
s3c2410 中断异常处理[图]
基于ARM9芯片S3C2410a的GPRS数据终端设计
ARM系统中DMA方式在数据采集中的应用[图]
AD7888与S3C2410的SPI接口及Linux下嵌入式驱动的实现[图]
基于s3c2410的ARMer9开发平台的使用
ARM S3C2410硬件手册重点
基于ARM S3C2410与TMS320C6416的接口设计[图]
S3C2410上Jffs2的移植
ARM S3C2410驱动TFT-LCD的研究[图]
Blob 在S3C44B0 上的移植
MINIGUI在S3C2410开发板的移植
ARM MPlayer移植过程
在S3C2410上移植yaffs2文件系统
S3C2410 bootloader(vivi)阅读笔记
s3c2410 LCD图片显示
S3C2410 LCD 驱动程序移植及GUI程序编写[图]
S3C2410X开发总结及心得
U-Boot在S3C2410开发板上的移植
ARM SDT汇编格式与GNU汇编格式的移植
S3C2410初始化
S3C2410通过IIS总线与音频芯片UDA1380进行通信
在S3C2410上移植bluetooth(蓝牙)
MiniGUI在AT91RM9200开发板上的移植
S3c2410软件调试总结
uboot移植到S3C44B0X开发板的经历
S3C2410上触摸屏的应用实例
S3c2410的触摸屏及模数转换
S3C2410的快速启动技术
基于嵌入式linux和s3c2410平台的视频采集
S3C44B0下ucos-ii的移植
S3c2410 LCD驱动学习心得
uCOS II 的移植
uCGUI 移植到 S3C44B0X的实验
s3c2410移植MPlayer到linux2.6

 
最新开源项目
 
 
  查看更多...  
 
本站相关产品   淘宝网店
 




 
  查看更多...  

 

本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4