| // 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 |