如何通过客观方法估算VoIP通话MOS值:RTCP数据转换疑问
问题:RTCP数据转换为MOS值的标准参考与代码解析
我需要估算VoIP通话的语音流质量,在ITU G.107标准中找到核心公式:
R = R₀ - Iₛ - I_d - I_eff + A
但不清楚如何从RTP/UDP/IP/Ethernet栈中填充公式的变量值。我在MicroSIP代码库的global.cpp第404行找到相关实现(代码如下),但网络资料和代码注释中均无该公式到代码的转换说明,希望找到可靠的学术或标准参考,明确RTCP数据转换为MOS值的方法。
代码实现
bool msip_call_statistics(call_user_data *user_data, float *MOS) { if (pjsua_var.state != PJSUA_STATE_RUNNING) { return false; } if (!pjsua_call_has_media(user_data->call_id)) { return false; } pjsua_stream_stat stat; pj_status_t status = pjsua_call_get_stream_stat(user_data->call_id, 0, &stat); if (status != PJ_SUCCESS) { return false; } int LOCAL_DELAY = 30; float R; float a = 0.0f; float b = 19.8f; float c = 29.7f; float rx_loss = 0.0; float rx_jit = 0.0; float avg_latency = 0.0; int pkt_last = stat.rtcp.rx.pkt - user_data->rx_pkt_prev; int loss_last = stat.rtcp.rx.loss - user_data->rx_loss_prev; rx_loss = (pkt_last == 0) ? 1.0f : ((float)loss_last / (float)(pkt_last + loss_last)); user_data->rx_pkt_prev = stat.rtcp.rx.pkt; user_data->rx_loss_prev = stat.rtcp.rx.loss; rx_jit = (float)stat.rtcp.rx.jitter.last / 1000; avg_latency = (stat.rtcp.rtt.last / 2000.0f) + LOCAL_DELAY + PJMEDIA_SND_DEFAULT_PLAY_LATENCY + PJMEDIA_SND_DEFAULT_REC_LATENCY + rx_jit; { float d = avg_latency; float d2 = d - 177.3f; float Id = 0.024f * d + 0.11f * (d - 177.3f) * (d2 < 0 ? 0 : 1); float P = rx_loss; float Ie = a + b * (float)log(1 + c * P); R = 94.2f - Id - Ie; } if (R < 0) { *MOS = 1; } else if (R > 100) { *MOS = 4.5; } else { *MOS = 1 + 0.035f * R + 7.10f / 1000000 * R * (R - 60) * (100 - R); } return true; }
代码与ITU G.107(E-Model)的对应关系
这段代码是E-Model的简化实现,针对VoIP场景做了参数默认取值,对应关系如下:
- R₀(基准质量分):代码中直接使用
94.2f,这是G.711等高质量语音编码的默认基准值,代表无损耗、无延迟的理想语音质量。 - Iₛ(编码损耗):代码未单独计算,因为默认使用高质量编码,Iₛ已合并到R₀的取值中。
- I_d(延迟损耗):通过
avg_latency计算,完全符合G.107的分段公式:avg_latency由单向网络延迟(RTT/2)、本地处理延迟(30ms)、设备播放/录音延迟、抖动缓冲延迟(rx_jit)组成,这些数据全部来自RTCP统计。- 当延迟
d ≤ 177.3ms时,I_d = 0.024*d;当d > 177.3ms时,额外叠加0.11*(d-177.3)的惩罚项。
- I_eff(有效丢包损耗):代码中
Ie = a + b*log(1 + c*P),其中P是从RTCP计算出的丢包率(rx_loss),a=0、b=19.8、c=29.7是VoIP场景下的标准经验参数,对应G.107中丢包对语音质量的影响模型。 - A(用户满意度调整因子):代码未体现,默认取0,该因子仅在特定场景(如降噪、回声消除优化)下添加。
MOS值转换
代码中R值到MOS的映射是标准的E-Model转换公式:
- 当
R < 0时,MOS取最小值1; - 当
R > 100时,MOS取最大值4.5; - 中间范围用多项式
MOS = 1 + 0.035R + 7.1e-6*R*(R-60)*(100-R)计算,完全符合ITU标准。
可靠参考资料
- ITU-T G.107:即E-Model标准,详细定义了R值的计算逻辑、各参数含义及取值范围,是VoIP质量评估的核心依据。
- ITU-T G.114:定义了VoIP延迟的指标要求,帮助理解I_d参数的计算依据。
- PJMEDIA官方文档:代码基于PJSUA/PJMEDIA框架,其统计模块的设计完全对齐ITU标准,可参考框架内的语音质量计算逻辑说明。
内容的提问来源于stack exchange,提问作者exception
相关产品推荐
相关产品推荐

