Merged
Conversation
Add QOE_AGGREGATE action name and kpi.* attribute constants to NRVideoDefs.h. Add qoeAggregateEnabled, qoeAggregateIntervalMultiplier, and isQoeAggregateEnabled to NRVAVideoConfiguration for controlling QoE event frequency relative to harvest cycles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce NRQoEAggregator to compute Quality of Experience metrics: - Time-weighted average bitrate and peak bitrate tracking - Rebuffering ratio from connection-type buffer events - Startup time (timeSinceRequested minus pre-roll ad duration) - Startup and playback failure flags Uses a static dispatch table for action routing and @synchronized for thread safety. Reads fully-assembled attributes from the tracker pipeline (no parallel state or direct player API calls). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add qoeEventProvider callback and enqueueFinalQoeEvent to NRVAHarvestManager. QoE events are generated at harvest time (not heartbeat time) and injected directly into the batch array, bypassing the crash-safe buffer. Key design: - Provider block called only when batch contains VideoAction events - Multiplier formula (count-1)%N controls QoE frequency - enqueueFinalQoeEvent accepts pre-built events from sendEnd to avoid race conditions with tracker thread cleanup - pendingFinalQoe takes priority and auto-clears the provider Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
NRVideoTracker changes: - Initialize QoE aggregator when feature is enabled - Snapshot content event attributes in preSendAction for QoE reuse - Register qoeEventProvider block at sendStart (content path) - Build final QoE eagerly at sendEnd and enqueue via enqueueFinalQoeEvent to avoid race with aggregator reset - buildQoeEvent composes attributes from lastContentEventAttributes (filtering timeSince*/bufferType) overlaid with KPI metrics NRVAVideo facade: - Add setQoeEventProvider and enqueueFinalQoeEvent pass-throughs - Add isQoeAggregateEnabled for tracker feature check Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace dead CDN URLs for Sintel and Airshow with working streams: - Sintel -> Apple bipbop HEVC test stream (~30 min adaptive VOD) - Airshow -> Akamai live HLS test stream Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ll others The previous implementation only counted "connection"-type buffers. Android and JS SDKs use a simpler approach: skip the first CONTENT_BUFFER_END (initial buffer) and accumulate all subsequent ones regardless of bufferType. This aligns rebuffering metrics across all three platforms. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…upError/hadPlaybackError Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ering Use explicit bufferType check rather than skipping the first CONTENT_BUFFER_END by position. This is more correct — it skips the actual initial buffer type regardless of event ordering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Align with Android and JS SDKs which emit unprefixed attribute names (e.g. startupTime, not kpi.startupTime). QOE_PREFIX set to empty string. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… the same viewId as their content Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace blocklist approach with strict whitelist of 19 context attributes carried over from the last content event. Removes 17 attributes not produced by the iOS video core (asn, device, page, etc.). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d centralized KPI keys Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tegration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…by session flag Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on attributes to QoE whitelist Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 tests covering NRQoEAggregator KPI computation (startup time, bitrate tracking, rebuffering skip-first logic, error flags, reset) and NRVAHarvestManager QoE integration (multiplier gate, dirty check, pending final QoE priority). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix updatePlayTime() to accumulate ad vs content playtime separately - Fix getAttributes() to use totalAdPlaytime for ad events, totalPlaytime for content events - Remove double-counting logic in sendEnd() for ad playtime - Remove unnecessary totalPreRollAdTime from CONTENT_START attributes - Consolidate playtime logic within existing ad/content conditional blocks This resolves the bug where totalPlaytime exceeded contentPlayhead due to ad playtime contaminating content playtime measurements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Only accumulate content playtime after CONTENT_START to prevent pre-roll ad time from contaminating totalPlaytime - Fix live detection race condition by checking item status before updating isLive property - Clean up code formatting This resolves the issue where totalPlaytime was showing 614s instead of 600s due to ~14s contamination from pre-roll ad tracking during CONTENT_REQUEST phase. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change ad events to use correct field name 'totalAdPlaytime' instead of 'totalPlaytime' - Prevents ad playtime from contaminating content playtime field - Removes confusion between ad and content playtime tracking This resolves the issue where ad events were incorrectly overwriting the totalPlaytime field with ad playtime values, causing field contamination. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move totalPreRollAdTime tracking to QoE aggregator internal state - Add setTotalPreRollAdTime method to provide clean interface - Remove dependency on passing totalPreRollAdTime through event attributes - Prevent NRDB contamination by keeping internal data internal - Fix startupTime calculation: timeSinceRequested - totalPreRollAdTime This resolves the issue where startupTime was showing 16+ seconds instead of the correct ~7 seconds due to missing totalPreRollAdTime subtraction. The QoE aggregator now manages its own state instead of relying on external attributes. Benefits: - Clean architecture: aggregator owns its internal state - Future-proof: core data remains on tracker for other use cases - No NRDB risk: internal calculations don't leak to database - Modular: QoE can be disabled without losing core tracking data Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multiple fixes to resolve totalPlaytime accuracy and application crashes: 1. **Fix EXC_BAD_ACCESS crash in setTotalPreRollAdTime**: - Replace property with instance variable for safer memory access - Add nil checks to prevent crashes on deallocated aggregator - Use direct variable access instead of property setter/getter 2. **Fix totalPlaytime session-based tracking**: - Restore hasContentStarted flag for proper content session boundaries - Change from isStarted (playing state) to hasContentStarted (session state) - Now accumulates time during entire content session: playing, paused, buffering, seeking - Prevents pre-roll ad time contamination while capturing full engagement time 3. **Fix CONTENT_END totalPlaytime accuracy**: - Use live calculation only for CONTENT_END to capture final unflushed playtime - Regular content events use efficient stored values for performance - Consistent totalPlaytime values between QOE_AGGREGATE and CONTENT_END 4. **Simplify sendEnd logic**: - Remove unnecessary complexity from final QoE generation - Session-based tracking naturally handles timing without race conditions - Clean, maintainable code with single source of truth Expected results: - No more application crashes when clicking video links - totalPlaytime ≈ contentDuration (~101s) when video watched completely - Consistent, non-regressing totalPlaytime values across all events - Proper separation between ad and content playtime tracking Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolves race condition where multiple QOE events could be generated in the same harvest cycle at boundary conditions (e.g., CONTENT_END). - Remove duplicate QOE_AGGREGATE events from batch before adding latest - Ensure only one authoritative QOE event per harvest cycle - Add debug logging for duplicate detection - Handle boundary conditions without modifying provider pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: QOE
Replace broken single global QoE provider with multi-tracker collection system. Harvest manager now discovers and collects QoE from all active video trackers independently, ensuring each video session reports QoE correctly instead of only the last active tracker. - Remove legacy qoeEventProvider system from harvest manager - Add per-tracker cycle management and session lifecycle tracking - Implement proper dirty checking to avoid duplicate QoE events - Standardize logging to use NRVA_DEBUG_LOG consistently Fixes multi-video QoE reporting where previously only one tracker's metrics were sent during harvest cycles. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each tracker manages its own cycle count independently, making the global counter redundant and potentially confusing.
fix: resolve QoE deduplication issue in multi-video scenarios
fix: New Bitrate Metrics Added
fix: Reset timeSince started and requested attr
rajeevkumar-nr
approved these changes
Mar 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.