summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorJingning Han <jingning@google.com>2018-09-04 14:08:45 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-09-04 14:08:45 +0000
commitc19db84816775d07aeaa0f93fce71d2dd8758292 (patch)
tree6a01c8d06f13ea7e5131582c4a294553c859d287 /vp9
parent7a32bc8f3aa888516b3d355e7e72c8e0feca098c (diff)
parentfc905edb3a0f0330957094b2836ef8bf03573e04 (diff)
downloadlibvpx-c19db84816775d07aeaa0f93fce71d2dd8758292.tar
libvpx-c19db84816775d07aeaa0f93fce71d2dd8758292.tar.gz
libvpx-c19db84816775d07aeaa0f93fce71d2dd8758292.tar.bz2
libvpx-c19db84816775d07aeaa0f93fce71d2dd8758292.zip
Merge "Build arf index stack"
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_bitstream.c15
-rw-r--r--vp9/encoder/vp9_encoder.c27
-rw-r--r--vp9/encoder/vp9_encoder.h5
-rw-r--r--vp9/encoder/vp9_firstpass.h5
4 files changed, 50 insertions, 2 deletions
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 79fc160c1..21a68bf39 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -909,10 +909,25 @@ int vp9_get_refresh_mask(VP9_COMP *cpi) {
(cpi->refresh_golden_frame << cpi->alt_fb_idx);
} else {
int arf_idx = cpi->alt_fb_idx;
+ GF_GROUP *const gf_group = &cpi->twopass.gf_group;
if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
arf_idx = gf_group->arf_update_idx[gf_group->index];
}
+
+ if (cpi->multi_layer_arf) {
+ for (arf_idx = 0; arf_idx < REF_FRAMES; ++arf_idx) {
+ if (arf_idx != cpi->alt_fb_idx && arf_idx != cpi->lst_fb_idx &&
+ arf_idx != cpi->gld_fb_idx) {
+ int idx;
+ for (idx = 0; idx < gf_group->stack_size; ++idx)
+ if (arf_idx == gf_group->arf_index_stack[idx]) break;
+ if (idx == gf_group->stack_size) break;
+ }
+ }
+ }
+ cpi->twopass.gf_group.top_arf_idx = arf_idx;
+
if (cpi->use_svc && cpi->svc.use_set_ref_frame_config &&
cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS)
return cpi->svc.update_buffer_slot[cpi->svc.spatial_layer_id];
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index c4efd9954..7f9f2c5d5 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3169,6 +3169,15 @@ void update_multi_arf_ref_frames(VP9_COMP *cpi) {
void update_ref_frames(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
BufferPool *const pool = cm->buffer_pool;
+ GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+
+ // Pop ARF.
+ if (cm->show_existing_frame) {
+ cpi->lst_fb_idx = cpi->alt_fb_idx;
+ cpi->alt_fb_idx =
+ stack_pop(gf_group->arf_index_stack, gf_group->stack_size);
+ --gf_group->stack_size;
+ }
// At this point the new frame has been encoded.
// If any buffer copy / swapping is signaled it should be done here.
@@ -3196,16 +3205,25 @@ void update_ref_frames(VP9_COMP *cpi) {
cpi->gld_fb_idx = tmp;
} else { /* For non key/golden frames */
if (cpi->refresh_alt_ref_frame) {
- int arf_idx = cpi->alt_fb_idx;
+ int arf_idx = gf_group->top_arf_idx;
if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
arf_idx = gf_group->arf_update_idx[gf_group->index];
}
+ // Push new ARF into stack.
+ stack_push(gf_group->arf_index_stack, cpi->alt_fb_idx,
+ gf_group->stack_size);
+ ++gf_group->stack_size;
+
+ assert(arf_idx < REF_FRAMES);
+
ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
memcpy(cpi->interp_filter_selected[ALTREF_FRAME],
cpi->interp_filter_selected[0],
sizeof(cpi->interp_filter_selected[0]));
+
+ cpi->alt_fb_idx = arf_idx;
}
if (cpi->refresh_golden_frame) {
@@ -6091,9 +6109,14 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
}
}
+ // Clear arf index stack before group of pictures processing starts.
+ if (cpi->twopass.gf_group.index == 1) {
+ stack_init(cpi->twopass.gf_group.arf_index_stack, MAX_LAG_BUFFERS * 2);
+ cpi->twopass.gf_group.stack_size = 0;
+ }
+
if (arf_src_index) {
assert(arf_src_index <= rc->frames_to_key);
-
if ((source = vp9_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) {
cpi->alt_ref_source = source;
diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h
index 9adcb4522..446e030ba 100644
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -834,6 +834,11 @@ static INLINE void stack_push(int *stack, int new_item, int stack_size) {
stack[0] = new_item;
}
+static INLINE void stack_init(int *stack, int length) {
+ int idx;
+ for (idx = 0; idx < length; ++idx) stack[idx] = -1;
+}
+
int vp9_get_quantizer(struct VP9_COMP *cpi);
static INLINE int frame_is_kf_gf_arf(const VP9_COMP *cpi) {
diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h
index 0a7e1adf7..e1c882df4 100644
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -143,6 +143,11 @@ typedef struct {
unsigned char brf_src_offset[MAX_STATIC_GF_GROUP_LENGTH + 2];
unsigned char bidir_pred_enabled[MAX_STATIC_GF_GROUP_LENGTH + 2];
int bit_allocation[MAX_STATIC_GF_GROUP_LENGTH + 2];
+
+ // TODO(jingning): The array size of arf_stack could be reduced.
+ int arf_index_stack[MAX_LAG_BUFFERS * 2];
+ int top_arf_idx;
+ int stack_size;
} GF_GROUP;
typedef struct {