当前位置: 首页 > >

Mplayer

发布时间:

Mplayer 播放器
一.Mplayer 支持的格式 MPlayer 是一个 LINUX 下的视频播放器,它支持相当多的媒体格式,无论在音频播放还 是在视频播放方面,可以说它支持的格式是相当全面的。 视频格式支持:MPEG、AVI、ASF 与 WMV、QuickTime 与 OGG/OGM、SDP、PVA、GIF。 音频格式支持:MP3、WAV、OGG/OGM 文件(Vorbis)、WMA 与 ASF、MP4、CD 音频、XMMS。 二. Mplayer 中头文件的功能分析 config.h version.h mp_msg.h help_mp.h en.h" cfg-mplayer-def.h default_config = sub_reader.h libvo/video_out.h libvo/font_load.h libao2/audio_out.h // 拥有格式自动发现功能的字幕(subtitle)阅读器 // 该文件包含 libvo 视频输出的公共函数、变量 // 有关字体装载的例程 // 音频输出驱动程序相关结构定义和全局数据 // Mplayer 运行时的选项缺省值头文件 char* // 各种本地配置宏定义头 // 版本定义头 #define VERSION "1.0pre7try2-3.4.2" // 消息处理头 // 根据配置自动生成的帮助头 #include "help/help_mp-

libmpcodecs/dec_audio.h // 音频解码 libmpcodecs/dec_video.h // 视频解码 libmpdemux/matroska.h libmpdemux/stream.h libmpdemux/demuxer.h libmpdemux/stheader.h get_path.c spudec.h edl.h m_option.h m_config.h // 多路解复用,媒体容器格式 matroska 处理头 // 流处理 // 多路解复用头文件 // 媒体流头处理 // 路径获取头文件 // SPU 子画面单元头,DVD 字幕流 // 剪辑控制清单 // 选项类型处理头 // 配置处理头文件

三. MPlayer.main 主流程简要说明 int main() { 1) 变量声明,电影信息 movie info: 2) 初始化,消息系统……

- 1 -

play_next_file: 3)播放文件 filename 的循环 goto play_next_file 开始 main: 4) 主处理 main 5) 播放真正主循环 2010 ~3541 while (!eof) { 5.1) 播放音频 PLAY AUDIO 5.3) 处理暂停 PAUSE 5.4) 处理 EDL 5.5) 键盘事件处理, 搜索 2400~3216 while (!brk_cmd && (cmd=mp_input_get_cmd(0,0,0))!=NULL) 5.6) 时间寻道(秒) if (seek_to_sec) 5.7) 寻道 3243 ~ 3306, if (rel_seek_secs || abs_seek_pos) 5.8) 处理 GUI 5.9) 变更 Update OSD 5.10) 找到字幕 find sub 5.11) 处理 X11 窗口 5.12) DVD 字幕 sub: } goto_next_file: 6) 播放结束,转到下个文件 goto_next_file: } 四.Mplayer 源码分析 从 Mplayer.c 的 main 开始处理参数 mconfig = m_config_new(); m_config_register_options(mconfig,mplayer_opts); // TODO : add something to let modules register their options mp_input_register_options(mconfig); parse_cfgfiles(mconfig); 初始化 mpctx 结构体,mpctx 应该是 mplayer context 的意思,顾名思义是一个统筹全局的 变量。 static MPContext *mpctx = &mpctx_s; // Not all functions in mplayer.c take the context as an argument yet static MPContext mpctx_s = { 2017 ~ 2064 decode_audio(sh_audio, ...); 5.2) 播放视频 PLAY VIDEO, 2068 ~ 2300 decode_video(sh_video, ...); while (!eof)

- 2 -

