xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
12 
13 #include <string.h>
14 
15 #include "absl/types/optional.h"
16 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
17 #include "rtc_base/checks.h"
18 #include "rtc_base/logging.h"
19 
20 namespace webrtc {
21 
22 static const size_t kGenericHeaderLength = 1;
23 static const size_t kExtendedHeaderLength = 2;
24 
RtpPacketizerGeneric(rtc::ArrayView<const uint8_t> payload,PayloadSizeLimits limits,const RTPVideoHeader & rtp_video_header)25 RtpPacketizerGeneric::RtpPacketizerGeneric(
26     rtc::ArrayView<const uint8_t> payload,
27     PayloadSizeLimits limits,
28     const RTPVideoHeader& rtp_video_header)
29     : remaining_payload_(payload) {
30   BuildHeader(rtp_video_header);
31 
32   limits.max_payload_len -= header_size_;
33   payload_sizes_ = SplitAboutEqually(payload.size(), limits);
34   current_packet_ = payload_sizes_.begin();
35 }
36 
RtpPacketizerGeneric(rtc::ArrayView<const uint8_t> payload,PayloadSizeLimits limits)37 RtpPacketizerGeneric::RtpPacketizerGeneric(
38     rtc::ArrayView<const uint8_t> payload,
39     PayloadSizeLimits limits)
40     : header_size_(0), remaining_payload_(payload) {
41   payload_sizes_ = SplitAboutEqually(payload.size(), limits);
42   current_packet_ = payload_sizes_.begin();
43 }
44 
45 RtpPacketizerGeneric::~RtpPacketizerGeneric() = default;
46 
NumPackets() const47 size_t RtpPacketizerGeneric::NumPackets() const {
48   return payload_sizes_.end() - current_packet_;
49 }
50 
NextPacket(RtpPacketToSend * packet)51 bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) {
52   RTC_DCHECK(packet);
53   if (current_packet_ == payload_sizes_.end())
54     return false;
55 
56   size_t next_packet_payload_len = *current_packet_;
57 
58   uint8_t* out_ptr =
59       packet->AllocatePayload(header_size_ + next_packet_payload_len);
60   RTC_CHECK(out_ptr);
61 
62   if (header_size_ > 0) {
63     memcpy(out_ptr, header_, header_size_);
64     // Remove first-packet bit, following packets are intermediate.
65     header_[0] &= ~RtpFormatVideoGeneric::kFirstPacketBit;
66   }
67 
68   memcpy(out_ptr + header_size_, remaining_payload_.data(),
69          next_packet_payload_len);
70 
71   remaining_payload_ = remaining_payload_.subview(next_packet_payload_len);
72 
73   ++current_packet_;
74 
75   // Packets left to produce and data left to split should end at the same time.
76   RTC_DCHECK_EQ(current_packet_ == payload_sizes_.end(),
77                 remaining_payload_.empty());
78 
79   packet->SetMarker(remaining_payload_.empty());
80   return true;
81 }
82 
BuildHeader(const RTPVideoHeader & rtp_video_header)83 void RtpPacketizerGeneric::BuildHeader(const RTPVideoHeader& rtp_video_header) {
84   header_size_ = kGenericHeaderLength;
85   header_[0] = RtpFormatVideoGeneric::kFirstPacketBit;
86   if (rtp_video_header.frame_type == VideoFrameType::kVideoFrameKey) {
87     header_[0] |= RtpFormatVideoGeneric::kKeyFrameBit;
88   }
89   if (const auto* generic_header = absl::get_if<RTPVideoHeaderLegacyGeneric>(
90           &rtp_video_header.video_type_header)) {
91     // Store bottom 15 bits of the picture id. Only 15 bits are used for
92     // compatibility with other packetizer implemenetations.
93     uint16_t picture_id = generic_header->picture_id;
94     header_[0] |= RtpFormatVideoGeneric::kExtendedHeaderBit;
95     header_[1] = (picture_id >> 8) & 0x7F;
96     header_[2] = picture_id & 0xFF;
97     header_size_ += kExtendedHeaderLength;
98   }
99 }
100 }  // namespace webrtc
101