blob: 94edf64d5a4123c3e9fa7912bedc99d5e049bb93 [file] [log] [blame]
philipelceac5d52021-12-07 18:13:09 +01001/*
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
philipel8615bf02022-05-05 15:12:13 +020011#ifndef API_VIDEO_FRAME_BUFFER_H_
12#define API_VIDEO_FRAME_BUFFER_H_
philipelceac5d52021-12-07 18:13:09 +010013
14#include <map>
15#include <memory>
16#include <utility>
17
18#include "absl/container/inlined_vector.h"
19#include "absl/types/optional.h"
Jonas Orelande62c2f22022-03-29 11:04:48 +020020#include "api/field_trials_view.h"
philipelceac5d52021-12-07 18:13:09 +010021#include "api/video/encoded_frame.h"
22#include "modules/video_coding/utility/decoded_frames_history.h"
23
24namespace 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.
31class FrameBuffer {
32 public:
philipel1bcd8272022-05-03 15:21:34 +020033 struct DecodabilityInfo {
34 uint32_t next_rtp_timestamp;
35 uint32_t last_rtp_timestamp;
36 };
37
Evan Shrubsole66fcd162022-06-15 08:25:22 +000038 // The `max_size` determines the maximum number of frames the buffer will
philipelceac5d52021-12-07 18:13:09 +010039 // store, and max_decode_history determines how far back (by frame ID) the
40 // buffer will store if a frame was decoded or not.
Jonas Orelande02f9ee2022-03-25 12:43:14 +010041 FrameBuffer(int max_size,
42 int max_decode_history,
43 // TODO(hta): remove field trials!
Jonas Orelande62c2f22022-03-29 11:04:48 +020044 const FieldTrialsView& field_trials);
philipelceac5d52021-12-07 18:13:09 +010045 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
Evan Shrubsole66fcd162022-06-15 08:25:22 +000050 // 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);
philipelceac5d52021-12-07 18:13:09 +010054
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;
philipel1bcd8272022-05-03 15:21:34 +020065 absl::optional<DecodabilityInfo> DecodableTemporalUnitsInfo() const;
philipelceac5d52021-12-07 18:13:09 +010066
67 int GetTotalNumberOfContinuousTemporalUnits() const;
68 int GetTotalNumberOfDroppedFrames() const;
Evan Shrubsole9a999052021-12-12 15:27:00 +010069 size_t CurrentSize() const;
philipelceac5d52021-12-07 18:13:09 +010070
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_;
philipel1bcd8272022-05-03 15:21:34 +020095 absl::optional<DecodabilityInfo> decodable_temporal_units_info_;
philipelceac5d52021-12-07 18:13:09 +010096 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
philipel8615bf02022-05-05 15:12:13 +0200106#endif // API_VIDEO_FRAME_BUFFER_H_