.osd_function = OSD_PLAY, .begin_skip = MP_NOPTS_VALUE, .play_tree_step = 1, .global_sub_pos = -1, .set_of_sub_pos = -1, .file_format = DEMUXER_TYPE_UNKNOWN, .loop_times = -1, #ifdef HAS_DVBIN_SUPPORT .last_dvb_step = 1, #endif }; 原型 typedef struct MPContext { int osd_show_percentage; int osd_function; ao_functions_t *audio_out; play_tree_t *playtree; play_tree_iter_t *playtree_iter; int eof; int play_tree_step; int loop_times; stream_t *stream; demuxer_t *demuxer; sh_audio_t *sh_audio; sh_video_t *sh_video; demux_stream_t *d_audio; demux_stream_t *d_video; demux_stream_t *d_sub; mixer_t mixer; vo_functions_t *video_out; // Frames buffered in the vo ready to flip. Currently always 0 or 1. // This is really a vo variable but currently there’s no suitable vo // struct. int num_buffered_frames; // AV sync: the next frame should be shown when the audio out has this // much (in seconds) buffered data left. Increased when more data is

- 3 -

// written to the ao, decreased when moving to the next frame. // In the audio-only case used as a timer since the last seek // by the audio CPU usage meter. double delay; float begin_skip; ///< start time of the current skip while on edlout mode // audio is muted if either EDL or user activates mute short edl_muted; ///< Stores whether EDL is currently in muted mode. short user_muted; ///< Stores whether user wanted muted mode. int global_sub_size; // this encompasses all subtitle sources int global_sub_pos; // this encompasses all subtitle sources int set_of_sub_pos; int set_of_sub_size; int global_sub_indices[SUB_SOURCES]; 一些 GUI 相关的操作 打开字幕流 打开音视频流 mpctx->stream=open_stream(filename,0,&mpctx->file_format); fileformat 文 件 还 是 TV 流 DEMUXER_TYPE_PLAYLIST 或 DEMUXER_TYPE_UNKNOWN DEMUXER_TYPE_TV current_module 记录状态 vobsub open_stream handle_playlist dumpstream stream_reset(mpctx->stream); stream_seek(mpctx->stream,mpctx->stream->start_pos); f=fopen(stream_dump_name,”wb”); dump 文件流 stream->type==STREAMTYPE_DVD //============ Open DEMUXERS — DETECT file type ====================== Demux。分离视频流和音频流 mpctx->demuxer=demux_open(mpctx->stream,mpctx>file_format,audio_id,video_id,dvdsub_id,filename); Demux 过程 demux_open get_demuxer_type_from_name …… mpctx->d_audio=mpctx->demuxer->audio; mpctx->d_video=mpctx->demuxer->video; mpctx->d_sub=mpctx->demuxer->sub; mpctx->sh_audio=mpctx->d_audio->sh;

- 4 -

mpctx->sh_video=mpctx->d_video->sh; 分离了之后就开始分别 Play audio 和 video 这里只关心 play video /*======================== 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 } } 关键的函数是 update_video 根据 pts 是否正确调整一下同步并在必要的时候丢帧处理。 最终调用 decode_video 开始解码(包括 generate_video_frame 里)。 mpi = mpvdec->decode(sh_video, start, in_size, drop_frame); mpvdec 是在 main 里通过 reinit_video_chain 的一系列调用动态选定的解码程序。 其实就一结构体。它的原型是 typedef struct vd_functions_s { vd_info_t *info; int (*init)(sh_video_t *sh); void (*uninit)(sh_video_t *sh); int (*control)(sh_video_t *sh,int cmd,void* arg, …); mp_image_t* (*decode)(sh_video_t *sh,void* data,int len,int flags); } vd_functions_t; 这是所有解码器必须实现的接口。

- 5 -

int (*init)(sh_video_t *sh);是一个名为 init 的指针,指向一个接受 sh_video_t *类型 参数,并返回 int 类型值的函数地址。 那些 vd_开头的文件都是解码相关的。随便打开一个 vd 文件以上几个函数和 info 变量肯定都 包含了。 mpi 被 mplayer 用来存储解码后的图像。在 mp_image.h 里定义。 typedef struct mp_image_s { unsigned short flags; unsigned char type; unsigned char bpp; // bits/pixel. NOT depth! for RGB it will be n*8 unsigned int imgfmt; int width,height; // stored dimensions int x,y,w,h; // visible dimensions unsigned char* planes[MP_MAX_PLANES]; int stride[MP_MAX_PLANES]; char * qscale; int qstride; int pict_type; // 0->unknown, 1->I, 2->P, 3->B int fields; int qscale_type; // 0->mpeg1/4/h263, 1->mpeg2 int num_planes; /* these are only used by planar formats Y,U(Cb),V(Cr) */ int chroma_width; int chroma_height; int chroma_x_shift; // horizontal int chroma_y_shift; // vertical /* for private use by filter or vo driver (to store buffer id or dmpi) */ void* priv; } mp_image_t; 图像在解码以后会输出到显示器,mplayer 本来就是一个视频播放器么。 但也有可能作为输入 提供给编码器进行二次编码,MP 附带的 mencoder.exe 就是专门用来编码的。在这之前可以定 义 filter 对图像进行处理,以实现各种效果。所有以 vf_开头的文件,都是这样的 filter。 图像的显示是通过 vo,即 video out 来实现的。解码器只负责把解码完成的帧传给 vo,怎样 显示就不用管了。这也是*台相关性最大的部分,单独分出来的好处是不言而喻的,像在 Windows 下有通过 direcx 实现的 vo,Linux 下有输出到 X 的 vo。vo_*文件是各种不同的 vo 实 现,只是他们不都是以显示为目的,像 vo_md5sum.c 只是计算一下图像的 md5 值。 在解码完成以后,即得到 mpi 以后,filter_video 被调用,其结果是整个 filter 链上的所

