main函数流程分析,分本地和网络两种情况 1. 本地文件的播放,以mp3文件的播放为例,命令行输入:mplayer test.mp3 只给出关键步骤 2. open_stream, 打开文件流 open_stream_full 找到合适的打开文件的方式,对于本地文件选择 open_stream_plugin stream_info_file,使用它的open_f函数读取文件 open_f 成功,返回文件句柄,文件访问函数 对于流媒体文件,第8行改成如下的第10行,表明流媒体文件选择stream_info_rtsp_sip open_live_rtsp_sip 3. mpctx->stream 2854行,记录文件流的信息,文件句柄,访问函数等 4. demux_open 打开分离器(音视频) demux_open_stream 从demuxer_list中找到合适的demuxer描述符,此处为demuxer_desc_audio new_demuxer stream_seek cache_stream_seek_long stream_seek_long 读取部分数据至内存 stream_fill_buffer while(stream_fill_buffer(s) > 0 && pos >= 0) { demux_audio_open 使用demuxer_desc_audio的打开函数,读取媒体数据的信息,头信息 对于m4v视频demuxer_desc_lavf_preferred,打开demux_open_lavf 对于流媒体文件,上面的第15行换成如下的第18行,使用demuxer_desc_rtp,使用sdp文件建立流媒体会话, demux_open_rtp 创建媒体会话,创建音视频数据接收会话,初始化音视频的codec 初始化视频解码器及输出设备 5. reinit_video_chain init_best_video_out 从video_out_drivers数组中找出视频输出设备video_out_gl preinit(vo_gl.c) vf_open_filter 在众多驱动中过滤出需要的那种 vf_open_plugin open(vf_vo.c) vf_info_vo init_best_video_codec init_video 初始化视频解码器,从mpcodecs_vd_drivers数组中选择合适的解码器 选择mpcodecs_vd_ffmpeg解码m4v的视频文件,vd_ffmpeg.c 初始化音频解码器及输出设备 6. reinit_audio_chain init_best_audio_codec mpcodecs_ad_drivers(见LIBAD_EXTERN(mp3lib)),ad_internal.h init_audio 选择mpcodecs_ad_mp3lib解码mp3的音频文件 init_best_audio_out 从audio_out_drivers选择音频输出设备audio_out_win32 init 初始化 开始播放 音频,mp3 7. fill_audio_out_buffers decode_audio dec_audio.c mpadec->decode_audio MP3_DecodeFrame 获取数据并解码 read_frame stream_read_frame_body mp3_read mplayer_audio_read demux_read_data ds_fill_buffer demux_fill_buffer demux_audio_fill_buffer(demux_audio.c) stream_read cache_stream_fill_buffer stream_fill_buffer fill_buffer(stream_file.c) 如果是流媒体,上面的47行将变为: demux_rtp_fill_buffer(demux_rtp.cpp) play write_waveOutBuffer 视频 8. update_video video_read_frame read_video_packet demux_pattern_3 demux_read_data ds_fill_buffer demux_fill_buffer demux_lavf_fill_buffer(m4v) 对于流媒体的视频,上面的一行将变为: demux_rtp_fill_buffer(demux_rtp.cpp) decode_video decode(vd_ffmpeg.c) avctx->opaque=sh; 在 filter_video put_image(vf_vo.c) ========================================================================================= 另一种读取视频文件的过程: demux_mpg_es_fill_buffer ds_read_packet stream_read cache_stream_fill_buffer stream_fill_buffer read default:s->fill_buffer fill_buffer stream_file.c windows下的界面部分,由编译开关HAVE_NEW_GUI控制 mplayer.c文件下的 2661~2668行,界面初始化 2692~2727行,界面的消息循环,获取用户的命令,如文件名,执行 视频驱动如果是directx,相应的处理函数在vo_directx.c文件中 ffmpeg编解码器中的avcodec_decode_video函数可以解析出视频的规格,即高和宽 ff_h263_decode_frame ff_mpeg4_decode_picture_header解析MPEG4视频的头信息 decode_vol_header解析出高和宽 具体过程如下: avcodec_decode_video ff_h263_decode_frame MPV_frame_start alloc_picture ff_mpeg4_decode_picture_header 解析出高和宽 get_buffer init_vo mpcodecs_config_vo 打印到屏幕 网络流媒体的视频高和宽必须解码才能获取,过程如下: 如何从一个音视频文件中分出音视频流? 参考m4v_demuxer,分离器使用宏REGISTER_DEMUXER注册或REGISTER_MUXDEMUX,见allformats.c文件 lavf_check_file在打开之前运行,从而获取真正的demuxer 对于.m4v文件,打开demux_open_lavf中av_open_input_stream获取流信息,音频视频 demux_open_stream时,new_demuxer开辟音视频流的缓存 文件扩展名是.mp4时,打开流mov_read_header,首先重置音视频部分: stream_reset s->control(demux_mov_control) 对于mp4流媒体 根据sdp初始化: bih->biCompression = sh_video->format = mmioFOURCC('m','p','4','v'); 确定视频解码器: init_video中find_video_codec,使用上面的biCompression到文件codecs.conf文件中找到ffodivx,对于的 驱动为ffmpeg |
|