日韩性视频-久久久蜜桃-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 帧情况下的处理的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 九九久久网 | 啪啪日韩 | 国产日韩一区二区三区 | 一边摸上面一边摸下面 | 久久精品网址 | 女同在线视频 | 日韩中文免费 | 激情网av | 亚洲精品中文字幕在线观看 | 亚洲人交配视频 | 最新在线视频 | 精品无码人妻一区二区免费蜜桃 | 亚洲婷婷久久综合 | 亚洲人在线观看视频 | 欧美女优一区二区 | 插我一区二区在线观看 | 正在播放国产一区 | 亚洲国产精品激情在线观看 | 国产精品毛片一区二区 | 国产精品高潮呻吟久久av野狼 | 少妇性生活视频 | 国产一区在线观看视频 | 麻豆md0049免费 | av在线资源网| 这里只有精品22 | 国产偷人爽久久久久久老妇app | 欧美精品偷拍 | 91视频在线观看网站 | а 天堂 在线 | 亚洲天堂免费观看 | 亚洲欧美专区 | 日本一区二区网站 | 国产第一色 | 日本一区二区三区视频在线 | 神马久久久久 | 欧美日韩中文在线 | 制服丝袜在线第一页 | 国产精品伦| 深田咏美av在线 | a∨色狠狠一区二区三区 | 香蕉久热 | 91久久精品在线 | 亚洲性xxx | 亚洲一区二区三区四区不卡 | 中文字幕永久视频 | 特黄特色免费视频 | 黑人日批视频 | 三级黄片毛片 | 精品小视频在线观看 | 欧洲亚洲自拍 | 极品新婚夜少妇真紧 | www.亚洲人| 天堂视频免费在线观看 | 天天干天天透 | 国产美女永久免费 | 阿v视频免费在线观看 | 精品国产一区二区三区久久久久久 | 伊伊成人 | 免费播放毛片 | 九九99精品 | 永久在线免费观看 | 曰韩一级片 | 男人私人影院 | 色悠悠国产 | 亚洲爆爽| 黄色应用在线观看 | 天天干狠狠插 | 久久女人天堂 | 久久久精品人妻av一区二区三区 | 国产精品一区二区三区四区 | 欧美黑人精品一区二区不卡 | 人人艹人人爽 | 久久9精品区-无套内射无码 | 欧美老女人xx | 国产日韩欧美一区二区 | 国产精品国产三级国产 | 免费在线国产精品 | 人妻熟女一区二区三区 | 日韩一区二区免费看 | 久久成人动漫 | 国产精品无码一本二本三本色 | 99久久99久久精品国产片桃花 | 亚洲一区国产一区 | 91老师国产黑色丝袜在线 | 国产三级a | 国产麻豆a毛片 | 日韩v片| 制服丝袜第一页在线观看 | 精品国产第一页 | 日韩黄色免费 | 中文字幕9 | 日韩中文久久 | 中国新婚夫妻性猛交 | 二级毛片在线观看 | 亚洲成av人片在线观看 | 日韩在线播放中文字幕 | 黄色网页入口 | 欧美日韩国产图片 | 中文在线不卡视频 |