Repository navigation
fix: no startup pause from the shared loss burst, and a paused cell gets another try (#148) - #149
Conversation
|
/review |
Code Review by Qodo
1. Startup losses can still pause cells
|
…fit go on), only when the grid starts, and a resumed cell gets its audio route back Co-Authored-By: Claude <noreply@anthropic.com>
|
/review |
| boolean warming = nowMs - startMs < warmupMs; | ||
| if (warming) quietSinceMs = nowMs; |
There was a problem hiding this comment.
1. Startup losses can still pause cells 📎 Requirement gap ≡ Correctness
The planner suppresses only the current lossy sample during one global warm-up window, while each cell reports loss-rate deltas accumulated since its previous sample. When cells settle at different times or a loss interval crosses the 10-second boundary, transient startup losses enter lossyTimes after warm-up and can trigger demotion or pausing within the loss window.
Agent Prompt
## Issue description
Startup losses can be sampled after the planner-wide warm-up expires because each cell's loss-rate interval is independent and is not reset or discarded at the warm-up boundary. Staggered decoder startup can therefore produce enough post-warm-up samples to trigger overload actions for a transient startup burst.
## Fix Focus Areas
- android/app/src/main/java/com/openipc/decoder/DecodePlanner.java[166-187]
- android/app/src/main/java/com/openipc/decoder/Decoder.java[1161-1166]
- android/app/src/main/java/com/openipc/decoder/QuadCell.java[314-330]
## Recommended Fix
Ensure loss samples covering each decoder's startup period are discarded rather than counted after the global warm-up expires. Reset or baseline the per-cell loss counters at the warm-up boundary, or otherwise tag and ignore startup-derived samples until each cell has completed its startup settling interval, while continuing to accept losses that occur after startup as overload evidence.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| pausedReason = null; | ||
| problem = null; | ||
| setKeyFramesOnly(true); | ||
| start(); |
There was a problem hiding this comment.
3. Old stream callbacks can stall resumed video 🐞 Bug ☼ Reliability
QuadCell.resume() restarts the same cell while an SDP callback from its stopped session can still reach onSdp() and reset the resumed decoder's state. If the old callback passes its generation check just before the pause and runs after the new session starts, it can clear the new stream's queues or close its decoder.
Agent Prompt
## Issue description
Resuming a paused cell reuses its `QuadCell`, but an SDP callback from the stopped RTSP generation can run after the new session starts and reset its decoder state.
## Fix Focus Areas
- android/app/src/main/java/com/openipc/decoder/QuadCell.java[515-522]
- android/app/src/main/java/com/openipc/decoder/RtspSession.java[443-445]
## Recommended Fix
Make SDP callback delivery atomic with respect to session stop and generation replacement, or tag callbacks with their generation and reject stale callbacks before they mutate the cell.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
Code review by qodo was updated up to the latest commit bb7dc58 |
|
Qodo on bb7dc58:
|
The rationale does not fully close either open concern:
The available review context does not include management URLs for these findings. |
…fit go on), only when the grid starts, and a resumed cell gets its audio route back Co-Authored-By: Claude <noreply@anthropic.com>
fix: no startup pause from the shared loss burst, and a paused cell gets another try (#148)
Closes #148.
DecodePlanner.WARMUP_MS, set by the app; 0 in tests) the planner takes no loss-based decision — every decoder starts at once and loses frames for a second or two. That time counts neither as lossy nor as quiet.Paused: decoder overloaded) gets another try on key frames once there were no losses forresumeWaitMs(30 s, doubled with every pause, at most 10 min) — counted from the last loss, so promotion probes do not hold it back. New actionRESUME→QuadCell.resume().lossesDuringTheWarmupDecideNothing,aPausedCellPlaysAgainAfterAQuietPeriod.Device test (AG-216, CI build 8fd516c, 3×3 + U): 3 cold starts in a row, 40 s each — no cell paused. Before (v2 ea5c093 and #146 builds): slot 8 paused at startup in 4 of 5 starts and stayed paused.