blob: 5528079d9d95798627ffc6c7fa68d352b92b79a9 [file] [log] [blame]
// 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
// (if stream-per-group)
// 0-45: group ID
// (if stream-per-object)
// 20-45: group ID
// 0-19: object ID
webtransport::SendOrder SendOrderForStream(MoqtPriority subscriber_priority,
MoqtPriority publisher_priority,
uint64_t group_id,
MoqtDeliveryOrder delivery_order) {
const int64_t track_bits = (Flip<8>(subscriber_priority) << 54) |
(Flip<8>(publisher_priority) << 46);
group_id = OnlyLowestNBits<46>(group_id);
if (delivery_order == MoqtDeliveryOrder::kAscending) {
group_id = Flip<46>(group_id);
}
return track_bits | group_id;
}
webtransport::SendOrder SendOrderForStream(MoqtPriority subscriber_priority,
MoqtPriority publisher_priority,
uint64_t group_id,
uint64_t object_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);
object_id = OnlyLowestNBits<20>(object_id);
if (delivery_order == MoqtDeliveryOrder::kAscending) {
group_id = Flip<26>(group_id);
}
object_id = Flip<20>(object_id); // Object ID is always ascending.
return track_bits | (group_id << 20) | object_id;
}
const webtransport::SendOrder kMoqtControlStreamSendOrder =
std::numeric_limits<webtransport::SendOrder>::max();
} // namespace moqt