xref: /aosp_15_r20/external/webrtc/api/video/frame_buffer.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2021 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_VIDEO_FRAME_BUFFER_H_
12 #define API_VIDEO_FRAME_BUFFER_H_
13 
14 #include <map>
15 #include <memory>
16 #include <utility>
17 
18 #include "absl/container/inlined_vector.h"
19 #include "absl/types/optional.h"
20 #include "api/field_trials_view.h"
21 #include "api/video/encoded_frame.h"
22 #include "modules/video_coding/utility/decoded_frames_history.h"
23 
24 namespace webrtc {
25 // The high level idea of the FrameBuffer is to order frames received from the
26 // network into a decodable stream. Frames are order by frame ID, and grouped
27 // into temporal units by timestamp. A temporal unit is decodable after all
28 // referenced frames outside the unit has been decoded, and a temporal unit is
29 // continuous if all referenced frames are directly or indirectly decodable.
30 // The FrameBuffer is thread-unsafe.
31 class FrameBuffer {
32  public:
33   struct DecodabilityInfo {
34     uint32_t next_rtp_timestamp;
35     uint32_t last_rtp_timestamp;
36   };
37 
38   // The `max_size` determines the maximum number of frames the buffer will
39   // store, and max_decode_history determines how far back (by frame ID) the
40   // buffer will store if a frame was decoded or not.
41   FrameBuffer(int max_size,
42               int max_decode_history,
43               // TODO(hta): remove field trials!
44               const FieldTrialsView& field_trials);
45   FrameBuffer(const FrameBuffer&) = delete;
46   FrameBuffer& operator=(const FrameBuffer&) = delete;
47   ~FrameBuffer() = default;
48 
49   // Inserted frames may only reference backwards, and must have no duplicate
50   // references. Frame insertion will fail if `frame` is a duplicate, has
51   // already been decoded, invalid, or if the buffer is full and the frame is
52   // not a keyframe. Returns true if the frame was successfully inserted.
53   bool InsertFrame(std::unique_ptr<EncodedFrame> frame);
54 
55   // Mark all frames belonging to the next decodable temporal unit as decoded
56   // and returns them.
57   absl::InlinedVector<std::unique_ptr<EncodedFrame>, 4>
58   ExtractNextDecodableTemporalUnit();
59 
60   // Drop all frames in the next decodable unit.
61   void DropNextDecodableTemporalUnit();
62 
63   absl::optional<int64_t> LastContinuousFrameId() const;
64   absl::optional<int64_t> LastContinuousTemporalUnitFrameId() const;
65   absl::optional<DecodabilityInfo> DecodableTemporalUnitsInfo() const;
66 
67   int GetTotalNumberOfContinuousTemporalUnits() const;
68   int GetTotalNumberOfDroppedFrames() const;
69   size_t CurrentSize() const;
70 
71  private:
72   struct FrameInfo {
73     std::unique_ptr<EncodedFrame> encoded_frame;
74     bool continuous = false;
75   };
76 
77   using FrameMap = std::map<int64_t, FrameInfo>;
78   using FrameIterator = FrameMap::iterator;
79 
80   struct TemporalUnit {
81     // Both first and last are inclusive.
82     FrameIterator first_frame;
83     FrameIterator last_frame;
84   };
85 
86   bool IsContinuous(const FrameIterator& it) const;
87   void PropagateContinuity(const FrameIterator& frame_it);
88   void FindNextAndLastDecodableTemporalUnit();
89   void Clear();
90 
91   const bool legacy_frame_id_jump_behavior_;
92   const size_t max_size_;
93   FrameMap frames_;
94   absl::optional<TemporalUnit> next_decodable_temporal_unit_;
95   absl::optional<DecodabilityInfo> decodable_temporal_units_info_;
96   absl::optional<int64_t> last_continuous_frame_id_;
97   absl::optional<int64_t> last_continuous_temporal_unit_frame_id_;
98   video_coding::DecodedFramesHistory decoded_frame_history_;
99 
100   int num_continuous_temporal_units_ = 0;
101   int num_dropped_frames_ = 0;
102 };
103 
104 }  // namespace webrtc
105 
106 #endif  // API_VIDEO_FRAME_BUFFER_H_
107