- 6 -

有 filter 都被调用了一遍,包括最后的 VO,在 vo 的 put_image 里把图像输出到显示器。 这个 时候需要考虑的是图像存储的方法即用哪种色彩空间。

五.MPlayer skin 的格式
MPlayer 有没有内建的皮肤,因此为了能够使用 GUI 必须安装至少一种皮肤。 1.1 目录 skin 的搜索目录(按顺序)是: $(DATADIR)/Skin/ $(PREFIX)/share/mplayer/Skin/ ~/.mplayer/Skin/ 注意,第一个路径依赖于 MPlayer 的安装配置(见 configure 脚本的--prefix 和--datadir 的 参数)。 所有的 skin 被安装到上面列出的一个目录下的自己的目录中,例如: $(PREFIX)/share/mplayer/Skin/default/ 1.2 图像格式 图像必须是真彩的(24 或者 32bpp)PNG 图片。 在主窗口(见下面)中你能使用包含“透明色”的图像:用颜色#FF00FF(深红) 填充的区域在 MPlayer 看来是完全透明的。这意味着你甚至能改变窗口外形如果你的 X 服务器有 XShape 扩 展。 1.3 Skin 的组成部分 目前有三个要被修饰的窗口:主窗口,副窗口,播放条和 Skin 菜单(右键单击弹出)。 主窗口和/或者播放条是控制 MPlayer 的地方。窗口的背景是图像,按钮、滑动条和标签可以 (而且必须)放置在这里,对于每一个项目,都必须指定其位置和大小。 一个按钮有三种状态(按下,释放,禁止),所以按钮图像必须垂直地划分成三部分。细节参 见按钮项目。 滑动条(主要用于搜寻条和音量/*衡控制)可以有任意多的状态,只要你把图像分成上下排 列的足够多份。细节参见 hpotmeter 和 potmeter。 标签有一点特殊:字符需要从图像文件中绘制,而图像中的字符用 字体描述文件描述。后者 一个纯文本文件规定图像中每一字符的 x,y 坐标和大小(图像文件和他的字体描述文件共同 组成一个字体)。细节参见 dlabel 和 slabel。 注意:所有图像都能像图像格式一节中说明的使用透明色。如果 X Server 不支持 XShape 扩 展,透明的部分将显示为黑色。 如果你想使用这个特性,主窗口背景图像的宽度应该能被 8 整 除。 subwindow 是电影显示的地方。如果没有载入电影它将显示一个指定的图像,在这里不允许使 用透明色。 skin 菜单仅仅是提供一个通过菜单控制 MPlayer 的方法。菜单需要两个图像:一个是基础图

- 7 -

