@@ -190,6 +190,153 @@ namespace stream::adaptive_bitrate {
190190 unrecovered_loss,
191191 };
192192
193+ /* *
194+ * @brief Timing and direction retained across encoder decisions.
195+ */
196+ struct decision_history_t {
197+ decision_direction_e direction = decision_direction_e::none; // /< Latest non-probe command direction.
198+ std::optional<time_point_t > last_decision_at; // /< Time of the last emitted encoder command.
199+ std::optional<time_point_t > last_increase_at; // /< Time of the last recovery increase.
200+ std::optional<time_point_t > last_direction_reversal_at; // /< Latest non-probe command direction reversal.
201+ };
202+
203+ /* *
204+ * @brief Handle malformed or protocol-mismatched telemetry.
205+ *
206+ * @param snapshot Telemetry snapshot to inspect.
207+ * @return `true` when the snapshot was handled and observation must stop.
208+ */
209+ bool handle_invalid_telemetry (const network_metrics::snapshot_t &snapshot);
210+
211+ /* *
212+ * @brief Hold adaptation after telemetry report limiting.
213+ *
214+ * @param snapshot Telemetry snapshot to inspect.
215+ * @return `true` when rate limiting was observed and observation must stop.
216+ */
217+ bool handle_rate_limited_telemetry (const network_metrics::snapshot_t &snapshot);
218+
219+ /* *
220+ * @brief Record whether a snapshot carries actionable loss telemetry.
221+ *
222+ * @param snapshot Telemetry snapshot to inspect.
223+ * @return `true` when the snapshot can update controller evidence.
224+ */
225+ bool accept_telemetry_signal (const network_metrics::snapshot_t &snapshot);
226+
227+ /* *
228+ * @brief Classify the strongest degradation present in one telemetry window.
229+ *
230+ * @param snapshot Telemetry snapshot to classify.
231+ * @param unrecovered_ratio Ratio of unrecovered data shards.
232+ * @param recovered_ratio Ratio of FEC-recovered data shards.
233+ * @param high_latency Whether latency corroborates recovery pressure.
234+ * @return Classified degradation, or `none` for a healthy window.
235+ */
236+ static degradation_e classify_degradation (
237+ const network_metrics::snapshot_t &snapshot,
238+ long double unrecovered_ratio,
239+ long double recovered_ratio,
240+ bool high_latency
241+ );
242+
243+ /* *
244+ * @brief Accumulate one degraded telemetry window.
245+ *
246+ * @param degradation Degradation observed in the window.
247+ * @param now Monotonic observation time.
248+ */
249+ void observe_degradation (degradation_e degradation, time_point_t now);
250+
251+ /* *
252+ * @brief Update recovery evidence from one non-degraded telemetry window.
253+ *
254+ * @param snapshot Telemetry snapshot to observe.
255+ * @param recovered_ratio Ratio of FEC-recovered data shards.
256+ * @param high_latency Whether latency remains elevated.
257+ * @param now Monotonic observation time.
258+ */
259+ void observe_stability (
260+ const network_metrics::snapshot_t &snapshot,
261+ long double recovered_ratio,
262+ bool high_latency,
263+ time_point_t now
264+ );
265+
266+ /* *
267+ * @brief Clear unconfirmed degraded-window evidence.
268+ */
269+ void reset_degradation_confirmation ();
270+
271+ /* *
272+ * @brief Consume a fresh control-channel liveness sample.
273+ *
274+ * @param control_liveness_token Latest control-channel receive token.
275+ * @return `true` when the token is valid and was not previously consumed.
276+ */
277+ bool consume_control_liveness (std::uint32_t control_liveness_token);
278+
279+ /* *
280+ * @brief Update the stable RTT floor from live control-channel telemetry.
281+ *
282+ * @param now Monotonic control-loop time.
283+ * @param live_rtt_ms Current smoothed RTT.
284+ * @param live_rtt_variance_ms Current RTT variance.
285+ * @return `true` when live latency is materially elevated.
286+ */
287+ bool observe_live_latency (time_point_t now, std::uint32_t live_rtt_ms, std::uint32_t live_rtt_variance_ms);
288+
289+ /* *
290+ * @brief Check whether the encoder command spacing interval has elapsed.
291+ *
292+ * @param now Monotonic control-loop time.
293+ * @return `true` when another decision may be emitted.
294+ */
295+ bool decision_is_allowed (time_point_t now) const ;
296+
297+ /* *
298+ * @brief Record and return one encoder decision.
299+ *
300+ * @param target_kbps Requested encoder target.
301+ * @param reason Stable diagnostic reason for the command.
302+ * @param now Monotonic decision time.
303+ * @return Recorded encoder decision.
304+ */
305+ decision_t emit_decision (std::uint32_t target_kbps, decision_reason_e reason, time_point_t now);
306+
307+ /* *
308+ * @brief Emit a decrease for confirmed degradation when possible.
309+ *
310+ * @param now Monotonic control-loop time.
311+ * @param decision_allowed Whether command spacing permits a decision.
312+ * @return A decrease command, or no value.
313+ */
314+ std::optional<decision_t > reduce_for_pending_degradation (time_point_t now, bool decision_allowed);
315+
316+ /* *
317+ * @brief Check all stable recovery prerequisites.
318+ *
319+ * @param now Monotonic control-loop time.
320+ * @param live_latency_high Whether live latency remains elevated.
321+ * @param fresh_control_liveness Whether a new reliable acknowledgement was observed.
322+ * @param decision_allowed Whether command spacing permits a decision.
323+ * @return `true` when recovery may increase the bitrate.
324+ */
325+ bool recovery_is_allowed (
326+ time_point_t now,
327+ bool live_latency_high,
328+ bool fresh_control_liveness,
329+ bool decision_allowed
330+ ) const ;
331+
332+ /* *
333+ * @brief Check whether an upward direction reversal remains in cooldown.
334+ *
335+ * @param now Monotonic control-loop time.
336+ * @return `true` while another upward reversal is blocked.
337+ */
338+ bool upward_reversal_is_cooling_down (time_point_t now) const ;
339+
193340 state_e state_ = state_e::fixed_disabled; // /< Current lifecycle state.
194341 std::uint32_t floor_kbps_ = 0 ; // /< Session floor, capped by the client ceiling.
195342 std::uint32_t ceiling_kbps_ = 0 ; // /< Immutable effective client ceiling.
@@ -205,11 +352,8 @@ namespace stream::adaptive_bitrate {
205352 bool telemetry_seen_ = false ; // /< Whether a valid FEC report has been observed.
206353 bool fallback_after_acknowledgement_ = false ; // /< Defer invalid-telemetry fallback while an encoder command is in flight.
207354 bool recovery_blocked_by_rate_limit_ = false ; // /< Require a valid stable FEC report after telemetry overload.
208- decision_direction_e last_decision_direction_ = decision_direction_e::none; // /< Latest non-probe command direction.
209355 std::optional<time_point_t > first_bad_window_at_; // /< Time of the first consecutive bad window.
210356 std::optional<time_point_t > stable_since_; // /< Start of the current no-new-pressure period.
211- std::optional<time_point_t > last_decision_at_; // /< Time of the last emitted encoder command.
212- std::optional<time_point_t > last_increase_at_; // /< Time of the last recovery increase.
213- std::optional<time_point_t > last_direction_reversal_at_; // /< Latest non-probe command direction reversal.
357+ decision_history_t decision_history_; // /< Timing and direction of prior encoder decisions.
214358 };
215359} // namespace stream::adaptive_bitrate
0 commit comments