Introduce padding streams.

Those will be used to probe bandwidth up.

PiperOrigin-RevId: 676674649
diff --git a/quiche/quic/moqt/moqt_messages.cc b/quiche/quic/moqt/moqt_messages.cc
index a1a7729..2ecdbf6 100644
--- a/quiche/quic/moqt/moqt_messages.cc
+++ b/quiche/quic/moqt/moqt_messages.cc
@@ -104,6 +104,8 @@
       return "STREAM_HEADER_TRACK";
     case MoqtDataStreamType::kStreamHeaderGroup:
       return "STREAM_HEADER_GROUP";
+    case MoqtDataStreamType::kPadding:
+      return "PADDING";
   }
   return "Unknown stream type " + absl::StrCat(static_cast<int>(type));
 }
diff --git a/quiche/quic/moqt/moqt_messages.h b/quiche/quic/moqt/moqt_messages.h
index 87f47ac..0a6bc55 100644
--- a/quiche/quic/moqt/moqt_messages.h
+++ b/quiche/quic/moqt/moqt_messages.h
@@ -64,6 +64,9 @@
   kObjectDatagram = 0x01,
   kStreamHeaderTrack = 0x50,
   kStreamHeaderGroup = 0x51,
+
+  // Currently QUICHE-specific.  All data on a kPadding stream is ignored.
+  kPadding = 0x26d3,
 };
 
 enum class QUICHE_EXPORT MoqtMessageType : uint64_t {
diff --git a/quiche/quic/moqt/moqt_parser.cc b/quiche/quic/moqt/moqt_parser.cc
index 9e9b079..0ae2720 100644
--- a/quiche/quic/moqt/moqt_parser.cc
+++ b/quiche/quic/moqt/moqt_parser.cc
@@ -52,7 +52,7 @@
 bool IsAllowedStreamType(uint64_t value) {
   constexpr std::array kAllowedStreamTypes = {
       MoqtDataStreamType::kObjectStream, MoqtDataStreamType::kStreamHeaderGroup,
-      MoqtDataStreamType::kStreamHeaderTrack};
+      MoqtDataStreamType::kStreamHeaderTrack, MoqtDataStreamType::kPadding};
   for (MoqtDataStreamType type : kAllowedStreamTypes) {
     if (static_cast<uint64_t>(type) == value) {
       return true;
@@ -914,7 +914,7 @@
         continue;
       }
 
-      case kData:
+      case kData: {
         if (payload_length_remaining_ == 0) {
           // Special case: kObject, which does not have explicit length.
           if (metadata_->object_status != MoqtObjectStatus::kNormal) {
@@ -933,6 +933,10 @@
         payload_length_remaining_ -= payload.size();
 
         continue;
+      }
+
+      case kPadding:
+        return "";
     }
   }
   return "";
diff --git a/quiche/quic/moqt/moqt_parser.h b/quiche/quic/moqt/moqt_parser.h
index 2f25f02..f129f72 100644
--- a/quiche/quic/moqt/moqt_parser.h
+++ b/quiche/quic/moqt/moqt_parser.h
@@ -176,6 +176,8 @@
     kSubheader,
     // The next thing to be read is the object payload.
     kData,
+    // The next thing to be read (and ignored) is padding.
+    kPadding,
   };
 
   // Infers the current state of the parser.
@@ -183,6 +185,9 @@
     if (!type_.has_value()) {
       return kStreamType;
     }
+    if (type_ == MoqtDataStreamType::kPadding) {
+      return kPadding;
+    }
     if (!metadata_.has_value()) {
       return kHeader;
     }
diff --git a/quiche/quic/moqt/moqt_parser_test.cc b/quiche/quic/moqt/moqt_parser_test.cc
index a074f16..53bbdf8 100644
--- a/quiche/quic/moqt/moqt_parser_test.cc
+++ b/quiche/quic/moqt/moqt_parser_test.cc
@@ -175,7 +175,7 @@
 
   std::vector<std::string> object_payloads_;
   bool end_of_message_ = false;
-  std::optional<absl::string_view> parsing_error_;
+  std::optional<std::string> parsing_error_;
   MoqtError parsing_error_code_;
   uint64_t messages_received_ = 0;
   std::optional<TestMessageBase::MessageStructuredData> last_message_;
@@ -1145,4 +1145,17 @@
             "SUBSCRIBE_DONE ContentExists has invalid value");
 }
 
+TEST_F(MoqtMessageSpecificTest, PaddingStream) {
+  MoqtDataParser parser(&visitor_);
+  std::string buffer(32, '\0');
+  quic::QuicDataWriter writer(buffer.size(), buffer.data());
+  ASSERT_TRUE(writer.WriteVarInt62(
+      static_cast<uint64_t>(MoqtDataStreamType::kPadding)));
+  for (int i = 0; i < 100; ++i) {
+    parser.ProcessData(buffer, false);
+    ASSERT_EQ(visitor_.messages_received_, 0);
+    ASSERT_EQ(visitor_.parsing_error_, std::nullopt);
+  }
+}
+
 }  // namespace moqt::test
diff --git a/quiche/quic/moqt/test_tools/moqt_test_message.h b/quiche/quic/moqt/test_tools/moqt_test_message.h
index f653b26..9633ef3 100644
--- a/quiche/quic/moqt/test_tools/moqt_test_message.h
+++ b/quiche/quic/moqt/test_tools/moqt_test_message.h
@@ -1133,6 +1133,8 @@
       return std::make_unique<StreamHeaderTrackMessage>();
     case MoqtDataStreamType::kStreamHeaderGroup:
       return std::make_unique<StreamHeaderGroupMessage>();
+    case MoqtDataStreamType::kPadding:
+      return nullptr;
   }
   return nullptr;
 }