| /* |
| * Copyright (c) 2022, Alliance for Open Media. All rights reserved |
| * |
| * This source code is subject to the terms of the BSD 2 Clause License and |
| * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| * was not distributed with this source code in the LICENSE file, you can |
| * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| * Media Patent License 1.0 was not distributed with this source code in the |
| * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
| */ |
| |
| #ifndef AOM_AV1_REFERENCE_MANAGER_H_ |
| #define AOM_AV1_REFERENCE_MANAGER_H_ |
| |
| #include <deque> |
| #include <iostream> |
| #include <vector> |
| |
| #include "av1/ratectrl_qmode_interface.h" |
| |
| namespace aom { |
| |
| enum class RefUpdateType { kForward, kBackward, kLast, kNone }; |
| |
| class RefFrameManager { |
| public: |
| explicit RefFrameManager(int ref_frame_table_size, int max_ref_frames) |
| : ref_frame_table_(ref_frame_table_size), |
| max_ref_frames_(max_ref_frames) { |
| // forward_max_size_ define max number of arf frames that can exists at |
| // the same time. In the other words, it's the max size of forward_stack_. |
| // TODO(angiebird): Figure out if this number is optimal. |
| forward_max_size_ = ref_frame_table_size - 2; |
| cur_global_order_idx_ = 0; |
| Reset(); |
| } |
| ~RefFrameManager() = default; |
| |
| RefFrameManager(const RefFrameManager &) = delete; |
| RefFrameManager &operator=(const RefFrameManager &) = delete; |
| |
| friend std::ostream &operator<<(std::ostream &os, |
| const RefFrameManager &rfm) { |
| os << "=" << std::endl; |
| os << "forward: "; |
| for (const auto &ref_idx : rfm.forward_stack_) { |
| os << rfm.ref_frame_table_[ref_idx].order_idx << " "; |
| } |
| os << std::endl; |
| os << "backward: "; |
| for (const auto &ref_idx : rfm.backward_queue_) { |
| os << rfm.ref_frame_table_[ref_idx].order_idx << " "; |
| } |
| os << std::endl; |
| os << "last: "; |
| for (const auto &ref_idx : rfm.last_queue_) { |
| os << rfm.ref_frame_table_[ref_idx].order_idx << " "; |
| } |
| os << std::endl; |
| return os; |
| } |
| |
| void Reset(); |
| int AllocateRefIdx(); |
| int GetRefFrameCountByType(RefUpdateType ref_update_type) const; |
| int GetRefFrameCount() const; |
| std::vector<ReferenceFrame> GetRefFrameListByPriority() const; |
| int GetRefFrameIdxByPriority(RefUpdateType ref_update_type, |
| int priority_idx) const; |
| GopFrame GetRefFrameByPriority(RefUpdateType ref_update_type, |
| int priority_idx) const; |
| GopFrame GetRefFrameByIndex(int ref_idx) const; |
| void UpdateOrder(int global_order_idx); |
| int ColocatedRefIdx(int global_order_idx); |
| int ForwardMaxSize() const { return forward_max_size_; } |
| int MaxRefFrame() const { return max_ref_frames_; } |
| int CurGlobalOrderIdx() const { return cur_global_order_idx_; } |
| void UpdateRefFrameTable(GopFrame *gop_frame); |
| ReferenceFrame GetPrimaryRefFrame(const GopFrame &gop_frame) const; |
| |
| private: |
| int forward_max_size_; |
| int cur_global_order_idx_; |
| RefFrameTable ref_frame_table_; |
| int max_ref_frames_; |
| bool allow_two_fwd_frames_; |
| std::deque<int> free_ref_idx_list_; |
| std::vector<int> forward_stack_; |
| std::deque<int> backward_queue_; |
| std::deque<int> last_queue_; |
| }; |
| |
| } // namespace aom |
| |
| #endif // AOM_AV1_REFERENCE_MANAGER_H_ |