在S3C2440上移植Mplayer_Micro2440

小学期实践: 在S3C2440上移植Mplayer

硬件平台:
Micro2440开发板
主机系统:
RedHat Linux AS5
交叉编译器:
arm-Linux-gcc-4.3.2
源程序: 
libmad-0.15.1b.tar.gz
MPlayer-1.0rc2.tar.bz2

步骤:
1、搭建交叉编译环境(略)
2、编译安装库文件libmad
3、编译安装MPlayer
-------------------------------------------------------------------------------------

2. 编译安装库文件libmad

tar zvxf libmad-0.15.1b.tar.gz

./configure CC=arm-linux-gcc --host=arm-linux --disable-shared --disable-debugging --prefix=/workspace/micro2440/libmad/mad

make

完成之后会出现“--fforce-mem”相关的错误,打开Makefile文件,并找到并删除“--fforce-mem”选项,然后重新make一次就OK了,原因是gcc4.3.2已经将“--fforce-mem”选项去除了,所以会出现上面的错误。

make install

安装完成后,在/workspace/micro2440/mad/目录下,会生产两个子目录includelib

可能报错:

checking for C compiler default output file name... configure: error: C compiler cannot create executables
See `config.log' for more details.

----检查交叉工具的安装  我是直接root登录  重新configure一次就行了

---------------------------------------------------------------------------------------


3、编译安装MPlayer

tar jxvf MPlayer-1.0rc2.tar.bz2

cd  /workspace/micro2440/mplayer/MPlayer-1.0rc2

./configure --host-cc=gcc --cc=arm-linux-gcc --target=arm --enable-static --disable-win32dll --disable-dvdread --disable-dvdread-internal --disable-dvdnav --disable-libdvdcss-internal --enable-fbdev --disable-mencoder --disable-live --enable-mad --enable-libavcodec_a --disable-live --with-extraincdir=/workspace/micro2440/libmad/mad/include --with-extralibdir=/workspace/micro2440/libmad/mad/lib  2>&1 | tee logfile

•配置项解释
ü--enable-mad 是使用libmad支持.
ü--disable-dvbhead --disable-dvdread --disable-dvdnav --disable-dvdread-internal 都是跟DVD相关库
ü--enable-fbdev  打开framebuffer支持.ARM开发板必须的.
ü--enable-static 设置静态连接,如果使用静态编译尺寸大约是8M,动态编译是6M多,这样可能是无论哪种编译方式,mplayer都把自带的解码库链接到自身,多出2M应该是系统标准库的尺寸。
ü--disable-mencoder 禁止编码功能
ü--disable-live 禁止live 555流媒体
ü--enable-libavcodec_a 启用静态的libavcodec解码

make

如果出现不支持pld[r1]指令的问题

在MPlayer-1.0rc2/libmpeg2/motion_comp_arm_s.S文件

和MPlayer-1.0rc2/libavcodec/armv4l/dsputil_arm_s.S文件的开始处写入

#ifndefHAVE_PLD

.macro pldreg

.endm

#endif

重新 make

----------------------------------------------------------------------------------------------

测试运行

将mplayer复制到相应的nfs,确保视频文件和音频文件在同一目录
播放视频:

  ./mplayer panda.mpg -framedrop -quiet -vf rotate=1

或者:

  ./mplayer panda.mpg

播放音频:

  ./mplayerNew_Soul.mp3


如果只有视频,而没有声音,这是因为目标系统上有/dev/dsp音频设备文件,但是是OSS音频驱动需要的是/dev/sound/dsp设备文件,这问题的简单解决方法是建一个符号链接

#mkdir -p /dev/sound

#ln -s /dev/dsp /dev/sound/

----------------------------------------------------------------------------------------------

mplayer运行在slave模式下,用一个程序控制mplayer

在前面已经成功编译mplayer 的基础上,我们进一步研究mplayer 另一种重要的运行模式--slave 模式。并且编写一个多线程的程序,通过这个程序来控制mplayer 播放音视频文件
实际上,带有图形界面的mplayer播放器,例如用QT开发的mplayer播放器,就是利用mplayer运行在slave模式下的原理

•简介:
–默认mplayer是从键盘上获得控制信息
–mplayer另外提供了一种更为灵活的控制方式,用来进行播放控制——slave模式
–在slave模式下,MPlayer为后台运行其他程序,不再截获键盘事件
–MPlayer会从标准输入读一个换行符(\n)分隔开的命令。
•操作:
–#mplayer -input cmdlist

//会打印出一份当前mplayer所支持的所有slave模式的命令


方法一:从控制台输入控制命令(测试使用)

运行mplayer-slave -quiet <movie>,并在控制台窗口输入slave命令。

//-slave启动从模式 

//-quiet不输出冗余的信息

例如:

./mplayernew_soul.mp3 -slave -quiet

或者:

./mplayerpanda.mpg -slave -quiet 


常用的 Mplayer指令:
•loadfile  string       //参数string为歌曲名字。
•mute1/0//静音开关
•pause//暂停/取消暂停
•get_time_length//返回值是播放文件的长度,以秒为单位。
•seekvalue  //向前查找到文件的位置播放参数value为秒数。
•get_percent_pos//返回文件的百分比(0--100)
•get_time_pos//打印出在文件的当前位置用秒表示,采用浮点数
•volume<value> [abs] //增大/减小音量,或将其设置为<value>,如果[abs]不为零
•get_file_name//打印出当前文件名
•get_meta_album//打印出当前文件的'专辑'的元数据
•get_meta_artist//打印出当前文件的'艺术家'的元数据
•get_meta_comment//打印出当前文件的'评论'的元数据
•get_meta_genre//打印出当前文件的'流派'的元数据
•get_meta_title//打印出当前文件的'标题'的元数据
•get_meta_year//打印出当前文件的'年份'的元数据

方法二:从有名管道(fifo)输入控制命令(应用编程中使用)

 #mkfifo</tmp/fifofile>

 #mplayer  -slave -input  file=</tmp/fifofile><movie>

//用户可以通过往管道里写入slave命令来实现对应的功能


-----------------------------------------------------------------

任务:

•这里给出一个原始的程序mplayer-slave-cmd.c,这个程序是个多线程的程序,该程序以slave模式启动mplayer播放器,但是这个程序本身也有些bug,我们的任务就是先仔细阅读程序,然后修改这些bug。
•注意:编译这个程序前,需要先设置交叉编译环境;运行该程序时,确保本程序、mplayer以及相应的音频或者视频文件在同一路径下。

编译命令:

  arm-linux-gccmplayer-slave-cmd.c -o mplayer-slave-cmd –lpthread

提示:编译多线程的程序,参数-lpthread不能少


任务1:

1、程序运行之后,在mplayer没有信息输出的情况下,仍然不断输出“the msg read form pipe is”,怎样

修改程序,才能让程序在mplayer有信息输出的情况下,才输出该信息;而mplayer没有信息输出的情况

下,该信息不会出现?

注:这个问题有时一运行就会出现,有时在输入quit命令之后才会出现。

提示:判断管道读取的内容


任务2:

正常的信息输出顺序应该是“pleaseinput you cmd:”和“themsgread form pipe is”交替出现

(蓝色字体为用户输入的命令)

例如:

pleaseinput you cmd:get_time_pos

*get_time_pos

*

themsgread form pipe is ANS_TIME_POSITION=40.6

pleaseinput you cmd:

但是实际会出现下面这种情况:

pleaseinput you cmd:get_time_pos

*get_time_pos

*

pleaseinput you cmd:thmsgread form pipe is ANS_TIME_POSITION=40.6

请修改程序解决这个问题

提示:使用usleep函数,usleep(n)表示sleepn微秒


任务3:

本程序并没有结束线程和退出的命令,请修改程序,在输入“quit”命令时(退出mplayer的命令),也退出本程序。

-----------------------------------------------------------
贴上修改完的C文件:mplayer-slave-cmd.c
[cpp]  view plain copy
  1. #include <pthread.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <unistd.h>  
  5. #include <fcntl.h>  
  6. #include <sys/stat.h>  
  7. #include <sys/types.h>  
  8. #include <string.h>  
  9.   
  10. #define MS  1000        /*usleep()*/  
  11. #define REC_MSG_CHNUM   100 /*received the number of characters message*/  
  12.   
  13. /**********************全局变量定义区*****************/  
  14. int fd_fifo;            //创建有名管道,用于向mplayer发送命令  
  15. int fd_pipe[2];         //创建无名管道, 用于从mplayer读取命令  
  16.   
  17. pthread_t tid1;  
  18. pthread_t tid2;  
  19.   
  20. //从标准输入写入命名管道  
  21. void *get_pthread(void *arg)  
  22. {  
  23.     char buf[REC_MSG_CHNUM];  
  24.       
  25.     while(0 != strncmp(buf, "quit", 4)) {  
  26.         printf("please input you cmd:");  
  27.         fflush(stdout);                     //清空输入缓冲区  
  28.         fgets(buf, sizeof(buf), stdin);             //从标准输入获取数据  
  29.         buf[strlen(buf)] = '\0';  
  30.         printf("*%s*\n", buf);  
  31.           
  32.         //Print the message on the screen that is from the writing end ring pipe read             
  33.         if (write(fd_fifo, buf, strlen(buf)) != strlen(buf))  
  34.             perror("write");                //将命令写入命名管道  
  35.       
  36.         usleep(50*MS);  //延时 微妙  
  37.     }  
  38.       
  39.     pthread_cancel(tid2);   //注销掉tid2  
  40.     printf("print pthread exit!\nget pthread exit!\n");  
  41. }  
  42.   
  43. //输出无名管道的信息  
  44. void *print_pthread(void *arg)  
  45. {  
  46.     int size = 0;  
  47.     char buf[REC_MSG_CHNUM];  
  48.     close(fd_pipe[1]);  
  49.       
  50.     while(1) {  
  51.         /* 
  52.         size=read(fd_pipe[0], buf, sizeof(buf));    //从无名管道的写端读取信息打印在屏幕上 
  53.         buf[size]='\0';      
  54.         printf("the msg read form pipe is %s\n",buf); 
  55.         */  
  56.           
  57.         if ((size=read(fd_pipe[0], buf, sizeof(buf))) == -1) {                
  58.             perror("read pipe");  
  59.             exit(0);          
  60.         }  
  61.         if(size == 0)  
  62.             continue;             
  63.         buf[size] = '\0';  
  64.         printf("the msg read form pipe is: %s\n", buf);  
  65.     }  
  66. }  
  67.   
  68. int main(int argc, char* argv[])  
  69. {  
  70.     int fd, ret;  
  71.     char buf[100];  
  72.     pid_t pid;  
  73.       
  74.     unlink("/tmp/my_fifo");                 //如果有名管道存在,则先删除  
  75.     mkfifo("/tmp/my_fifo",O_CREAT|0666);  
  76.     perror("mkfifo");  
  77.       
  78.     if (pipe(fd_pipe)<0) {                   //创建无名管道  
  79.         perror("pipe error\n");  
  80.         exit(-1);  
  81.     }  
  82.   
  83.     pid = fork();  
  84.     if (pid < 0) {  
  85.         perror("fork");  
  86.     }  
  87.     if (pid == 0) {                     //子进程播放mplayer  
  88.         close(fd_pipe[0]);  
  89.         dup2(fd_pipe[1], 1);                //将子进程的标准输出重定向到管道的写端  
  90.         fd_fifo = open("/tmp/my_fifo",O_RDWR);      //打开有名管道   
  91.           
  92.         /*运行mplayer*/   //等同于   ./mplayer -slave -quiet -input file=  
  93.         execlp("./mplayer""mplayer""-slave""-quiet""-input""file=/tmp/my_fifo""new.mp3", NULL);  
  94.     } else {  
  95.         fd_fifo = open("/tmp/my_fifo", O_RDWR);  
  96.         if (fd < 0)  
  97.             perror("open");  
  98.               
  99.         ret = pthread_create(&tid1, NULL, get_pthread, NULL);       //从键盘获取控制信息  
  100.         if (ret != 0) {  
  101.             printf("Create get thread error\n");  
  102.             return ret;  
  103.         }  
  104.                   
  105.         ret = pthread_create(&tid2, NULL, print_pthread, NULL);     //打印从无名管道收到的信息  
  106.         if(ret != 0)  
  107.         {  
  108.             printf("Create print thread error\n");  
  109.             return ret;  
  110.         }  
  111.           
  112.         pthread_join(tid1, NULL);  
  113.         //pthread_join(tid2, NULL);  
  114.           
  115.         printf("\nprocess exit!\n");  
  116.     }  
  117.     return 0;  
  118. }  

你可能感兴趣的:(在S3C2440上移植Mplayer_Micro2440)