| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CAST_STREAMING_IMPL_STATISTICS_COMMON_H_ |
| #define CAST_STREAMING_IMPL_STATISTICS_COMMON_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include "cast/streaming/public/constants.h" |
| #include "cast/streaming/public/frame_id.h" |
| #include "cast/streaming/rtp_time.h" |
| #include "platform/api/time.h" |
| |
| namespace openscreen::cast { |
| |
| struct StatisticsEvent { |
| enum class Type : int { |
| kUnknown = 0, |
| |
| // Sender side frame events. |
| kFrameCaptureBegin = 1, |
| kFrameCaptureEnd = 2, |
| kFrameEncoded = 3, |
| kFrameAckReceived = 4, |
| |
| // Receiver side frame events. |
| kFrameAckSent = 5, |
| kFrameDecoded = 6, |
| kFramePlayedOut = 7, |
| |
| // Sender side packet events. |
| kPacketSentToNetwork = 8, |
| kPacketRetransmitted = 9, |
| kPacketRtxRejected = 10, |
| |
| // Receiver side packet events. |
| kPacketReceived = 11, |
| |
| kNumOfEvents = kPacketReceived + 1 |
| }; |
| |
| // Serialized values for the statistics events for use by the RTCP builder |
| // and parser logic. *Do not modify existing values* since they are shared by |
| // both libcast-based devices as well as a variety of legacy implementations. |
| // |
| // NOTE: Events 1 to 8 have been replaced with events 11 to 14 (e.g. |
| // kAudioAckSent and kVideoAckSent merged into a single event kAckSent). |
| // Events 9 and 10 (to log duplicated packets) have been fully removed. Future |
| // events may reuse those values. |
| enum class WireType : uint8_t { |
| kUnknown = 0, |
| |
| // Legacy audio event types. |
| kAudioAckSent = 1, |
| kAudioPlayoutDelay = 2, |
| kAudioFrameDecoded = 3, |
| kAudioPacketReceived = 4, |
| |
| // Legacy video event types. |
| kVideoAckSent = 5, |
| kVideoRenderDelay = 6, |
| kVideoFrameDecoded = 7, |
| kVideoPacketReceived = 8, |
| |
| // New unified event types. |
| kUnifiedAckSent = 11, |
| kUnifiedRenderDelay = 12, |
| kUnifiedFrameDecoded = 13, |
| kUnifiedPacketReceived = 14, |
| |
| kNumOfEvents = kUnifiedPacketReceived + 1 |
| }; |
| |
| enum class MediaType : int { kUnknown = 0, kAudio = 1, kVideo = 2 }; |
| |
| static Type FromWireType(WireType wire_type); |
| static WireType ToWireType(Type type); |
| static MediaType ToMediaType(StreamType type); |
| |
| constexpr StatisticsEvent(FrameId frame_id, |
| Type type, |
| MediaType media_type, |
| RtpTimeTicks rtp_timestamp, |
| uint32_t size, |
| Clock::time_point timestamp, |
| Clock::time_point received_timestamp) |
| : frame_id(frame_id), |
| type(type), |
| media_type(media_type), |
| rtp_timestamp(rtp_timestamp), |
| size(size), |
| timestamp(timestamp), |
| received_timestamp(received_timestamp) {} |
| |
| constexpr StatisticsEvent() = default; |
| StatisticsEvent(const StatisticsEvent& other); |
| StatisticsEvent(StatisticsEvent&& other) noexcept; |
| StatisticsEvent& operator=(const StatisticsEvent& other); |
| StatisticsEvent& operator=(StatisticsEvent&& other); |
| ~StatisticsEvent() = default; |
| |
| bool operator==(const StatisticsEvent& other) const; |
| |
| // The frame this event is associated with. |
| FrameId frame_id; |
| |
| // The type of this frame event. |
| Type type = Type::kUnknown; |
| |
| // Whether this was audio or video (or unknown). |
| MediaType media_type = MediaType::kUnknown; |
| |
| // The RTP timestamp of the frame this event is associated with. |
| RtpTimeTicks rtp_timestamp; |
| |
| // Size of this packet, or the frame it is associated with. |
| // Note: we use uint32_t instead of size_t for byte count because this struct |
| // is sent over IPC which could span 32 & 64 bit processes. |
| uint32_t size = 0; |
| |
| // Time of event logged. |
| Clock::time_point timestamp; |
| |
| // Time that the event was received by the sender. Only set for receiver-side |
| // events. |
| Clock::time_point received_timestamp; |
| }; |
| |
| struct FrameEvent : public StatisticsEvent { |
| constexpr FrameEvent(FrameId frame_id_in, |
| Type type_in, |
| MediaType media_type_in, |
| RtpTimeTicks rtp_timestamp_in, |
| uint32_t size_in, |
| Clock::time_point timestamp_in, |
| Clock::time_point received_timestamp_in, |
| int width, |
| int height, |
| Clock::duration delay_delta, |
| bool key_frame, |
| int target_bitrate) |
| : StatisticsEvent(frame_id_in, |
| type_in, |
| media_type_in, |
| rtp_timestamp_in, |
| size_in, |
| timestamp_in, |
| received_timestamp_in), |
| width(width), |
| height(height), |
| delay_delta(delay_delta), |
| key_frame(key_frame), |
| target_bitrate(target_bitrate) {} |
| |
| constexpr FrameEvent() = default; |
| FrameEvent(const FrameEvent& other); |
| FrameEvent(FrameEvent&& other) noexcept; |
| FrameEvent& operator=(const FrameEvent& other); |
| FrameEvent& operator=(FrameEvent&& other); |
| ~FrameEvent() = default; |
| |
| bool operator==(const FrameEvent& other) const; |
| |
| // Resolution of the frame. Only set for video FRAME_CAPTURE_END events. |
| int width = 0; |
| int height = 0; |
| |
| // Only set for FRAME_PLAYOUT events. |
| // If this value is zero the frame is rendered on time. |
| // If this value is positive it means the frame is rendered late. |
| // If this value is negative it means the frame is rendered early. |
| Clock::duration delay_delta{}; |
| |
| // Whether the frame is a key frame. Only set for video FRAME_ENCODED event. |
| bool key_frame = false; |
| |
| // The requested target bitrate of the encoder at the time the frame is |
| // encoded. Only set for video FRAME_ENCODED event. |
| int target_bitrate = 0; |
| }; |
| |
| struct PacketEvent : public StatisticsEvent { |
| constexpr PacketEvent(FrameId frame_id_in, |
| Type type_in, |
| MediaType media_type_in, |
| RtpTimeTicks rtp_timestamp_in, |
| uint32_t size_in, |
| Clock::time_point timestamp_in, |
| Clock::time_point received_timestamp_in, |
| uint16_t packet_id, |
| uint16_t max_packet_id) |
| : StatisticsEvent(frame_id_in, |
| type_in, |
| media_type_in, |
| rtp_timestamp_in, |
| size_in, |
| timestamp_in, |
| received_timestamp_in), |
| packet_id(packet_id), |
| max_packet_id(max_packet_id) {} |
| |
| constexpr PacketEvent() = default; |
| PacketEvent(const PacketEvent& other); |
| PacketEvent(PacketEvent&& other) noexcept; |
| PacketEvent& operator=(const PacketEvent& other); |
| PacketEvent& operator=(PacketEvent&& other); |
| ~PacketEvent() = default; |
| |
| bool operator==(const PacketEvent& other) const; |
| |
| // The packet this event is associated with. |
| uint16_t packet_id = 0; |
| |
| // The highest packet ID seen so far at time of event. |
| uint16_t max_packet_id = 0; |
| }; |
| |
| } // namespace openscreen::cast |
| |
| #endif // CAST_STREAMING_IMPL_STATISTICS_COMMON_H_ |