全部博文(207)
分类: LINUX
2012-12-07 16:32:30
一、 针对XXXX平台mplayer移植主要分为两大部分
1.视频解码移植
2.视频输出移植
二、 Mplayer流程分析
I. MPlayer.main 主流程简要说明
int main() {
1) 变量声明,电影信息 movie
info:
2) 初始化,消息系统……
play_next_file:
3)播放文件 filename 的循环 goto
play_next_file 开始
main:
4) 主处理 main
5) 播放真正主循环 2010
~3541 while (!eof)
while (!eof) {
5.1) 播放音频 PLAY
AUDIO 2017 ~ 2064 decode_audio(sh_audio, ...);
5.2) 播放视频 PLAY
VIDEO, 2068 ~ 2300 decode_video(sh_video, ...);
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:
}
II. Mplayer流程框架图
三、 视频解码移植
由以上分析可知XXXX mplayer的视频解码流程为:
指定解码器若无指定则遍历init_best_video_codec(mplayer.c)-->
解码器初始化init_video(dec_video.c) --> find_video_codec
选择相应解码驱动mpcodecs_vd_drivers[](vd.c)-->
这里选用mpcodecs_vd_ffmpeg(vd.c):
vd_functions_t mpcodecs_vd_ffmpeg = { (vd_ffmpeg.c)
&info,
init,
uninit,
control,
decode
};(vd_ffmpeg.c)
ffmpetg解码器初始化init -->
选择相应格式(h264,h263,mpeg4,mpeg2等)的解码驱动avcodec_find_decoder_by_name(libavcodec/utils.c) -->
解码注册avcodec_register_all -->(H264, h264)REGISTER_DECODER(MPEG4, mpeg4).......
在此选取h264编码格式为列
AVCodec h264_decoder = { (libavcodec/h264.c)
"h264",
CODEC_TYPE_VIDEO,
CODEC_ID_H264,
sizeof(H264Context),
ff_h264_decode_init,
NULL,
ff_h264_decode_end,
decode_frame,
/*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.flush= flush_dpb,
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.pix_fmts= ff_hwaccel_pixfmt_list_420,
};
对结构体h264_decoder继续分析,其中ff_h264_decode_init和 decode_frame 为重点。
ff_h264_decode_init -->
XXX_vpu_codec_init(STD_AVC,0,s->width,s->height) ##最终解码初始化函数出现,此函数需移植(见代码)。
decode_frame -->
XXX_vpu_codec_decode(STD_AVC, avctx ,avpkt); ##最终硬解码执行函数,需移植(见代码)。
四、 视频输出移植
mplayer视频输出包括两层:filter和video out层。video out层是被包含在filter之中。其中插件 vf_vo.c就是对video out层的包装。视频解码完毕后是通过filter(vf_vo.c)来调用vo_XXX89fb.c
mplayer视频输出流程为:
初始化:
reinit_video_chain(mplayer.c)-->
指定相应视频输出插件init_best_video_out(video_out.c)
视频输出操作结构体数组video_out = video_out_drivers [ ]
选取video_out_XXX89fb(vo_XXX89fb.c)## 所包含函数需移植-->
LIBVO_EXTERN(XXX89fb)
vo_functions_t video_out_XXX89fb{
&info,//插件基本信息
prinit, //预初始化视频输出插件,该步骤初始化和视频格式不相关的部分
config, // 配置视频输出的插件,包括视频输出的分辨率,视频输出的格式等
control, //控制视频输出插件
draw_frame,
draw_slice,
draw_osd,
flip_page,//刷新OSD
check_events,
uninit
};
预初始化 video_out-> preinit -->
打开并初始化vo过滤器 vf_open_filter(NULL,"vo",vf_arg)(vf.c)-->
输出配置 :
init_best_video_codec -->
init_video(sh_video, NULL, NULL, status, &selected)-->
init(sh_video) -->
init_vo(vd_ffmpeg.c)-->
mpcodecs_config_vo(vd.c)
vf->query_format(vf, out_fmt)匹配codec中的out输出格式,如果有不需要转化支持的(VFCAP_CSP_SUPPORTED_BY_HW),则选择。否则选择第一个满足VFCAP_CSP_SUPPORTED的输出格式。
vf_config_wrapper(vf.c)-->
vf->config(vf_vo.c)-->
config_video_out(video_out.c)->
vo->config()(vo_XXX89fb.c)
视频播放:
generate_video_frame(mplayer.c)-->
视频解码decode_video(video_out.c)-->
视频过滤filter_video(dec_video.c)
视频播放put_image(vf_vo.c)
vf->control(VOCTRL_DRAW_IMAGE,mpi)(vo_XXXXfb.c)
绘制OSD
vf->control(vf, VFCTRL_DRAW_OSD, NULL); -->