使用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; }