像用来显示菜单的正常状态,另一个用来显示被选择的项目。当菜单弹出时,显示第一个图 像。如果你把鼠标在菜单条目上移动,当前选择的项目从第二个图像中复制并覆盖到当前鼠 标指针下面的菜单项目上。 (第二个图像从来不作为整体来显示)。 一个菜单选项用图像中的位置和大小定义(细节参见 skin 菜单)。 为了使按钮,滑动条和菜单项工作,MPlayer 必须知道如果他们被点击的话应该做什么。 这是 利用消息(事件)机制完成的。对于这些项目,你必须定义当他们被点击时将会产生的消息。 1.4 文件 需要制作下列的文件构成一个 skin: 一个配置文件称为 skin,告诉 MPlayer 如何将 skin 的不同部分放在一起,以及如果你在窗 口中某处点击的话应该做什么。 主窗口的背景图像。 主窗口上代表物件的图像(包括一个或更多字体描述文件用来显示标签)。 在副窗口中显示的图像(可选)。 skin 菜单的两个图像(仅当你想要创建菜单时才需要他们)。 除了 skin 的配置文件之外,可以给其它文件起随便什么名字(但字体描述文件必须以.fnt 为 扩展名)。 2 skin 文件 如上所述,这是 skin 的配置文件。它是基于行的;注释行必须以';'开头(只有空格和 tab 可 以放在';'之前)。 文件由 section 组成。每一段描述一个程序的 skin,使用下列的形式: section = section name . . . end 目前只有一个程序,所以只需要一个 section:它的名称是 movieplayer。 这个段中每个窗口用下列形式的块描述: window = window name . . . end 其中 window name 可以是下面各字串中的一项: main -- 对于主窗口 sub -- 对于副窗口 menu -- 对于 skin 菜单

- 8 -

playbar - 播放条 (副窗口和 skin 菜单块是可选的,不一定要创建菜单或者修饰副窗口 )。 在一个窗口的描述块内,用下列形式的一行定义窗口中的每一项目: item = parameter 其中 item 是定义 GUI 项目的类型的字串,parameter 是一个数字或者文字值 (或者一组用逗 号分开的值的列表)。 把上述的放在一起,整个文件看起来就有点像这样: section = movieplayer window = main ; ... items for main window ... end window = sub ; ... items for subwindow ... end window = menu ; ... items for skin menu ... end window = playbar ; ... items for playbar ... end end 图像文件的名称必须不带目录名 -- 图像在 Skin 目录中被搜索,可以(但是并不需要)规定扩 展名。如果文件不存在,MPlayer 将试图装载<filename>.<ext>文件, <ext>可以是 png 或者 PNG(按这个顺序尝试),第一个匹配文件将被使用。 最后是一些用来定位的语句。 通过给定 X 和 Y 坐标主窗口和副窗口可以放置在屏幕的不同的角 落。 0 代表顶端或左端,-1 代表中心然后-2 代表右边或底部: (0, 0)----(-1, 0)----(-2, 0) | | | | | | | | | | | |

(0,-1)----(-1,-1)----(-2,-1)

- 9 -

(0,-2)----(-1,-2)----(-2,-2)

