mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00

This is cleaner than checking the size before and after, as is currently done in FrameBufferProxy Bug: webrtc:14168 Change-Id: Iac896ddf7b1b0b8513159451de7cd8a10668a49a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265663 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Commit-Queue: Evan Shrubsole <eshr@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/main@{#37222}
106 lines
3.8 KiB
C++
106 lines
3.8 KiB
C++
/*
|
|
* 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;
|
|
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();
|
|
|
|
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;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // API_VIDEO_FRAME_BUFFER_H_
|