Android 播放器首屏時間問題

因看到盧_俊 ——直播疑難雜癥排查(3)— 首開慢的博文。故描述一下我在工作中遇到這方面問題的解決方式艾猜。

首先聲明一下庇茫,因為是基于ijkplayer而封裝的播放器,所以我的方案是在此基礎(chǔ)上實現(xiàn)的嫉父。

在這篇直播疑難雜癥排查(3)— 首開慢博文中總結(jié)了很全面,我讀了收益很大缕题。

2.1 點擊播放后才從服務(wù)器取播放地址
2.2 DNS 解析慢
2.3 播放策略原因
2.4 播放參數(shù)配置
2.5 服務(wù)端線路原因

想必大家都對上述問題都做過相關(guān)研究且在實際的項目中優(yōu)化過,所以我這里就描述一下不一樣的地方胖腾。
主要探討的是

2.4 播放參數(shù)配置

其實一開始的方案和文章所描述的一樣烟零,設(shè)置這2個參數(shù)來減少 avformat_find_stream_info 函數(shù)的調(diào)用時間。但由于需要解決下述問題:
1咸作、很容易出現(xiàn)參數(shù)設(shè)置過大無法有效的減少時間調(diào)用锨阿,設(shè)置過小出現(xiàn)無法解析全部碼流信息

因為需要提供通用的播放器SDK以支持多種流格式多種碼率以及點播直播。所以決定試一試其它方案解決這個問題记罚。

替換掉 avformat_find_stream_info 函數(shù)

這個想法是看到一篇博文VLC優(yōu)化(1) avformat_find_stream_info接口延遲降低 中描述所啟發(fā)墅诡。但實際操作中發(fā)現(xiàn),此方案局限性太大桐智。

avformat_find_stream_info 處理

比如都熟悉的RTMP協(xié)議末早,正常情況下RTMP流的視頻元數(shù)據(jù)就在最前面.理論上打開速度應(yīng)該非常快才對酵使。不應(yīng)該那么慢荐吉。參考對比rtmp web 播放
想必avformat_find_stream_info 函數(shù)內(nèi)部實行有些冗余的操作口渔,導(dǎo)致耗時較長样屠。
函數(shù)位于 libavformat/utils.c 文件里。日志分析,函數(shù)的大部分時間耗費在以下代碼域中(相關(guān)文件代碼)
以下是簡易代碼塊痪欲。

for (;;)
{
....
}

其實里面就是死循環(huán)讀取碼流信息悦穿,正常退出條件:
直到讀取到相關(guān)需要的信息
read_size >= probesize
讀取的音頻視頻流的時長 >= max_analyze_duration
為何已經(jīng)讀取到了相關(guān)解碼信息還不退出呢?查看一下循環(huán)內(nèi)有一段是檢查是否讀取到了必須的信息

for (i = 0; i < ic->nb_streams; i++) {
        int fps_analyze_framecount = 20;
        
        st = ic->streams[i];
        if (!has_codec_parameters(st, NULL))
            break;
        /* If the timebase is coarse (like the usual millisecond precision
         * of mkv), we need to analyze more frames to reliably arrive at
         * the correct fps. */
        if (av_q2d(st->time_base) > 0.0005)
            fps_analyze_framecount *= 2;
        if (!tb_unreliable(st->internal->avctx))
            fps_analyze_framecount = 0;
        if (ic->fps_probe_size >= 0)
            fps_analyze_framecount = ic->fps_probe_size;
        if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
            fps_analyze_framecount = 0;
        /* variable fps and no guess at the real fps */
        if (!(st->r_frame_rate.num && st->avg_frame_rate.num) &&
            st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            int count = (ic->iformat->flags & AVFMT_NOTIMESTAMPS) ?
                st->info->codec_info_duration_fields/2 :
                st->info->duration_count;
            if (count < fps_analyze_framecount)
                break;
        }
        if (st->parser && st->parser->parser->split &&
            !st->internal->avctx->extradata)
            break;
        if (st->first_dts == AV_NOPTS_VALUE &&
            !(ic->iformat->flags & AVFMT_NOTIMESTAMPS) &&
            st->codec_info_nb_frames < ((st->disposition & AV_DISPOSITION_ATTACHED_PIC) ? 1 : ic->max_ts_probe) &&
            (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
             st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO))
            break;
    }

我們看到為何已經(jīng)有了必須要的解碼信息if (!has_codec_parameters(st, NULL)) 還需要讀取那些信息才能退出呢业踢?其實主要還是為了 fps 的信息獲取操作栗柒。其實這個信息對視頻打開播放沒有影響。所以我在死循環(huán)內(nèi)添加了以下邏輯代碼:

     for (int j = 0; j < ic->nb_streams; j++){
        st = ic->streams[j];
        if (has_codec_parameters(st, NULL)){
            if (st->parser && st->parser->parser->split && !st->codecpar->extradata){
                av_log(ic, AV_LOG_DEBUG, "%d has_codec_parameters but no extradata \n",j);
            }else {
                if(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){
                    prob_video_ok = 1;
                    av_log(ic, AV_LOG_DEBUG, "%d video  has_codec_parameters \n",j);
                }else if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO){
                    prob_audio_ok = 1;
                    av_log(ic, AV_LOG_DEBUG, "%d audio  has_codec_parameters \n",j);
                }
            }
        }
    }       

