Some checks failed
dev release / build (push) Failing after 12s
Builds out the full v1 scope: a vendored+patched openscreen subset for low-latency Cast Streaming (Mirroring receiver 0F5096E8) alongside the existing Cast V2/HLS and new DLNA/AVTransport casting paths, breadcastd's Idle/Casting state machine with a private IPC socket, the breadcast GTK4 popup as a thin IPC client, and bread.cast.*/bread.command.cast.* breadd integration (device discovery, start/stop, mirroring lifecycle events). Also adds bakery/systemd/Forgejo CI packaging. Validated end-to-end against a real Chromecast/Google TV: negotiated Cast Streaming session, live pipeline playback, and daemon+GUI click-to-cast/ stop through the actual popup.
223 lines
7.2 KiB
C++
223 lines
7.2 KiB
C++
// 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,
|
|
kFrameDroppedByEncoder = 15,
|
|
|
|
kNumOfEvents = kFrameDroppedByEncoder + 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_
|