Implement Cast Streaming mirroring, DLNA casting, daemon+GUI, and breadd integration
Some checks failed
dev release / build (push) Failing after 12s
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.
This commit is contained in:
parent
887c29002f
commit
8c745d18e0
283 changed files with 36788 additions and 0 deletions
223
breadcast-caststream-sys/vendor/openscreen/cast/streaming/impl/statistics_common.h
vendored
Normal file
223
breadcast-caststream-sys/vendor/openscreen/cast/streaming/impl/statistics_common.h
vendored
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
// 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_
|
||||
Loading…
Add table
Add a link
Reference in a new issue