Start · Sprachen · JavaScript · Referenz · RTCOutboundRtpStreamStats.qpSum

RTCOutboundRtpStreamStats.qpSum

Eigenschaft

Summe der Quantisierungsparameter (QP) aller Frames, die der Sender bisher für diesen ausgehenden Videostream codiert hat. Dient als Maß für die Codierqualität.

seit JavaScript Baseline: Chrome, Edge, Firefox, Safari (neuere Ve Kategorie: webapi

Signatur

RTCOutboundRtpStreamStats.qpSum

Beschreibung

Die Eigenschaft qpSum des Wörterbuchs RTCOutboundRtpStreamStats enthält eine vorzeichenlose Ganzzahl. Sie ist die Summe der Quantisierungsparameter (QP) aller Frames, die der Encoder für diesen ausgehenden RTP-Videostream bisher erzeugt hat. Je höher der QP, desto stärker komprimiert der Encoder, und desto schlechter ist die Bildqualität meist.

Ein einzelner Wert von qpSum hilft allein wenig. Aussagekräftig wird er erst, wenn man ihn durch framesEncoded teilt. So erhält man den durchschnittlichen QP pro Frame. Noch genauer wird es, wenn man die Differenz zwischen zwei Messungen bildet: ΔqpSum / ΔframesEncoded. Das ergibt den mittleren QP im Messintervall, und damit lassen sich Qualitätseinbrüche in Echtzeit erkennen, etwa bei knapper Bandbreite oder hoher CPU-Last.

Die Werte lassen sich nur innerhalb desselben Codecs vergleichen. Welcher QP-Bereich gilt, hängt vom Codec ab: VP8 und VP9 nutzen 0–127, H.264 nutzt 0–51, AV1 nutzt 0–255. Welcher Codec aktiv ist, erfährt man über codecId und den zugehörigen RTCCodecStats-Eintrag. Die Eigenschaft gibt es nur bei Video-Streams (kind === "video").

Rückgabewert

Typ
number | undefined
Beschreibung
Vorzeichenlose 64-Bit-Ganzzahl mit der bisherigen QP-Summe aller codierten Frames. Bei Audio-Streams fehlt der Wert (undefined), ebenso wenn der Browser ihn nicht meldet.

Beispiele

Durchschnittlichen QP pro Frame auslesen

// pc ist eine bestehende RTCPeerConnection mit gesendetem Video
const logAverageQp = async (pc) => {
  const stats = await pc.getStats();
  stats.forEach((report) => {
    if (report.type === 'outbound-rtp' && report.kind === 'video' && report.qpSum !== undefined) {
      const avgQp = report.framesEncoded > 0 ? report.qpSum / report.framesEncoded : 0;
      console.log(`SSRC ${report.ssrc}: Ø QP = ${avgQp.toFixed(1)}`);
    }
  });
};

await logAverageQp(pc);
SSRC 123456789: Ø QP = 28.4

QP im Intervall überwachen (Delta-Berechnung)

const previous = new Map();

const monitorQp = async (sender) => {
  const stats = await sender.getStats();
  for (const report of stats.values()) {
    if (report.type !== 'outbound-rtp' || report.kind !== 'video') continue;
    const prev = previous.get(report.id);
    if (prev) {
      const frames = report.framesEncoded - prev.framesEncoded;
      const qp = report.qpSum - prev.qpSum;
      if (frames > 0) {
        const intervalQp = qp / frames;
        console.log(`Intervall-QP (${report.rid ?? 'default'}): ${intervalQp.toFixed(1)}`);
        if (intervalQp > 40) console.warn('Qualität sinkt – Bandbreite oder CPU prüfen');
      }
    }
    previous.set(report.id, { qpSum: report.qpSum, framesEncoded: report.framesEncoded });
  }
};

const [videoSender] = pc.getSenders().filter((s) => s.track?.kind === 'video');
setInterval(() => monitorQp(videoSender), 2000);
Intervall-QP (default): 31.2 Intervall-QP (default): 44.7 Warnung: Qualität sinkt – Bandbreite oder CPU prüfen

QP zusammen mit dem Codec ausgeben

const qpWithCodec = async (pc) => {
  const stats = await pc.getStats();
  for (const r of stats.values()) {
    if (r.type === 'outbound-rtp' && r.kind === 'video' && r.framesEncoded) {
      const codec = stats.get(r.codecId);
      console.log(codec?.mimeType, (r.qpSum / r.framesEncoded).toFixed(1));
    }
  }
};

await qpWithCodec(pc);
video/VP8 27.9

// Wichtig · Fallstricke

  • Codec-abhängig: QP-Werte lassen sich nicht zwischen Codecs vergleichen, weil VP8/VP9 (0–127), H.264 (0–51) und AV1 (0–255) unterschiedliche Skalen haben. Wechselt der Codec mitten in der Sitzung, verliert die Delta-Berechnung ihre Aussagekraft.
  • Kumulativ: qpSum wächst nur. Für aktuelle Qualitätswerte bildet man immer Differenzen zwischen zwei getStats()-Aufrufen.
  • Simulcast: Jede Schicht (rid) hat einen eigenen outbound-rtp-Eintrag mit eigenem qpSum.
  • Kompatibilität: Ob und wie der Wert gemeldet wird, unterscheidet sich zwischen Browsern und Encodern, zum Beispiel bei Hardware-Encodern. Vor der Nutzung auf undefined prüfen. Bei Audio-Streams fehlt die Eigenschaft immer.
  • Ein hoher QP ist nur ein Hinweis auf schlechte Qualität. Er misst die Qualität nicht direkt, denn auch der Bildinhalt beeinflusst ihn (z. B. viel Bewegung).