音視頻同步
主要解析:以音頻為基準(zhǔn),讓視頻同步音頻
思路
-
視頻慢了則丟掉部分視頻幀(視覺->畫?跳幀)文章來源:http://www.zghlxwxcb.cn/news/detail-730877.html
-
視頻快了則繼續(xù)渲染上?幀文章來源地址http://www.zghlxwxcb.cn/news/detail-730877.html
具體實(shí)現(xiàn)
一個(gè)國際標(biāo)準(zhǔn):音頻幀-視頻幀時(shí)間戳的差值在-100ms~25ms內(nèi)流暢
1.差值=音頻播放時(shí)間戳-視頻播放時(shí)間戳----diff=pts_audio-pts_video(注意區(qū)分?。。?2.判斷邏輯:
(無法感知區(qū)間:min=-125ms,max=45ms)
- max<diff:畫后音前,視頻落后了,丟幀不渲染(趕進(jìn)度),直接下一幀
- min<diff<max:正常渲染
- diff<min:畫前音后,視頻超前了,持續(xù)顯示當(dāng)前幀,
視頻播放線程先睡會(huì)_阻塞:sleep(diff-max)
然后繼續(xù)渲染當(dāng)前視頻幀
ffplay具體源碼
/* if video is slave, we try to correct big delays by
duplicating or deleting a frame
通過重復(fù)幀或者刪除幀來糾正延遲*/
diff = get_clock(&is->vidclk) - get_master_clock(is);
/* skip or repeat frame. We take into account the
delay to compute the threshold. I still don't know
if it is the best guess */
sync_threshold = FFMAX(AV_SYNC_THRESHOLD_MIN,
FFMIN(AV_SYNC_THRESHOLD_MAX, delay));
if (!isnan(diff) && fabs(diff) < is->max_frame_duration) { // diff在最大幀duration內(nèi)
if (diff <= -sync_threshold) { // 視頻已經(jīng)落后了
delay = FFMAX(0, delay + diff); // 上一幀持續(xù)的時(shí)間往小的方向去調(diào)整
}
else if (diff >= sync_threshold && delay > AV_SYNC_FRAMEDUP_THRESHOLD) {
// 視頻超前
delay = delay + diff; // 上一幀持續(xù)時(shí)間往大的方向去調(diào)整
av_log(NULL, AV_LOG_INFO, "video: delay=%0.3f A-V=%f\n",
delay, -diff);
}
else if (diff >= sync_threshold) {
// 上一幀持續(xù)時(shí)間往大的方向去調(diào)整
delay = 2 * delay; // 保持在 2 * AV_SYNC_FRAMEDUP_THRESHOLD內(nèi), 即是2*0.1 = 0.2秒內(nèi)
} else {
// 音視頻同步精度在 -sync_threshold ~ +sync_threshold
// 其他條件就是 delay = delay; 維持原來的delay, 依靠frame_timer+duration和當(dāng)前時(shí)間進(jìn)行對(duì)比
}
}
到了這里,關(guān)于【音視頻】ffplay解析-音視頻同步的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!