这里有个例子可以把这个搞清楚,假设有个叫 main.png 的图像用来做主窗口: base = main, -1, -1 MPlayer 将尝试装载 main,main.png,main.PNG 文件。 2.1 主窗口和播放条 下面是所有能用于'window = main' . . . 'end'和'window = playbar' 项目的列表。 base = image, X, Y 指定用于主窗口的背景图像,窗口将显示在屏幕上的 X,Y 位置,窗口的大小与图像相同。 注意:这些参数目前对显示窗口不起作用。 警告:图像中的透明区域(彩色的#FF00FF )在没有 XShape 扩展的 X 服务器上是黑色的。图像 的宽度必须能被 8 整除。 button = image, X, Y, width, height, message 将一个大小为 width*height 的按钮放置在 X,Y 的位置,指定的 message 将在按钮被点击时 产生。制定的图像必须有从上到下三个部分 (根据按钮的可能状态),像这样: +------------+ | | | pressed released disabled | | | +------------+ +------------+ +------------+ decoration = enable|disable 允许或禁止 window manager 修饰主窗口,缺省设定是禁止。 注意:这对显示窗口无效。 hpotmeter = button, bwidth, bheight, phases, numphases, default, X, Y, width, height, message vpotmeter = button, bwidth, bheight, phases, numphases, default, X, Y, width, height, message 在 X,Y 位置放置一个大小为 width*height 的水*滑动条。 所用的图像可以划分成不同的部分 用来显示滑动条的不同状态(例如,你能做一个音量滑动条,当音量从最小变到最大时,滑 动条的颜色从绿色变成红色。)。hpotmeter 可以有一个能被水*拖曳的按钮。 参数是: button -- 用于按钮的图像(必须有从上到下三部分,跟 button 中一样) . . 'end'块中的

- 10 -

bwidth,bheight -- 按钮的大小 phases -- 用于 hpotmeter 的不同的状态的图像。 如果你想不要这样的图像可以使用一个特殊 的值 NULL。图像必须像这样被垂直划分成 numphases 个部分: +------------+ | | phase #1 phase #2 ... +------------+ | phase #n | +------------+ numphases -- phase 图像中储存的状态的数量 default -- hpotmeter 的缺省值(范围 0 到 100) X,Y -- hpotmeter 的位置 width,height -- hpotmeter 的宽度和高度 message -- 当 hpotmeter 的值改变时产生的消息 potmeter = phases, numphases, default, X, Y, width, height, message 没有按钮的 hpotmeter,描述参数参见 hpotmeter。 font = fontfile, fontid 定义一个字体。fontfile 是以.fnt 为扩展名的字体描述文件的名字 (不要加上扩展名)。 fontid 用来代表这种字体(见 dlabel 和 slabel),可以定义 25 个字体。 slabel = X, Y, fontid, "text" 在 X,Y 位置放置一个静态的标签。text 将用 fontid 代表的字体显示,text 只能是无格式文 本($x 之类的变量不起作用)而且必须封在一对双引号中(但是"字符不能是 text 的一部分)。 标签由 fontid 代表的字体显示。 dlabel = X, Y, length, align, fontid, "text" 在 X,Y 位置放置一个动态的标签。标签被称为动态的,因为它的 text 周期性地刷新。标签的 最大限度长度由 leghth 给定(它的高度是字符的高度)。如果将要显示的 text 比给定的宽度 宽,它将滚动显示,否则它将在指定的空间之内按 align 参数的值对齐显示:0 表示靠右对 齐,1 表示居中对齐,2 表示靠左对齐。 要显示的文本由 text 给定,text 必须封在一对双引号中(但是"字符不能是 text 的一部分)。 标签使用由 fontid 代表的字体显示。可以在文本中使用下列变量: Variable Meaning $1 hh:mm:ss 格式的播放时间 $2 mmmm:ss 格式的播放时间 | | +------------+ +------------+

- 11 -

$3 $4 $5 $6 $7 $8 $v $V $b $B $$ $a $t $o $f $F $T $p $s $e $x $y $C

hh(小时)格式的播放时间 mm(分)格式的播放时间 ss(秒)格式的播放时间 hh:mm:ss 格式的电影长度 mmmm:ss 格式的电影长度 h:mm:ss 格式的电影长度 xxx.xx%格式的音量 xxx.x 格式的音量 xxx.xx%格式的声道*衡 xxx.x 格式的声道*衡 $字符 一个代表音频格式的字母(none: n,mono: m,stereo: t) track 号(在播放列表中) 文件名 小写格式文件名 大写格式文件名 一个代表媒体流类型的字幕(文件: f,Video CD: v,DVD: d,URL: u) "p"字符(如果电影正在播放并且字体中有"p"这个字符) "s"字符(如果电影停止播放并且字体中有"s"这个字符) "e"字符(如果 playback 被暂停并且字体中有"e"这个字符) 电影宽度 电影高度 使用的编解码器的名字

注意:$a,$T,$p,$s 和$e 变量都返回应该被显示作为特殊的符号 (例如,"e"通常代表像| |这样的暂停符号)的字符,更多信息参见符号部分。 2.2 副窗口 下列的项目能用于'window = sub' . . . 'end'块。 base = image, X, Y, width, height 窗口将在屏幕给定的 X,Y 位置出现(0,0 是左上角)。可以用-1 指定中心-2 指定右边(X)和底 部(Y)。窗口将和图像一样大。 width 和 height 指定窗口的大小,他们是可选的(如果没有他 们,窗口是与图像同样的大小)。 background = R, G, B 设置背景颜色,在图像小于窗口时有用。 2.3 Skin 菜单 如前所述,菜单用两个图像显示。正常的菜单条目从 base 项指定的图像中获得,当前选择的 条目则从 selected 项指定的图像中获得。必须通过 menu 项定义每个菜单条目的位置和大小。 这些是能用于'window = menu'. . . 'end'之间的项目。 base = image 正常的菜单条目的图像。 selected = image

- 12 -

所有条目都被选择的菜单的图像。 menu = X, Y, width, height, essage 定义图像中一个菜单条目的 X,Y 位置和大小。 当鼠标在该条目上被释放时产生 message 消息。 3 字体 字体由一个图像和一个描述文件定义。可以将字符放置在图像中的任何地方,但是必须确保 他们的位置和大小被精确的提交给描述文件。 字体描述文件随着(以.fnt 为扩展名)能有以';'开始的注释行。文件必须有像这样的行 image = image 其中 image 是用于字体的图像文件的名字(不必制定扩展名)。 "char" = X, Y, width, height 这里 X 和 Y 指定 char 字符在图像中的位置(0,0 表示左上角)。width 和 height 是以象素为单 位的字符的尺寸。 下面例子中用 font.png 定义 A,B,C 三个字符。 ; Can be "font" instead of "font.png". image = font.png ; Three characters are enough for demonstration purposes :-) "A" = "B" = 0,0, 7,13 7,0, 7,13

"C" = 14,0, 7,13 3.1 符号 dlabel 中使用的一些变量返回的字符有特殊的意义。这些字符被显示为符号,使得播放 DVD 时显示一个漂亮的 DVD logo 而不是字符‘d’。 下列的表格列出所有能被用来显示符号的字符(所以要求另一种字体)。 字符 p s e n m t f v d u 4.GUI 信息 GUI 信息是能被按钮,滑动条和菜单项产生的消息。 注意:一些信息可能不像所预想的那样工作(或者根本不工作),因为 GUI 还在开发中。 符号 播放 停止 暂停 无声 单声道 立体声 媒体流是文件 媒体流是 Video CD 媒体流是 DVD 媒体流是 URL

- 13 -

Playback 控制: evNext:跳到播放列表中下一个 track。 evPause :暂停播放。 evPauseSwitchToPlay :与 evPlaySwitchToPause 一起形成开关。 他们能用来实现普通的播放 /暂停按钮。两条信息应该被分配到窗口中同一位置的两个按钮上。这条信息暂停播放并使 evPlaySwitchToPause 按钮的图像显示出来(表明点击按钮能继续播放)。 evPlay :开始播放。 evPlaySwitchToPause : 与 evPauseSwitchToPlay 对 应 的 消 息 。 这 条 信 息 开 始 播 放 并 使 evPauseSwitchToPlay 按钮的图像显示出来(表明点击按钮能暂停播放)。 evPrev :跳到播放列表中上一个 track。 evStop :停止播放。 搜索: evBackward10sec evBackward1min evBackward10min 向后搜索 10 秒/1 分钟/10 分钟。 evForward10sec evForward1min evForward10min 向前搜索 10 秒/1 分钟/10 分钟。 evSetMoviePosition 搜索到制定位置(能被滑动条使用;使用与滑动条相关的值( 0-100% ))。 视频控制: evDoubleSize:把电影窗口置为双倍大小。 evFullScreen :切换全屏方式。 evNormalSize:把电影窗口置为正常大小。 音频控制: evDecAudioBufDelay:减少音频缓冲延迟。 evDecBalance:减少声道*衡。 evDecVolume:减少音量。 evIncAudioBufDelay:增加音频缓冲延迟。 evIncBalance:增加声道*衡。 evIncVolume:增加音量。 evMute:禁音/取消禁音。 evSetBalance:设置声道*衡(能被滑动条使用;使用与滑动条相关的值( 0-100% ))。 evSetVolume:设置音量(能被滑动条使用;使用与滑动条相关的值( 0-100% ))。

- 14 -

其他: evAbout:打开关于窗口。 evEqualizer:打开/关闭均衡器。 evExit:退出程序。 evIconify:窗口图标化。 evLoad:装载文件(打开一个文件浏览窗口,你能在其中选择文件)。 evLoadPlay:功能与 evLoad 一样,但是它在文件之后装载自动地开始播放。 evNone:空信息,它没有效果(也许 CVS 版本除外:-))。 evPlaylist:打开/关闭播放列表窗口。 evPlayDVD:尝试打开指定的 DVD-ROM 驱动器中的碟片。 evPlayVCD:尝试打开指定的 CD-ROM 驱动器中的碟片。 evPreferences:打开选项设置窗口。 evSetAspect:设置显示图像的屏幕高宽比。 evSetURL:显示 URL 对话窗口。 evSkinBrowser:打开 skin 浏览器窗口。

- 15 -

- 16 -

Libmpdemux/Demuxer.c { New_demuxer(stream) Open_demux_fmt(demux) }

fmt 的值为 : avi,real,rtp…. 等 对应函数分布在 demux_avi.c, demux_real.c,demux_rtp.c…. 中

Mplayer.c main () { Init input and gui demux_open init_best_audio_codec

Libmpcodes/dec_audio.c audio_codec_list=NULL { selectcode() Initcode() } Libvo/video_out.c video_driver_list=NULL {video_out_drivers video_driver->preinit()}

Libmpcodes/dec_audio.c { 从 mpcodecs_ad_drivers 中选择解码器初始化 } Ad.c mpcodecs_ad_drivers:mp3, acm,pcm….. 等的解码器分布于文 件 ad_mp3lib.c,ad_acm.c,ad_pcm.c

init_best_video_out Libmpcodes/vf.c { vf_open_plugin(filter_list) }

Libvo/video_out.c video_out_drivers:svga,directx…. 等 驱动分布于 vo_svga.c,vo_directx.c 等文件中

vf_open_filter

Libmpcodes/vf.c filter_list: noise, yvu9,eq 等 fileter 分布于 vf_eq.c, vf_noise.c,vf_yuv9.c 等文件中

init_best_video_codec preinit_audio_filters init_best_audio_out

Libmpcodes/dec_video.c video_codec_list =NULL { init_video () }

Libmpcodes/dec_video.c 从 mpcodecs_vd_drivers 中选择 解码器初始化

build_afilter_chain { init_audio_filters } Events loop { decode_audio audio_out->play video_read_frame decode_video } Exit }

Libao2/audio_out.c audio_driver_list=NULL {audio_out_drivers audio_out->init()}

Vd.c mpcodecs_vd_drivers: xvid ,qtvideo…. 等解码器分布于 vd_xvid.c,vd_qtvideo.c 等文件中

Libao2/audio_out.c audio_out_drivers: win32,dsound 等驱动分布于 ao_win32.c,ao_dsound.c 等文件中

Libmpcodes/dec_audio.c { af_init }

Libaf/af.c filter_list: delay,volume 等 filter 分布于 af_delay.c,af_volume.c 等 文件中

- 17 -

- 18 -

Libmpcodecs/dec_audio.c { ad_driver-> decode_audio }

mp3,acm,pcm 等解码器的 decode_audio 函数分布于 ad_mp3lib.c, ad_acm.c, ad_pcm.c 等文件中

win32,dsound 等驱动的播放函数分布于 ao_win32.c, ao_dsound.c 等文件中

Mplayer.c main () { ……….. Events loop { decode_audio audio_out->play video_read_frame decode_video } Exit }

Libmpmuxer/video.c { read_video_packet }

Libmpmuxer/parse_es.c { demux_getc }

Libmpcodecs/dec_video.c { mpvdec->decode vf->put_image }

Libmpmuxer/demuxer.h { ds_fill_buffer } Libmpmuxer/demuxer.c {}

Libmpcodecs/vf_vo.c { video_out->draw_frame }

xvid,qtvideo…. 等解码器 的 decode 函数分布于 vd_xvid.c, vd_qtvideo.c 等 文件中 { mpcodecs_get_image ……}

svga,directx…. 等驱动中的 draw_frame 函数分布于 vo_svga.c, vo_directx.c 等文 件中

Libmpcodecs/vd.c { vf_get_image }

Libmpcodecs/vf.c { vf_get_image }

noise,yvu9,eq 等 fileter 的 get_image 函数分布于 vf_eq.c, vf_noise.c, vf_yuv9.c 等文件中 - 19 -

- 20 -




友情链接: