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 windows