blob: 951d65d286f4c87f663773a7246eeca9be4854db [file] [log] [blame]
/*
* 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_