ref: f6a52bee7db6b54308fa080b84ebfe12977f6b45
parent: b7e9a463f88982505f938557bc9dcea1178b39c2
author: Jingning Han <jingning@google.com>
date: Thu Oct 11 08:16:01 EDT 2018
Refactor tpl model setup to support multi-layer ARF setup Generalize the tpl model framework to support the newly designed GOP structure system. The existing tpl model assumes single layer ARF. This design will separate the tpl model operation for GOP with and without ARF cases. When a GOP has ARF, the maximum lookahead offset would upper limit the needed frame buffer to build the tpl model for the entire GOP. When a GOP does not have ARF, we would use the temporal model in a different approach. The first step will focus on GOP with ARF. All the tpl model related operation will only be triggered by ARF frame generation. Change-Id: I13ab03a7bc68f5a4f6b03f2cb01c10befe955e73
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2359,7 +2359,8 @@
vp9_set_speed_features_framesize_dependent(cpi);
if (cpi->sf.enable_tpl_model) {
- for (frame = 0; frame < MAX_LAG_BUFFERS; ++frame) {
+ // TODO(jingning): Reduce the actual memory use for tpl model build up.
+ for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) {
int mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
int mi_rows = mi_cols_aligned_to_sb(cm->mi_rows);
@@ -2572,7 +2573,7 @@
vp9_denoiser_free(&(cpi->denoiser));
#endif
- for (frame = 0; frame < MAX_LAG_BUFFERS; ++frame) {
+ for (frame = 0; frame < MAX_ARF_GOP_SIZE; ++frame) {
vpx_free(cpi->tpl_stats[frame].tpl_stats_ptr);
cpi->tpl_stats[frame].is_valid = 0;
}
@@ -5361,12 +5362,14 @@
int pframe_qindex = cpi->tpl_stats[2].base_qindex;
RefCntBuffer *frame_bufs = cm->buffer_pool->frame_bufs;
- int recon_frame_index[REFS_PER_FRAME + 1] = { -1, -1, -1, -1 };
+ int8_t recon_frame_index[REFS_PER_FRAME + MAX_ARF_LAYERS];
+ memset(recon_frame_index, -1, sizeof(recon_frame_index));
+
// TODO(jingning): To be used later for gf frame type parsing.
(void)gf_group;
- for (i = 0; i < FRAME_BUFFERS && frame_idx < REFS_PER_FRAME + 1; ++i) {
+ for (i = 0; i < FRAME_BUFFERS; ++i) {
if (frame_bufs[i].ref_count == 0) {
alloc_frame_mvs(cm, i);
if (vpx_realloc_frame_buffer(&frame_bufs[i].buf, cm->width, cm->height,
@@ -5381,6 +5384,8 @@
recon_frame_index[frame_idx] = i;
++frame_idx;
+
+ if (frame_idx >= REFS_PER_FRAME + cpi->oxcf.enable_auto_arf) break;
}
}
@@ -5452,7 +5457,7 @@
void init_tpl_stats(VP9_COMP *cpi) {
int frame_idx;
- for (frame_idx = 0; frame_idx < MAX_LAG_BUFFERS; ++frame_idx) {
+ for (frame_idx = 0; frame_idx < MAX_ARF_GOP_SIZE; ++frame_idx) {
TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx];
memset(tpl_frame->tpl_stats_ptr, 0,
tpl_frame->height * tpl_frame->width *
@@ -6116,7 +6121,7 @@
#endif // CONFIG_NON_GREEDY_MV
static void setup_tpl_stats(VP9_COMP *cpi) {
- GF_PICTURE gf_picture[MAX_LAG_BUFFERS];
+ GF_PICTURE gf_picture[MAX_ARF_GOP_SIZE];
const GF_GROUP *gf_group = &cpi->twopass.gf_group;
int tpl_group_frames = 0;
int frame_idx;
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -495,6 +495,9 @@
struct scale_factors sf;
} ARNRFilterData;
+// Maximum operating frame buffer size needed for a GOP using ARF reference.
+#define MAX_ARF_GOP_SIZE (2 * MAX_LAG_BUFFERS)
+
typedef struct VP9_COMP {
QUANTS quants;
ThreadData td;
@@ -518,7 +521,7 @@
#endif
YV12_BUFFER_CONFIG *raw_source_frame;
- TplDepFrame tpl_stats[MAX_LAG_BUFFERS];
+ TplDepFrame tpl_stats[MAX_ARF_GOP_SIZE];
YV12_BUFFER_CONFIG *tpl_recon_frames[REFS_PER_FRAME + 1];
TileDataEnc *tile_data;