mplayer 源码分析.docx

上传人:b****3 文档编号:11613620 上传时间:2023-06-01 格式:DOCX 页数:12 大小:82.72KB
下载 相关 举报
mplayer 源码分析.docx_第1页
第1页 / 共12页
mplayer 源码分析.docx_第2页
第2页 / 共12页
mplayer 源码分析.docx_第3页
第3页 / 共12页
mplayer 源码分析.docx_第4页
第4页 / 共12页
mplayer 源码分析.docx_第5页
第5页 / 共12页
mplayer 源码分析.docx_第6页
第6页 / 共12页
mplayer 源码分析.docx_第7页
第7页 / 共12页
mplayer 源码分析.docx_第8页
第8页 / 共12页
mplayer 源码分析.docx_第9页
第9页 / 共12页
mplayer 源码分析.docx_第10页
第10页 / 共12页
mplayer 源码分析.docx_第11页
第11页 / 共12页
mplayer 源码分析.docx_第12页
第12页 / 共12页
亲,该文档总共12页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

mplayer 源码分析.docx

《mplayer 源码分析.docx》由会员分享,可在线阅读,更多相关《mplayer 源码分析.docx(12页珍藏版)》请在冰点文库上搜索。

mplayer 源码分析.docx

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中头文件的功能分析

1.config.h // 各种本地配置宏定义头  

2.version.h // 版本定义头 #define VERSION "1.0pre7try2-3.4.2"  

3.mp_msg.h // 消息处理头  

4.help_mp.h // 根据配置自动生成的帮助头 #include "help/help_mpen.h"  

5.cfg-mplayer-def.h // Mplayer 运行时的选项缺省值头文件 char*  

6.default_config =  

7.sub_reader.h // 拥有格式自动发现功能的字幕(subtitle)阅读器  

8.libvo/video_out.h // 该文件包含 libvo 视频输出的公共函数、变量  

9.libvo/font_load.h // 有关字体装载的例程  

10.libao2/audio_out.h // 音频输出驱动程序相关结构定义和全局数据  

11.libmpcodecs/dec_audio.h // 音频解码  

12.libmpcodecs/dec_video.h // 视频解码  

13.libmpdemux/matroska.h // 多路解复用,媒体容器格式 matroska 处理头  

14.libmpdemux/stream.h // 流处理  

15.libmpdemux/demuxer.h // 多路解复用头文件  

16.libmpdemux/stheader.h // 媒体流头处理  

17.get_path.c // 路径获取头文件  

18.spudec.h // SPU 子画面单元头,DVD 字幕流  

19.edl.h // 剪辑控制清单  

20.m_option.h // 选项类型处理头  

21.m_config.h // 配置处理头文件  

三.MPlayer.main主流程简要说明

1.int main() {  

2.1) 变量声明,电影信息 movie info:

  

3.2) 初始化,消息系统……  

4.play_next_file:

  

5.3)播放文件 filename 的循环 goto play_next_file 开始  

6.main:

  

7.4) 主处理 main  

8.5) 播放真正主循环 2010 ~3541 while (!

eof)  

9.while (!

eof) {  

10.5.1) 播放音频 PLAY AUDIO 2017 ~ 2064 decode_audio(sh_audio, ...);  

11.5.2) 播放视频 PLAY VIDEO, 2068 ~ 2300 decode_video(sh_video, ...);  

12.5.3) 处理暂停 PAUSE  

13.5.4) 处理 EDL  

14.5.5) 键盘事件处理, 搜索2400~3216 while (!

brk_cmd &&  

15.(cmd=mp_input_get_cmd(0,0,0))!

=NULL)  

16.5.6) 时间寻道(秒) if (seek_to_sec)  

17.5.7) 寻道 3243 ~ 3306, if (rel_seek_secs || abs_seek_pos)  

18.5.8) 处理 GUI  

19.5.9) 变更 Update OSD  

20.5.10) 找到字幕 find sub  

21.5.11) 处理 X11 窗口  

22.5.12) DVD 字幕 sub:

  

23.}  

24.goto_next_file:

  

25.6) 播放结束,转到下个文件 goto_next_file:

  

26.}  

四.Mplayer源码分析

从Mplayer.c的main开始处理参数

1.mconfig = m_config_new();  

2.m_config_register_options(mconfig,mplayer_opts);  

3.// TODO :

 add something to let modules register their options  

4.mp_input_register_options(mconfig);  

5.parse_cfgfiles(mconfig);  

初始化mpctx结构体,mpctx应该是mplayercontext的意思,顾名思义是一个统筹全局的变量。

[cpp] viewplaincopy

1.static MPContext *mpctx = &mpctx_s;  

