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
203
breadcast-caststream-sys/vendor/openscreen/cast/streaming/sender_packet_router.h
vendored
Normal file
203
breadcast-caststream-sys/vendor/openscreen/cast/streaming/sender_packet_router.h
vendored
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
// Copyright 2020 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_SENDER_PACKET_ROUTER_H_
|
||||
#define CAST_STREAMING_SENDER_PACKET_ROUTER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "cast/streaming/impl/bandwidth_estimator.h"
|
||||
#include "cast/streaming/public/constants.h"
|
||||
#include "cast/streaming/public/environment.h"
|
||||
#include "cast/streaming/ssrc.h"
|
||||
#include "platform/api/time.h"
|
||||
#include "platform/base/span.h"
|
||||
#include "util/alarm.h"
|
||||
#include "util/raw_ptr.h"
|
||||
#include "util/raw_ref.h"
|
||||
|
||||
namespace openscreen::cast {
|
||||
|
||||
// Manages network packet transmission for one or more Senders, directing each
|
||||
// inbound packet to a specific Sender instance, pacing the transmission of
|
||||
// outbound packets, and employing network bandwidth/availability monitoring and
|
||||
// congestion control.
|
||||
//
|
||||
// Instead of just sending packets whenever they want, Senders must request
|
||||
// transmission from the SenderPacketRouter. The router then calls-back to each
|
||||
// Sender, in the near future, when it has allocated an available time slice for
|
||||
// transmission. The Sender is allowed to decide, at that exact moment, which
|
||||
// packet most needs to be sent.
|
||||
//
|
||||
// Pacing strategy: Packets are sent in bursts. This allows the platform
|
||||
// (operating system) to collect many small packets into a short-term buffer,
|
||||
// which allows for optimizations at the link layer. For example, multiple
|
||||
// packets can be sent together as one larger transmission unit, and this can be
|
||||
// critical for good performance over shared-medium networks (such as 802.11
|
||||
// WiFi). https://en.wikipedia.org/wiki/Frame-bursting
|
||||
class SenderPacketRouter : public BandwidthEstimator,
|
||||
public Environment::PacketConsumer {
|
||||
public:
|
||||
class Sender {
|
||||
public:
|
||||
// Called to provide the Sender with what looks like a RTCP packet meant for
|
||||
// it specifically (among other Senders) to process. `arrival_time`
|
||||
// indicates when the packet arrived (i.e., when it was received from the
|
||||
// platform).
|
||||
virtual void OnReceivedRtcpPacket(Clock::time_point arrival_time,
|
||||
ByteView packet) = 0;
|
||||
|
||||
// Populates the given `buffer` with a RTCP/RTP packet that will be sent
|
||||
// immediately. Returns the portion of `buffer` contaning the packet, or an
|
||||
// empty Span if nothing is ready to send.
|
||||
virtual ByteBuffer GetRtcpPacketForImmediateSend(
|
||||
Clock::time_point send_time,
|
||||
ByteBuffer buffer) = 0;
|
||||
virtual ByteBuffer GetRtpPacketForImmediateSend(Clock::time_point send_time,
|
||||
ByteBuffer buffer) = 0;
|
||||
|
||||
// Returns the point-in-time at which RTP sending should resume, or kNever
|
||||
// if it should be suspended until an explicit call to RequestRtpSend(). The
|
||||
// implementation may return a value on or before "now" to indicate an
|
||||
// immediate resume is desired.
|
||||
virtual Clock::time_point GetRtpResumeTime() = 0;
|
||||
|
||||
// Returns the last logged RTP timestamp, for use in expanding truncated
|
||||
// packet RTP timestamps for metrics purposes.
|
||||
virtual RtpTimeTicks GetLastRtpTimestamp() const = 0;
|
||||
|
||||
// Returns the type of stream that this sender is providing.
|
||||
virtual StreamType GetStreamType() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Sender();
|
||||
};
|
||||
|
||||
// Constructs an instance with default burst parameters appropriate for the
|
||||
// given `max_burst_bitrate`.
|
||||
explicit SenderPacketRouter(Environment& environment,
|
||||
int max_burst_bitrate = kDefaultMaxBurstBitrate);
|
||||
|
||||
// Constructs an instance with specific burst parameters. The maximum bitrate
|
||||
// will be computed based on these (and Environment::GetMaxPacketSize()).
|
||||
SenderPacketRouter(Environment& environment,
|
||||
int max_packets_per_burst,
|
||||
std::chrono::milliseconds burst_interval);
|
||||
|
||||
~SenderPacketRouter();
|
||||
|
||||
int max_packet_size() const { return packet_buffer_size_; }
|
||||
int max_burst_bitrate() const { return max_burst_bitrate_; }
|
||||
|
||||
// Called from a Sender constructor/destructor to register/deregister a Sender
|
||||
// instance that processes RTP/RTCP packets from a Receiver having the given
|
||||
// SSRC.
|
||||
void OnSenderCreated(Ssrc receiver_ssrc, Sender* client);
|
||||
void OnSenderDestroyed(Ssrc receiver_ssrc);
|
||||
|
||||
// Requests an immediate send of a RTCP packet, and then RTCP sending will
|
||||
// repeat at regular intervals (see kRtcpSendInterval) until the Sender is
|
||||
// de-registered.
|
||||
void RequestRtcpSend(Ssrc receiver_ssrc);
|
||||
|
||||
// Requests an immediate send of a RTP packet. RTP sending will continue until
|
||||
// the Sender stops providing packet data.
|
||||
//
|
||||
// See also: Sender::GetRtpResumeTime().
|
||||
void RequestRtpSend(Ssrc receiver_ssrc);
|
||||
|
||||
// A reasonable default maximum bitrate for bursting. Congestion control
|
||||
// should always be employed to limit the Senders' sustained/average outbound
|
||||
// data volume for "fair" use of the network.
|
||||
static constexpr int kDefaultMaxBurstBitrate = 24 << 20; // 24 megabits/sec
|
||||
|
||||
// The minimum amount of time between burst-sends. The methodology by which
|
||||
// this value was determined is lost knowledge, but is likely the result of
|
||||
// experimentation with various network and operating system configurations.
|
||||
// This value came from the original Chrome Cast Streaming implementation.
|
||||
static constexpr std::chrono::milliseconds kDefaultBurstInterval{10};
|
||||
|
||||
// A special time_point value representing "never."
|
||||
static constexpr Clock::time_point kNever = Clock::time_point::max();
|
||||
|
||||
private:
|
||||
struct SenderEntry {
|
||||
Ssrc receiver_ssrc;
|
||||
raw_ptr<Sender> sender;
|
||||
Clock::time_point next_rtcp_send_time;
|
||||
Clock::time_point next_rtp_send_time;
|
||||
|
||||
// Entries are ordered by the transmission priority (high→low), as implied
|
||||
// by their SSRC. See ssrc.h for details.
|
||||
bool operator<(const SenderEntry& other) const {
|
||||
return ComparePriority(receiver_ssrc, other.receiver_ssrc) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
using SenderEntries = std::vector<SenderEntry>;
|
||||
|
||||
// Environment::PacketConsumer implementation.
|
||||
void OnReceivedPacket(const IPEndpoint& source,
|
||||
Clock::time_point arrival_time,
|
||||
std::vector<uint8_t> packet) final;
|
||||
|
||||
// Helper to return an iterator pointing to the entry corresponding to the
|
||||
// given `receiver_ssrc`, or "end" if not found.
|
||||
SenderEntries::iterator FindEntry(Ssrc receiver_ssrc);
|
||||
|
||||
// Examine the next send time for all Senders, and decide whether to schedule
|
||||
// a burst-send.
|
||||
void ScheduleNextBurst();
|
||||
|
||||
// Performs a burst-send of packets. This is called whenever the Alarm fires.
|
||||
void SendBurstOfPackets();
|
||||
|
||||
// Send an RTCP packet from each Sender that has one ready, and return the
|
||||
// number of packets sent.
|
||||
int SendJustTheRtcpPackets(Clock::time_point send_time);
|
||||
|
||||
// Send zero or more RTP packets from each Sender, up to a maximum of
|
||||
// `num_packets_to_send`, and return the number of packets sent.
|
||||
int SendJustTheRtpPackets(Clock::time_point send_time,
|
||||
int num_packets_to_send);
|
||||
|
||||
// Returns the maximum number of packets to send in one burst, based on the
|
||||
// given parameters.
|
||||
static int ComputeMaxPacketsPerBurst(
|
||||
int max_burst_bitrate,
|
||||
int packet_size,
|
||||
std::chrono::milliseconds burst_interval);
|
||||
|
||||
// Returns the maximum bitrate inferred by the given parameters.
|
||||
static int ComputeMaxBurstBitrate(int packet_size,
|
||||
int max_packets_per_burst,
|
||||
std::chrono::milliseconds burst_interval);
|
||||
|
||||
const raw_ref<Environment> environment_;
|
||||
const int packet_buffer_size_;
|
||||
const std::unique_ptr<uint8_t[]> packet_buffer_;
|
||||
const int max_packets_per_burst_;
|
||||
const std::chrono::milliseconds burst_interval_;
|
||||
const int max_burst_bitrate_;
|
||||
|
||||
// Schedules the task that calls back into this SenderPacketRouter at a later
|
||||
// time to send the next burst of packets.
|
||||
Alarm alarm_;
|
||||
|
||||
// The current list of Senders and their timing information. This is
|
||||
// maintained in order of the priority implied by the Sender SSRC's.
|
||||
SenderEntries senders_;
|
||||
|
||||
// The last time a burst of packets was sent. This is used to determine the
|
||||
// next burst time.
|
||||
Clock::time_point last_burst_time_ = Clock::time_point::min();
|
||||
};
|
||||
|
||||
} // namespace openscreen::cast
|
||||
|
||||
#endif // CAST_STREAMING_SENDER_PACKET_ROUTER_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue