Red de conocimiento informático - Problemas con los teléfonos móviles - ¿Cuánto ancho de banda requiere un servidor webrtc?

¿Cuánto ancho de banda requiere un servidor webrtc?

Hay dos algoritmos de adaptación de ancho de banda para webrtc:

1. Control del ancho de banda del extremo de origen. El principio es aumentar o disminuir dinámicamente el ancho de banda a través de estadísticas de pérdida de paquetes en rtp. Cuando se reduce el ancho de banda, el algoritmo TFRC es. Se utiliza para aumentar la suavidad.

2. El principio de estimación del ancho de banda en el extremo receptor es estimar el ancho de banda a partir de los datos rtcp recibidos; utilizar el filtrado de Kalman para analizar el tiempo de envío y recepción de cada cuadro, a fin de obtener el ancho de banda de la red; utilización, corrija el ancho de banda estimado.

Estos dos algoritmos se complementan entre sí. El receptor envía el ancho de banda estimado al remitente y el remitente ajusta el ancho de banda de envío en función del ancho de banda recibido y la tasa de pérdida de paquetes.

A continuación se analizarán los dos algoritmos:

2. Análisis del algoritmo de estimación del ancho de banda en el lado del receptor

Combinado con el documento http://tools. .ietf/html/draft-alvestrand-rtcweb-congestion-02 y código fuente webrtc/modules/remote_bitrate_estimator/overuse_detector.cc para análisis

Modelo de estimación de ancho de banda: d(i) = dL(i) / c + w (i) d(i) La diferencia en el tiempo de transmisión de la red entre dos tramas de datos, dL(i) La diferencia de tamaño entre dos tramas de datos, c es la capacidad de transmisión de la red, w(i) w(i ) es nuestro enfoque, determinado principalmente por la velocidad de envío, la capacidad de enrutamiento de la red y la capacidad de transmisión de la red están determinadas por tres factores w (i) se ajusta a la distribución gaussiana. La conclusión es: cuando w (i) aumenta, el ancho de banda se utiliza en exceso; cuando w (i) disminuye, el ancho de banda está infrautilizado; cuando w (i) es cero, el uso del ancho de banda es correcto. Por lo tanto, siempre que podamos calcular w (i), podemos determinar la red actual. uso y aumentar o disminuir la tasa de envío

Algoritmo: Filtro de Kalman

theta_hat(i) = [1/C_hat(i) m_hat(i)]^T // El. el estado del i-ésimo punto de tiempo está representado por C, m****, theta_hat(i) es el valor estimado en este momento

z(i) = d(i) - h_bar(i )^T*.bar(i)^T*θ_hat(i-1)//d(i) es el valor de prueba, que es fácil de calcular. Este último puede considerarse como el valor estimado de d(i-1). ), entonces z(i) es la desviación de d(i), es decir, el residual.

theta_hat(i) = theta_hat(i-1) + z( i) * k_ bar(i) // Bien, este es el resultado que queremos. La clave está en la selección del valor k, de la siguiente manera Las dos fórmulas son la derivación específica del valor k, consulte la siguiente publicación del blog <. /p>

E(i-1) * h_bar(i)

k_bar(i) = ----- ---------------. ------------------------

var_v_hat + h_bar( i)^T * E(i-1) * h_bar(i )

E(i) = (I - K_bar(i) * h_bar(i)^T)* E(i-1) + Q(i ) // h_bar(i) se calcula en función del tamaño del paquete de el fotograma

Se puede ver que solo necesitamos conocer la duración del fotograma actual, el tiempo de envío, el tiempo de recepción y el estado del fotograma anterior. Puede calcular el uso de la red.

A continuación, echemos un vistazo más de cerca al código:

[cpp] ver

plaincopy

void OveruseDetector::UpdateKalman( int64_t t_delta,

double ts_delta,

uint32_t frame_size,

uint32_t prev_frame_size) {

const double min_frame_period = UpdateMinFramePeriod(ts_delta);

const double drift = CurrentDrift();

// Compensar la deriva

const double t_ts_delta = t_delta - ts_delta / drift; (i)

double fs_delta = static_cast(frame_size) - prev_frame_size;

// Actualizar filtro de Kalman

const double scale_factor = min_frame_period / (1000.0 / 30.0.0);

E_[0][0] += ruido_proceso_[0] * factor_escala

E_[1][1] += ruido_proceso_[1] * scale_factor;

if ((hipótesis_ == kBwOverusing &

if ((hipótesis_ == kBwOverusing & & offset_ < prev_offset_) |

(hipótesis_ == kBwUnderusing && offset_ > prev_ offset_)){

E_[1][1] += 10 * process_noise_[1] * scale_factor

}

const; double h[ 2] = {fs_delta, 1.0}; //es decir

Constante double Eh[2] = {E_[0][0]*h[0] + E_[0][1] *h[ 1],

E_[1][0]*h[0] + E_[1][1]*h[1]}

Residual doble constante; = t_ts_delta - pendiente_*h[0] - offset_; //i. Por ejemplo, z(i), la pendiente es 1/C

const bool stable_state =

(BWE_MIN (num_of_deltas_, 60) * fabsf(offset_) < umbral_);

// Intentamos filtrar fotogramas muy tardíos. Por ejemplo, los fotogramas clave periódicos

// no se ajustan al modelo gaussiano.

if (fabsf(residual) < 3 * sqrt(var_noise_)){

UpdateNoiseEstimate(residual, min_frame_period, stable_state) else {

p>

UpdateNoiseEstimate(3 * sqrt(var_noise_), min_frame_period, stable_state);

}

Doble denominación constante = var_noise_ + h[0]* Eh[0] + h[1]*Eh[1];

Constante doble K[2] = {Eh[0] / denom,

Eh[1] / denom }; //es decir, k_bar

const double IKh[2][2] = {{1.0 - K[0]*h[0], -K[0]*h[1]},

{-K[1]*h[0], 1.0 - K[1]*h[1]}};

Constante doble e00 = E_[0][0]

Constante doble e01 = E_[0][1]

// Estado de actualización

E_[0][0] = e00 * IKh[ 0][0] + E_[1] [0] * IKh[0][1];

E_[0][1] = e01 * IKh[0][0] + E_[1 ][1] * IKh[0][1];

E_[1][0] = e00 * IKh[1][0] + E_[1][0] * IKh[1] [1];

E_[1][1] = e01 * IKh[1][0] + E_[1][1] * IKh[1][1]

// Matriz de varianza de asociación, debe ser una matriz semifinita positiva

afirmar(E_[0][0] + E_[1][1] >= 0 && amp;

E_[0][ 0] * E_[1][1] - E_[0][1] * E_[1][0] >= 0 &&

E_[0] [0] >= 0);

pendiente_ = pendiente_ + K[0] * residual; //1/C

prev_offset_ = offset_

offset_ = offset_ + K [1] * residual; // theta_hat(i)

Detect(ts_delta

}

[cpp] vista

copia simple

Uso de ancho de banda OveruseDetector::Detect(double ts_delta) {

if (num_of_deltas_ < 2) {

return kBwNormal;

const double T = BWE_MIN(num_of_deltas_, 60) * offset_; //es decir, gamma_1

if (fabsf(T) > umbral_) {

if (offset_ > 0) {

if (time_over_using_ ==

-1) {

// Inicializa el temporizador. Digamos que hemos comprometido demasiado

// la mitad del tiempo desde la última

/ muestra.

// Uso excesivo de temporizadores.

/ Muestreo.

time_over_using_ = ts_delta / 2;

} else {

// Incrementa el temporizador

time_over_using_ += ts_delta;

}

over_use_counter_ ++;

if (time_over_using_ > kOverUsingTimeThreshold //kOverUsingTimeThreshold es gamma_2, gamama_3=1

&& amp; 1) {

if (offset_ >= prev_offset_) {

time_over_using_ = 0;

over_use_counter_ = 0

hipótesis_ = kBwOverusing

}

}

} más {

time_over_using_ = -1

over_use_counter_ = 0;

hipótesis_ = kBwUnderusing

}

} else {

time_over_using_ = -1;

over_use_counter_ = 0; p> p>

hipótesis_ = kBwNormal;

}

Devuelve hipótesis_;