blob: 2e976cca83c877a5e45e6361c42cc08c24a07c0d [file] [log] [blame]
// 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_