1 /*
2  *  Copyright (c) 2019 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 API_RTP_PACKET_INFOS_H_
12 #define API_RTP_PACKET_INFOS_H_
13 
14 #include <cstdint>
15 #include <utility>
16 #include <vector>
17 
18 #include "api/ref_counted_base.h"
19 #include "api/rtp_packet_info.h"
20 #include "api/scoped_refptr.h"
21 #include "rtc_base/system/rtc_export.h"
22 
23 namespace webrtc {
24 
25 // Semi-immutable structure to hold information about packets used to assemble
26 // an audio or video frame. Uses internal reference counting to make it very
27 // cheap to copy.
28 //
29 // We should ideally just use |std::vector<RtpPacketInfo>| and have it
30 // |std::move()|-ed as the per-packet information is transferred from one object
31 // to another. But moving the info, instead of copying it, is not easily done
32 // for the current video code.
33 class RTC_EXPORT RtpPacketInfos {
34  public:
35   using vector_type = std::vector<RtpPacketInfo>;
36 
37   using value_type = vector_type::value_type;
38   using size_type = vector_type::size_type;
39   using difference_type = vector_type::difference_type;
40   using const_reference = vector_type::const_reference;
41   using const_pointer = vector_type::const_pointer;
42   using const_iterator = vector_type::const_iterator;
43   using const_reverse_iterator = vector_type::const_reverse_iterator;
44 
45   using reference = const_reference;
46   using pointer = const_pointer;
47   using iterator = const_iterator;
48   using reverse_iterator = const_reverse_iterator;
49 
RtpPacketInfos()50   RtpPacketInfos() {}
RtpPacketInfos(const vector_type & entries)51   explicit RtpPacketInfos(const vector_type& entries)
52       : data_(Data::Create(entries)) {}
53 
RtpPacketInfos(vector_type && entries)54   explicit RtpPacketInfos(vector_type&& entries)
55       : data_(Data::Create(std::move(entries))) {}
56 
57   RtpPacketInfos(const RtpPacketInfos& other) = default;
58   RtpPacketInfos(RtpPacketInfos&& other) = default;
59   RtpPacketInfos& operator=(const RtpPacketInfos& other) = default;
60   RtpPacketInfos& operator=(RtpPacketInfos&& other) = default;
61 
62   const_reference operator[](size_type pos) const { return entries()[pos]; }
63 
at(size_type pos)64   const_reference at(size_type pos) const { return entries().at(pos); }
front()65   const_reference front() const { return entries().front(); }
back()66   const_reference back() const { return entries().back(); }
67 
begin()68   const_iterator begin() const { return entries().begin(); }
end()69   const_iterator end() const { return entries().end(); }
rbegin()70   const_reverse_iterator rbegin() const { return entries().rbegin(); }
rend()71   const_reverse_iterator rend() const { return entries().rend(); }
72 
cbegin()73   const_iterator cbegin() const { return entries().cbegin(); }
cend()74   const_iterator cend() const { return entries().cend(); }
crbegin()75   const_reverse_iterator crbegin() const { return entries().crbegin(); }
crend()76   const_reverse_iterator crend() const { return entries().crend(); }
77 
empty()78   bool empty() const { return entries().empty(); }
size()79   size_type size() const { return entries().size(); }
80 
81  private:
82   class Data : public rtc::RefCountedBase {
83    public:
Create(const vector_type & entries)84     static rtc::scoped_refptr<Data> Create(const vector_type& entries) {
85       // Performance optimization for the empty case.
86       if (entries.empty()) {
87         return nullptr;
88       }
89 
90       return new Data(entries);
91     }
92 
Create(vector_type && entries)93     static rtc::scoped_refptr<Data> Create(vector_type&& entries) {
94       // Performance optimization for the empty case.
95       if (entries.empty()) {
96         return nullptr;
97       }
98 
99       return new Data(std::move(entries));
100     }
101 
entries()102     const vector_type& entries() const { return entries_; }
103 
104    private:
Data(const vector_type & entries)105     explicit Data(const vector_type& entries) : entries_(entries) {}
Data(vector_type && entries)106     explicit Data(vector_type&& entries) : entries_(std::move(entries)) {}
~Data()107     ~Data() override {}
108 
109     const vector_type entries_;
110   };
111 
empty_entries()112   static const vector_type& empty_entries() {
113     static const vector_type& value = *new vector_type();
114     return value;
115   }
116 
entries()117   const vector_type& entries() const {
118     if (data_ != nullptr) {
119       return data_->entries();
120     } else {
121       return empty_entries();
122     }
123   }
124 
125   rtc::scoped_refptr<Data> data_;
126 };
127 
128 }  // namespace webrtc
129 
130 #endif  // API_RTP_PACKET_INFOS_H_
131