vp8rtppacketizer.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /**
  2. * Copyright (c) 2026 Paul-Louis Ageneau
  3. *
  4. * This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  7. */
  8. #if RTC_ENABLE_MEDIA
  9. #include "vp8rtppacketizer.hpp"
  10. #include <cstring>
  11. namespace rtc {
  12. VP8RtpPacketizer::VP8RtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig,
  13. size_t maxFragmentSize)
  14. : RtpPacketizer(std::move(rtpConfig)), mMaxFragmentSize(maxFragmentSize) {}
  15. std::vector<binary> VP8RtpPacketizer::fragment(binary data) {
  16. /*
  17. * VP8 payload descriptor
  18. *
  19. * 0 1 2 3 4 5 6 7
  20. * +-+-+-+-+-+-+-+-+
  21. * |X|R|N|S|R| PID | (REQUIRED)
  22. * +-+-+-+-+-+-+-+-+
  23. * X: |I|L|T|K| RSV | (OPTIONAL)
  24. * +-+-+-+-+-+-+-+-+
  25. * I: |M| PictureID | (OPTIONAL)
  26. * +-+-+-+-+-+-+-+-+
  27. *
  28. * X: Extended control bits present
  29. * R: Reserved (always 0)
  30. * N: Non-reference frame
  31. * S: Start of VP8 partition (1 for first fragment, 0 otherwise)
  32. * PID: Partition index (assumed 0)
  33. * I: PictureID present
  34. * M: PictureID 15-byte extension flag
  35. */
  36. const uint8_t N = 0b00100000;
  37. const uint8_t S = 0b00010000;
  38. if (data.empty())
  39. return {};
  40. const size_t descriptorSize = 1;
  41. if (mMaxFragmentSize <= descriptorSize)
  42. return {};
  43. bool isKeyframe = (std::to_integer<uint8_t>(data[0]) & 0b00000001) == 0;
  44. std::vector<binary> payloads;
  45. size_t index = 0;
  46. size_t remaining = data.size();
  47. bool firstFragment = true;
  48. while (remaining > 0) {
  49. size_t payloadSize = std::min(mMaxFragmentSize - descriptorSize, remaining);
  50. binary payload(descriptorSize + payloadSize);
  51. // Set 1-byte Payload Descriptor
  52. uint8_t descriptor = 0;
  53. if (!isKeyframe) {
  54. descriptor |= N;
  55. }
  56. if (firstFragment) {
  57. descriptor |= S;
  58. firstFragment = false;
  59. }
  60. payload[0] = std::byte(descriptor);
  61. // Copy data
  62. std::memcpy(payload.data() + descriptorSize, data.data() + index, payloadSize);
  63. payloads.push_back(std::move(payload));
  64. index += payloadSize;
  65. remaining -= payloadSize;
  66. }
  67. return payloads;
  68. }
  69. } // namespace rtc
  70. #endif /* RTC_ENABLE_MEDIA */