blob: 1f3f71a4a53bd37f715dc594b981291225379118 [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
11#ifndef MODULES_VIDEO_CODING_FRAME_BUFFER3_H_
12#define MODULES_VIDEO_CODING_FRAME_BUFFER3_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/units/timestamp.h"
21#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:
33 // The `max_size` determines the maxmimum number of frames the buffer will
34 // store, and max_decode_history determines how far back (by frame ID) the
35 // buffer will store if a frame was decoded or not.
36 FrameBuffer(int max_size, int max_decode_history);
37 FrameBuffer(const FrameBuffer&) = delete;
38 FrameBuffer& operator=(const FrameBuffer&) = delete;
39 ~FrameBuffer() = default;
40
41 // Inserted frames may only reference backwards, and must have no duplicate
42 // references.
43 void InsertFrame(std::unique_ptr<EncodedFrame> frame);
44
45 // Mark all frames belonging to the next decodable temporal unit as decoded
46 // and returns them.
47 absl::InlinedVector<std::unique_ptr<EncodedFrame>, 4>
48 ExtractNextDecodableTemporalUnit();
49
50 // Drop all frames in the next decodable unit.
51 void DropNextDecodableTemporalUnit();
52
53 absl::optional<int64_t> LastContinuousFrameId() const;
54 absl::optional<int64_t> LastContinuousTemporalUnitFrameId() const;
55 absl::optional<uint32_t> NextDecodableTemporalUnitRtpTimestamp() const;
56 absl::optional<uint32_t> LastDecodableTemporalUnitRtpTimestamp() const;
57
58 int GetTotalNumberOfContinuousTemporalUnits() const;
59 int GetTotalNumberOfDroppedFrames() const;
Evan Shrubsole9a999052021-12-12 15:27:00 +010060 size_t CurrentSize() const;
philipelceac5d52021-12-07 18:13:09 +010061
62 private:
63 struct FrameInfo {
64 std::unique_ptr<EncodedFrame> encoded_frame;
65 bool continuous = false;
66 };
67
68 using FrameMap = std::map<int64_t, FrameInfo>;
69 using FrameIterator = FrameMap::iterator;
70
71 struct TemporalUnit {
72 // Both first and last are inclusive.
73 FrameIterator first_frame;
74 FrameIterator last_frame;
75 };
76
77 bool IsContinuous(const FrameIterator& it) const;
78 void PropagateContinuity(const FrameIterator& frame_it);
79 void FindNextAndLastDecodableTemporalUnit();
80 void Clear();
81
82 const bool legacy_frame_id_jump_behavior_;
83 const size_t max_size_;
84 FrameMap frames_;
85 absl::optional<TemporalUnit> next_decodable_temporal_unit_;
86 absl::optional<uint32_t> last_decodable_temporal_unit_timestamp_;
87 absl::optional<int64_t> last_continuous_frame_id_;
88 absl::optional<int64_t> last_continuous_temporal_unit_frame_id_;
89 video_coding::DecodedFramesHistory decoded_frame_history_;
90
91 int num_continuous_temporal_units_ = 0;
92 int num_dropped_frames_ = 0;
93};
94
95} // namespace webrtc
96
97#endif // MODULES_VIDEO_CODING_FRAME_BUFFER3_H_