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
257
breadcast-caststream-sys/vendor/openscreen/cast/streaming/rtp_time.h
vendored
Normal file
257
breadcast-caststream-sys/vendor/openscreen/cast/streaming/rtp_time.h
vendored
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
// Copyright 2015 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_RTP_TIME_H_
|
||||
#define CAST_STREAMING_RTP_TIME_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
#include "cast/streaming/impl/expanded_value_base.h"
|
||||
#include "platform/api/time.h"
|
||||
#include "util/saturate_cast.h"
|
||||
|
||||
namespace openscreen::cast {
|
||||
|
||||
// Forward declarations (see below).
|
||||
class RtpTimeDelta;
|
||||
class RtpTimeTicks;
|
||||
|
||||
// Convenience operator overloads for logging.
|
||||
std::ostream& operator<<(std::ostream& out, const RtpTimeDelta rhs);
|
||||
std::ostream& operator<<(std::ostream& out, const RtpTimeTicks rhs);
|
||||
|
||||
// The difference between two RtpTimeTicks values. This data type is modeled
|
||||
// off of Chromium's base::TimeDelta, and used for performing compiler-checked
|
||||
// arithmetic with RtpTimeTicks.
|
||||
//
|
||||
// This data type wraps a value, providing only the meaningful set of math
|
||||
// operations that may be performed on the value. RtpTimeDeltas may be
|
||||
// added/subtracted with other RtpTimeDeltas to produce a RtpTimeDelta holding
|
||||
// the sum/difference. RtpTimeDeltas may also be multiplied or divided by
|
||||
// integer amounts. Finally, RtpTimeDeltas may be divided by other
|
||||
// RtpTimeDeltas to compute a number of periods (trunc'ed to an integer), or
|
||||
// modulo each other to determine a time period remainder.
|
||||
//
|
||||
// The base class provides bit truncation/extension features for
|
||||
// wire-formatting, and also the comparison operators.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// // Time math.
|
||||
// RtpTimeDelta zero;
|
||||
// RtpTimeDelta one_second_later =
|
||||
// zero + RtpTimeDelta::FromTicks(kAudioSamplingRate);
|
||||
// RtpTimeDelta ten_seconds_later = one_second_later * 10;
|
||||
// int64_t ten_periods = ten_seconds_later / one_second_later;
|
||||
//
|
||||
// // Logging convenience.
|
||||
// OSP_DLOG_INFO << "The RTP time offset is " << ten_seconds_later;
|
||||
//
|
||||
// // Convert (approximately!) between RTP timebase and microsecond timebase:
|
||||
// RtpTimeDelta nine_seconds_in_rtp = ten_seconds_later - one_second_later;
|
||||
// using std::chrono::microseconds;
|
||||
// microseconds nine_seconds_duration =
|
||||
// nine_seconds_in_rtp.ToDuration<microseconds>(kAudioSamplingRate);
|
||||
// RtpTimeDelta two_seconds_in_rtp =
|
||||
// RtpTimeDelta::FromDuration(std::chrono::seconds(2),
|
||||
// kAudioSamplingRate);
|
||||
class RtpTimeDelta : public ExpandedValueBase<int64_t, RtpTimeDelta> {
|
||||
public:
|
||||
constexpr RtpTimeDelta() : ExpandedValueBase(0) {}
|
||||
|
||||
// Arithmetic operators (with other deltas).
|
||||
constexpr RtpTimeDelta operator+(RtpTimeDelta rhs) const {
|
||||
return RtpTimeDelta(value_ + rhs.value_);
|
||||
}
|
||||
constexpr RtpTimeDelta operator-(RtpTimeDelta rhs) const {
|
||||
return RtpTimeDelta(value_ - rhs.value_);
|
||||
}
|
||||
constexpr RtpTimeDelta& operator+=(RtpTimeDelta rhs) {
|
||||
return (*this = (*this + rhs));
|
||||
}
|
||||
constexpr RtpTimeDelta& operator-=(RtpTimeDelta rhs) {
|
||||
return (*this = (*this - rhs));
|
||||
}
|
||||
constexpr RtpTimeDelta operator-() const { return RtpTimeDelta(-value_); }
|
||||
|
||||
// Multiplicative operators (with other deltas).
|
||||
constexpr int64_t operator/(RtpTimeDelta rhs) const {
|
||||
return value_ / rhs.value_;
|
||||
}
|
||||
constexpr RtpTimeDelta operator%(RtpTimeDelta rhs) const {
|
||||
return RtpTimeDelta(value_ % rhs.value_);
|
||||
}
|
||||
constexpr RtpTimeDelta& operator%=(RtpTimeDelta rhs) {
|
||||
return (*this = (*this % rhs));
|
||||
}
|
||||
|
||||
// Multiplicative operators (with integer types).
|
||||
template <typename IntType>
|
||||
constexpr RtpTimeDelta operator*(IntType rhs) const {
|
||||
static_assert(std::numeric_limits<IntType>::is_integer,
|
||||
"|rhs| must be a POD integer type");
|
||||
return RtpTimeDelta(value_ * rhs);
|
||||
}
|
||||
template <typename IntType>
|
||||
constexpr RtpTimeDelta operator/(IntType rhs) const {
|
||||
static_assert(std::numeric_limits<IntType>::is_integer,
|
||||
"|rhs| must be a POD integer type");
|
||||
return RtpTimeDelta(value_ / rhs);
|
||||
}
|
||||
template <typename IntType>
|
||||
constexpr RtpTimeDelta& operator*=(IntType rhs) {
|
||||
return (*this = (*this * rhs));
|
||||
}
|
||||
template <typename IntType>
|
||||
constexpr RtpTimeDelta& operator/=(IntType rhs) {
|
||||
return (*this = (*this / rhs));
|
||||
}
|
||||
|
||||
// Maps this RtpTimeDelta to an approximate std::chrono::duration using the
|
||||
// given RTP timebase. Assumes a zero-valued Duration corresponds to a
|
||||
// zero-valued RtpTimeDelta.
|
||||
template <typename Duration>
|
||||
Duration ToDuration(int rtp_timebase) const {
|
||||
OSP_CHECK_GT(rtp_timebase, 0);
|
||||
constexpr Duration kOneSecond =
|
||||
std::chrono::duration_cast<Duration>(std::chrono::seconds(1));
|
||||
return Duration(ToNearestRepresentativeValue<typename Duration::rep>(
|
||||
static_cast<double>(value_) / rtp_timebase * kOneSecond.count()));
|
||||
}
|
||||
|
||||
// Maps the `duration` to an approximate RtpTimeDelta using the given RTP
|
||||
// timebase. Assumes a zero-valued Duration corresponds to a zero-valued
|
||||
// RtpTimeDelta.
|
||||
template <typename Duration>
|
||||
static constexpr RtpTimeDelta FromDuration(Duration duration,
|
||||
int rtp_timebase) {
|
||||
constexpr Duration kOneSecond =
|
||||
std::chrono::duration_cast<Duration>(std::chrono::seconds(1));
|
||||
static_assert(kOneSecond > Duration::zero(),
|
||||
"Duration is too coarse-grained to represent one second.");
|
||||
return RtpTimeDelta(ToNearestRepresentativeValue<int64_t>(
|
||||
static_cast<double>(duration.count()) / kOneSecond.count() *
|
||||
rtp_timebase));
|
||||
}
|
||||
|
||||
// Construct a RtpTimeDelta from an exact number of ticks.
|
||||
static constexpr RtpTimeDelta FromTicks(int64_t ticks) {
|
||||
return RtpTimeDelta(ticks);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ExpandedValueBase<int64_t, RtpTimeDelta>;
|
||||
friend class RtpTimeTicks;
|
||||
friend std::ostream& operator<<(std::ostream& out, const RtpTimeDelta rhs);
|
||||
|
||||
constexpr explicit RtpTimeDelta(int64_t ticks) : ExpandedValueBase(ticks) {}
|
||||
|
||||
constexpr int64_t value() const { return value_; }
|
||||
|
||||
template <typename Rep>
|
||||
static std::enable_if_t<std::is_floating_point<Rep>::value, Rep>
|
||||
ToNearestRepresentativeValue(double ticks) {
|
||||
return Rep(ticks);
|
||||
}
|
||||
|
||||
template <typename Rep>
|
||||
static std::enable_if_t<std::is_integral<Rep>::value, Rep>
|
||||
ToNearestRepresentativeValue(double ticks) {
|
||||
return rounded_saturate_cast<Rep>(ticks);
|
||||
}
|
||||
};
|
||||
|
||||
// A media timestamp whose timebase matches the periodicity of the content
|
||||
// (e.g., for audio, the timebase would be the sampling frequency). This data
|
||||
// type is modeled off of Chromium's base::TimeTicks.
|
||||
//
|
||||
// This data type wraps a value, providing only the meaningful set of math
|
||||
// operations that may be performed on the value. The difference between two
|
||||
// RtpTimeTicks is a RtpTimeDelta. Likewise, adding or subtracting a
|
||||
// RtpTimeTicks with a RtpTimeDelta produces an off-set RtpTimeTicks.
|
||||
//
|
||||
// The base class provides bit truncation/extension features for
|
||||
// wire-formatting, and also the comparison operators.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// // Time math.
|
||||
// RtpTimeTicks origin;
|
||||
// RtpTimeTicks at_one_second =
|
||||
// origin + RtpTimeDelta::FromTicks(kAudioSamplingRate);
|
||||
// RtpTimeTicks at_two_seconds =
|
||||
// at_one_second + RtpTimeDelta::FromTicks(kAudioSamplingRate);
|
||||
// RtpTimeDelta elasped_in_between = at_two_seconds - at_one_second;
|
||||
// RtpTimeDelta thrice_as_much_elasped = elasped_in_between * 3;
|
||||
// RtpTimeTicks at_four_seconds = at_one_second + thrice_as_much_elasped;
|
||||
//
|
||||
// // Logging convenience.
|
||||
// OSP_DLOG_INFO << "The RTP timestamp is " << at_four_seconds;
|
||||
//
|
||||
// // Convert (approximately!) between RTP timebase and stream time offsets in
|
||||
// // microsecond timebase:
|
||||
// using std::chrono::microseconds;
|
||||
// microseconds four_seconds_since_stream_start =
|
||||
// at_four_seconds.ToTimeSinceOrigin<microseconds>(kAudioSamplingRate);
|
||||
// RtpTimeTicks at_three_seconds = RtpTimeDelta::FromTimeSinceOrigin(
|
||||
// std::chrono::seconds(3), kAudioSamplingRate);
|
||||
class RtpTimeTicks : public ExpandedValueBase<int64_t, RtpTimeTicks> {
|
||||
public:
|
||||
constexpr explicit RtpTimeTicks(int64_t value) : ExpandedValueBase(value) {}
|
||||
constexpr RtpTimeTicks() : ExpandedValueBase(0) {}
|
||||
|
||||
constexpr int64_t value() const { return value_; }
|
||||
|
||||
// Compute the difference between two RtpTimeTickses.
|
||||
constexpr RtpTimeDelta operator-(RtpTimeTicks rhs) const {
|
||||
return RtpTimeDelta(value_ - rhs.value_);
|
||||
}
|
||||
|
||||
// Return a new RtpTimeTicks before or after this one.
|
||||
constexpr RtpTimeTicks operator+(RtpTimeDelta rhs) const {
|
||||
return RtpTimeTicks(value_ + rhs.value());
|
||||
}
|
||||
constexpr RtpTimeTicks operator-(RtpTimeDelta rhs) const {
|
||||
return RtpTimeTicks(value_ - rhs.value());
|
||||
}
|
||||
constexpr RtpTimeTicks& operator+=(RtpTimeDelta rhs) {
|
||||
return (*this = (*this + rhs));
|
||||
}
|
||||
constexpr RtpTimeTicks& operator-=(RtpTimeDelta rhs) {
|
||||
return (*this = (*this - rhs));
|
||||
}
|
||||
|
||||
// Maps this RtpTimeTicks to an approximate std::chrono::duration representing
|
||||
// the amount of time since the origin point (e.g., the start of a stream)
|
||||
// using the given `rtp_timebase`. Assumes a zero-valued Duration corresponds
|
||||
// to a zero-valued RtpTimeTicks.
|
||||
template <typename Duration>
|
||||
Duration ToTimeSinceOrigin(int rtp_timebase) const {
|
||||
return (*this - RtpTimeTicks()).ToDuration<Duration>(rtp_timebase);
|
||||
}
|
||||
|
||||
// Maps the `time_since_origin` to an approximate RtpTimeTicks using the given
|
||||
// RTP timebase. Assumes a zero-valued Duration corresponds to a zero-valued
|
||||
// RtpTimeTicks.
|
||||
template <typename Duration>
|
||||
static constexpr RtpTimeTicks FromTimeSinceOrigin(Duration time_since_origin,
|
||||
int rtp_timebase) {
|
||||
return RtpTimeTicks() +
|
||||
RtpTimeDelta::FromDuration(time_since_origin, rtp_timebase);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ExpandedValueBase<int64_t, RtpTimeTicks>;
|
||||
friend std::ostream& operator<<(std::ostream& out, const RtpTimeTicks rhs);
|
||||
};
|
||||
|
||||
} // namespace openscreen::cast
|
||||
|
||||
#endif // CAST_STREAMING_RTP_TIME_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue