Merge "Fix typos" into nextgenv2
diff --git a/av1/common/common_data.h b/av1/common/common_data.h
index 4165e35..5b72b81 100644
--- a/av1/common/common_data.h
+++ b/av1/common/common_data.h
@@ -859,4 +859,8 @@
} // extern "C"
#endif
+static const int tx_size_1d[TX_SIZES] = { 4, 8, 16, 32 };
+
+static const int tx_size_2d[TX_SIZES] = { 16, 64, 256, 1024 };
+
#endif // AV1_COMMON_COMMON_DATA_H_
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index d0ad807..85c68e1 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -41,6 +41,12 @@
struct AV1Common;
+typedef struct {
+ const int16_t *scan;
+ const int16_t *iscan;
+ const int16_t *neighbors;
+} SCAN_ORDER;
+
struct seg_counts {
unsigned int tree_total[MAX_SEGMENTS];
unsigned int tree_mispred[MAX_SEGMENTS];
@@ -62,6 +68,31 @@
aom_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS]
[SWITCHABLE_FILTERS - 1];
+#if CONFIG_ADAPT_SCAN
+ // TODO(angiebird): try aom_prob
+ uint32_t non_zero_prob_4X4[TX_TYPES][16];
+ uint32_t non_zero_prob_8X8[TX_TYPES][64];
+ uint32_t non_zero_prob_16X16[TX_TYPES][256];
+ uint32_t non_zero_prob_32X32[TX_TYPES][1024];
+
+ DECLARE_ALIGNED(16, int16_t, scan_4X4[TX_TYPES][16]);
+ DECLARE_ALIGNED(16, int16_t, scan_8X8[TX_TYPES][64]);
+ DECLARE_ALIGNED(16, int16_t, scan_16X16[TX_TYPES][256]);
+ DECLARE_ALIGNED(16, int16_t, scan_32X32[TX_TYPES][1024]);
+
+ DECLARE_ALIGNED(16, int16_t, iscan_4X4[TX_TYPES][16]);
+ DECLARE_ALIGNED(16, int16_t, iscan_8X8[TX_TYPES][64]);
+ DECLARE_ALIGNED(16, int16_t, iscan_16X16[TX_TYPES][256]);
+ DECLARE_ALIGNED(16, int16_t, iscan_32X32[TX_TYPES][1024]);
+
+ int16_t nb_4X4[TX_TYPES][(16 + 1) * 2];
+ int16_t nb_8X8[TX_TYPES][(64 + 1) * 2];
+ int16_t nb_16X16[TX_TYPES][(256 + 1) * 2];
+ int16_t nb_32X32[TX_TYPES][(1024 + 1) * 2];
+
+ SCAN_ORDER sc[TX_SIZES][TX_TYPES];
+#endif // CONFIG_ADAPT_SCAN
+
#if CONFIG_REF_MV
aom_prob newmv_prob[NEWMV_MODE_CONTEXTS];
aom_prob zeromv_prob[ZEROMV_MODE_CONTEXTS];
@@ -161,6 +192,14 @@
[COEFF_CONTEXTS];
unsigned int switchable_interp[SWITCHABLE_FILTER_CONTEXTS]
[SWITCHABLE_FILTERS];
+#if CONFIG_ADAPT_SCAN
+ unsigned int non_zero_count_4X4[TX_TYPES][16];
+ unsigned int non_zero_count_8X8[TX_TYPES][64];
+ unsigned int non_zero_count_16X16[TX_TYPES][256];
+ unsigned int non_zero_count_32X32[TX_TYPES][1024];
+ unsigned int txb_count[TX_SIZES][TX_TYPES];
+#endif
+
#if CONFIG_REF_MV
unsigned int newmv_mode[NEWMV_MODE_CONTEXTS][2];
unsigned int zeromv_mode[ZEROMV_MODE_CONTEXTS][2];
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index bbcedc4..afc9da4 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -195,13 +195,6 @@
int new_fb_idx;
FRAME_TYPE last_frame_type; /* last frame's frame type for motion search.*/
-#if CONFIG_EXT_REFS
- // frame type of the frame before last frame
- FRAME_TYPE last2_frame_type;
- // TODO(zoeliu): To check whether last3_frame_type is still needed.
- // frame type of the frame two frames before last frame
- FRAME_TYPE last3_frame_type;
-#endif // CONFIG_EXT_REFS
FRAME_TYPE frame_type;
int show_frame;
diff --git a/av1/common/pred_common.c b/av1/common/pred_common.c
index 5d8cad0..35067f2 100644
--- a/av1/common/pred_common.c
+++ b/av1/common/pred_common.c
@@ -167,101 +167,60 @@
}
#if CONFIG_EXT_REFS
-
-#define CHECK_BWDREF_OR_ALTREF(ref_frame) \
- (((ref_frame) == BWDREF_FRAME) || ((ref_frame) == ALTREF_FRAME))
-
-int av1_get_reference_mode_context(const AV1_COMMON *cm,
- const MACROBLOCKD *xd) {
- int ctx;
- const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
- const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
- const int has_above = xd->up_available;
- const int has_left = xd->left_available;
-
- (void)cm;
-
- // Note:
- // The mode info data structure has a one element border above and to the
- // left of the entries corresponding to real macroblocks.
- // The prediction flags in these dummy entries are initialized to 0.
- if (has_above && has_left) { // both edges available
- if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi))
- // neither edge uses comp pred (0/1)
- ctx = CHECK_BWDREF_OR_ALTREF(above_mbmi->ref_frame[0]) ^
- CHECK_BWDREF_OR_ALTREF(left_mbmi->ref_frame[0]);
- else if (!has_second_ref(above_mbmi))
- // one of two edges uses comp pred (2/3)
- ctx = 2 + (CHECK_BWDREF_OR_ALTREF(above_mbmi->ref_frame[0]) ||
- !is_inter_block(above_mbmi));
- else if (!has_second_ref(left_mbmi))
- // one of two edges uses comp pred (2/3)
- ctx = 2 + (CHECK_BWDREF_OR_ALTREF(left_mbmi->ref_frame[0]) ||
- !is_inter_block(left_mbmi));
- else // both edges use comp pred (4)
- ctx = 4;
- } else if (has_above || has_left) { // one edge available
- const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
-
- if (!has_second_ref(edge_mbmi))
- // edge does not use comp pred (0/1)
- ctx = CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]);
- else
- // edge uses comp pred (3)
- ctx = 3;
- } else { // no edges available (1)
- ctx = 1;
- }
- assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS);
- return ctx;
-}
-
-#else // CONFIG_EXT_REFS
-
-int av1_get_reference_mode_context(const AV1_COMMON *cm,
- const MACROBLOCKD *xd) {
- int ctx;
- const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
- const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
- const int has_above = xd->up_available;
- const int has_left = xd->left_available;
- // Note:
- // The mode info data structure has a one element border above and to the
- // left of the entries corresponding to real macroblocks.
- // The prediction flags in these dummy entries are initialized to 0.
- if (has_above && has_left) { // both edges available
- if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi))
- // neither edge uses comp pred (0/1)
- ctx = (above_mbmi->ref_frame[0] == cm->comp_fixed_ref) ^
- (left_mbmi->ref_frame[0] == cm->comp_fixed_ref);
- else if (!has_second_ref(above_mbmi))
- // one of two edges uses comp pred (2/3)
- ctx = 2 + (above_mbmi->ref_frame[0] == cm->comp_fixed_ref ||
- !is_inter_block(above_mbmi));
- else if (!has_second_ref(left_mbmi))
- // one of two edges uses comp pred (2/3)
- ctx = 2 + (left_mbmi->ref_frame[0] == cm->comp_fixed_ref ||
- !is_inter_block(left_mbmi));
- else // both edges use comp pred (4)
- ctx = 4;
- } else if (has_above || has_left) { // one edge available
- const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
-
- if (!has_second_ref(edge_mbmi))
- // edge does not use comp pred (0/1)
- ctx = edge_mbmi->ref_frame[0] == cm->comp_fixed_ref;
- else
- // edge uses comp pred (3)
- ctx = 3;
- } else { // no edges available (1)
- ctx = 1;
- }
- assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS);
- return ctx;
-}
-
+#define CHECK_BACKWARD_REFS(ref_frame) \
+ (((ref_frame) >= BWDREF_FRAME) && ((ref_frame) <= ALTREF_FRAME))
+#define IS_BACKWARD_REF_FRAME(ref_frame) CHECK_BACKWARD_REFS(ref_frame)
+#else
+#define IS_BACKWARD_REF_FRAME(ref_frame) ((ref_frame) == cm->comp_fixed_ref)
#endif // CONFIG_EXT_REFS
+int av1_get_reference_mode_context(const AV1_COMMON *cm,
+ const MACROBLOCKD *xd) {
+ int ctx;
+ const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
+ const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
+ const int has_above = xd->up_available;
+ const int has_left = xd->left_available;
+
+#if CONFIG_EXT_REFS
+ (void)cm;
+#endif // CONFIG_EXT_REFS
+
+ // Note:
+ // The mode info data structure has a one element border above and to the
+ // left of the entries corresponding to real macroblocks.
+ // The prediction flags in these dummy entries are initialized to 0.
+ if (has_above && has_left) { // both edges available
+ if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi))
+ // neither edge uses comp pred (0/1)
+ ctx = IS_BACKWARD_REF_FRAME(above_mbmi->ref_frame[0]) ^
+ IS_BACKWARD_REF_FRAME(left_mbmi->ref_frame[0]);
+ else if (!has_second_ref(above_mbmi))
+ // one of two edges uses comp pred (2/3)
+ ctx = 2 + (IS_BACKWARD_REF_FRAME(above_mbmi->ref_frame[0]) ||
+ !is_inter_block(above_mbmi));
+ else if (!has_second_ref(left_mbmi))
+ // one of two edges uses comp pred (2/3)
+ ctx = 2 + (IS_BACKWARD_REF_FRAME(left_mbmi->ref_frame[0]) ||
+ !is_inter_block(left_mbmi));
+ else // both edges use comp pred (4)
+ ctx = 4;
+ } else if (has_above || has_left) { // one edge available
+ const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
+
+ if (!has_second_ref(edge_mbmi))
+ // edge does not use comp pred (0/1)
+ ctx = IS_BACKWARD_REF_FRAME(edge_mbmi->ref_frame[0]);
+ else
+ // edge uses comp pred (3)
+ ctx = 3;
+ } else { // no edges available (1)
+ ctx = 1;
+ }
+ assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS);
+ return ctx;
+}
+
#if CONFIG_EXT_REFS
// TODO(zoeliu): Future work will be conducted to optimize the context design
@@ -323,8 +282,8 @@
if (frfa == frfl && CHECK_GOLDEN_OR_LAST3(frfa)) {
pred_context = 0;
} else if (l_sg && a_sg) { // single/single
- if ((CHECK_BWDREF_OR_ALTREF(frfa) && CHECK_LAST_OR_LAST2(frfl)) ||
- (CHECK_BWDREF_OR_ALTREF(frfl) && CHECK_LAST_OR_LAST2(frfa))) {
+ if ((CHECK_BACKWARD_REFS(frfa) && CHECK_LAST_OR_LAST2(frfl)) ||
+ (CHECK_BACKWARD_REFS(frfl) && CHECK_LAST_OR_LAST2(frfa))) {
pred_context = 4;
} else if (CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl)) {
pred_context = 1;
@@ -426,7 +385,7 @@
else if (CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl))
pred_context = 2 + (frfa != frfl);
else if (frfa == frfl ||
- (CHECK_BWDREF_OR_ALTREF(frfa) && CHECK_BWDREF_OR_ALTREF(frfl)))
+ (CHECK_BACKWARD_REFS(frfa) && CHECK_BACKWARD_REFS(frfl)))
pred_context = 3;
else
pred_context = 4;
@@ -527,7 +486,7 @@
else if (CHECK_LAST_OR_LAST2(frfa) || CHECK_LAST_OR_LAST2(frfl))
pred_context = 2 + (frfa != frfl);
else if (frfa == frfl ||
- (CHECK_BWDREF_OR_ALTREF(frfa) && CHECK_BWDREF_OR_ALTREF(frfl)))
+ (CHECK_BACKWARD_REFS(frfa) && CHECK_BACKWARD_REFS(frfl)))
pred_context = 3;
else
pred_context = 4;
@@ -798,10 +757,10 @@
const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
if (!has_second_ref(edge_mbmi))
- pred_context = 4 * (!CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]));
+ pred_context = 4 * (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]));
else
- pred_context = 1 + (!CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]) ||
- !CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[1]));
+ pred_context = 1 + (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]) ||
+ !CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[1]));
} else { // inter/inter
const int above_has_second = has_second_ref(above_mbmi);
const int left_has_second = has_second_ref(left_mbmi);
@@ -812,24 +771,23 @@
const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
if (above_has_second && left_has_second) {
- pred_context = 1 + (!CHECK_BWDREF_OR_ALTREF(above0) ||
- !CHECK_BWDREF_OR_ALTREF(above1) ||
- !CHECK_BWDREF_OR_ALTREF(left0) ||
- !CHECK_BWDREF_OR_ALTREF(left1));
+ pred_context =
+ 1 + (!CHECK_BACKWARD_REFS(above0) || !CHECK_BACKWARD_REFS(above1) ||
+ !CHECK_BACKWARD_REFS(left0) || !CHECK_BACKWARD_REFS(left1));
} else if (above_has_second || left_has_second) {
const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
- if (!CHECK_BWDREF_OR_ALTREF(rfs))
- pred_context = 3 + (!CHECK_BWDREF_OR_ALTREF(crf1) ||
- !CHECK_BWDREF_OR_ALTREF(crf2));
+ if (!CHECK_BACKWARD_REFS(rfs))
+ pred_context =
+ 3 + (!CHECK_BACKWARD_REFS(crf1) || !CHECK_BACKWARD_REFS(crf2));
else
pred_context =
- !CHECK_BWDREF_OR_ALTREF(crf1) || !CHECK_BWDREF_OR_ALTREF(crf2);
+ !CHECK_BACKWARD_REFS(crf1) || !CHECK_BACKWARD_REFS(crf2);
} else {
- pred_context = 2 * (!CHECK_BWDREF_OR_ALTREF(above0)) +
- 2 * (!CHECK_BWDREF_OR_ALTREF(left0));
+ pred_context = 2 * (!CHECK_BACKWARD_REFS(above0)) +
+ 2 * (!CHECK_BACKWARD_REFS(left0));
}
}
} else if (has_above || has_left) { // one edge available
@@ -838,10 +796,10 @@
pred_context = 2;
} else { // inter
if (!has_second_ref(edge_mbmi))
- pred_context = 4 * (!CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]));
+ pred_context = 4 * (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]));
else
- pred_context = 1 + (!CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]) ||
- !CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[1]));
+ pred_context = 1 + (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]) ||
+ !CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[1]));
}
} else { // no edges available
pred_context = 2;
@@ -876,7 +834,7 @@
} else if (above_intra || left_intra) { // intra/inter or inter/intra
const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
if (!has_second_ref(edge_mbmi)) {
- if (!CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]))
+ if (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]))
pred_context = 3;
else
pred_context = 4 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME);
@@ -912,12 +870,12 @@
else
pred_context = 1 + 2 * (crf1 == BWDREF_FRAME || crf2 == BWDREF_FRAME);
} else {
- if (!CHECK_BWDREF_OR_ALTREF(above0) && !CHECK_BWDREF_OR_ALTREF(left0)) {
+ if (!CHECK_BACKWARD_REFS(above0) && !CHECK_BACKWARD_REFS(left0)) {
pred_context = 2 + (above0 == left0);
- } else if (!CHECK_BWDREF_OR_ALTREF(above0) ||
- !CHECK_BWDREF_OR_ALTREF(left0)) {
+ } else if (!CHECK_BACKWARD_REFS(above0) ||
+ !CHECK_BACKWARD_REFS(left0)) {
const MV_REFERENCE_FRAME edge0 =
- !CHECK_BWDREF_OR_ALTREF(above0) ? left0 : above0;
+ !CHECK_BACKWARD_REFS(above0) ? left0 : above0;
pred_context = 4 * (edge0 == BWDREF_FRAME);
} else {
pred_context =
@@ -929,7 +887,7 @@
const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
if (!is_inter_block(edge_mbmi) ||
- (!CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]) &&
+ (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]) &&
!has_second_ref(edge_mbmi)))
pred_context = 2;
else if (!has_second_ref(edge_mbmi))
@@ -970,7 +928,7 @@
} else if (above_intra || left_intra) { // intra/inter or inter/intra
const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
if (!has_second_ref(edge_mbmi)) {
- if (CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]))
+ if (CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]))
pred_context = 3;
else
pred_context = 4 * CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
@@ -1009,12 +967,11 @@
pred_context =
1 + 2 * (CHECK_LAST_OR_LAST2(crf1) || CHECK_LAST_OR_LAST2(crf2));
} else {
- if (CHECK_BWDREF_OR_ALTREF(above0) && CHECK_BWDREF_OR_ALTREF(left0)) {
+ if (CHECK_BACKWARD_REFS(above0) && CHECK_BACKWARD_REFS(left0)) {
pred_context = 2 + (above0 == left0);
- } else if (CHECK_BWDREF_OR_ALTREF(above0) ||
- CHECK_BWDREF_OR_ALTREF(left0)) {
+ } else if (CHECK_BACKWARD_REFS(above0) || CHECK_BACKWARD_REFS(left0)) {
const MV_REFERENCE_FRAME edge0 =
- CHECK_BWDREF_OR_ALTREF(above0) ? left0 : above0;
+ CHECK_BACKWARD_REFS(above0) ? left0 : above0;
pred_context = 4 * CHECK_LAST_OR_LAST2(edge0);
} else {
pred_context =
@@ -1026,7 +983,7 @@
const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
if (!is_inter_block(edge_mbmi) ||
- (CHECK_BWDREF_OR_ALTREF(edge_mbmi->ref_frame[0]) &&
+ (CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]) &&
!has_second_ref(edge_mbmi)))
pred_context = 2;
else if (!has_second_ref(edge_mbmi))
diff --git a/av1/common/pred_common.h b/av1/common/pred_common.h
index 6b0a3d5..b3ef1c4 100644
--- a/av1/common/pred_common.h
+++ b/av1/common/pred_common.h
@@ -127,7 +127,6 @@
const int pred_context = av1_get_pred_context_comp_bwdref_p(cm, xd);
return cm->fc->comp_bwdref_prob[pred_context][0];
}
-
#endif // CONFIG_EXT_REFS
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
diff --git a/av1/common/scan.c b/av1/common/scan.c
index 919fe8c..945c65e 100644
--- a/av1/common/scan.c
+++ b/av1/common/scan.c
@@ -11,6 +11,7 @@
#include <assert.h>
+#include "av1/common/common_data.h"
#include "av1/common/scan.h"
DECLARE_ALIGNED(16, static const int16_t, default_scan_4x4[16]) = {
@@ -4166,3 +4167,239 @@
}
};
#endif // CONFIG_EXT_TX
+
+#if CONFIG_ADAPT_SCAN
+// TX_32X32 will has 1024 coefficients whose indexes can be represented in 10
+// bits
+#define COEFF_IDX_BITS 10
+#define COEFF_IDX_SIZE (1 << COEFF_IDX_BITS)
+#define COEFF_IDX_MASK (COEFF_IDX_SIZE - 1)
+
+static uint32_t *get_non_zero_prob(FRAME_CONTEXT *fc, TX_SIZE tx_size,
+ TX_TYPE tx_type) {
+ switch (tx_size) {
+ case TX_4X4: return fc->non_zero_prob_4X4[tx_type];
+ case TX_8X8: return fc->non_zero_prob_8X8[tx_type];
+ case TX_16X16: return fc->non_zero_prob_16X16[tx_type];
+ case TX_32X32: return fc->non_zero_prob_32X32[tx_type];
+ default: assert(0); return NULL;
+ }
+}
+
+static int16_t *get_adapt_scan(FRAME_CONTEXT *fc, TX_SIZE tx_size,
+ TX_TYPE tx_type) {
+ switch (tx_size) {
+ case TX_4X4: return fc->scan_4X4[tx_type];
+ case TX_8X8: return fc->scan_8X8[tx_type];
+ case TX_16X16: return fc->scan_16X16[tx_type];
+ case TX_32X32: return fc->scan_32X32[tx_type];
+ default: assert(0); return NULL;
+ }
+}
+
+static int16_t *get_adapt_iscan(FRAME_CONTEXT *fc, TX_SIZE tx_size,
+ TX_TYPE tx_type) {
+ switch (tx_size) {
+ case TX_4X4: return fc->iscan_4X4[tx_type];
+ case TX_8X8: return fc->iscan_8X8[tx_type];
+ case TX_16X16: return fc->iscan_16X16[tx_type];
+ case TX_32X32: return fc->iscan_32X32[tx_type];
+ default: assert(0); return NULL;
+ }
+}
+
+static int16_t *get_adapt_nb(FRAME_CONTEXT *fc, TX_SIZE tx_size,
+ TX_TYPE tx_type) {
+ switch (tx_size) {
+ case TX_4X4: return fc->nb_4X4[tx_type];
+ case TX_8X8: return fc->nb_8X8[tx_type];
+ case TX_16X16: return fc->nb_16X16[tx_type];
+ case TX_32X32: return fc->nb_32X32[tx_type];
+ default: assert(0); return NULL;
+ }
+}
+
+static uint32_t *get_non_zero_counts(FRAME_COUNTS *counts, TX_SIZE tx_size,
+ TX_TYPE tx_type) {
+ switch (tx_size) {
+ case TX_4X4: return counts->non_zero_count_4X4[tx_type];
+ case TX_8X8: return counts->non_zero_count_8X8[tx_type];
+ case TX_16X16: return counts->non_zero_count_16X16[tx_type];
+ case TX_32X32: return counts->non_zero_count_32X32[tx_type];
+ default: assert(0); return NULL;
+ }
+}
+
+void av1_update_scan_prob(AV1_COMMON *cm, TX_SIZE tx_size, TX_TYPE tx_type,
+ int rate_16) {
+ FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx];
+ uint32_t *prev_non_zero_prob = get_non_zero_prob(pre_fc, tx_size, tx_type);
+ uint32_t *non_zero_prob = get_non_zero_prob(cm->fc, tx_size, tx_type);
+ uint32_t *non_zero_count = get_non_zero_counts(&cm->counts, tx_size, tx_type);
+ const int tx2d_size = tx_size_2d[tx_size];
+ unsigned int block_num = cm->counts.txb_count[tx_size][tx_type];
+ int i;
+ for (i = 0; i < tx2d_size; i++) {
+ int64_t curr_prob =
+ block_num == 0 ? 0 : (non_zero_count[i] << 16) / block_num;
+ int64_t prev_prob = prev_non_zero_prob[i];
+ int64_t pred_prob =
+ (curr_prob * rate_16 + prev_prob * ((1 << 16) - rate_16)) >> 16;
+ non_zero_prob[i] = clamp(pred_prob, 0, UINT16_MAX);
+ }
+}
+
+static void update_scan_count(int16_t *scan, int max_scan,
+ const tran_low_t *dqcoeffs,
+ uint32_t *non_zero_count) {
+ int i;
+ for (i = 0; i < max_scan; ++i) {
+ int coeff_idx = scan[i];
+ non_zero_count[coeff_idx] += (dqcoeffs[coeff_idx] != 0);
+ }
+}
+
+void av1_update_scan_count_facade(AV1_COMMON *cm, TX_SIZE tx_size,
+ TX_TYPE tx_type, const tran_low_t *dqcoeffs,
+ int max_scan) {
+ int16_t *scan = get_adapt_scan(cm->fc, tx_size, tx_type);
+ uint32_t *non_zero_count = get_non_zero_counts(&cm->counts, tx_size, tx_type);
+ update_scan_count(scan, max_scan, dqcoeffs, non_zero_count);
+ ++cm->counts.txb_count[tx_size][tx_type];
+}
+
+static int cmp_prob(const void *a, const void *b) {
+ return *(const uint32_t *)b > *(const uint32_t *)a ? 1 : -1;
+}
+
+void av1_augment_prob(uint32_t *prob, int size, int tx1d_size) {
+ int r, c;
+ for (r = 0; r < size; r++) {
+ for (c = 0; c < size; c++) {
+ const int coeff_idx = r * tx1d_size + c;
+ const int idx = r * size + c;
+ const uint32_t mask_16 = ((1 << 16) - 1);
+ const uint32_t tie_breaker = ~(((r + c) << COEFF_IDX_BITS) | coeff_idx);
+ // prob[idx]: 16 bits r+c: 6 bits coeff_idx: 10 bits
+ prob[idx] = (prob[idx] << 16) | (mask_16 & tie_breaker);
+ }
+ }
+}
+
+// topological sort
+static void dfs_scan(int tx1d_size, int *scan_idx, int coeff_idx, int16_t *scan,
+ int16_t *iscan) {
+ const int r = coeff_idx / tx1d_size;
+ const int c = coeff_idx % tx1d_size;
+
+ if (iscan[coeff_idx] != -1) return;
+
+ if (r > 0) dfs_scan(tx1d_size, scan_idx, coeff_idx - tx1d_size, scan, iscan);
+
+ if (c > 0) dfs_scan(tx1d_size, scan_idx, coeff_idx - 1, scan, iscan);
+
+ scan[*scan_idx] = coeff_idx;
+ iscan[coeff_idx] = *scan_idx;
+ ++(*scan_idx);
+}
+
+void av1_update_neighbors(int tx_size, const int16_t *scan,
+ const int16_t *iscan, int16_t *neighbors) {
+ const int tx1d_size = tx_size_1d[tx_size];
+ const int tx2d_size = tx_size_2d[tx_size];
+ int scan_idx;
+ for (scan_idx = 0; scan_idx < tx2d_size; ++scan_idx) {
+ const int coeff_idx = scan[scan_idx];
+ const int r = coeff_idx / tx1d_size;
+ const int c = coeff_idx % tx1d_size;
+ const int has_left = c > 0 && iscan[coeff_idx - 1] < scan_idx;
+ const int has_above = r > 0 && iscan[coeff_idx - tx1d_size] < scan_idx;
+
+ if (has_left && has_above) {
+ neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - 1;
+ neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - tx1d_size;
+ } else if (has_left) {
+ neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - 1;
+ neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - 1;
+ } else if (has_above) {
+ neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - tx1d_size;
+ neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - tx1d_size;
+ } else {
+ neighbors[scan_idx * MAX_NEIGHBORS + 0] = scan[0];
+ neighbors[scan_idx * MAX_NEIGHBORS + 1] = scan[0];
+ }
+ }
+ neighbors[tx2d_size * MAX_NEIGHBORS + 0] = scan[0];
+ neighbors[tx2d_size * MAX_NEIGHBORS + 1] = scan[0];
+}
+
+void av1_update_sort_order(TX_SIZE tx_size, const uint32_t *non_zero_prob,
+ int16_t *sort_order) {
+ uint32_t temp[COEFF_IDX_SIZE];
+ const int tx1d_size = tx_size_1d[tx_size];
+ const int tx2d_size = tx_size_2d[tx_size];
+ int sort_idx;
+ assert(tx2d_size <= COEFF_IDX_SIZE);
+ memcpy(temp, non_zero_prob, tx2d_size * sizeof(*non_zero_prob));
+ av1_augment_prob(temp, tx1d_size, tx1d_size);
+ qsort(temp, tx2d_size, sizeof(*temp), cmp_prob);
+ for (sort_idx = 0; sort_idx < tx2d_size; ++sort_idx) {
+ const int coeff_idx = (temp[sort_idx] & COEFF_IDX_MASK) ^ COEFF_IDX_MASK;
+ sort_order[sort_idx] = coeff_idx;
+ }
+}
+
+void av1_update_scan_order(TX_SIZE tx_size, int16_t *sort_order, int16_t *scan,
+ int16_t *iscan) {
+ int coeff_idx;
+ int scan_idx;
+ int sort_idx;
+ const int tx1d_size = tx_size_1d[tx_size];
+ const int tx2d_size = tx_size_2d[tx_size];
+
+ for (coeff_idx = 0; coeff_idx < tx2d_size; ++coeff_idx) {
+ iscan[coeff_idx] = -1;
+ }
+
+ scan_idx = 0;
+ for (sort_idx = 0; sort_idx < tx2d_size; ++sort_idx) {
+ coeff_idx = sort_order[sort_idx];
+ dfs_scan(tx1d_size, &scan_idx, coeff_idx, scan, iscan);
+ }
+}
+
+void av1_update_scan_order_facade(AV1_COMMON *cm, TX_SIZE tx_size,
+ TX_TYPE tx_type) {
+ int16_t sort_order[1024];
+ uint32_t *non_zero_prob = get_non_zero_prob(cm->fc, tx_size, tx_type);
+ int16_t *scan = get_adapt_scan(cm->fc, tx_size, tx_type);
+ int16_t *iscan = get_adapt_iscan(cm->fc, tx_size, tx_type);
+ int16_t *nb = get_adapt_nb(cm->fc, tx_size, tx_type);
+ const int tx2d_size = tx_size_2d[tx_size];
+ assert(tx2d_size <= 1024);
+ av1_update_sort_order(tx_size, non_zero_prob, sort_order);
+ av1_update_scan_order(tx_size, sort_order, scan, iscan);
+ av1_update_neighbors(tx_size, scan, iscan, nb);
+}
+
+void av1_init_scan_order(AV1_COMMON *cm) {
+ TX_SIZE tx_size;
+ TX_TYPE tx_type;
+ for (tx_size = TX_4X4; tx_size < TX_SIZES; ++tx_size) {
+ for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
+ uint32_t *non_zero_prob = get_non_zero_prob(cm->fc, tx_size, tx_type);
+ const int tx2d_size = tx_size_2d[tx_size];
+ int i;
+ SCAN_ORDER *sc = &cm->fc->sc[tx_size][tx_type];
+ for (i = 0; i < tx2d_size; ++i) {
+ non_zero_prob[i] = (1 << 16) / 2; // init non_zero_prob to 0.5
+ }
+ av1_update_scan_order_facade(cm, tx_size, tx_type);
+ sc->scan = get_adapt_scan(cm->fc, tx_size, tx_type);
+ sc->iscan = get_adapt_iscan(cm->fc, tx_size, tx_type);
+ sc->neighbors = get_adapt_nb(cm->fc, tx_size, tx_type);
+ }
+ }
+}
+
+#endif // CONFIG_ADAPT_SCAN
diff --git a/av1/common/scan.h b/av1/common/scan.h
index c183ba9..7b6698f 100644
--- a/av1/common/scan.h
+++ b/av1/common/scan.h
@@ -16,6 +16,7 @@
#include "aom_ports/mem.h"
#include "av1/common/enums.h"
+#include "av1/common/onyxc_int.h"
#include "av1/common/blockd.h"
#ifdef __cplusplus
@@ -24,15 +25,40 @@
#define MAX_NEIGHBORS 2
-typedef struct {
- const int16_t *scan;
- const int16_t *iscan;
- const int16_t *neighbors;
-} SCAN_ORDER;
-
extern const SCAN_ORDER av1_default_scan_orders[TX_SIZES];
extern const SCAN_ORDER av1_intra_scan_orders[TX_SIZES][TX_TYPES];
+#if CONFIG_ADAPT_SCAN
+void av1_update_scan_prob(AV1_COMMON *cm, TX_SIZE tx_size, TX_TYPE tx_type,
+ int rate_16);
+void av1_update_scan_count_facade(AV1_COMMON *cm, TX_SIZE tx_size,
+ TX_TYPE tx_type, const tran_low_t *dqcoeffs,
+ int max_scan);
+
+// embed r + c and coeff_idx info with nonzero probabilities. When sorting the
+// nonzero probabilities, if there is a tie, the coefficient with smaller r + c
+// will be scanned first
+void av1_augment_prob(uint32_t *prob, int size, int tx1d_size);
+
+// apply quick sort on nonzero probabilities to obtain a sort order
+void av1_update_sort_order(TX_SIZE tx_size, const uint32_t *non_zero_prob,
+ int16_t *sort_order);
+
+// apply topological sort on the nonzero probabilities sorting order to
+// guarantee each to-be-scanned coefficient's upper and left coefficient will be
+// scanned before the to-be-scanned coefficient.
+void av1_update_scan_order(TX_SIZE tx_size, int16_t *sort_order, int16_t *scan,
+ int16_t *iscan);
+
+// For each coeff_idx in scan[], update its above and left neighbors in
+// neighbors[] accordingly.
+void av1_update_neighbors(int tx_size, const int16_t *scan,
+ const int16_t *iscan, int16_t *neighbors);
+void av1_update_scan_order_facade(AV1_COMMON *cm, TX_SIZE tx_size,
+ TX_TYPE tx_type);
+void av1_init_scan_order(AV1_COMMON *cm);
+#endif
+
static INLINE int get_coef_context(const int16_t *neighbors,
const uint8_t *token_cache, int c) {
return (1 + token_cache[neighbors[MAX_NEIGHBORS * c + 0]] +
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index b202802..7d69d78 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3254,10 +3254,6 @@
RefCntBuffer *const frame_bufs = pool->frame_bufs;
int i, mask, ref_index = 0;
size_t sz;
-#if CONFIG_EXT_REFS
- cm->last3_frame_type = cm->last2_frame_type;
- cm->last2_frame_type = cm->last_frame_type;
-#endif // CONFIG_EXT_REFS
cm->last_frame_type = cm->frame_type;
cm->last_intra_only = cm->intra_only;
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index aa3ea71..7068604 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2500,8 +2500,6 @@
#if CONFIG_ENTROPY
AV1_COMMON *cm = &cpi->common;
SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
- unsigned int eob_counts_copy[TX_SIZES][PLANE_TYPES][REF_TYPES][COEF_BANDS]
- [COEFF_CONTEXTS];
int i;
av1_coeff_probs_model dummy_frame_coef_probs[PLANE_TYPES];
@@ -2526,8 +2524,10 @@
#if CONFIG_ENTROPY
if (cm->do_subframe_update &&
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
+ unsigned int this_eob_counts_copy[PLANE_TYPES][REF_TYPES][COEF_BANDS]
+ [COEFF_CONTEXTS];
av1_coeff_count coef_counts_copy[PLANE_TYPES];
- av1_copy(eob_counts_copy, cpi->common.counts.eob_branch[tx_size]);
+ av1_copy(this_eob_counts_copy, cpi->common.counts.eob_branch[tx_size]);
av1_copy(coef_counts_copy, cpi->td.rd_counts.coef_counts[tx_size]);
build_tree_distribution(cpi, tx_size, frame_branch_ct,
frame_coef_probs);
@@ -2539,7 +2539,7 @@
build_tree_distribution(cpi, tx_size, cpi->branch_ct_buf[i][tx_size],
dummy_frame_coef_probs);
}
- av1_copy(cpi->common.counts.eob_branch[tx_size], eob_counts_copy);
+ av1_copy(cpi->common.counts.eob_branch[tx_size], this_eob_counts_copy);
av1_copy(cpi->td.rd_counts.coef_counts[tx_size], coef_counts_copy);
update_coef_probs_subframe(w, cpi, tx_size, cpi->branch_ct_buf,
@@ -2567,6 +2567,8 @@
av1_copy(subframe_stats->coef_probs_buf[0], cm->fc->coef_probs);
if (cm->do_subframe_update &&
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
+ unsigned int eob_counts_copy[TX_SIZES][PLANE_TYPES][REF_TYPES][COEF_BANDS]
+ [COEFF_CONTEXTS];
av1_copy(eob_counts_copy, cm->counts.eob_branch);
for (i = 1; i <= cpi->common.coef_probs_update_idx; ++i) {
for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index c39b78a..c22c5a8 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -300,7 +300,7 @@
cm->frame_context_idx = ARF_FRAME;
#else
if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
-#endif
+#endif // CONFIG_EXT_REFS
else if (cpi->rc.is_src_frame_alt_ref)
cm->frame_context_idx = OVERLAY_FRAME;
else if (cpi->refresh_golden_frame)
@@ -308,7 +308,7 @@
#if CONFIG_EXT_REFS
else if (cpi->refresh_bwd_ref_frame)
cm->frame_context_idx = BRF_FRAME;
-#endif
+#endif // CONFIG_EXT_REFS
else
cm->frame_context_idx = REGULAR_FRAME;
}
@@ -4412,7 +4412,8 @@
arf_sign_bias =
(cpi->rc.source_alt_ref_active && !cpi->refresh_alt_ref_frame);
}
-#endif
+#endif // CONFIG_EXT_REFS
+
cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
#if CONFIG_EXT_REFS
cm->ref_frame_sign_bias[BWDREF_FRAME] = cm->ref_frame_sign_bias[ALTREF_FRAME];
@@ -4430,7 +4431,7 @@
// Get which arf used as ALTREF_FRAME
if (cpi->oxcf.pass == 2)
arf_idx += cpi->twopass.gf_group.arf_ref_idx[cpi->twopass.gf_group.index];
-#endif
+#endif // CONFIG_EXT_REFS
if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame)
return mask;
@@ -4446,7 +4447,7 @@
for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref)
for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
-#endif
+#endif // CONFIG_EXT_REFS
for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter) {
if ((ref_total[LAST_FRAME] &&
@@ -4597,14 +4598,12 @@
// Update the frame type
cm->last_frame_type = cm->frame_type;
-#if CONFIG_EXT_REFS
// Since we allocate a spot for the OVERLAY frame in the gf group, we need
// to do post-encoding update accordingly.
if (cpi->rc.is_src_frame_alt_ref) {
av1_set_target_rate(cpi);
av1_rc_postencode_update(cpi, *size);
}
-#endif
cm->last_width = cm->width;
cm->last_height = cm->height;
@@ -4773,10 +4772,6 @@
cpi->ref_frame_flags = get_ref_frame_flags(cpi);
#endif // !CONFIG_EXT_REFS
-#if CONFIG_EXT_REFS
- cm->last3_frame_type = cm->last2_frame_type;
- cm->last2_frame_type = cm->last_frame_type;
-#endif // CONFIG_EXT_REFS
cm->last_frame_type = cm->frame_type;
av1_rc_postencode_update(cpi, *size);
@@ -5041,7 +5036,7 @@
rc->is_src_frame_alt_ref =
#if CONFIG_EXT_REFS
(gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE) ||
-#endif
+#endif // CONFIG_EXT_REFS
(gf_group->update_type[gf_group->index] == OVERLAY_UPDATE);
} else {
rc->is_src_frame_alt_ref =
@@ -5409,7 +5404,8 @@
cpi->alt_fb_idx = gf_group->arf_ref_idx[gf_group->index];
}
}
-#endif
+#endif // CONFIG_EXT_REFS
+
// Start with a 0 size frame.
*size = 0;
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 003ecb3..1e10531 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -23,6 +23,7 @@
#include "aom_scale/aom_scale.h"
#include "aom_scale/yv12config.h"
+#include "aom_dsp/variance.h"
#include "av1/common/entropymv.h"
#include "av1/common/quant_common.h"
#include "av1/common/reconinter.h" // av1_setup_dst_planes()
@@ -37,7 +38,6 @@
#include "av1/encoder/mcomp.h"
#include "av1/encoder/quantize.h"
#include "av1/encoder/rd.h"
-#include "aom_dsp/variance.h"
#define OUTPUT_FPF 0
#define ARF_STATS_OUTPUT 0
@@ -1580,10 +1580,6 @@
double modified_err = 0.0;
double err_fraction;
int mid_boost_bits = 0;
-#if !CONFIG_EXT_REFS
- int mid_frame_idx;
- unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
-#endif
#if CONFIG_EXT_REFS
// The use of bi-predictive frames are only enabled when following 3
// conditions are met:
@@ -1597,6 +1593,7 @@
(rc->baseline_gf_interval - rc->source_alt_ref_pending);
int bipred_group_end = 0;
int bipred_frame_index = 0;
+
int arf_pos[MAX_EXT_ARFS + 1];
const unsigned char ext_arf_interval =
(unsigned char)(rc->baseline_gf_interval / (cpi->num_extra_arfs + 1) - 1);
@@ -1605,17 +1602,20 @@
int ext_arf_boost[MAX_EXT_ARFS];
int is_sg_bipred_enabled = is_bipred_enabled;
int accumulative_subgroup_interval = 0;
+#else
+ int mid_frame_idx;
+ unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
#endif // CONFIG_EXT_REFS
#if CONFIG_EXT_REFS
av1_zero_array(ext_arf_boost, MAX_EXT_ARFS);
-#endif
+#endif // CONFIG_EXT_REFS
key_frame = cpi->common.frame_type == KEY_FRAME;
#if !CONFIG_EXT_REFS
get_arf_buffer_indices(arf_buffer_indices);
-#endif
+#endif // !CONFIG_EXT_REFS
// For key frames the frame target rate is already set and it
// is also the golden frame.
@@ -1635,7 +1635,7 @@
#else
gf_group->arf_update_idx[frame_index] = arf_buffer_indices[0];
gf_group->arf_ref_idx[frame_index] = arf_buffer_indices[0];
-#endif
+#endif // CONFIG_EXT_REFS
// Step over the golden frame / overlay frame
if (EOF == input_stats(twopass, &frame_stats)) return;
}
@@ -1667,16 +1667,15 @@
#if CONFIG_EXT_REFS
gf_group->arf_update_idx[frame_index] = 0;
gf_group->arf_ref_idx[frame_index] = 0;
+
+ gf_group->bidir_pred_enabled[frame_index] = 0;
+ gf_group->brf_src_offset[frame_index] = 0;
+// NOTE: "bidir_pred_frame_index" stays unchanged for ARF_UPDATE frames.
#else
gf_group->arf_update_idx[frame_index] = arf_buffer_indices[0];
gf_group->arf_ref_idx[frame_index] =
arf_buffer_indices[cpi->multi_arf_last_grp_enabled &&
rc->source_alt_ref_active];
-#endif // CONFIG_EXT_REFS && CONFIG_EXT_ARFS
-#if CONFIG_EXT_REFS
- gf_group->bidir_pred_enabled[frame_index] = 0;
- gf_group->brf_src_offset[frame_index] = 0;
-// NOTE: "bidir_pred_frame_index" stays unchanged for ARF_UPDATE frames.
#endif // CONFIG_EXT_REFS
#if CONFIG_EXT_REFS
@@ -1730,13 +1729,14 @@
#if !CONFIG_EXT_REFS
// Define middle frame
mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
-#endif
+#endif // !CONFIG_EXT_REFS
// Allocate bits to the other frames in the group.
for (i = 0; i < rc->baseline_gf_interval - rc->source_alt_ref_pending; ++i) {
#if !CONFIG_EXT_REFS
int arf_idx = 0;
-#endif
+#endif // !CONFIG_EXT_REFS
+
if (EOF == input_stats(twopass, &frame_stats)) break;
modified_err = calculate_modified_err(cpi, twopass, oxcf, &frame_stats);
@@ -1753,8 +1753,9 @@
target_frame_size -= (target_frame_size >> 4);
#if !CONFIG_EXT_REFS
if (frame_index <= mid_frame_idx) arf_idx = 1;
-#endif
+#endif // !CONFIG_EXT_REFS
}
+
#if CONFIG_EXT_REFS
gf_group->arf_update_idx[frame_index] = which_arf;
gf_group->arf_ref_idx[frame_index] = which_arf;
@@ -1762,6 +1763,7 @@
gf_group->arf_update_idx[frame_index] = arf_buffer_indices[arf_idx];
gf_group->arf_ref_idx[frame_index] = arf_buffer_indices[arf_idx];
#endif // CONFIG_EXT_REFS
+
target_frame_size =
clamp(target_frame_size, 0, AOMMIN(max_bits, (int)total_group_bits));
@@ -1773,6 +1775,7 @@
is_bipred_enabled &&
(subgroup_interval[which_arf] > rc->bipred_group_interval);
}
+
// NOTE: BIDIR_PRED is only enabled when the length of the bi-predictive
// frame group interval is strictly smaller than that of the GOLDEN
// FRAME group interval.
@@ -1841,6 +1844,7 @@
#endif // CONFIG_EXT_REFS
++frame_index;
+
#if CONFIG_EXT_REFS
// Check if we need to update the ARF
if (cpi->num_extra_arfs && frame_index > arf_pos[which_arf]) {
@@ -1858,7 +1862,7 @@
++frame_index;
}
}
-#endif
+#endif // CONFIG_EXT_REFS
}
// Note:
@@ -1871,7 +1875,8 @@
#else
gf_group->arf_update_idx[frame_index] = arf_buffer_indices[0];
gf_group->arf_ref_idx[frame_index] = arf_buffer_indices[0];
-#endif
+#endif // CONFIG_EXT_REFS
+
if (rc->source_alt_ref_pending) {
gf_group->update_type[frame_index] = OVERLAY_UPDATE;
gf_group->rf_level[frame_index] = INTER_NORMAL;
@@ -1887,8 +1892,7 @@
gf_group->rf_level[arf_pos[i]] = INTER_LOW;
}
}
-#endif
-#if !CONFIG_EXT_REFS
+#else
// Final setup for second arf and its overlay.
if (cpi->multi_arf_enabled) {
gf_group->bit_allocation[2] =
@@ -1896,11 +1900,12 @@
gf_group->update_type[mid_frame_idx] = OVERLAY_UPDATE;
gf_group->bit_allocation[mid_frame_idx] = 0;
}
-#endif
+#endif // CONFIG_EXT_REFS
} else {
gf_group->update_type[frame_index] = GF_UPDATE;
gf_group->rf_level[frame_index] = GF_ARF_STD;
}
+
#if CONFIG_EXT_REFS
gf_group->bidir_pred_enabled[frame_index] = 0;
gf_group->brf_src_offset[frame_index] = 0;
@@ -1909,6 +1914,7 @@
// Note whether multi-arf was enabled this group for next time.
cpi->multi_arf_last_grp_enabled = cpi->multi_arf_enabled;
}
+
// Analyse and define a gf/arf group.
static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
AV1_COMMON *const cm = &cpi->common;
@@ -2116,8 +2122,8 @@
cpi->num_extra_arfs = get_number_of_extra_arfs(rc->baseline_gf_interval,
rc->source_alt_ref_pending);
// Currently at maximum two extra ARFs' are allowed
- assert(cpi->num_extra_arfs <= 2);
-#endif
+ assert(cpi->num_extra_arfs <= MAX_EXT_ARFS);
+#endif // CONFIG_EXT_REFS
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index 84f9791..db459cc 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -193,7 +193,7 @@
else
return 0;
}
-#endif
+#endif // CONFIG_EXT_REFS
#ifdef __cplusplus
} // extern "C"
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index aaca103..2141f30 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -193,7 +193,7 @@
if (cpi->rc.is_src_frame_alt_ref) {
#else
if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
-#endif
+#endif // CONFIG_EXT_REFS
// If there is an active ARF at this location use the minimum
// bits on this frame even if it is a constructed arf.
// The active maximum quantizer insures that an appropriate
@@ -1189,11 +1189,12 @@
#else
// Update the Golden frame usage counts.
if (cpi->refresh_golden_frame) {
-#endif
+#endif // CONFIG_EXT_REFS
+
#if CONFIG_EXT_REFS
// We will not use internal overlay frames to replace the golden frame
if (!rc->is_src_frame_ext_arf)
-#endif
+#endif // CONFIG_EXT_REFS
// this frame refreshes means next frames don't unless specified by user
rc->frames_since_golden = 0;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index ce8695a..8d151a7 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -875,8 +875,9 @@
* can skip this if the last coefficient in this transform block, e.g. the
* 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
* were non-zero). */
-int av1_cost_coeffs(MACROBLOCK *x, int plane, int block, int coeff_ctx,
- TX_SIZE tx_size, const int16_t *scan, const int16_t *nb,
+int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
+ int block, int coeff_ctx, TX_SIZE tx_size,
+ const int16_t *scan, const int16_t *nb,
int use_fast_coef_costing) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
@@ -903,6 +904,7 @@
assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
: get_uv_tx_size(mbmi, pd) == tx_size);
#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
+ (void)cm;
if (eob == 0) {
// single eob token
@@ -1069,8 +1071,9 @@
static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
struct rdcost_block_args *args) {
- return av1_cost_coeffs(args->x, plane, block, coeff_ctx, tx_size,
- args->scan_order->scan, args->scan_order->neighbors,
+ return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
+ tx_size, args->scan_order->scan,
+ args->scan_order->neighbors,
args->use_fast_coef_costing);
}
@@ -1887,6 +1890,7 @@
PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
BLOCK_SIZE bsize, int *y_skip, int64_t rd_thresh) {
+ const AV1_COMMON *const cm = &cpi->common;
PREDICTION_MODE mode;
MACROBLOCKD *const xd = &x->e_mbd;
int64_t best_rd = rd_thresh;
@@ -1958,7 +1962,7 @@
av1_xform_quant(x, 0, block, row + idy, col + idx, BLOCK_8X8,
TX_4X4, AV1_XFORM_QUANT_FP);
#endif // CONFIG_NEW_QUANT
- ratey += av1_cost_coeffs(x, 0, block, coeff_ctx, TX_4X4,
+ ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
scan_order->scan, scan_order->neighbors,
cpi->sf.use_fast_coef_costing);
*(tempa + idx) = !(p->eobs[block] == 0);
@@ -1984,7 +1988,7 @@
TX_4X4, AV1_XFORM_QUANT_FP);
#endif // CONFIG_NEW_QUANT
av1_optimize_b(x, 0, block, TX_4X4, coeff_ctx);
- ratey += av1_cost_coeffs(x, 0, block, coeff_ctx, TX_4X4,
+ ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
scan_order->scan, scan_order->neighbors,
cpi->sf.use_fast_coef_costing);
*(tempa + idx) = !(p->eobs[block] == 0);
@@ -2078,7 +2082,7 @@
av1_xform_quant(x, 0, block, row + idy, col + idx, BLOCK_8X8, TX_4X4,
AV1_XFORM_QUANT_B);
#endif // CONFIG_NEW_QUANT
- ratey += av1_cost_coeffs(x, 0, block, coeff_ctx, TX_4X4,
+ ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
scan_order->scan, scan_order->neighbors,
cpi->sf.use_fast_coef_costing);
*(tempa + idx) = !(p->eobs[block] == 0);
@@ -2103,7 +2107,7 @@
AV1_XFORM_QUANT_FP);
#endif // CONFIG_NEW_QUANT
av1_optimize_b(x, 0, block, TX_4X4, coeff_ctx);
- ratey += av1_cost_coeffs(x, 0, block, coeff_ctx, TX_4X4,
+ ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
scan_order->scan, scan_order->neighbors,
cpi->sf.use_fast_coef_costing);
*(tempa + idx) = !(p->eobs[block] == 0);
@@ -2888,6 +2892,7 @@
int blk_row, int blk_col, int plane, int block,
int plane_bsize, int coeff_ctx, int *rate, int64_t *dist,
int64_t *bsse, int *skip) {
+ const AV1_COMMON *const cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
const struct macroblock_plane *const p = &x->plane[plane];
struct macroblockd_plane *const pd = &xd->plane[plane];
@@ -3012,7 +3017,7 @@
}
}
*dist += tmp * 16;
- *rate += av1_cost_coeffs(x, plane, block, coeff_ctx, tx_size,
+ *rate += av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
scan_order->scan, scan_order->neighbors, 0);
*skip &= (p->eobs[block] == 0);
}
@@ -4349,6 +4354,7 @@
int64_t *distortion, int64_t *sse,
ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
int ir, int ic, int mi_row, int mi_col) {
+ const AV1_COMMON *const cm = &cpi->common;
int k;
MACROBLOCKD *xd = &x->e_mbd;
struct macroblockd_plane *const pd = &xd->plane[0];
@@ -4428,7 +4434,7 @@
thisdistortion += dist;
thissse += ssz;
thisrate +=
- av1_cost_coeffs(x, 0, block, coeff_ctx, tx_size, scan_order->scan,
+ av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
scan_order->neighbors, cpi->sf.use_fast_coef_costing);
*(ta + (k & 1)) = !(p->eobs[block] == 0);
*(tl + (k >> 1)) = !(p->eobs[block] == 0);
diff --git a/av1/encoder/rdopt.h b/av1/encoder/rdopt.h
index 16afaf3..5d9fc12 100644
--- a/av1/encoder/rdopt.h
+++ b/av1/encoder/rdopt.h
@@ -26,8 +26,9 @@
struct macroblock;
struct RD_COST;
-int av1_cost_coeffs(MACROBLOCK *x, int plane, int block, int coeff_ctx,
- TX_SIZE tx_size, const int16_t *scan, const int16_t *nb,
+int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
+ int block, int coeff_ctx, TX_SIZE tx_size,
+ const int16_t *scan, const int16_t *nb,
int use_fast_coef_costing);
void av1_rd_pick_intra_mode_sb(const struct AV1_COMP *cpi, struct macroblock *x,
struct RD_COST *rd_cost, BLOCK_SIZE bsize,
diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c
index 561beed..fd0f76b 100644
--- a/av1/encoder/tokenize.c
+++ b/av1/encoder/tokenize.c
@@ -353,6 +353,7 @@
static void cost_coeffs_b(int plane, int block, int blk_row, int blk_col,
BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
struct tokenize_b_args *const args = arg;
+ const AV1_COMMON *cm = &args->cpi->common;
ThreadData *const td = args->td;
MACROBLOCK *const x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -365,7 +366,7 @@
const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type, ref);
int pt = get_entropy_context(tx_size, pd->above_context + blk_col,
pd->left_context + blk_row);
- int rate = av1_cost_coeffs(x, plane, block, pt, tx_size, scan_order->scan,
+ int rate = av1_cost_coeffs(cm, x, plane, block, pt, tx_size, scan_order->scan,
scan_order->neighbors, 0);
args->this_rate += rate;
av1_set_contexts(xd, pd, plane_bsize, tx_size, p->eobs[block] > 0, blk_col,
diff --git a/configure b/configure
index 7901ef3..99d2bb8 100755
--- a/configure
+++ b/configure
@@ -287,6 +287,7 @@
cb4x4
frame_size
delta_q
+ adapt_scan
"
CONFIG_LIST="
dependency_tracking