xref: /aosp_15_r20/external/webrtc/modules/video_coding/packet_buffer.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef MODULES_VIDEO_CODING_PACKET_BUFFER_H_
12*d9f75844SAndroid Build Coastguard Worker #define MODULES_VIDEO_CODING_PACKET_BUFFER_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <queue>
16*d9f75844SAndroid Build Coastguard Worker #include <set>
17*d9f75844SAndroid Build Coastguard Worker #include <vector>
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker #include "absl/base/attributes.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_packet_info.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/video/encoded_image.h"
23*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_packet_received.h"
24*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_video_header.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/copy_on_write_buffer.h"
26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/sequence_number_util.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h"
28*d9f75844SAndroid Build Coastguard Worker 
29*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
30*d9f75844SAndroid Build Coastguard Worker namespace video_coding {
31*d9f75844SAndroid Build Coastguard Worker 
32*d9f75844SAndroid Build Coastguard Worker class PacketBuffer {
33*d9f75844SAndroid Build Coastguard Worker  public:
34*d9f75844SAndroid Build Coastguard Worker   struct Packet {
35*d9f75844SAndroid Build Coastguard Worker     Packet() = default;
36*d9f75844SAndroid Build Coastguard Worker     Packet(const RtpPacketReceived& rtp_packet,
37*d9f75844SAndroid Build Coastguard Worker            const RTPVideoHeader& video_header);
38*d9f75844SAndroid Build Coastguard Worker     Packet(const Packet&) = delete;
39*d9f75844SAndroid Build Coastguard Worker     Packet(Packet&&) = delete;
40*d9f75844SAndroid Build Coastguard Worker     Packet& operator=(const Packet&) = delete;
41*d9f75844SAndroid Build Coastguard Worker     Packet& operator=(Packet&&) = delete;
42*d9f75844SAndroid Build Coastguard Worker     ~Packet() = default;
43*d9f75844SAndroid Build Coastguard Worker 
codecPacket44*d9f75844SAndroid Build Coastguard Worker     VideoCodecType codec() const { return video_header.codec; }
widthPacket45*d9f75844SAndroid Build Coastguard Worker     int width() const { return video_header.width; }
heightPacket46*d9f75844SAndroid Build Coastguard Worker     int height() const { return video_header.height; }
47*d9f75844SAndroid Build Coastguard Worker 
is_first_packet_in_framePacket48*d9f75844SAndroid Build Coastguard Worker     bool is_first_packet_in_frame() const {
49*d9f75844SAndroid Build Coastguard Worker       return video_header.is_first_packet_in_frame;
50*d9f75844SAndroid Build Coastguard Worker     }
is_last_packet_in_framePacket51*d9f75844SAndroid Build Coastguard Worker     bool is_last_packet_in_frame() const {
52*d9f75844SAndroid Build Coastguard Worker       return video_header.is_last_packet_in_frame;
53*d9f75844SAndroid Build Coastguard Worker     }
54*d9f75844SAndroid Build Coastguard Worker 
55*d9f75844SAndroid Build Coastguard Worker     // If all its previous packets have been inserted into the packet buffer.
56*d9f75844SAndroid Build Coastguard Worker     // Set and used internally by the PacketBuffer.
57*d9f75844SAndroid Build Coastguard Worker     bool continuous = false;
58*d9f75844SAndroid Build Coastguard Worker     bool marker_bit = false;
59*d9f75844SAndroid Build Coastguard Worker     uint8_t payload_type = 0;
60*d9f75844SAndroid Build Coastguard Worker     uint16_t seq_num = 0;
61*d9f75844SAndroid Build Coastguard Worker     uint32_t timestamp = 0;
62*d9f75844SAndroid Build Coastguard Worker     int times_nacked = -1;
63*d9f75844SAndroid Build Coastguard Worker 
64*d9f75844SAndroid Build Coastguard Worker     rtc::CopyOnWriteBuffer video_payload;
65*d9f75844SAndroid Build Coastguard Worker     RTPVideoHeader video_header;
66*d9f75844SAndroid Build Coastguard Worker   };
67*d9f75844SAndroid Build Coastguard Worker   struct InsertResult {
68*d9f75844SAndroid Build Coastguard Worker     std::vector<std::unique_ptr<Packet>> packets;
69*d9f75844SAndroid Build Coastguard Worker     // Indicates if the packet buffer was cleared, which means that a key
70*d9f75844SAndroid Build Coastguard Worker     // frame request should be sent.
71*d9f75844SAndroid Build Coastguard Worker     bool buffer_cleared = false;
72*d9f75844SAndroid Build Coastguard Worker   };
73*d9f75844SAndroid Build Coastguard Worker 
74*d9f75844SAndroid Build Coastguard Worker   // Both `start_buffer_size` and `max_buffer_size` must be a power of 2.
75*d9f75844SAndroid Build Coastguard Worker   PacketBuffer(size_t start_buffer_size, size_t max_buffer_size);
76*d9f75844SAndroid Build Coastguard Worker   ~PacketBuffer();
77*d9f75844SAndroid Build Coastguard Worker 
78*d9f75844SAndroid Build Coastguard Worker   ABSL_MUST_USE_RESULT InsertResult
79*d9f75844SAndroid Build Coastguard Worker   InsertPacket(std::unique_ptr<Packet> packet);
80*d9f75844SAndroid Build Coastguard Worker   ABSL_MUST_USE_RESULT InsertResult InsertPadding(uint16_t seq_num);
81*d9f75844SAndroid Build Coastguard Worker   void ClearTo(uint16_t seq_num);
82*d9f75844SAndroid Build Coastguard Worker   void Clear();
83*d9f75844SAndroid Build Coastguard Worker 
84*d9f75844SAndroid Build Coastguard Worker   void ForceSpsPpsIdrIsH264Keyframe();
85*d9f75844SAndroid Build Coastguard Worker   void ResetSpsPpsIdrIsH264Keyframe();
86*d9f75844SAndroid Build Coastguard Worker 
87*d9f75844SAndroid Build Coastguard Worker  private:
88*d9f75844SAndroid Build Coastguard Worker   void ClearInternal();
89*d9f75844SAndroid Build Coastguard Worker 
90*d9f75844SAndroid Build Coastguard Worker   // Tries to expand the buffer.
91*d9f75844SAndroid Build Coastguard Worker   bool ExpandBufferSize();
92*d9f75844SAndroid Build Coastguard Worker 
93*d9f75844SAndroid Build Coastguard Worker   // Test if all previous packets has arrived for the given sequence number.
94*d9f75844SAndroid Build Coastguard Worker   bool PotentialNewFrame(uint16_t seq_num) const;
95*d9f75844SAndroid Build Coastguard Worker 
96*d9f75844SAndroid Build Coastguard Worker   // Test if all packets of a frame has arrived, and if so, returns packets to
97*d9f75844SAndroid Build Coastguard Worker   // create frames.
98*d9f75844SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Packet>> FindFrames(uint16_t seq_num);
99*d9f75844SAndroid Build Coastguard Worker 
100*d9f75844SAndroid Build Coastguard Worker   void UpdateMissingPackets(uint16_t seq_num);
101*d9f75844SAndroid Build Coastguard Worker 
102*d9f75844SAndroid Build Coastguard Worker   // buffer_.size() and max_size_ must always be a power of two.
103*d9f75844SAndroid Build Coastguard Worker   const size_t max_size_;
104*d9f75844SAndroid Build Coastguard Worker 
105*d9f75844SAndroid Build Coastguard Worker   // The fist sequence number currently in the buffer.
106*d9f75844SAndroid Build Coastguard Worker   uint16_t first_seq_num_;
107*d9f75844SAndroid Build Coastguard Worker 
108*d9f75844SAndroid Build Coastguard Worker   // If the packet buffer has received its first packet.
109*d9f75844SAndroid Build Coastguard Worker   bool first_packet_received_;
110*d9f75844SAndroid Build Coastguard Worker 
111*d9f75844SAndroid Build Coastguard Worker   // If the buffer is cleared to `first_seq_num_`.
112*d9f75844SAndroid Build Coastguard Worker   bool is_cleared_to_first_seq_num_;
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker   // Buffer that holds the the inserted packets and information needed to
115*d9f75844SAndroid Build Coastguard Worker   // determine continuity between them.
116*d9f75844SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Packet>> buffer_;
117*d9f75844SAndroid Build Coastguard Worker 
118*d9f75844SAndroid Build Coastguard Worker   absl::optional<uint16_t> newest_inserted_seq_num_;
119*d9f75844SAndroid Build Coastguard Worker   std::set<uint16_t, DescendingSeqNumComp<uint16_t>> missing_packets_;
120*d9f75844SAndroid Build Coastguard Worker 
121*d9f75844SAndroid Build Coastguard Worker   std::set<uint16_t, DescendingSeqNumComp<uint16_t>> received_padding_;
122*d9f75844SAndroid Build Coastguard Worker 
123*d9f75844SAndroid Build Coastguard Worker   // Indicates if we should require SPS, PPS, and IDR for a particular
124*d9f75844SAndroid Build Coastguard Worker   // RTP timestamp to treat the corresponding frame as a keyframe.
125*d9f75844SAndroid Build Coastguard Worker   bool sps_pps_idr_is_h264_keyframe_;
126*d9f75844SAndroid Build Coastguard Worker };
127*d9f75844SAndroid Build Coastguard Worker 
128*d9f75844SAndroid Build Coastguard Worker }  // namespace video_coding
129*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
130*d9f75844SAndroid Build Coastguard Worker 
131*d9f75844SAndroid Build Coastguard Worker #endif  // MODULES_VIDEO_CODING_PACKET_BUFFER_H_
132