diff options
Diffstat (limited to 'third_party/libwebrtc/api/video/frame_buffer.h')
-rw-r--r-- | third_party/libwebrtc/api/video/frame_buffer.h | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/video/frame_buffer.h b/third_party/libwebrtc/api/video/frame_buffer.h new file mode 100644 index 0000000000..81fd12da58 --- /dev/null +++ b/third_party/libwebrtc/api/video/frame_buffer.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VIDEO_FRAME_BUFFER_H_ +#define API_VIDEO_FRAME_BUFFER_H_ + +#include <map> +#include <memory> +#include <utility> + +#include "absl/container/inlined_vector.h" +#include "absl/types/optional.h" +#include "api/field_trials_view.h" +#include "api/video/encoded_frame.h" +#include "modules/video_coding/utility/decoded_frames_history.h" + +namespace webrtc { +// The high level idea of the FrameBuffer is to order frames received from the +// network into a decodable stream. Frames are order by frame ID, and grouped +// into temporal units by timestamp. A temporal unit is decodable after all +// referenced frames outside the unit has been decoded, and a temporal unit is +// continuous if all referenced frames are directly or indirectly decodable. +// The FrameBuffer is thread-unsafe. +class FrameBuffer { + public: + struct DecodabilityInfo { + uint32_t next_rtp_timestamp; + uint32_t last_rtp_timestamp; + }; + + // The `max_size` determines the maximum number of frames the buffer will + // store, and max_decode_history determines how far back (by frame ID) the + // buffer will store if a frame was decoded or not. + FrameBuffer(int max_size, + int max_decode_history, + // TODO(hta): remove field trials! + const FieldTrialsView& field_trials); + FrameBuffer(const FrameBuffer&) = delete; + FrameBuffer& operator=(const FrameBuffer&) = delete; + ~FrameBuffer() = default; + + // Inserted frames may only reference backwards, and must have no duplicate + // references. Frame insertion will fail if `frame` is a duplicate, has + // already been decoded, invalid, or if the buffer is full and the frame is + // not a keyframe. Returns true if the frame was successfully inserted. + bool InsertFrame(std::unique_ptr<EncodedFrame> frame); + + // Mark all frames belonging to the next decodable temporal unit as decoded + // and returns them. + absl::InlinedVector<std::unique_ptr<EncodedFrame>, 4> + ExtractNextDecodableTemporalUnit(); + + // Drop all frames in the next decodable unit. + void DropNextDecodableTemporalUnit(); + + absl::optional<int64_t> LastContinuousFrameId() const; + absl::optional<int64_t> LastContinuousTemporalUnitFrameId() const; + absl::optional<DecodabilityInfo> DecodableTemporalUnitsInfo() const; + + int GetTotalNumberOfContinuousTemporalUnits() const; + int GetTotalNumberOfDroppedFrames() const; + int GetTotalNumberOfDiscardedPackets() const; + size_t CurrentSize() const; + + private: + struct FrameInfo { + std::unique_ptr<EncodedFrame> encoded_frame; + bool continuous = false; + }; + + using FrameMap = std::map<int64_t, FrameInfo>; + using FrameIterator = FrameMap::iterator; + + struct TemporalUnit { + // Both first and last are inclusive. + FrameIterator first_frame; + FrameIterator last_frame; + }; + + bool IsContinuous(const FrameIterator& it) const; + void PropagateContinuity(const FrameIterator& frame_it); + void FindNextAndLastDecodableTemporalUnit(); + void Clear(); + void UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it, + FrameIterator end_it); + + const bool legacy_frame_id_jump_behavior_; + const size_t max_size_; + FrameMap frames_; + absl::optional<TemporalUnit> next_decodable_temporal_unit_; + absl::optional<DecodabilityInfo> decodable_temporal_units_info_; + absl::optional<int64_t> last_continuous_frame_id_; + absl::optional<int64_t> last_continuous_temporal_unit_frame_id_; + video_coding::DecodedFramesHistory decoded_frame_history_; + + int num_continuous_temporal_units_ = 0; + int num_dropped_frames_ = 0; + int num_discarded_packets_ = 0; +}; + +} // namespace webrtc + +#endif // API_VIDEO_FRAME_BUFFER_H_ |