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