天天看點

doubango播放不均勻的問題及改進辦法

使用doubango做視訊的朋友,如果觀察過播放,就會發現忽快忽慢。

 這個問題亦引起吾之重視。頭目甲提拔的總監不解決(伺服器、終端一句代碼也沒改),那麼隻能吾解決了。

 首先,播放器是沒有問題的。

 其次,網絡問題不予考慮。因為有問題咱也沒辦法。可以做幀緩沖。

 那麼,唯一能改進的,就是接收包之後,派發的代碼。

 吾跟蹤了派發流程,最後發現問題是出在tdav_video_jb.c。

 吾又研究了派發代碼,然後就感覺自己智商低,沒看明白怎麼回事。怎麼辦?最後幹脆全部删除,按照自己的思路寫。問題果然解決了。新代碼如下:

/**
新的處理邏輯:
緩沖區中幀數太少,等待指定時間。
目前一幀資料不完整,等待指定時間和次數。
緩沖區中幀數太多,或超過等待條件式,不論目前幀是否完整,立即處理。
考慮到收到幀的時間間隔并不均勻,是以這裡也不進行間隔控制。
判斷有效幀數?可以考慮。
按理說,latency_min、latency_max應該根據幀率實時調整。
注意幀率不是自己這邊控制的,隻能計算。
*/
static void* TSK_STDCALL _tdav_video_jb_decode_thread_func(void *arg)
{
    tdav_video_jb_t* jb = (tdav_video_jb_t*)arg;
    tdav_session_av_t* session = (tdav_session_av_t*)jb->cb_data_any.usr_data;
    //tdav_session_video_t* video = (tdav_session_video_t*)session;
 
    tdav_video_frame_t* frame;
    uint64_t next_decode_duration = 0, now;
 
    tsk_list_item_t *item;
 
    jb->decode_last_seq_num = -1;
    jb->decode_last_seq_num_with_mark = -1; // -1 -> unset
    jb->decode_last_time = tsk_time_now();
 
    //這是何意?
    (void)(now);
 
    TSK_DEBUG_INFO("Video jitter buffer thread - ENTER");
 
    while(jb->started) {
        now = tsk_time_now();
        if (next_decode_duration > 0) {
            tsk_condwait_timedwait(jb->decode_thread_cond, next_decode_duration);
            next_decode_duration = 0;
        }
 
        if(!jb->started) {
            break;
        }
 
        //是否考慮判斷有效幀數?
        if (jb->frames_count < jb->latency_min)
        {
            next_decode_duration = WAIT_FRAME_DATA_DELAY;
            continue;
        }
 
        tsk_safeobj_lock(jb); // against get_frame()
        tsk_list_lock(jb->frames); // against put()
 
        /**
        如果目前流出錯,應該迅速處理。或根據上一秒的丢包情況調整緩沖區。
        目前測試發現,必須有jb->latency_max>=MAX。否則必然崩潰。
        為了避免出錯,一切照舊。實際上以現在網絡之發達情況,多等亦無用。
        */
       //暫時不便公開。
 
        //對應create,是真正要釋放了。
        TSK_OBJECT_SAFE_FREE(item);
 
    }   //while(jb->started)
 
    TSK_DEBUG_INFO("Video jitter buffer thread - EXIT");
 
    return tsk_null;
}      

繼續閱讀