FFmpeg - ffplay.c 流程簡析

FFplay.c

在這裏插入圖片描述

main()

主函數

avformat_network_init()

初始化網絡庫()This is optional, and not recommended anymore.

http://ffmpeg.org/doxygen/trunk/group__lavf__core.html#ga84542023693d61e8564c5d457979c932

show_banner()

打印輸出FFmpeg版本信息(編譯時間,編譯選項,類庫信息等)

parse_options() 解析命令行輸入選項

  1. parse_option()解析參數

  2. find_option()_根據參數找到對應的OptionDef

  3. write_option()_執行OptionDef

SDL_Init() 初始化SDL,FFPlay中的視頻與音頻都是使用到了SDL

SDL_CreateWindow()創建SDL窗口

https://wiki.libsdl.org/SDL_CreateWindow

SDL_CreateRedner()爲SDL窗口創建SDL渲染上下文

https://wiki.libsdl.org/SDL_CreateRenderer

https://wiki.libsdl.org/SDL_RendererFlags

stream_open()

打開輸入媒體

frame_queue_init()初始化幀隊列,FrameQueue內部是個有限數組,內部根據max_size_來初始化默認緩存數據

f->queue[i].frame = av_frame_alloc()

frame_queue_destory()銷燬幀隊列,釋放初始化時的緩存數據av_frame_free()

packet_queue_init()初始化包隊列,PacketQueue內部是個自定義鏈表

init_clock()初始化時鐘,使用默認值(NAN/-1)來初始化時鐘的pst/last_update/pst_dirft/serial_等數據。

  1. av_gettime_relative()從未指明的某個點獲取到現在的時間(納秒)https://ffmpeg.org/doxygen/3.2/time_8c.html#adf0e36df54426fa167e3cc5a3406f3b7

  2. set_clock_at(c,pts,serial,time)

read_thread()

幀讀取線程

avformat_alloc_context()初始化上下文

http://ffmpeg.org/doxygen/trunk/group__lavf__core.html#gac7a91abf2f59648d995894711f070f62

avformat_open_input()打開文件流,讀取文件頭部數據

avformat_find_stream_info()獲取媒體流信息

avformat_seek_file()

av_dump_format()輸出媒體信息到控制檯

av_find_best_stream()獲取最合適的流

av_guess_sample_aspect_ratio()獲取流採樣率

AVCodecParameters編解碼器參數

set_default_window_size()設置窗口大小

  1. calculate_display_rect()根據屏幕寬高和流像素寬高計算出可顯示區域

stream_component_open()分別打開視頻/音頻/字幕解碼線程

av_read_pause()/av_read_play()暫停或者播放網絡流

http://ffmpeg.org/doxygen/trunk/group__lavf__decoding.html#ga27db687592d99f25ccf81a3b3ee8da9c

avformat_seek_file()快進

http://ffmpeg.org/doxygen/trunk/group__lavf__decoding.html#ga3b40fc8d2fda6992ae6ea2567d71ba30

packet_queue_flush()清空包隊列緩存

stream_has_enough_packets()是否有足夠的包緩存

av_read_frame()讀取一幀流原始數據

packet_queue_put()將讀取的包數據加入到隊列中

stream_component_open()

分別打開視頻/音頻/字幕解碼線程

avcodec_alloc_context3() 創建編解碼器上下文

avcodec_parameters_to_context()從流中複製參數到編解碼器上下文中

avcodec_find_decoder()根據編碼ID獲取編解碼器

avcodec_find_decoder_by_name()根據名稱查找編解碼器

avcodec_open2() 根據編解碼器初始化編解碼器上下文

audio_open()打開音頻解碼

  1. av_get_default_channel_layout(wanted_nb_channels)

  2. av_get_channel_layout_nb_channels(wanted_channel_layout)

  3. sdl_audio_callback()

    1. audio_decode_frame()

      1. synchronize_audio()

      2. swr_convert()

  4. SDL_OpenAudioDevice()https://wiki.libsdl.org/SDL_OpenAudioDevice

audio_thread()解碼音頻幀

  1. decoder_decode_frame()

    1. avcodec_send_packet()

    2. avcodec_receive_frame()

video_thread()解碼視頻幀

  1. get_video_frame()獲取視頻幀

    1. decoder_decode_frame()

    2. av_guess_sample_aspect_ratio()

  2. queue_picture() 入隊視頻圖像數據

    1. frame_queue_peek_writable() 從幀緩存區中等待獲取一個可用數據

    2. av_frame_move_ref()轉移引用

    3. frame_queue_push()增加幀隊列size

subtitle_thread()__解碼字幕幀

  1. frame_queue_peek_writable()

  2. decoder_decode_frame()

  3. frame_queue_push()

event_loop()

處理鍵盤事件與視頻刷新

video_refresh()處理視頻刷新與顯示

  1. frame_queue_peek_last()出隊圖像

  2. frame_queue_peek()

  3. video_display()顯示圖像

    1. video_open()開打窗口

    2. video_image_display()圖像展示

      1. frame_queue_peek_last()

      2. calculate_display_rect()計算顯示畫面的位置。當拉伸了SDL的窗口的時候,可以讓其中的視頻保持縱橫比

      3. upload_texture()

      4. SDL_RenderCopyEx()

參考:

  1. https://blog.csdn.net/leixiaohua1020/article/details/39762143
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章