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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Seek 策略以及在有 B 帧情况下的处理

發布時間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Seek 策略以及在有 B 帧情况下的处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在知識星球分享的文章,順便也在公眾號發表一下,不足之處,歡迎指正。

一個關于音視頻領域專業問答的小圈子!!

最近在做 Seek 相關功能時遇到的問題排查,順便也學到了一些新的東西,和大家分享下。

在視頻播放時執行 Seek 到任意點的操作,一般都是 Seek 到任意點往前最近的 I 幀,然后再逐幀解碼到指定時間點。

這里可以優化,假設當前時間和指定時間在一個 GOP 內,就可以不用 seek ,直接順序向下解碼就好。

而正是這個優化出現了一點問題,現象如下:

已經判斷播放點 A 和 Seek 點 B 不在一個 GOP 內,然后執行 av_seek_frame 方法還是把時間點 A 所在 GOP 全部解碼了,導致播放上出現了卡頓。

這里就很奇怪了,明明判斷不在一個 GOP ,那 Seek 時就應該從時間點 B 所在 GOP 的 I 幀開始解碼, 但執行時還是解碼了上一個 GOP 的內容。

到底是判斷是否同一個 GOP 的函數出問題了還是 Seek 方法有問題呢?

帶著疑問開始深入源碼探索。

FFmpeg 沒有直接提供判斷兩幀是否同一個 GOP 的方法,所以通過 av_index_search_timestamp 方法得到傳入時間點最近的 I 幀的 index 索引,如果兩個時間點的索引相同則表示為同一個 GOP 內,因為最近的 I 幀相同。

然而 av_index_search_timestamp 方法是通過 AVIndexEntry 中的 timestamp 來判斷的,它是一個 DTS 值,通過二分查找得到最近的索引。

在沒有 B 幀的情況下,I 幀的 PTS 等于 DTS ,所以判斷不會出問題。然而正是有了 B 幀,如果 I 幀的 PTS 和 DTS 不相等的話,那么上面的判斷相當于是拿一個 PTS 值和 I 幀的 DTS 比較是否同一個 GOP 了。

如果將錯就錯,判斷 GOP 時得到結論是非同一個 GOP ,那么 Seek 也應該是非同一個 GOP ,但現實恰恰相反,Seek 當做了同一個 GOP ,這里面肯定有計算出問題了,繼續深入源碼。

通過在 mov.c 源碼中看到了如下的操作:

