| /* | |
| * Copyright (c) 2025 The WebRTC project authors. All Rights Reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #ifndef VIDEO_TIMING_SIMULATOR_DECODABILITY_SIMULATOR_H_ | |
| #define VIDEO_TIMING_SIMULATOR_DECODABILITY_SIMULATOR_H_ | |
| #include <cstdint> | |
| #include <set> | |
| #include <span> | |
| #include <vector> | |
| #include "absl/algorithm/container.h" | |
| #include "api/numerics/samples_stats_counter.h" | |
| #include "api/units/data_size.h" | |
| #include "api/units/time_delta.h" | |
| #include "api/units/timestamp.h" | |
| #include "logging/rtc_event_log/rtc_event_log_parser.h" | |
| #include "rtc_base/checks.h" | |
| #include "video/timing/simulator/frame_base.h" | |
| #include "video/timing/simulator/results_base.h" | |
| #include "video/timing/simulator/stream_base.h" | |
| namespace webrtc::video_timing_simulator { | |
| // The `DecodabilitySimulator` takes an `ParsedRtcEventLog` and produces a | |
| // sequence of metadata about decodable frames that were contained in the log. | |
| class DecodabilitySimulator { | |
| public: | |
| struct Config { | |
| // Whether or not to reset the stream state on newly logged streams with the | |
| // same SSRC. This can be useful for simulation, but likely not for data | |
| // analysis. | |
| bool reuse_streams = false; | |
| // If non-empty, will only simulate video streams whose main SSRCs is | |
| // contained in the set. | |
| std::set<uint32_t> ssrc_filter = {}; | |
| }; | |
| // Metadata about a single decodable frame. | |
| struct Frame : public FrameBase<Frame> { | |
| // -- Values -- | |
| // Frame information. | |
| int num_packets = -1; // Required. | |
| DataSize size = DataSize::Zero(); // Required. | |
| // RTP header information. | |
| int64_t unwrapped_rtp_timestamp = -1; // Required. | |
| // Frame timestamps. | |
| Timestamp assembled_timestamp = Timestamp::PlusInfinity(); // Required. | |
| Timestamp decodable_timestamp = Timestamp::PlusInfinity(); | |
| // -- Populated values -- | |
| // One-way delay relative some baseline. | |
| TimeDelta frame_delay_variation = TimeDelta::PlusInfinity(); | |
| // -- Value accessors -- | |
| Timestamp ArrivalTimestampInternal() const { return decodable_timestamp; } | |
| // -- Per-frame metrics -- | |
| // Time spent waiting for reference frames to arrive. | |
| TimeDelta UndecodableDuration() const { | |
| RTC_DCHECK(assembled_timestamp.IsFinite()); | |
| return decodable_timestamp - assembled_timestamp; | |
| } | |
| }; | |
| // All frames in one stream. | |
| struct Stream : public StreamBase<Stream, Frame> { | |
| Timestamp creation_timestamp = Timestamp::PlusInfinity(); | |
| uint32_t ssrc = 0; | |
| std::vector<Frame> frames; | |
| // -- Per-stream metrics -- | |
| // Total number of decodable frames. | |
| int NumDecodableFrames() const { | |
| return CountFiniteTimestamps(&Frame::decodable_timestamp); | |
| } | |
| // Samples of undecodable durations in ms. | |
| SamplesStatsCounter UndecodableDurationMs() const { | |
| return BuildSamplesMs(&Frame::UndecodableDuration); | |
| } | |
| }; | |
| // All streams. | |
| struct Results : public ResultsBase<Results> { | |
| std::vector<Stream> streams; | |
| }; | |
| explicit DecodabilitySimulator(Config config); | |
| ~DecodabilitySimulator(); | |
| DecodabilitySimulator(const DecodabilitySimulator&) = delete; | |
| DecodabilitySimulator& operator=(const DecodabilitySimulator&) = delete; | |
| Results Simulate(const ParsedRtcEventLog& parsed_log) const; | |
| private: | |
| const Config config_; | |
| }; | |
| // -- Comparators and sorting -- | |
| inline bool DecodableOrder(const DecodabilitySimulator::Frame& a, | |
| const DecodabilitySimulator::Frame& b) { | |
| return a.decodable_timestamp < b.decodable_timestamp; | |
| } | |
| inline void SortByDecodableOrder( | |
| std::span<DecodabilitySimulator::Frame> frames) { | |
| absl::c_stable_sort(frames, DecodableOrder); | |
| } | |
| // -- Inter-frame metrics -- | |
| // Difference in decodable time between two frames. | |
| inline TimeDelta InterDecodableTime(const DecodabilitySimulator::Frame& cur, | |
| const DecodabilitySimulator::Frame& prev) { | |
| if (!cur.decodable_timestamp.IsFinite() && | |
| !prev.decodable_timestamp.IsFinite()) { | |
| return TimeDelta::PlusInfinity(); | |
| } | |
| return cur.decodable_timestamp - prev.decodable_timestamp; | |
| } | |
| } // namespace webrtc::video_timing_simulator | |
| #endif // VIDEO_TIMING_SIMULATOR_DECODABILITY_SIMULATOR_H_ |