mplayer的執行過程分析(本地、網路)
阿新 • • 發佈:2019-02-16
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
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