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