本文档详细介绍TUTK P2P SDK中APP端传输状况估算及丢帧判断的实现方法,包括设备端发送FPS计算、网络波动识别、丢帧分析逻辑,适用于音视频传输场景的网络状态监测。
一、APP端传输状况估算与丢帧判断方法
目前 APP 端暂无直接反馈传输状况的接口,但可通过间接方法估算:通过接收端实际 FPS 与设备端理论发送 FPS 对比,判断网络波动;通过帧时间戳差值分析,判断是否存在丢帧。以下为具体实现方案:
1. 计算设备端发送FPS(理论值)
核心逻辑:基于设备端传输的帧时间戳(单位:ms),计算连续帧的时间戳差值平均值,进而推导理论发送 FPS。建议统计 10 次时间戳差值,去除极值后计算平均值,结果更准确。
/*
* 此用例用以演示如何估算设备端的发送fps。
* 此计算用例中,设备端传过来的时间戳以ms为单位。
* 计算10次
*/
#define MAX_CAL_COUNT 10
unsigned int last_ts = 0;//用以存放上次的时间戳
bool need_cal_send_fps = true;
int ts_tmp[MAX_CAL_COUNT] = {0};//用以存放时间戳差值
int ts_tmp_arr_index = 0;
int fps;
while(1){
int ret = avRecvFrameData2(avIndex, buf, video_buf_size, &outBufSize, &outFrmSize, (char *)&frameInfo, sizeof(FRAMEINFO_t), &outFrmInfoSize, &frmNo);
if(ret > 0){
if(need_cal_send_fps && ts_tmp_arr_index < MAX_CAL_COUNT){
if(last_ts){
int ts_from_last = frameInfo.timestamp - last_ts; //与上一帧的时间戳差值
if(ts_from_last > 0){
ts_tmp[ts_tmp_arr_index++] = ts_from_last;
}
if(ts_tmp_arr_index == MAX_CAL_COUNT){
//计算时间戳差值的平均值,可以去掉一个最高,一个最低再算。
int ts = average(ts_tmp, MAX_CAL_COUNT);
fps = 1000 / ts; //此为设备端理论的发送fps
}
}
else{
last_ts = frameInfo.timestamp;
}
}
}
}
示例计算:若 10 次时间戳差值为 ts_tmp[10] = {40,40,80,40,40,40,40,40,40,35},去除一个最大值(80)和一个最小值(35)后,剩余 8 次差值均为 40ms,平均值为 40ms,则理论发送 FPS = 1000 / 40 = 25。
网络波动判断:APP 端统计接收端实际 FPS(recv_fps),持续对比 3-5 秒。正常情况下 recv_fps 应稳定在理论发送 FPS 附近;若两者差距过大或 FPS 暴增暴减,说明网络波动较大。
2. 丢帧判断方法
核心说明:开启重传后通常不会丢帧,但设备端调用 avSendFrameData 接口返回 AV_ER_EXCEED_MAX_SIZE(-20006) 时,该帧会被 SDK 丢弃(未进入缓存区)。由于 SDK 仅对缓存区的帧进行编号,APP 端拿到的帧号(frmNo)仍会连续,无法通过帧号判断丢帧,需通过时间戳差值分析。
/*
* 先计算前后时间戳理论差值(aver_ts_from_last)
* 再根据当前差值跟理论差值的差距判断是否丢帧
*/
unsigned int last_ts = 0;//用以存放上次的时间戳
int aver_ts_from_last = 0;//用以存放时间戳差值的平均值,计算方法参考上文
while(1){
int ret = avRecvFrameData2(avIndex, buf, video_buf_size, &outBufSize, &outFrmSize, (char *)&frameInfo, sizeof(FRAMEINFO_t), &outFrmInfoSize, &frmNo);
if(ret > 0){
if(last_ts){
int ts_from_last = frameInfo.timestamp - last_ts; //与上一帧的时间戳差值
if(ts_from_last > 1.5 * aver_ts_from_last){
printf("video maybe lost...\n");
}
}
else{
last_ts = frameInfo.timestamp;
continue;
}
last_ts = frameInfo.timestamp;
}
}
说明:示例中通过时间戳差值的倍数阈值判断丢帧,可根据实际业务场景调整阈值(如2倍),平衡检测灵敏度与误判率;建议结合滑动窗口算法统计实际FPS,减少瞬时波动影响。
判断逻辑:若当前帧与上一帧的时间戳差值(ts_from_last)超过理论平均差值(aver_ts_from_last)的 1.5 倍,则判定为该帧前存在丢帧。可根据实际业务场景调整阈值(如 2 倍),平衡灵敏度与误判率。