static?int?mov_seek_stream(AVFormatContext?*s,?AVStream?*st,?int64_t?timestamp,?int?flags) {MOVStreamContext?*sc?=?st->priv_data;FFStream?*const?sti?=?ffstream(st);int?sample,?time_sample,?ret;unsigned?int?i;//?Here?we?consider?timestamp?to?be?PTS,?hence?try?to?offset?it?so?that?we//?can?search?over?the?DTS?timeline.timestamp?-=?(sc->min_corrected_pts?+?sc->dts_shift);ret?=?mov_seek_fragment(s,?st,?timestamp);if?(ret?<?0)return?ret;sample?=?av_index_search_timestamp(st,?timestamp,?flags);av_log(s,?AV_LOG_TRACE,?"stream?%d,?timestamp?%"PRId64",?sample?%d\n",?st->index,?timestamp,?sample);//?省略部分代碼

注意到如下一行代碼:

timestamp?-=?(sc->min_corrected_pts?+?sc->dts_shift);

也就是說我們傳入的時間都會被減上一個值,然后再執行 av_index_search_timestamp 方法,而這個值導致判斷 GOP 和 Seek 之間的關鍵幀索引出問題了。

正如代碼中的注釋所示,假設傳入的時間是 PTS 值,然后給它減去偏移以得到 DTS 值,因為 av_index_search_timestamp 方法就通過 DTS 進行比較的嘛。

出現問題的原因就是 seek 的時間點正好在 I 幀的 PTS 和 DTS 范圍之間了,執行 seek 時減去偏差值就小于 DTS 了,所以變成了同一個 GOP 。

現在要解決問題就是如何得到 sc->min_corrected_pts + sc->dts_shif 之和,然后判斷 GOP 時減去它以修正得到 DTS 值。

還好通過遍歷源碼發現它的值是不會運行時改變的,一旦決定了就定下來了。另外我們可以用第一個 I 幀的 DTS 值作為偏移值。

auto?indexEntry?=?avStream->index_entries;auto?nbIndexEntry?=?avStream->nb_index_entries;for?(int?i?=?0;?i?<?nbIndexEntry;?++i)?{if?(indexEntry[i].flags?==?AVINDEX_KEYFRAME)?{DTSOffset?=?indexEntry[i].timestamp;return;}}

如果沒有 B 幀,DTS 值為 0 ,有 B 幀,那么首幀的 DTS 值就可以用來做偏差值進行計算了。

一個音視頻領域專業問答的小圈子!

推薦閱讀:

音視頻開發工作經驗分享 || 視頻版

OpenGL ES 學習資源分享

開通專輯 | 細數那些年寫過的技術文章專輯

Android NDK 免費視頻在線學習!!!

你想要的音視頻開發資料庫來了

推薦幾個堪稱教科書級別的 Android 音視頻入門項目

覺得不錯,點個在看唄~

總結

以上是生活随笔為你收集整理的Seek 策略以及在有 B 帧情况下的处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本一区二区三区免费视频 | 台湾a级片| 日韩综合中文字幕 | 欧美久久久久久又粗又大 | 亚洲高清网| 国内自拍xxxx18 | 亚洲再线 | 欧美成人免费高清视频 | 久久久久久伦理 | 欧美久久久久 | 日本a天堂| 好吊色综合| 人人妻人人澡人人爽人人dvd | 依依激情网 | 亚洲午夜精品久久久 | 久久11| 一区二区视频在线免费观看 | 日韩在线欧美在线 | 日日夜夜天天 | 国产色频| 一级黄色片在线观看 | 香蕉视频成人在线观看 | 一区二区三区久久 | 人妻少妇偷人精品久久久任期 | 怡红院一区| 亚洲永久网站 | 国产乱仑视频 | 久久久久亚洲av无码专区体验 | 亚洲精品aa| 国产在线一区二区三区四区 | 搡老熟女老女人一区二区 | 久久久久久久久99 | 欧美日韩伊人 | 免费在线看黄网站 | 一级黄色大片免费观看 | 永久久久久久久 | 377人体粉嫩噜噜噜 www.av黄色 | 国产精品一区二区三区四区视频 | 日韩一区二区三免费高清在线观看 | 成人v片| 国产伦精品一区二区三区视频孕妇 | 久久这里有精品 | 欧美成人免费视频 | 少妇又色又紧又大爽又刺激 | 久久久久亚洲av成人网人人网站 | 91麻豆精品国产 | 成人深夜网站 | 一卡二卡三卡四卡 | 久久依人网| 国产亚洲成av人片在线观看桃 | 九九色九九 | 91视频 - 8mav| 天堂免费在线视频 | 成人三级做爰av | 七月婷婷综合 | 日韩免费精品 | 亚洲美女在线视频 | 国产一线在线观看 | 叶山小百合av一区二区 | 6080午夜伦理 | 日韩偷拍一区 | 欧美一级黄视频 | 欧美亚韩一区二区三区 | 亚洲无限看 | www.rihan | 欧美高清视频一区 | 国产在线播放一区 | 国内自拍一区 | 69xx欧美 | 国产精品宾馆在线精品酒店 | 成人免费在线播放 | 乱人伦中文字幕 | 日日碰狠狠添天天爽无码 | 国产精品亚洲AV色欲三区不卡 | 久久久久久久久91 | 日韩 欧美 自拍 | 久久免费视频1 | 亚洲春色av| 免费福利视频在线观看 | 免费久久av | 国产高潮在线观看 | 少妇高潮网站 | 色七七网站 | 久久久成人精品一区二区三区 | 日日草日日干 | 99久热 | 伊人春色在线 | 免费av成人 | 黄色片免费观看视频 | 久久av红桃一区二区小说 | 成长快手短视频在线观看 | 免费看一级 | 国产精品欧美久久久久久 | 国产精品一区二区在线免费观看 | 日韩精品中文在线 | 日韩三级中文 | 日韩wwww| 日韩黄色片网站 | 男女拍拍拍 |