日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ffplay分析 (音视频同步:主时钟为音频)

發(fā)布時間:2023/12/1 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ffplay分析 (音视频同步:主时钟为音频) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

《ffplay的數(shù)據(jù)結(jié)構(gòu)分析》
《ffplay分析(從啟動到讀取線程的操作)》
《ffplay分析(視頻解碼線程的操作)》
《ffplay分析(音頻解碼線程的操作)》
《ffplay 分析(音頻從Frame(解碼后)隊列取數(shù)據(jù)到SDL輸出)》
《ffplay分析 (視頻從Frame(解碼后)隊列取數(shù)據(jù)到SDL輸出)》
《ffplay分析 (暫停 / 播放處理)》
《ffplay分析 (seek操作處理)》
《ffplay源碼(版本:ffmpeg-4.2.1)》

ffplay分析 (音視頻同步:主時鐘為音頻)

  • 一、分析:
    • 1、refresh_loop_wait_event():在refresh_loop_wait_event()函數(shù)內(nèi)的remaining_time就是間隔判斷的休眠時間,這個值有默認值。但如果視頻快了這個值就是同步計算后返回的當前這一幀還要繼續(xù)顯示的時間,就會在這里休眠等待,但也不一定是多長時間都會休眠,返回的值要和默認的比較選擇一個更小的值進行休眠。這樣可以多次判斷更精準。
    • 2、refresh_loop_wait_event():使用remaining_time調(diào)用video_fresh()進行視頻顯示,就會進行操作是接著往下顯示視頻幀還是保持顯示當前幀不變。
    • 3、refresh_loop_wait_event():從Frame(解碼后)隊列中取出上一幀顯示的幀和將要顯示的一幀。并且進行判斷序列是否一樣,不同直接丟棄,獲取下一幀。
    • 4、refresh_loop_wait_event():判斷是否是新的序列開始然后重置is->frame_timer,這個值表示在系統(tǒng)時間里上一幀的顯示時間,因為系統(tǒng)時間是變化的,只有使用系統(tǒng)時間才可以判斷每幀的顯示時長 是否到達了。
    • 5、refresh_loop_wait_event():調(diào)用vp_duration()計算上一幀的持續(xù)時間(理論上的)
    • 6、vp_duration():計算上一幀的持續(xù)時間(理論上的)
    • 7、refresh_loop_wait_event():調(diào)用compute_target_delay()計算上一幀的持續(xù)時間(同步后實際上的)
    • 8、compute_target_delay():判斷主時鐘不是視頻才行同步計算,獲取視頻時鐘與主時鐘的差值
    • 9、compute_target_delay():根據(jù)delay(理論上的上一幀的顯示時長)設置同步閥值
    • 10、compute_target_delay():使用diff差值和sync_threshold閥值判斷當前視頻與主時鐘相比是否快還是慢,計算上一幀(當前顯示的這)
    • 11、refresh_loop_wait_event():獲取當前的系統(tǒng)時間和經(jīng)過compute_target_delay()計算返回的當前顯示的幀的實際持續(xù)時長,判斷是否保持顯示當前的這一幀實行延時就是當前視頻快了,或往下走就是
    • 12、refresh_loop_wait_event():此時可以顯示下一幀了,設置is->frame_timer新顯示的這一幀的系統(tǒng)時間
    • 13、refresh_loop_wait_event():更新視頻時鐘
    • 14、refresh_loop_wait_event():丟幀處理
    • 15、refresh_loop_wait_event():到最后可以正常顯示新的一幀就是先調(diào)用frame_queue_next()移動讀索引,然后調(diào)用video_display()顯示新的一幀了

一、分析:

因為音頻和視頻解碼時間并不是都能在同一個時間點同時解碼完成進行播放,所以如果都在各自解碼完成后自主的直接播放就可能數(shù)據(jù)的時間點匹配不上。所以要有個基準的時間軸讓播放的數(shù)據(jù)匹配對應這個時間軸來進行播放。

ffplay 默認的音視頻同步方法就是音頻時鐘作為主時鐘,視頻同步音頻。音頻解碼完成直接播放,視頻就要實時的檢測音頻當前的時間點,進行匹配。

視頻播放時:
(1)通過一個循環(huán)播放和一個休眠時間間隔的判斷當前視頻時鐘和音頻時鐘的差值。
(2)這個差值有個閥值的范圍在范圍內(nèi)都還是示為同步的,不作為處理,讓視頻幀按照duration顯示。如果差值是正數(shù)而且超出閥值范圍才表示視頻快了,此時當前顯示的視頻幀就要延長顯示時間。
(3)如果差值是負數(shù)而且超出閥值范圍才表示視頻慢了,此時當前顯示的視頻幀就要加快顯示時間。一般都是直接下一幀。而且如果還慢了一幀,就連當前將要顯示的幀都拋棄,再顯示下一幀。

1、refresh_loop_wait_event():在refresh_loop_wait_event()函數(shù)內(nèi)的remaining_time就是間隔判斷的休眠時間,這個值有默認值。但如果視頻快了這個值就是同步計算后返回的當前這一幀還要繼續(xù)顯示的時間,就會在這里休眠等待,但也不一定是多長時間都會休眠,返回的值要和默認的比較選擇一個更小的值進行休眠。這樣可以多次判斷更精準。

2、refresh_loop_wait_event():使用remaining_time調(diào)用video_fresh()進行視頻顯示,就會進行操作是接著往下顯示視頻幀還是保持顯示當前幀不變。

3、refresh_loop_wait_event():從Frame(解碼后)隊列中取出上一幀顯示的幀和將要顯示的一幀。并且進行判斷序列是否一樣,不同直接丟棄,獲取下一幀。

4、refresh_loop_wait_event():判斷是否是新的序列開始然后重置is->frame_timer,這個值表示在系統(tǒng)時間里上一幀的顯示時間,因為系統(tǒng)時間是變化的,只有使用系統(tǒng)時間才可以判斷每幀的顯示時長 是否到達了。

5、refresh_loop_wait_event():調(diào)用vp_duration()計算上一幀的持續(xù)時間(理論上的)

6、vp_duration():計算上一幀的持續(xù)時間(理論上的)

7、refresh_loop_wait_event():調(diào)用compute_target_delay()計算上一幀的持續(xù)時間(同步后實際上的)

8、compute_target_delay():判斷主時鐘不是視頻才行同步計算,獲取視頻時鐘與主時鐘的差值

9、compute_target_delay():根據(jù)delay(理論上的上一幀的顯示時長)設置同步閥值

10、compute_target_delay():使用diff差值和sync_threshold閥值判斷當前視頻與主時鐘相比是否快還是慢,計算上一幀(當前顯示的這)

11、refresh_loop_wait_event():獲取當前的系統(tǒng)時間和經(jīng)過compute_target_delay()計算返回的當前顯示的幀的實際持續(xù)時長,判斷是否保持顯示當前的這一幀實行延時就是當前視頻快了,或往下走就是

12、refresh_loop_wait_event():此時可以顯示下一幀了,設置is->frame_timer新顯示的這一幀的系統(tǒng)時間

13、refresh_loop_wait_event():更新視頻時鐘

14、refresh_loop_wait_event():丟幀處理

15、refresh_loop_wait_event():到最后可以正常顯示新的一幀就是先調(diào)用frame_queue_next()移動讀索引,然后調(diào)用video_display()顯示新的一幀了

總結(jié)

以上是生活随笔為你收集整理的ffplay分析 (音视频同步:主时钟为音频)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。