blob: 9a5eb207c68c77854b3a1edc0c2d09a618839752 [file] [log] [blame] [edit]
// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "quiche/quic/moqt/moqt_priority.h"
#include <cstdint>
#include <limits>
#include "quiche/web_transport/web_transport.h"
namespace moqt {
namespace {
template <uint64_t NumBits>
constexpr uint64_t Flip(uint64_t number) {
static_assert(NumBits <= 63);
return (1ull << NumBits) - 1 - number;
}
template <uint64_t N>
constexpr uint64_t OnlyLowestNBits(uint64_t value) {
static_assert(N <= 62);
return value & ((1ull << (N + 1)) - 1);
}
} // namespace
// The send order is packed into a signed 64-bit integer as follows:
// 63: always zero to indicate a positive number
// 62: 0 for data streams, 1 for control streams
// 54-61: subscriber priority
// 46-53: publisher priority
// 20-45: group ID
// 0-19: object (for Datagrams) or subgroup (for streams) ID
webtransport::SendOrder SendOrderForStream(MoqtPriority subscriber_priority,
MoqtPriority publisher_priority,
uint64_t group_id,
uint64_t subgroup_id,
MoqtDeliveryOrder delivery_order) {
const int64_t track_bits = (Flip<8>(subscriber_priority) << 54) |
(Flip<8>(publisher_priority) << 46);
group_id = OnlyLowestNBits<26>(group_id);
subgroup_id = OnlyLowestNBits<20>(subgroup_id);
if (delivery_order == MoqtDeliveryOrder::kAscending) {
group_id = Flip<26>(group_id);
}
subgroup_id = Flip<20>(subgroup_id);
return track_bits | (group_id << 20) | subgroup_id;
}
webtransport::SendOrder SendOrderForDatagram(MoqtPriority subscriber_priority,
MoqtPriority publisher_priority,
uint64_t group_id,
uint64_t object_id,
MoqtDeliveryOrder delivery_order) {
return SendOrderForStream(subscriber_priority, publisher_priority, group_id,
object_id, delivery_order);
}
webtransport::SendOrder SendOrderForFetch(MoqtPriority subscriber_priority) {
return (Flip<8>(subscriber_priority) << 54);
}
webtransport::SendOrder UpdateSendOrderForSubscriberPriority(
const webtransport::SendOrder send_order,
MoqtPriority subscriber_priority) {
webtransport::SendOrder new_send_order = OnlyLowestNBits<54>(send_order);
const int64_t sub_bits = Flip<8>(subscriber_priority) << 54;
new_send_order |= sub_bits;
return new_send_order;
}
const webtransport::SendOrder kMoqtControlStreamSendOrder =
std::numeric_limits<webtransport::SendOrder>::max();
const webtransport::SendOrder kMoqtProbeStreamSendOrder =
std::numeric_limits<webtransport::SendOrder>::min();
} // namespace moqt