1. 程式人生 > >mplayer的執行過程分析(本地、網路)

mplayer的執行過程分析(本地、網路)

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