當獲取到了相關(guān)解碼信息后直接就退出這個死循環(huán)知举。
經(jīng)過測試確實減少了avformat_find_stream_info 函數(shù)調(diào)用時間瞬沦,然后打開流的速度快了很多。
測試中發(fā)現(xiàn)有時候顯示畫面快,有時候顯示慢雇锡。這是因為服務(wù)器沒有設(shè)置緩存GOP或者I幀的策略導(dǎo)致的,因為第一幀畫面需要I幀逛钻。

try_decode_frame 處理

因為播放業(yè)務(wù)集中在機頂盒上且是高碼率的流,而機頂盒硬件性能太差锰提。分析發(fā)現(xiàn) try_decode_frame 這個函數(shù)多次調(diào)用消耗很多時間曙痘。看一下下面對這個函數(shù)的描述:

 /* If still no information, we try to open the codec and to
     * decompress the frame. We try to avoid that in most cases as
     * it takes longer and uses more memory. For MPEG-4, we need to
     * decompress for QuickTime.
     *
     * If AV_CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
     * least one frame of codec data, this makes sure the codec initializes
     * the channel configuration and does not only trust the values from
     * the container. */

函數(shù)調(diào)用的地方描述了立肘,要避免調(diào)用這個函數(shù)边坤。因為這會消耗更長以及更多的內(nèi)存。從上面描述來看其實不調(diào)用這個函數(shù)也不會有問題谅年。

   if(decodec_state[pkt->stream_index] == 0)
    {
        int result = try_decode_frame(ic, st, pkt,(options && i < orig_nb_streams) ? &options[i] : NULL);
        if(result > 0){
            decodec_state[pkt->stream_index] = 1;
        }
    }

如果流的當前Track 已經(jīng)成功解碼茧痒,則下次就不用重復(fù)調(diào)用這個函數(shù)了。這個是因為的流很可能會出現(xiàn)前幾幀一直都是視頻幀,然后才是音頻幀融蹂。導(dǎo)致多次調(diào)用視頻幀進行try_decode_frame軟解浪費時間,尤其在低端設(shè)備上面以及H265編碼文黎。

簡單總結(jié)

其實沒有什么需要總結(jié)的。直接看直播疑難雜癥排查(3)— 首開慢這篇文章就好,已經(jīng)總結(jié)的很好殿较。不過最后強調(diào)一下

2.3 播放策略原因

這個優(yōu)化也非常重要,不亞于avformat_find_stream_info的優(yōu)化耸峭。

最后,本來打算做一個測試對比淋纲。因為發(fā)現(xiàn)沒有大家都能訪問的合適的測試流作為對比劳闹。而公司內(nèi)部的流外部無法訪問,也就作罷了。聲明一下:本人水平有限洽瞬。如有錯誤本涕,敬請指教。謝謝伙窃!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菩颖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子为障,更是在濱河造成了極大的恐慌晦闰,老刑警劉巖放祟,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異呻右,居然都是意外死亡跪妥,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門声滥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眉撵,“玉大人,你說我怎么就攤上這事落塑∨ε保” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵憾赁,是天一觀的道長仰挣。 經(jīng)常有香客問我,道長缠沈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任错蝴,我火速辦了婚禮洲愤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘顷锰。我一直安慰自己柬赐,他們只是感情好,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布官紫。 她就那樣靜靜地躺著肛宋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪束世。 梳的紋絲不亂的頭發(fā)上酝陈,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天,我揣著相機與錄音毁涉,去河邊找鬼沉帮。 笑死,一個胖子當著我的面吹牛贫堰,可吹牛的內(nèi)容都是我干的穆壕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼其屏,長吁一口氣:“原來是場噩夢啊……” “哼喇勋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起偎行,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤川背,失蹤者是張志新(化名)和其女友劉穎贰拿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渗常,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡壮不,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了皱碘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片询一。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖癌椿,靈堂內(nèi)的尸體忽然破棺而出健蕊,到底是詐尸還是另有隱情,我是刑警寧澤踢俄,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布缩功,位于F島的核電站,受9級特大地震影響都办,放射性物質(zhì)發(fā)生泄漏嫡锌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一琳钉、第九天 我趴在偏房一處隱蔽的房頂上張望势木。 院中可真熱鬧,春花似錦歌懒、人聲如沸啦桌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甫男。三九已至,卻和暖如春验烧,著一層夾襖步出監(jiān)牢的瞬間板驳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工碍拆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留笋庄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓倔监,卻偏偏與公主長得像直砂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子浩习,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容