VPLAY-12472 [CSAT][AAMP] Add logging for buffering start/end and buffering duration#1160
Conversation
There was a problem hiding this comment.
Pull request overview
Adds telemetry/logging to capture buffering start/end events along with buffering duration.
Changes:
- Introduces a new member to track buffering start time for duration calculations.
- Updates buffer change event handling to compute and log buffering duration.
- Sends buffering duration (
dur) as an int field in telemetry events.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| priv_aamp.h | Adds member variable to store buffering start time. |
| priv_aamp.cpp | Computes/logs buffering duration and includes it in telemetry payload. |
e0c6209 to
d217590
Compare
…ering duration Reason for change: Added buffering duration in the telementary along with buffer start and end Risks: Low Test Procedure: Refer jira ticket Priority: P1 Signed-off-by: lashminthaj <lashminthaj17@gmail.com>
8f9f94f to
65786fd
Compare
| std::string telemetryName = bufferingStopped?"VideoBufferingStart":"VideoBufferingEnd"; | ||
| at2.send(telemetryName,{/*int data*/},{/*string data*/},{/*float data*/}); | ||
| std::map<std::string,int> intData; | ||
| intData["dur"] = static_cast<int>(bufferingDurationMs); |
There was a problem hiding this comment.
bufferingDurationMs is cast from long long to int for telemetry without bounds checking. If the value is negative (time jump) or exceeds INT_MAX, this will wrap/truncate and emit incorrect telemetry. Consider clamping to a safe range before casting (e.g., 0..INT_MAX) or changing the telemetry schema to avoid narrowing if that’s supported.
| intData["dur"] = static_cast<int>(bufferingDurationMs); | |
| long long clampedDurationMs = bufferingDurationMs; | |
| if (clampedDurationMs < 0) | |
| { | |
| clampedDurationMs = 0; | |
| } | |
| else if (clampedDurationMs > static_cast<long long>(INT_MAX)) | |
| { | |
| clampedDurationMs = static_cast<long long>(INT_MAX); | |
| } | |
| intData["dur"] = static_cast<int>(clampedDurationMs); |
Signed-off-by: Philip Stroffolino <philip_stroffolino@cable.comcast.com>
| // from GStreamer error callbacks (via ScheduleRetune), with no common lock held at the | ||
| // call site. The compound check-and-set operations in SendBufferChangeEvent use | ||
| // compare_exchange_strong / exchange to keep the read-modify-write sequences race-free. | ||
| std::atomic<long long> mBufferingStartTimeMS; |
There was a problem hiding this comment.
mBufferingStartTimeMS has no in-class initializer. There are alternate PrivateInstanceAAMP constructor definitions used by unit-test fakes/mocks (e.g. test/utests/drm/mocks/aampMocks.cpp, test/utests/fakes/FakePrivateInstanceAAMP.cpp) that don't initialize this new member, leaving the atomic's value indeterminate. That can yield undefined behavior / bogus buffering durations when SendBufferChangeEvent() does compare_exchange_strong/exchange. Prefer giving the member an in-class initializer (e.g., {-1}) or updating all constructors to initialize it.
| std::atomic<long long> mBufferingStartTimeMS; | |
| std::atomic<long long> mBufferingStartTimeMS{-1}; |
| std::string telemetryName = bufferingStopped?"VideoBufferingStart":"VideoBufferingEnd"; | ||
| at2.send(telemetryName,{/*int data*/},{/*string data*/},{/*float data*/}); | ||
| std::map<std::string,int> intData; | ||
| intData["dur"] = static_cast<int>(bufferingDurationMs); |
There was a problem hiding this comment.
bufferingDurationMs is a long long but is narrowed to int for telemetry. If the buffering episode (or an unpaired start/end due to an error path) exceeds INT_MAX milliseconds, the cast becomes implementation-defined and can produce incorrect/negative values. Consider clamping to std::numeric_limits<int>::max() (or sending duration via a wider telemetry field type if available).
| intData["dur"] = static_cast<int>(bufferingDurationMs); | |
| int durationForTelemetry; | |
| if (bufferingDurationMs < 0) | |
| { | |
| durationForTelemetry = 0; | |
| } | |
| else if (bufferingDurationMs > INT_MAX) | |
| { | |
| durationForTelemetry = INT_MAX; | |
| } | |
| else | |
| { | |
| durationForTelemetry = static_cast<int>(bufferingDurationMs); | |
| } | |
| intData["dur"] = durationForTelemetry; |
Signed-off-by: Philip Stroffolino <philip_stroffolino@cable.comcast.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| std::map<std::string,int> intData; | ||
| intData["dur"] = static_cast<int>(bufferingDurationMs); | ||
| at2.send(telemetryName, intData, {/*string data*/}, {/*float data*/}); |
There was a problem hiding this comment.
bufferingDurationMs is a long long but is unconditionally narrowed to int for telemetry (static_cast<int>(bufferingDurationMs)). If a buffering episode is very long (or if the start timestamp is ever corrupted/uninitialized), this can overflow and send a negative/garbled duration. Clamp to INT_MAX (and 0) before casting, or extend the telemetry API usage to carry a 64-bit value if supported.
| p_aamp->SendBufferChangeEvent(true); | ||
| long long t2 = p_aamp->GetBufferingStartTimeMS(); | ||
| ASSERT_GE(t2, 0LL); | ||
| EXPECT_GT(t2, t1); // monotonic: second start must be later than first |
There was a problem hiding this comment.
This test asserts EXPECT_GT(t2, t1) using NOW_STEADY_TS_MS, which is a millisecond-truncated steady-clock counter. On platforms with coarse clock resolution, t2 can legitimately equal t1 even when time advanced (still monotonic), making the test flaky. Consider relaxing to EXPECT_GE(t2, t1) or structuring the assertion to avoid requiring a strict 1ms tick boundary.
| EXPECT_GT(t2, t1); // monotonic: second start must be later than first | |
| EXPECT_GE(t2, t1); // monotonic: second start must not be earlier than first |
Reason for change: Added buffering duration in the telementary along with buffer start and end
Risks: Low
Test Procedure: Refer jira ticket
Priority: P1