Skip to content

Conversation

@swatijha23
Copy link
Collaborator

@swatijha23 swatijha23 commented Dec 4, 2025

KPIs are calculated based on this doc - https://newrelic.atlassian.net/wiki/spaces/VERTSOL/pages/4702274467/KPIs+Transformation+QOE+Score

  1. kpi.startupTime
    kpi.startupTime = timeSinceRequested
    Source: TimeSince mechanism tracking time from CONTENT_REQUEST to current moment

  2. kpi.peakBitrate
    Formula: Maximum value tracking
    kpi.peakBitrate = MAX(bitrate_1, bitrate_2, ..., bitrate_n)

  3. kpi.hadStartupFailure

Formula: Boolean logic based on playback state
kpi.hadStartupFailure = (timeSinceStarted == null)

Logic:

  • true = Error occurred before CONTENT_START (no timeSinceStarted attribute exists)
  • false = Playback started successfully
  1. kpi.hadPlaybackFailure

Formula: Boolean flag set on error during playback
kpi.hadPlaybackFailure = qoeHadPlaybackFailure

Tracking Logic:
// On CONTENT_ERROR:

  1. kpi.totalRebufferingTime

Formula: Cumulative sum of rebuffering durations
kpi.totalRebufferingTime = Σ(rebuffer_duration_i) where buffer_type ≠ "initial"

Tracking Logic:
// On each CONTENT_BUFFER_END:

  1. kpi.rebufferingRatio

Formula: Percentage of time spent rebuffering
double rebufferingRatio = ((double) qoeTotalRebufferingTime / totalPlaytime) * 100;

7. kpi.totalPlaytime

Formula: Direct attribute mapping
kpi.totalPlaytime = totalPlaytime

Source: Accumulated through updatePlaytime() mechanism

  1. kpi.averageBitrate (NEW: Time-Weighted)

Formula: Time-weighted average of bitrates
// Primary calculation (time-weighted):
if (qoeTotalActiveTime > 0) {
kpi.averageBitrate = qoeTotalBitrateWeightedTime / qoeTotalActiveTime
}

// Fallback calculation (simple average):
else if (qoeBitrateCount > 0) {
kpi.averageBitrate = qoeBitrateSum / qoeBitrateCount
}

Time-Weighted Tracking:
// On each rendition change:
segmentDuration = currentTime - qoeLastRenditionChangeTime
qoeTotalBitrateWeightedTime += (previousBitrate × segmentDuration)
qoeTotalActiveTime += segmentDuration

// During calculation, include current segment:
currentSegmentDuration = currentTime - qoeLastRenditionChangeTime
totalWeightedTime = qoeTotalBitrateWeightedTime + (currentBitrate × currentSegmentDuration)
totalTime = qoeTotalActiveTime + currentSegmentDuration

averageBitrate = totalWeightedTime / totalTime

Mathematical Representation:
Average = Σ(bitrate_i × duration_i) / Σ(duration_i)

Where:

  • bitrate_i = bitrate during segment i
  • duration_i = time duration of segment i
  • i = 1 to n rendition changes

@swatijha23 swatijha23 requested a review from ametku December 23, 2025 08:06
Copy link
Contributor

@ametku ametku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added some comments as initial review. I need to verify more for qoe attrs.

@@ -0,0 +1,60 @@
name: Publish Release

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The QOE_AGGREGATE data is has a lot more attrs. The attrs in QOE_AGGREGATE should be selected. Please check browser implementation for the same

@@ -0,0 +1,60 @@
name: Publish Release

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@swatijha23 There is sometime wrong. these files should not be part of your PR. They are already part of master. can you fix it?

}
}
def applicationToken = localProperties.getProperty('nr.applicationToken', "")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even these files. I would suggest add your changes only part of this PR


// Time-weighted bitrate calculation fields
private Long qoeCurrentBitrate;
private Long qoeLastRenditionChangeTime;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually not rendition change but bitrate change. Can you refer to browser implementation


// Add captured timestamps to QOE_AGGREGATE events
if (contentRequestTimestamp != null) {
kpiAttributes.put("timeSinceRequested", contentRequestTimestamp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we including timeSinceRequested for QOE ? Please check browser implementation to verify the attrs part of QOE event

@swatijha23
Copy link
Collaborator Author

#75

@swatijha23 swatijha23 closed this Dec 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants