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
65
breadcast-caststream-sys/vendor/openscreen/util/base64.cc
vendored
Normal file
65
breadcast-caststream-sys/vendor/openscreen/util/base64.cc
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
// LOCAL PATCH (breadcast): upstream implements this on top of
|
||||
// third_party/modp_b64, which isn't fetched by a plain shallow clone of
|
||||
// openscreen (it's pulled in separately via gclient/DEPS). This is a
|
||||
// same-interface reimplementation on top of OpenSSL's EVP_Encode/DecodeBlock
|
||||
// instead, since system OpenSSL is already a build dependency here. See
|
||||
// vendor/openscreen/PATCHES.md.
|
||||
#include "util/base64.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace openscreen::base64 {
|
||||
|
||||
std::string Encode(ByteView input) {
|
||||
return Encode(std::string_view(reinterpret_cast<const char*>(input.data()),
|
||||
input.size()));
|
||||
}
|
||||
|
||||
std::string Encode(std::string_view input) {
|
||||
const auto* data = reinterpret_cast<const unsigned char*>(input.data());
|
||||
// EVP_EncodeBlock's output is 4*ceil(n/3) bytes plus a NUL terminator it
|
||||
// writes but doesn't count in the returned length.
|
||||
std::string out((4 * ((input.size() + 2) / 3)) + 1, '\0');
|
||||
const int output_size = EVP_EncodeBlock(
|
||||
reinterpret_cast<unsigned char*>(out.data()), data,
|
||||
static_cast<int>(input.size()));
|
||||
out.resize(static_cast<size_t>(output_size));
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Decode(std::string_view input, std::vector<uint8_t>* output) {
|
||||
if (input.size() % 4 != 0) {
|
||||
return false;
|
||||
}
|
||||
std::vector<uint8_t> out((input.size() / 4) * 3);
|
||||
if (!out.empty()) {
|
||||
const int decoded_size = EVP_DecodeBlock(
|
||||
out.data(), reinterpret_cast<const unsigned char*>(input.data()),
|
||||
static_cast<int>(input.size()));
|
||||
if (decoded_size < 0) {
|
||||
return false;
|
||||
}
|
||||
// EVP_DecodeBlock doesn't strip padding from the output size -- trim the
|
||||
// 1-2 bytes corresponding to trailing '=' padding characters, matching
|
||||
// the caller-visible behavior of a normal base64 decoder.
|
||||
size_t padding = 0;
|
||||
if (input.size() >= 2) {
|
||||
if (input[input.size() - 1] == '=') {
|
||||
++padding;
|
||||
}
|
||||
if (input[input.size() - 2] == '=') {
|
||||
++padding;
|
||||
}
|
||||
}
|
||||
out.resize(static_cast<size_t>(decoded_size) - padding);
|
||||
}
|
||||
*output = std::move(out);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace openscreen::base64
|
||||
Loading…
Add table
Add a link
Reference in a new issue