2.// Not all functions in mplayer.c take the context as an argument yet  

3.static MPContext mpctx_s = {  

4..osd_function = OSD_PLAY,  

5..begin_skip = MP_NOPTS_VALUE,  

6..play_tree_step = 1,  

7..global_sub_pos = -1,  

8..set_of_sub_pos = -1,  

9..file_format = DEMUXER_TYPE_UNKNOWN,  

10..loop_times = -1,  

11.#ifdef HAS_DVBIN_SUPPORT  

12..last_dvb_step = 1,  

13.#endif  

14.};  

原型

1.//真正统筹全局的结构  

2.typedef struct MPContext {  

3.    int osd_show_percentage;  

4.    int osd_function;  

5.    const ao_functions_t *audio_out;  

6.    play_tree_t *playtree;  

7.    play_tree_iter_t *playtree_iter;  

8.    int eof;  

9.    int play_tree_step;  

10.    int loop_times;  

11.  

12.    stream_t *stream;  

13.    demuxer_t *demuxer;  

14.    sh_audio_t *sh_audio;  

15.    sh_video_t *sh_video;  

16.    demux_stream_t *d_audio;  

17.    demux_stream_t *d_video;  

18.    demux_stream_t *d_sub;  

19.    mixer_t mixer;  

20.    const vo_functions_t *video_out;  

21.    // Frames buffered in the vo ready to flip. Currently always 0 or 1.  

22.    // This is really a vo variable but currently there's no suitable vo  

23.    // struct.  

24.    int num_buffered_frames;  

25.  

26.    // used to retry decoding after startup/seeking to compensate for codec delay  

27.    int startup_decode_retry;  

28.    // how long until we need to display the "current" frame  

29.    float time_frame;  

30.  

31.    // AV sync:

 the next frame should be shown when the audio out has this  

32.    // much (in seconds) buffered data left. Increased when more data is  

33.    // written to the ao, decreased when moving to the next frame.  

34.    // In the audio-only case used as a timer since the last seek  

35.    // by the audio CPU usage meter.  

36.    double delay;  

37.  

38.    float begin_skip; ///< start time of the current skip while on edlout mode  

39.    // audio is muted if either EDL or user activates mute  

40.    short edl_muted; ///< Stores whether EDL is currently in muted mode.  

41.    short user_muted; ///< Stores whether user wanted muted mode.  

42.  

43.    int global_sub_size; // this encompasses all subtitle sources  

44.    int global_sub_pos; // this encompasses all subtitle sources  

45.    int set_of_sub_pos;  

46.    int set_of_sub_size;  

47.    int sub_counts[SUB_SOURCES];  

48.#ifdef CONFIG_ASS  

49.    // set_of_ass_tracks[i] contains subtitles from set_of_subtitles[i]  

50.    // parsed by libass or NULL if format unsupported  

51.    ASS_Track* set_of_ass_tracks[MAX_SUBTITLE_FILES];  

52.#endif  

53.    sub_data* set_of_subtitles[MAX_SUBTITLE_FILES];  

54.  

55.    int file_format;  

56.  

57.#ifdef CONFIG_DVBIN  

58.    int last_dvb_step;  

59.    int dvbin_reopen;  

60.#endif  

61.  

62.    int was_paused;  

63.  

64.#ifdef CONFIG_DVDNAV  

65.    struct mp_image *nav_smpi;   ///< last decoded dvdnav video image  

66.    unsigned char *nav_buffer;   ///< last read dvdnav video frame  

67.    unsigned char *nav_start;    ///< pointer to last read video buffer  

68.    int            nav_in_size;  ///< last read size  

69.#endif  

70.} MPContext;  

一些GUI相关的操作

打开字幕流

打开音视频流

1.mpctx->stream=open_stream(filename,0,&mpctx->file_format);  

2.fileformat 文件还是TV 流DEMUXER_TYPE_PLAYLIST 或DEMUXER_TYPE_UNKNOWN  

3.DEMUXER_TYPE_TV  

4.current_module记录状态vobsub open_stream handle_playlist dumpstream  

5.stream_reset(mpctx->stream);  

6.stream_seek(mpctx->stream,mpctx->stream->start_pos);  

7.f=fopen(stream_dump_name,”wb”); dump文件流  

8.stream->type==STREAMTYPE_DVD  

//============OpenDEMUXERS—DETECTfiletype======================

Demux。

分离视频流和音频流

1.mpctx->demuxer=demux_open(mpctx->stream,mpctx-  

2.>file_format,audio_id,video_id,dvdsub_id,filename);  

3.Demux过程  

4.demux_open  

5.get_demuxer_type_from_name  

6.……  

7.mpctx->d_audio=mpctx->demuxer->audio;  

