您的位置:首页 > 其它

在S3C2440上移植Mplayer_Micro2440

2013-11-22 15:03 288 查看
小学期实践: 在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/目录下,会生产两个子目录include和lib

可能报错:

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
plaincopy

#include <pthread.h>  

#include <stdio.h>  

#include <stdlib.h>  

#include <unistd.h>  

#include <fcntl.h>  

#include <sys/stat.h>  

#include <sys/types.h>  

#include <string.h>  

  

#define MS  1000        /*usleep()*/  

#define REC_MSG_CHNUM   100 /*received the number of characters message*/  

  

/**********************全局变量定义区*****************/  

int fd_fifo;            //创建有名管道,用于向mplayer发送命令  

int fd_pipe[2];         //创建无名管道, 用于从mplayer读取命令  

  

pthread_t tid1;  

pthread_t tid2;  

  

//从标准输入写入命名管道  

void *get_pthread(void *arg)  

{  

    char buf[REC_MSG_CHNUM];  

      

    while(0 != strncmp(buf, "quit", 4)) {  

        printf("please input you cmd:");  

        fflush(stdout);                     //清空输入缓冲区  

        fgets(buf, sizeof(buf), stdin);             //从标准输入获取数据  

        buf[strlen(buf)] = '\0';  

        printf("*%s*\n", buf);  

          

        //Print the message on the screen that is from the writing end ring pipe read             

        if (write(fd_fifo, buf, strlen(buf)) != strlen(buf))  

            perror("write");                //将命令写入命名管道  

      

        usleep(50*MS);  //延时 微妙  

    }  

      

    pthread_cancel(tid2);   //注销掉tid2  

    printf("print pthread exit!\nget pthread exit!\n");  

}  

  

//输出无名管道的信息  

void *print_pthread(void *arg)  

{  

    int size = 0;  

    char buf[REC_MSG_CHNUM];  

    close(fd_pipe[1]);  

      

    while(1) {  

        /* 

        size=read(fd_pipe[0], buf, sizeof(buf));    //从无名管道的写端读取信息打印在屏幕上 

        buf[size]='\0';      

        printf("the msg read form pipe is %s\n",buf); 

        */  

          

        if ((size=read(fd_pipe[0], buf, sizeof(buf))) == -1) {                

            perror("read pipe");  

            exit(0);          

        }  

        if(size == 0)  

            continue;             

        buf[size] = '\0';  

        printf("the msg read form pipe is: %s\n", buf);  

    }  

}  

  

int main(int argc, char* argv[])  

{  

    int fd, ret;  

    char buf[100];  

    pid_t pid;  

      

    unlink("/tmp/my_fifo");                 //如果有名管道存在,则先删除  

    mkfifo("/tmp/my_fifo",O_CREAT|0666);  

    perror("mkfifo");  

      

    if (pipe(fd_pipe)<0) {                   //创建无名管道  

        perror("pipe error\n");  

        exit(-1);  

    }  

  

    pid = fork();  

    if (pid < 0) {  

        perror("fork");  

    }  

    if (pid == 0) {                     //子进程播放mplayer  

        close(fd_pipe[0]);  

        dup2(fd_pipe[1], 1);                //将子进程的标准输出重定向到管道的写端  

        fd_fifo = open("/tmp/my_fifo",O_RDWR);      //打开有名管道   

          

        /*运行mplayer*/   //等同于   ./mplayer -slave -quiet -input file=  

        execlp("./mplayer", "mplayer", "-slave", "-quiet", "-input", "file=/tmp/my_fifo", "new.mp3", NULL);  

    } else {  

        fd_fifo = open("/tmp/my_fifo", O_RDWR);  

        if (fd < 0)  

            perror("open");  

              

        ret = pthread_create(&tid1, NULL, get_pthread, NULL);       //从键盘获取控制信息  

        if (ret != 0) {  

            printf("Create get thread error\n");  

            return ret;  

        }  

                  

        ret = pthread_create(&tid2, NULL, print_pthread, NULL);     //打印从无名管道收到的信息  

        if(ret != 0)  

        {  

            printf("Create print thread error\n");  

            return ret;  

        }  

          

        pthread_join(tid1, NULL);  

        //pthread_join(tid2, NULL);  

          

        printf("\nprocess exit!\n");  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: