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
282
breadcast-caststream-sys/vendor/openscreen/util/trace_logging.h
vendored
Normal file
282
breadcast-caststream-sys/vendor/openscreen/util/trace_logging.h
vendored
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UTIL_TRACE_LOGGING_H_
|
||||
#define UTIL_TRACE_LOGGING_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "platform/base/trace_logging_types.h"
|
||||
|
||||
// All compile-time macros for tracing.
|
||||
// NOTE: The ternary operator is used here to ensure that the TraceLogger object
|
||||
// is only constructed if tracing is enabled, but at the same time is created in
|
||||
// the caller's scope. The C++ standards guide guarantees that the constructor
|
||||
// should only be called when IsTraceLoggingEnabled(...) evaluates to true.
|
||||
// static_cast calls are used because if the type of the result of the ternary
|
||||
// operator does not match the expected type, temporary storage is used for the
|
||||
// created object, which results in an extra call to the constructor and
|
||||
// destructor of the tracing objects.
|
||||
//
|
||||
// Further details about how these macros are used can be found in
|
||||
// docs/trace_logging.md.
|
||||
|
||||
#if defined(ENABLE_TRACE_LOGGING)
|
||||
|
||||
#define INCLUDING_FROM_UTIL_TRACE_LOGGING_H_
|
||||
#include "util/trace_logging/macro_support.h"
|
||||
#undef INCLUDING_FROM_UTIL_TRACE_LOGGING_H_
|
||||
|
||||
#define TRACE_SET_RESULT(result) \
|
||||
do { \
|
||||
if (TRACE_IS_ENABLED(openscreen::TraceCategory::kAny)) { \
|
||||
openscreen::internal::ScopedTraceOperation::set_result(result); \
|
||||
} \
|
||||
} while (false)
|
||||
#define TRACE_SET_HIERARCHY(ids) TRACE_SET_HIERARCHY_INTERNAL(__LINE__, ids)
|
||||
#define TRACE_HIERARCHY \
|
||||
(TRACE_IS_ENABLED(openscreen::TraceCategory::kAny) \
|
||||
? openscreen::internal::ScopedTraceOperation::hierarchy() \
|
||||
: openscreen::TraceIdHierarchy::Empty())
|
||||
#define TRACE_CURRENT_ID \
|
||||
(TRACE_IS_ENABLED(openscreen::TraceCategory::kAny) \
|
||||
? openscreen::internal::ScopedTraceOperation::current_id() \
|
||||
: kEmptyTraceId)
|
||||
#define TRACE_ROOT_ID \
|
||||
(TRACE_IS_ENABLED(openscreen::TraceCategory::kAny) \
|
||||
? openscreen::internal::ScopedTraceOperation::root_id() \
|
||||
: kEmptyTraceId)
|
||||
|
||||
namespace openscreen::internal {
|
||||
|
||||
template <typename T>
|
||||
std::string ToString(T&& val) {
|
||||
using DecayT = std::decay_t<T>;
|
||||
if constexpr (std::is_constructible_v<std::string, T>) {
|
||||
return std::string(std::forward<T>(val));
|
||||
} else if constexpr (std::is_arithmetic_v<DecayT>) {
|
||||
return std::to_string(val);
|
||||
} else {
|
||||
std::ostringstream oss;
|
||||
oss << val;
|
||||
return oss.str();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to extract a flow ID from various types (arithmetic or wrappers like
|
||||
// FrameId).
|
||||
template <typename T>
|
||||
constexpr uint64_t ToFlowId(const T& val) {
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
return static_cast<uint64_t>(val);
|
||||
} else {
|
||||
// Assume it's a numeric wrapper like FrameId with a .value() method.
|
||||
return static_cast<uint64_t>(val.value());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openscreen::internal
|
||||
|
||||
template <typename V1 = std::string, typename V2 = std::string>
|
||||
inline std::vector<openscreen::TraceEvent::Argument> ToArgumentArray(
|
||||
const char* argname = nullptr,
|
||||
V1&& argval = V1(),
|
||||
const char* argname_two = nullptr,
|
||||
V2&& argval_two = V2()) {
|
||||
std::vector<openscreen::TraceEvent::Argument> out;
|
||||
if (argname) {
|
||||
out.emplace_back(argname,
|
||||
openscreen::internal::ToString(std::forward<V1>(argval)));
|
||||
}
|
||||
if (argname_two) {
|
||||
out.emplace_back(argname_two, openscreen::internal::ToString(
|
||||
std::forward<V2>(argval_two)));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Synchronous Trace Macros.
|
||||
//
|
||||
// Scoped traces with no arguments.
|
||||
#define TRACE_SCOPED(category, name, ...) \
|
||||
TRACE_SCOPED_INTERNAL(__LINE__, category, name, ToArgumentArray(), \
|
||||
##__VA_ARGS__)
|
||||
#define TRACE_DEFAULT_SCOPED(category, ...) \
|
||||
TRACE_SCOPED(category, __PRETTY_FUNCTION__, ##__VA_ARGS__)
|
||||
|
||||
// Scoped traces with one argument.
|
||||
#define TRACE_SCOPED1(category, name, argname, argval, ...) \
|
||||
TRACE_SCOPED_INTERNAL(__LINE__, category, name, \
|
||||
ToArgumentArray(argname, argval), ##__VA_ARGS__)
|
||||
#define TRACE_DEFAULT_SCOPED1(category, argname, argval, ...) \
|
||||
TRACE_SCOPED1(category, __PRETTY_FUNCTION__, argname, argval, ##__VA_ARGS__)
|
||||
|
||||
// Scoped traces with two arguments.
|
||||
#define TRACE_SCOPED2(category, name, argname, argval, argname_two, \
|
||||
argval_two, ...) \
|
||||
TRACE_SCOPED_INTERNAL( \
|
||||
__LINE__, category, name, \
|
||||
ToArgumentArray(argname, argval, argname_two, argval_two), \
|
||||
##__VA_ARGS__)
|
||||
#define TRACE_DEFAULT_SCOPED2(category, argname, argval, argname_two, \
|
||||
argval_two, ...) \
|
||||
TRACE_SCOPED2(category, __PRETTY_FUNCTION__, argname, argval, argname_two, \
|
||||
argval_two, ##__VA_ARGS__)
|
||||
|
||||
// Asynchronous Trace Macros.
|
||||
#define TRACE_ASYNC_START(category, name, ...) \
|
||||
TRACE_ASYNC_START_INTERNAL(__LINE__, category, name, ToArgumentArray(), \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define TRACE_ASYNC_START1(category, name, argname, argval, ...) \
|
||||
TRACE_ASYNC_START_INTERNAL(__LINE__, category, name, \
|
||||
ToArgumentArray(argname, argval), ##__VA_ARGS__)
|
||||
|
||||
#define TRACE_ASYNC_START2(category, name, argname, argval, argname_two, \
|
||||
argval_two, ...) \
|
||||
TRACE_ASYNC_START_INTERNAL( \
|
||||
__LINE__, category, name, \
|
||||
ToArgumentArray(argname, argval, argname_two, argval_two), \
|
||||
##__VA_ARGS__)
|
||||
|
||||
#define TRACE_ASYNC_END(category, id, result) \
|
||||
TRACE_IS_ENABLED(category) \
|
||||
? openscreen::internal::ScopedTraceOperation::TraceAsyncEnd( \
|
||||
__LINE__, __FILE__, id, result) \
|
||||
: false
|
||||
|
||||
// Flow events are used to link trace events across different threads or
|
||||
// processes. Flows are linked by their flow_id.
|
||||
// - Flows can span across different trace categories.
|
||||
// - If a TRACE_FLOW_BEGIN is missing (e.g. because the embedder didn't
|
||||
// instrument it),
|
||||
// the first TRACE_FLOW_STEP encountered will effectively start the flow
|
||||
// visualization.
|
||||
#define TRACE_FLOW_BEGIN(category, name, flow_id) \
|
||||
TRACE_IS_ENABLED(category) \
|
||||
? openscreen::internal::ScopedTraceOperation::TraceFlow( \
|
||||
category, name, __FILE__, __LINE__, \
|
||||
openscreen::internal::ToFlowId(flow_id), \
|
||||
openscreen::FlowType::kFlowBegin) \
|
||||
: false
|
||||
|
||||
#define TRACE_FLOW_STEP(category, name, flow_id) \
|
||||
TRACE_IS_ENABLED(category) \
|
||||
? openscreen::internal::ScopedTraceOperation::TraceFlow( \
|
||||
category, name, __FILE__, __LINE__, \
|
||||
openscreen::internal::ToFlowId(flow_id), \
|
||||
openscreen::FlowType::kFlowStep) \
|
||||
: false
|
||||
|
||||
#define TRACE_FLOW_END(category, name, flow_id) \
|
||||
TRACE_IS_ENABLED(category) \
|
||||
? openscreen::internal::ScopedTraceOperation::TraceFlow( \
|
||||
category, name, __FILE__, __LINE__, \
|
||||
openscreen::internal::ToFlowId(flow_id), \
|
||||
openscreen::FlowType::kFlowEnd) \
|
||||
: false
|
||||
|
||||
#define TRACE_FLOW_BEGIN_WITH_TIME(category, name, flow_id, timestamp) \
|
||||
TRACE_IS_ENABLED(category) \
|
||||
? openscreen::internal::ScopedTraceOperation::TraceFlow( \
|
||||
category, name, __FILE__, __LINE__, \
|
||||
openscreen::internal::ToFlowId(flow_id), \
|
||||
openscreen::FlowType::kFlowBegin, timestamp) \
|
||||
: false
|
||||
|
||||
#define TRACE_FLOW_STEP_WITH_TIME(category, name, flow_id, timestamp) \
|
||||
TRACE_IS_ENABLED(category) \
|
||||
? openscreen::internal::ScopedTraceOperation::TraceFlow( \
|
||||
category, name, __FILE__, __LINE__, \
|
||||
openscreen::internal::ToFlowId(flow_id), \
|
||||
openscreen::FlowType::kFlowStep, timestamp) \
|
||||
: false
|
||||
|
||||
#define TRACE_FLOW_END_WITH_TIME(category, name, flow_id, timestamp) \
|
||||
TRACE_IS_ENABLED(category) \
|
||||
? openscreen::internal::ScopedTraceOperation::TraceFlow( \
|
||||
category, name, __FILE__, __LINE__, \
|
||||
openscreen::internal::ToFlowId(flow_id), \
|
||||
openscreen::FlowType::kFlowEnd, timestamp) \
|
||||
: false
|
||||
|
||||
#define TRACE_FLOW_DEFAULT_BEGIN(category, flow_id) \
|
||||
TRACE_FLOW_BEGIN(category, __PRETTY_FUNCTION__, flow_id)
|
||||
|
||||
#define TRACE_FLOW_DEFAULT_STEP(category, flow_id) \
|
||||
TRACE_FLOW_STEP(category, __PRETTY_FUNCTION__, flow_id)
|
||||
|
||||
#define TRACE_FLOW_DEFAULT_END(category, flow_id) \
|
||||
TRACE_FLOW_END(category, __PRETTY_FUNCTION__, flow_id)
|
||||
|
||||
#else // ENABLE_TRACE_LOGGING not defined
|
||||
|
||||
namespace openscreen::internal {
|
||||
// Consumes `args` (to avoid "warn unused variable" errors at compile time), and
|
||||
// provides a "void" result type in the macros below.
|
||||
template <typename... Args>
|
||||
inline void DoNothingForTracing(Args... args) {}
|
||||
} // namespace openscreen::internal
|
||||
|
||||
#define TRACE_SET_RESULT(result) \
|
||||
openscreen::internal::DoNothingForTracing(result)
|
||||
#define TRACE_SET_HIERARCHY(ids) openscreen::internal::DoNothingForTracing(ids)
|
||||
#define TRACE_HIERARCHY openscreen::TraceIdHierarchy::Empty()
|
||||
#define TRACE_CURRENT_ID openscreen::kEmptyTraceId
|
||||
#define TRACE_ROOT_ID openscreen::kEmptyTraceId
|
||||
#define TRACE_SCOPED(category, name, ...) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, ##__VA_ARGS__)
|
||||
#define TRACE_DEFAULT_SCOPED(category, ...) \
|
||||
TRACE_SCOPED(category, __PRETTY_FUNCTION__, ##__VA_ARGS__)
|
||||
|
||||
#define TRACE_SCOPED1(category, name, argname, argval, ...) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, argname, argval, \
|
||||
##__VA_ARGS__)
|
||||
#define TRACE_DEFAULT_SCOPED1(category, argname, argval, ...) \
|
||||
TRACE_SCOPED1(category, __PRETTY_FUNCTION__, argname, argval, ##__VA_ARGS__)
|
||||
|
||||
#define TRACE_SCOPED2(category, name, argname, argval, argname_two, \
|
||||
argval_two, ...) \
|
||||
openscreen::internal::DoNothingForTracing( \
|
||||
category, name, argname, argval, argname_two, argval_two, ##__VA_ARGS__)
|
||||
#define TRACE_DEFAULT_SCOPED2(category, argname, argval, argname_two, \
|
||||
argval_two, ...) \
|
||||
TRACE_SCOPED2(category, __PRETTY_FUNCTION__, argname, argval, argname_two, \
|
||||
argval_two, ##__VA_ARGS__)
|
||||
|
||||
#define TRACE_ASYNC_START(category, name, ...) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, ##__VA_ARGS__)
|
||||
#define TRACE_ASYNC_END(category, id, result) \
|
||||
openscreen::internal::DoNothingForTracing(category, id, result)
|
||||
|
||||
#define TRACE_FLOW_BEGIN(category, name, flow_id) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, flow_id)
|
||||
#define TRACE_FLOW_STEP(category, name, flow_id) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, flow_id)
|
||||
#define TRACE_FLOW_END(category, name, flow_id) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, flow_id)
|
||||
|
||||
#define TRACE_FLOW_BEGIN_WITH_TIME(category, name, flow_id, timestamp) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, flow_id, timestamp)
|
||||
|
||||
#define TRACE_FLOW_STEP_WITH_TIME(category, name, flow_id, timestamp) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, flow_id, timestamp)
|
||||
|
||||
#define TRACE_FLOW_END_WITH_TIME(category, name, flow_id, timestamp) \
|
||||
openscreen::internal::DoNothingForTracing(category, name, flow_id, timestamp)
|
||||
|
||||
#define TRACE_FLOW_DEFAULT_BEGIN(category, flow_id) \
|
||||
openscreen::internal::DoNothingForTracing(category, flow_id)
|
||||
#define TRACE_FLOW_DEFAULT_STEP(category, flow_id) \
|
||||
openscreen::internal::DoNothingForTracing(category, flow_id)
|
||||
#define TRACE_FLOW_DEFAULT_END(category, flow_id) \
|
||||
openscreen::internal::DoNothingForTracing(category, flow_id)
|
||||
|
||||
#endif // defined(ENABLE_TRACE_LOGGING)
|
||||
|
||||
#endif // UTIL_TRACE_LOGGING_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue