static gboolean kms_remb_local_update (KmsRembLocal * rl) { guint64 bitrate, packets_rcv_interval; guint fraction_lost, packets_rcv_interval_top; if (!get_video_recv_info (rl, &bitrate, &fraction_lost, &packets_rcv_interval)) { return FALSE; } if (!rl->probed) { if (bitrate == 0) { return FALSE; } rl->remb = bitrate; rl->probed = TRUE; } packets_rcv_interval_top = MAX (rl->packets_recv_interval_top, packets_rcv_interval); rl->fraction_lost_record = (rl->fraction_lost_record * (packets_rcv_interval_top - packets_rcv_interval) + fraction_lost * packets_rcv_interval) / packets_rcv_interval_top; rl->max_br = MAX (rl->max_br, bitrate); if (rl->avg_br == 0) { rl->avg_br = bitrate; } else { rl->avg_br = (rl->avg_br * 7 + bitrate) / 8; } GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "packets_rcv_interval: %" G_GUINT64_FORMAT ", fraction_lost_record: %" G_GUINT64_FORMAT, packets_rcv_interval, rl->fraction_lost_record); if (rl->fraction_lost_record == 0) { gint remb_base, remb_new; remb_base = MIN (rl->remb, rl->max_br); if (remb_base < rl->threshold) { GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "A.1) Exponential (%f)", rl->exponential_factor); remb_new = remb_base * (1 + rl->exponential_factor); } else { GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "A.2) Lineal (%" G_GUINT32_FORMAT ")", rl->lineal_factor); remb_new = remb_base + rl->lineal_factor; } rl->remb = MAX (rl->remb, remb_new); } else { gint remb_base, lineal_factor_new; remb_base = MAX (rl->remb, rl->avg_br); rl->threshold = remb_base * rl->threshold_factor; lineal_factor_new = (remb_base - rl->threshold) / rl->lineal_factor_grade; rl->lineal_factor = MAX (rl->lineal_factor_min, lineal_factor_new); if (rl->fraction_lost_record < rl->up_losses) { GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "B) Assumable losses"); rl->remb = MIN (rl->remb, rl->max_br); } else { GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "C) Too losses"); rl->remb = remb_base * rl->decrement_factor; rl->fraction_lost_record = 0; rl->max_br = 0; rl->avg_br = 0; } } if (rl->max_bw > 0) { rl->remb = MIN (rl->remb, rl->max_bw * 1000); } GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "REMB: %" G_GUINT32_FORMAT ", TH: %" G_GUINT32_FORMAT ", fraction_lost: %d, fraction_lost_record: %" G_GUINT64_FORMAT ", bitrate: %" G_GUINT64_FORMAT "," " max_br: %" G_GUINT32_FORMAT ", avg_br: %" G_GUINT32_FORMAT, rl->remb, rl->threshold, fraction_lost, rl->fraction_lost_record, bitrate, rl->max_br, rl->avg_br); return TRUE; }
static gboolean kms_remb_local_update (KmsRembLocal * rl) { guint64 bitrate; guint fraction_lost; if (!get_video_recv_info (rl, &bitrate, &fraction_lost)) { return FALSE; } if (!rl->probed) { if (bitrate == 0) { return FALSE; } rl->remb = bitrate; rl->probed = TRUE; } rl->max_br = MAX (rl->max_br, bitrate); if (rl->avg_br == 0) { rl->avg_br = bitrate; } else { rl->avg_br = (rl->avg_br * 7 + bitrate) / 8; } if (fraction_lost == 0) { gint remb_base, remb_new; remb_base = MIN (rl->remb, rl->max_br); if (remb_base < rl->threshold) { GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "A.1) Exponential (%f)", REMB_EXPONENTIAL_FACTOR); remb_new = remb_base * (1 + REMB_EXPONENTIAL_FACTOR); } else { GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "A.2) Lineal (%" G_GUINT32_FORMAT ")", rl->lineal_factor); remb_new = remb_base + rl->lineal_factor; } rl->remb = MAX (rl->remb, remb_new); } else if (fraction_lost < REMB_UP_LOSSES) { GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "B) Assumable losses"); rl->remb = MIN (rl->remb, rl->max_br); rl->threshold = rl->remb * REMB_THRESHOLD_FACTOR; } else { gint remb_base, lineal_factor_new; GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "C) Too losses"); remb_base = MAX (rl->remb, rl->avg_br); rl->remb = remb_base * REMB_DECREMENT_FACTOR; rl->threshold = remb_base * REMB_THRESHOLD_FACTOR; lineal_factor_new = (remb_base - rl->threshold) / REMB_LINEAL_FACTOR_GRADE; rl->lineal_factor = MAX (REMB_LINEAL_FACTOR_MIN, lineal_factor_new); rl->max_br = 0; rl->avg_br = 0; } if (rl->max_bw > 0) { rl->remb = MIN (rl->remb, rl->max_bw * 1000); } GST_TRACE_OBJECT (KMS_REMB_BASE (rl)->rtpsess, "REMB: %" G_GUINT32_FORMAT ", TH: %" G_GUINT32_FORMAT ", fraction_lost: %d, bitrate: %" G_GUINT64_FORMAT "," " max_br: %" G_GUINT32_FORMAT ", avg_br: %" G_GUINT32_FORMAT, rl->remb, rl->threshold, fraction_lost, bitrate, rl->max_br, rl->avg_br); return TRUE; }