Line data Source code
1 : /*
2 : * Copyright (c) 2016 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 WEBRTC_MODULES_VIDEO_CODING_FRAME_BUFFER2_H_
12 : #define WEBRTC_MODULES_VIDEO_CODING_FRAME_BUFFER2_H_
13 :
14 : #include <array>
15 : #include <map>
16 : #include <memory>
17 : #include <utility>
18 :
19 : #include "webrtc/base/constructormagic.h"
20 : #include "webrtc/base/criticalsection.h"
21 : #include "webrtc/base/event.h"
22 : #include "webrtc/base/thread_annotations.h"
23 : #include "webrtc/modules/video_coding/frame_object.h"
24 : #include "webrtc/modules/video_coding/include/video_coding_defines.h"
25 : #include "webrtc/modules/video_coding/inter_frame_delay.h"
26 : #include "webrtc/modules/video_coding/sequence_number_util.h"
27 :
28 : namespace webrtc {
29 :
30 : class Clock;
31 : class VCMJitterEstimator;
32 : class VCMTiming;
33 :
34 : namespace video_coding {
35 :
36 : class FrameBuffer {
37 : public:
38 : enum ReturnReason { kFrameFound, kTimeout, kStopped };
39 :
40 : FrameBuffer(Clock* clock,
41 : VCMJitterEstimator* jitter_estimator,
42 : VCMTiming* timing);
43 :
44 : virtual ~FrameBuffer();
45 :
46 : // Insert a frame into the frame buffer. Returns the picture id
47 : // of the last continuous frame or -1 if there is no continuous frame.
48 : int InsertFrame(std::unique_ptr<FrameObject> frame);
49 :
50 : // Get the next frame for decoding. Will return at latest after
51 : // |max_wait_time_ms|.
52 : // - If a frame is available within |max_wait_time_ms| it will return
53 : // kFrameFound and set |frame_out| to the resulting frame.
54 : // - If no frame is available after |max_wait_time_ms| it will return
55 : // kTimeout.
56 : // - If the FrameBuffer is stopped then it will return kStopped.
57 : ReturnReason NextFrame(int64_t max_wait_time_ms,
58 : std::unique_ptr<FrameObject>* frame_out);
59 :
60 : // Tells the FrameBuffer which protection mode that is in use. Affects
61 : // the frame timing.
62 : // TODO(philipel): Remove this when new timing calculations has been
63 : // implemented.
64 : void SetProtectionMode(VCMVideoProtection mode);
65 :
66 : // Start the frame buffer, has no effect if the frame buffer is started.
67 : // The frame buffer is started upon construction.
68 : void Start();
69 :
70 : // Stop the frame buffer, causing any sleeping thread in NextFrame to
71 : // return immediately.
72 : void Stop();
73 :
74 : private:
75 : struct FrameKey {
76 0 : FrameKey() : picture_id(0), spatial_layer(0) {}
77 0 : FrameKey(uint16_t picture_id, uint8_t spatial_layer)
78 0 : : picture_id(picture_id), spatial_layer(spatial_layer) {}
79 :
80 0 : bool operator<(const FrameKey& rhs) const {
81 0 : if (picture_id == rhs.picture_id)
82 0 : return spatial_layer < rhs.spatial_layer;
83 0 : return AheadOf(rhs.picture_id, picture_id);
84 : }
85 :
86 0 : bool operator<=(const FrameKey& rhs) const { return !(rhs < *this); }
87 :
88 : uint16_t picture_id;
89 : uint8_t spatial_layer;
90 : };
91 :
92 0 : struct FrameInfo {
93 : // The maximum number of frames that can depend on this frame.
94 : static constexpr size_t kMaxNumDependentFrames = 8;
95 :
96 : // Which other frames that have direct unfulfilled dependencies
97 : // on this frame.
98 : FrameKey dependent_frames[kMaxNumDependentFrames];
99 : size_t num_dependent_frames = 0;
100 :
101 : // A frame is continiuous if it has all its referenced/indirectly
102 : // referenced frames.
103 : //
104 : // How many unfulfilled frames this frame have until it becomes continuous.
105 : size_t num_missing_continuous = 0;
106 :
107 : // A frame is decodable if all its referenced frames have been decoded.
108 : //
109 : // How many unfulfilled frames this frame have until it becomes decodable.
110 : size_t num_missing_decodable = 0;
111 :
112 : // If this frame is continuous or not.
113 : bool continuous = false;
114 :
115 : // The actual FrameObject.
116 : std::unique_ptr<FrameObject> frame;
117 : };
118 :
119 : using FrameMap = std::map<FrameKey, FrameInfo>;
120 :
121 : // Update all directly dependent and indirectly dependent frames and mark
122 : // them as continuous if all their references has been fulfilled.
123 : void PropagateContinuity(FrameMap::iterator start)
124 : EXCLUSIVE_LOCKS_REQUIRED(crit_);
125 :
126 : // Marks the frame as decoded and updates all directly dependent frames.
127 : void PropagateDecodability(const FrameInfo& info)
128 : EXCLUSIVE_LOCKS_REQUIRED(crit_);
129 :
130 : // Advances |last_decoded_frame_it_| to |decoded| and removes old
131 : // frame info.
132 : void AdvanceLastDecodedFrame(FrameMap::iterator decoded)
133 : EXCLUSIVE_LOCKS_REQUIRED(crit_);
134 :
135 : // Update the corresponding FrameInfo of |frame| and all FrameInfos that
136 : // |frame| references.
137 : // Return false if |frame| will never be decodable, true otherwise.
138 : bool UpdateFrameInfoWithIncomingFrame(const FrameObject& frame,
139 : FrameMap::iterator info)
140 : EXCLUSIVE_LOCKS_REQUIRED(crit_);
141 :
142 : void UpdateJitterDelay() EXCLUSIVE_LOCKS_REQUIRED(crit_);
143 :
144 : void ClearFramesAndHistory() EXCLUSIVE_LOCKS_REQUIRED(crit_);
145 :
146 : void UpdateHistograms() const;
147 :
148 : FrameMap frames_ GUARDED_BY(crit_);
149 :
150 : rtc::CriticalSection crit_;
151 : Clock* const clock_;
152 : rtc::Event new_countinuous_frame_event_;
153 : VCMJitterEstimator* const jitter_estimator_ GUARDED_BY(crit_);
154 : VCMTiming* const timing_ GUARDED_BY(crit_);
155 : VCMInterFrameDelay inter_frame_delay_ GUARDED_BY(crit_);
156 : FrameMap::iterator last_decoded_frame_it_ GUARDED_BY(crit_);
157 : FrameMap::iterator last_continuous_frame_it_ GUARDED_BY(crit_);
158 : int num_frames_history_ GUARDED_BY(crit_);
159 : int num_frames_buffered_ GUARDED_BY(crit_);
160 : bool stopped_ GUARDED_BY(crit_);
161 : VCMVideoProtection protection_mode_ GUARDED_BY(crit_);
162 :
163 : RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(FrameBuffer);
164 :
165 : // For WebRTC.Video.JitterBufferDelayInMs metric.
166 : int64_t accumulated_delay_ = 0;
167 : int64_t accumulated_delay_samples_ = 0;
168 :
169 : // For WebRTC.Video.KeyFramesReceivedInPermille metric.
170 : int64_t num_total_frames_ = 0;
171 : int64_t num_key_frames_ = 0;
172 : };
173 :
174 : } // namespace video_coding
175 : } // namespace webrtc
176 :
177 : #endif // WEBRTC_MODULES_VIDEO_CODING_FRAME_BUFFER2_H_
|