1 /* 2 * Copyright (c) 2022, Alliance for Open Media. All rights reserved 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #ifndef AOM_AV1_QMODE_RC_REFERENCE_MANAGER_H_ 13 #define AOM_AV1_QMODE_RC_REFERENCE_MANAGER_H_ 14 15 #include <deque> 16 #include <iostream> 17 #include <vector> 18 19 #include "av1/qmode_rc/ratectrl_qmode_interface.h" 20 21 namespace aom { 22 23 enum class RefUpdateType { kForward, kBackward, kLast, kNone }; 24 25 class RefFrameManager { 26 public: RefFrameManager(int ref_frame_table_size,int max_ref_frames)27 explicit RefFrameManager(int ref_frame_table_size, int max_ref_frames) 28 : ref_frame_table_(ref_frame_table_size), 29 max_ref_frames_(max_ref_frames) { 30 // forward_max_size_ define max number of arf frames that can exists at 31 // the same time. In the other words, it's the max size of forward_stack_. 32 // TODO(angiebird): Figure out if this number is optimal. 33 forward_max_size_ = ref_frame_table_size - 2; 34 cur_global_order_idx_ = 0; 35 Reset(); 36 } 37 ~RefFrameManager() = default; 38 39 RefFrameManager(const RefFrameManager &) = delete; 40 RefFrameManager &operator=(const RefFrameManager &) = delete; 41 42 friend std::ostream &operator<<(std::ostream &os, 43 const RefFrameManager &rfm) { 44 os << "=" << std::endl; 45 os << "forward: "; 46 for (const auto &ref_idx : rfm.forward_stack_) { 47 os << rfm.ref_frame_table_[ref_idx].order_idx << " "; 48 } 49 os << std::endl; 50 os << "backward: "; 51 for (const auto &ref_idx : rfm.backward_queue_) { 52 os << rfm.ref_frame_table_[ref_idx].order_idx << " "; 53 } 54 os << std::endl; 55 os << "last: "; 56 for (const auto &ref_idx : rfm.last_queue_) { 57 os << rfm.ref_frame_table_[ref_idx].order_idx << " "; 58 } 59 os << std::endl; 60 return os; 61 } 62 63 void Reset(); 64 int AllocateRefIdx(); 65 int GetRefFrameCountByType(RefUpdateType ref_update_type) const; 66 int GetRefFrameCount() const; 67 std::vector<ReferenceFrame> GetRefFrameListByPriority() const; 68 int GetRefFrameIdxByPriority(RefUpdateType ref_update_type, 69 int priority_idx) const; 70 GopFrame GetRefFrameByPriority(RefUpdateType ref_update_type, 71 int priority_idx) const; 72 GopFrame GetRefFrameByIndex(int ref_idx) const; 73 void UpdateOrder(int global_order_idx); 74 int ColocatedRefIdx(int global_order_idx); ForwardMaxSize()75 int ForwardMaxSize() const { return forward_max_size_; } MaxRefFrame()76 int MaxRefFrame() const { return max_ref_frames_; } CurGlobalOrderIdx()77 int CurGlobalOrderIdx() const { return cur_global_order_idx_; } 78 void UpdateRefFrameTable(GopFrame *gop_frame); 79 ReferenceFrame GetPrimaryRefFrame(const GopFrame &gop_frame) const; 80 81 private: 82 int forward_max_size_; 83 int cur_global_order_idx_; 84 RefFrameTable ref_frame_table_; 85 int max_ref_frames_; 86 bool allow_two_fwd_frames_; 87 std::deque<int> free_ref_idx_list_; 88 std::vector<int> forward_stack_; 89 std::deque<int> backward_queue_; 90 std::deque<int> last_queue_; 91 }; 92 93 } // namespace aom 94 95 #endif // AOM_AV1_QMODE_RC_REFERENCE_MANAGER_H_ 96