8.mpctx->d_video=mpctx->demuxer->video;  

9.mpctx->d_sub=mpctx->demuxer->sub;  

10.mpctx->sh_audio=mpctx->d_audio->sh;  

11.mpctx->sh_video=mpctx->d_video->sh;  

分离了之后就开始分别Playaudio和video

这里只关心playvideo

1./*======================== PLAY VIDEO ============================*/  

2.vo_pts=mpctx->sh_video->timer*90000.0;  

3.vo_fps=mpctx->sh_video->fps;  

4.if (!

mpctx->num_buffered_frames) {  

5.double frame_time = update_video(&blit_frame);  

6.mp_dbg(MSGT_AVSYNC,MSGL_DBG2,”*** ftime=%5.3f ***\n”,frame_time);  

7.if (mpctx->sh_video->vf_inited < 0) {  

8.mp_msg(MSGT_CPLAYER,MSGL_FATAL, MSGTR_NotInitializeVOPorVO);  

9.mpctx->eof = 1; goto goto_next_file;  

10.}  

11.if (frame_time < 0)  

12.mpctx->eof = 1;  

13.else {  

14.// might return with !

eof && !

blit_frame if !

correct_pts  

15.mpctx->num_buffered_frames += blit_frame;  

16.time_frame += frame_time / playback_speed; // for nosound  

17.}  

18.}  

关键的函数是update_video根据pts是否正确调整一下同步并在必要的时候丢帧处理。

最终调用decode_video开始解码(包括generate_video_frame里)。

mpi=mpvdec->decode(sh_video,start,in_size,drop_frame);mpvdec是在main里通过reinit_video_chain的一系列调用动态选定的解码程序。

其实就一结构体。

它的原型是

1.typedef struct vd_functions_s  

2.{  

3.vd_info_t *info;  

4.int (*init)(sh_video_t *sh);  

5.void (*uninit)(sh_video_t *sh);  

6.int (*control)(sh_video_t *sh,int cmd,void* arg, …);  

7.mp_image_t* (*decode)(sh_video_t *sh,void* data,int len,int flags);  

8.} vd_functions_t;  

这是所有解码器必须实现的接口。

int(*init)(sh_video_t*sh);是一个名为init的指针,指向一个接受sh_video_t*类型参数,并返回int类型值的函数地址。

那些vd_开头的文件都是解码相关的。

随便打开一个vd文件以上几个函数和info变量肯定都包含了。

mpi被mplayer用来存储解码后的图像。

在mp_image.h里定义。

1.typedef struct mp_image_s {  

2.unsigned short flags;  

3.unsigned char type;  

4.unsigned char bpp; // bits/pixel. NOT depth!

 for RGB it will be n*8  

5.unsigned int imgfmt;  

6.int width,height; // stored dimensions  

7.int x,y,w,h; // visible dimensions  

8.unsigned char* planes[MP_MAX_PLANES];  

9.int stride[MP_MAX_PLANES];  

10.char * qscale;  

11.int qstride;  

12.int pict_type; // 0->unknown, 1->I, 2->P, 3->B  

13.int fields;  

14.int qscale_type; // 0->mpeg1/4/h263, 1->mpeg2  

15.int num_planes;  

16./* these are only used by planar formats Y,U(Cb),V(Cr) */  

17.int chroma_width;  

18.int chroma_height;  

19.int chroma_x_shift; // horizontal  

20.int chroma_y_shift; // vertical  

21./* for private use by filter or vo driver (to store buffer id or dmpi) */  

22.void* priv;  

23.} mp_image_t;  

图像在解码以后会输出到显示器,mplayer本来就是一个视频播放器么。

但也有可能作为输入提供给编码器进行二次编码,MP附带的mencoder.exe就是专门用来编码的。

在这之前可以定义filter对图像进行处理,以实现各种效果。

所有以vf_开头的文件,都是这样的filter。

图像的显示是通过vo,即videoout来实现的。

解码器只负责把解码完成的帧传给vo,怎样显示就不用管了。

这也是平台相关性最大的部分,单独分出来的好处是不言而喻的,像在Windows下有通过direcx实现的vo,Linux下有输出到X的vo。

vo_*文件是各种不同的vo实现,只是他们不都是以显示为目的,像vo_md5sum.c只是计算一下图像的md5值。

在解码完成以后,即得到mpi以后,filter_video被调用,其结果是整个filter链上的所有filter都被调用了一遍,包括最后的VO,在vo的put_image里把图像输出到显示器。

这个时候需要考虑的是图像存储的方法即用哪种色彩空间。

附上两张MPlayer结构图:

如有侵权请联系告知删除,感谢你们的配合!

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2