APP端的传输状况推算和丢帧估算
更新日期:2025/2/13
目前APP端并没有响应的接口来反馈当前的传输状况,不过有一些间接的方法可以做这样的估算,其依据便是接收端的fps和理论的发送fps做对比估算。
如何计算设备端的发送fps(理论值)?
/*
* 此用例用以演示如何估算设备端的发送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-1){
//计算时间戳差值的平均值,可以去掉一个最高,一个最低再算。
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,40},去掉一个最高,一个最低,计算出的时间戳差值是40ms,那么理论上发送的fps是25。
APP端再根据统计到的接收的实际fps持续对比几秒钟,正常的状况应该是recv_fps比较稳定在send_fps附近。出现差距大或者暴增暴减,实际都可以说明网络波动较大。
那么又如何判断当前是否丢帧呢?
正常情况下,开启重传是不会丢帧的,但是有些情况下,却又是客观存在的,问题出在avSendFrameData这个接口上面。这个接口如果在返回AV_ER_EXCEED_MAX_SIZE(-20006)后,实际这一帧是没有送进缓存区的,也就是实际上被SDK丢掉了。
但是APP端实际在检查frmNo的时候,是不会发现问题。因为SDK只会对送进缓存区的帧进行编号,所以即使设备端出现-20006,APP端拿到的帧号frmNo仍然是连续的。
所以针对这种情况,可以通过观察当前帧的时间戳,与上一帧的时间戳的差值,如果超过一点的偏差,则说明此帧前有丢帧。
/*
* 先计算前后时间戳理论差值
* 再根据当前差值跟理论差值的差距
*/
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{
continue;
}
}
}