ffplay分析 (视频从Frame(解码后)队列取数据到SDL输出)
生活随笔
收集整理的這篇文章主要介紹了
ffplay分析 (视频从Frame(解码后)队列取数据到SDL输出)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
《ffplay的數據結構分析》
《ffplay分析(從啟動到讀取線程的操作)》
《ffplay分析(視頻解碼線程的操作)》
《ffplay分析(音頻解碼線程的操作)》
《ffplay 分析(音頻從Frame(解碼后)隊列取數據到SDL輸出)》
《ffplay分析 (音視頻同步:主時鐘為音頻)》
《ffplay分析 (暫停 / 播放處理)》
《ffplay分析 (seek操作處理)》
《ffplay源碼(版本:ffmpeg-4.2.1)》
ffplay分析 (視頻從解碼后隊列取數據到SDL輸出)
- 一、分析:
- 1、main():在main()函數開始時有創建SDL窗口的處理
- 2、read_thread():開啟讀取線程后,在read_thread()讀取數據線程中設置視頻流時調用set_default_window_size()設置顯示窗口的默認大小和渲染區域大小
- 3、set_default_window_size():判斷命令行是否有指定寬高沒有就使用幀寬高,作為窗口寬高調用calculate_display_rect()計算渲染區域
- 4、calculate_display_rect():使用像素比例計算實際寬高比
- 5、calculate_display_rect():首先使用高度為基準計算渲染區域,如果寬度大于實際窗口再以寬度為基準重新計算
- 6、calculate_display_rect():計算保存返回上層的渲染區域參數
- 7、event_loop():SDL的事件循環調用了refresh_loop_wait_event()進行更新顯示和獲取SDL事件(在主線程更新,event_loop()在主線程調用)
- 8、refresh_loop_wait_event():調用SDL_PumpEvents()、SDL_PeepEvents()、獲取SDL事件。如果沒有事件才進入while更新畫面,否則返回上一層處理相應事件。
- 9、refresh_loop_wait_event():調用usleep()等待同步和設置remaining_time默認等待時間
- 10、refresh_loop_wait_event():調用video_refresh()進行視頻更新
- 11、video_refresh():判斷是否是實時流操作
- 12、video_refresh():判斷是否是音頻流顯示操作
- 13、video_refresh():視頻流顯示操作,如果沒有數據就什么不做
- 14、video_refresh():獲取上一幀顯示的幀和將要顯示的一幀,用來計算同步時間操作
- 15、video_refresh():判斷將要顯示的一幀的序列與現在解碼的不同就直接拋棄,重新獲取
- 16、video_refresh():判斷是否是新的播放序列,重置is->frame_timer
- 17、video_refresh():判斷是否暫停,直接保持顯示
- 18、video_refresh():計算上一幀持續顯示的時長
- 19、video_refresh():根據計算得到的delay判斷是否繼續顯示上一幀還是往下走繼續更新
- 20、video_refresh():根據is->frame_timer用于下一輪的操作
- 21、video_refresh():更新當前的視頻時鐘
- 22、video_refresh():判斷是否進行丟幀處理
- 23、video_refresh():調用frame_queue_next()移動到下一幀
- 24、video_refresh():調用video_display()真正開始渲染畫面的操作
- 25、video_display():判斷是視頻流調用video_image_display()顯示
- 26、video_image_display():獲取將要顯示的這一幀
- 27、video_image_display():調用calculate_display_rect()根據窗口比例計算渲染區域(圖像)的寬高,調用upload_texture()將frame的yuv更新到is->vid_texture(SDL_Texture)
- 28、video_display():video_image_display()結束后,返回到video_display()最終調用SDL_RenderPresent()顯示畫面
一、分析:
1、main():在main()函數開始時有創建SDL窗口的處理
2、read_thread():開啟讀取線程后,在read_thread()讀取數據線程中設置視頻流時調用set_default_window_size()設置顯示窗口的默認大小和渲染區域大小
3、set_default_window_size():判斷命令行是否有指定寬高沒有就使用幀寬高,作為窗口寬高調用calculate_display_rect()計算渲染區域
4、calculate_display_rect():使用像素比例計算實際寬高比
5、calculate_display_rect():首先使用高度為基準計算渲染區域,如果寬度大于實際窗口再以寬度為基準重新計算
6、calculate_display_rect():計算保存返回上層的渲染區域參數
7、event_loop():SDL的事件循環調用了refresh_loop_wait_event()進行更新顯示和獲取SDL事件(在主線程更新,event_loop()在主線程調用)
8、refresh_loop_wait_event():調用SDL_PumpEvents()、SDL_PeepEvents()、獲取SDL事件。如果沒有事件才進入while更新畫面,否則返回上一層處理相應事件。
9、refresh_loop_wait_event():調用usleep()等待同步和設置remaining_time默認等待時間
10、refresh_loop_wait_event():調用video_refresh()進行視頻更新
11、video_refresh():判斷是否是實時流操作
12、video_refresh():判斷是否是音頻流顯示操作
13、video_refresh():視頻流顯示操作,如果沒有數據就什么不做
14、video_refresh():獲取上一幀顯示的幀和將要顯示的一幀,用來計算同步時間操作
15、video_refresh():判斷將要顯示的一幀的序列與現在解碼的不同就直接拋棄,重新獲取
16、video_refresh():判斷是否是新的播放序列,重置is->frame_timer
17、video_refresh():判斷是否暫停,直接保持顯示
18、video_refresh():計算上一幀持續顯示的時長
19、video_refresh():根據計算得到的delay判斷是否繼續顯示上一幀還是往下走繼續更新
20、video_refresh():根據is->frame_timer用于下一輪的操作
21、video_refresh():更新當前的視頻時鐘
22、video_refresh():判斷是否進行丟幀處理
23、video_refresh():調用frame_queue_next()移動到下一幀
24、video_refresh():調用video_display()真正開始渲染畫面的操作
25、video_display():判斷是視頻流調用video_image_display()顯示
26、video_image_display():獲取將要顯示的這一幀
27、video_image_display():調用calculate_display_rect()根據窗口比例計算渲染區域(圖像)的寬高,調用upload_texture()將frame的yuv更新到is->vid_texture(SDL_Texture)
28、video_display():video_image_display()結束后,返回到video_display()最終調用SDL_RenderPresent()顯示畫面
總結
以上是生活随笔為你收集整理的ffplay分析 (视频从Frame(解码后)队列取数据到SDL输出)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ffplay 分析(音频从Frame(解
- 下一篇: 颐和园可以拍照吗