/* * Copyright (c) 2022 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 TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_FRAME_IN_FLIGHT_H_ #define TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_FRAME_IN_FLIGHT_H_ #include #include #include #include #include #include "absl/types/optional.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 "api/video/video_frame.h" #include "api/video/video_frame_type.h" #include "test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h" namespace webrtc { struct ReceiverFrameStats { // Time when last packet of a frame was received. Timestamp received_time = Timestamp::MinusInfinity(); Timestamp decode_start_time = Timestamp::MinusInfinity(); Timestamp decode_end_time = Timestamp::MinusInfinity(); Timestamp rendered_time = Timestamp::MinusInfinity(); // Will be set if there is frame rendered before this one. absl::optional prev_frame_rendered_time = absl::nullopt; absl::optional time_between_rendered_frames = absl::nullopt; // Type and encoded size of received frame. VideoFrameType frame_type = VideoFrameType::kEmptyFrame; DataSize encoded_image_size = DataSize::Bytes(0); absl::optional decoded_frame_width = absl::nullopt; absl::optional decoded_frame_height = absl::nullopt; // Can be not set if frame was dropped in the network. absl::optional used_decoder = absl::nullopt; bool dropped = false; bool decoder_failed = false; // Superfluous frames should be used for stats calculation for that peer. bool superfluous = false; }; // Represents a frame which was sent by sender and is currently on the way to // multiple receivers. Some receivers may receive this frame and some don't. // // Contains all statistic associated with the frame and gathered in multiple // points of the video pipeline. // // Internally may store the copy of the source frame which was sent. In such // case this frame is "alive". class FrameInFlight { public: FrameInFlight(size_t stream, uint16_t frame_id, Timestamp captured_time, absl::optional time_between_captured_frames, std::set expected_receivers); size_t stream() const { return stream_; } uint16_t id() const { return frame_id_; } Timestamp captured_time() const { return captured_time_; } void AddExpectedReceiver(size_t peer) { expected_receivers_.insert(peer); } void RemoveExpectedReceiver(size_t peer) { expected_receivers_.erase(peer); } std::vector GetPeersWhichDidntReceive() const; // Returns if all peers which were expected to receive this frame actually // received it or not. bool HaveAllPeersReceived() const; void SetPreEncodeTime(Timestamp time) { pre_encode_time_ = time; } void OnFrameEncoded(Timestamp time, absl::optional time_between_encoded_frames, VideoFrameType frame_type, DataSize encoded_image_size, uint32_t target_encode_bitrate, int stream_index, int qp, StreamCodecInfo used_encoder); bool HasEncodedTime() const { return encoded_time_.IsFinite(); } void OnFramePreDecode(size_t peer, Timestamp received_time, Timestamp decode_start_time, VideoFrameType frame_type, DataSize encoded_image_size); bool HasReceivedTime(size_t peer) const; void OnFrameDecoded(size_t peer, Timestamp time, int width, int height, const StreamCodecInfo& used_decoder); void OnDecoderError(size_t peer, const StreamCodecInfo& used_decoder); bool HasDecodeEndTime(size_t peer) const; void OnFrameRendered(size_t peer, Timestamp time); bool HasRenderedTime(size_t peer) const; // Crash if rendered time is not set for specified `peer`. Timestamp rendered_time(size_t peer) const { return receiver_stats_.at(peer).rendered_time; } // Marks that frame was dropped and wasn't seen by particular `peer`. void MarkDropped(size_t peer) { receiver_stats_[peer].dropped = true; } bool IsDropped(size_t peer) const; void MarkSuperfluous(size_t peer) { receiver_stats_[peer].superfluous = true; } void SetPrevFrameRenderedTime(size_t peer, webrtc::Timestamp time) { receiver_stats_[peer].prev_frame_rendered_time = time; } void SetTimeBetweenRenderedFrames(size_t peer, TimeDelta time) { receiver_stats_[peer].time_between_rendered_frames = time; } FrameStats GetStatsForPeer(size_t peer) const; private: bool IsSuperfluous(size_t peer) const; const size_t stream_; // Set of peer's indexes who are expected to receive this frame. This is not // the set of peer's indexes that received the frame. For example, if peer A // was among expected receivers, it received frame and then left the call, A // will be removed from this set, but the Stats for peer A still will be // preserved in the FrameInFlight. // // This set is used to determine if this frame is expected to be received by // any peer or can be safely deleted. It is responsibility of the user of this // object to decide when it should be deleted. std::set expected_receivers_; uint16_t frame_id_ = VideoFrame::kNotSetId; // Frame events timestamp. Timestamp captured_time_; Timestamp pre_encode_time_ = Timestamp::MinusInfinity(); Timestamp encoded_time_ = Timestamp::MinusInfinity(); absl::optional time_between_captured_frames_ = absl::nullopt; absl::optional time_between_encoded_frames_ = absl::nullopt; // Type and encoded size of sent frame. VideoFrameType frame_type_ = VideoFrameType::kEmptyFrame; DataSize encoded_image_size_ = DataSize::Bytes(0); uint32_t target_encode_bitrate_ = 0; // Sender side qp values per spatial or simulcast layer. If neither the // spatial or simulcast index is set in `EncodedImage`, 0 is used. std::map stream_layers_qp_; // Can be not set if frame was dropped by encoder. absl::optional used_encoder_ = absl::nullopt; // Map from the receiver peer's index to frame stats for that peer. std::unordered_map receiver_stats_; }; } // namespace webrtc #endif // TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_FRAME_IN_FLIGHT_H_