예제 #1
0
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;
}
예제 #2
0
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;
}