Compute strongest Sobel x and y edge component
Change-Id: I731975a3f5e49602a5e370e9aa6fa5b8dc01ce6a
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 87761e9..e96ca16 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -416,6 +416,9 @@
// detection). For reference, 556 is the value returned for a solid
// vertical black/white edge.
uint16_t edge_strength;
+ // The strongest edge strength seen along the x/y axis.
+ uint16_t edge_strength_x;
+ uint16_t edge_strength_y;
// [Saved stat index]
COMP_RD_STATS comp_rd_stats[MAX_COMP_RD_STATS];
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 50b619f..3423abf 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -510,15 +510,16 @@
cpi, cm->base_qindex + xd->delta_qindex + cm->y_dc_delta_q);
}
-static uint16_t edge_strength(const struct buf_2d *ref, const BLOCK_SIZE bsize,
- const bool high_bd, const int bd) {
+static EdgeInfo edge_info(const struct buf_2d *ref, const BLOCK_SIZE bsize,
+ const bool high_bd, const int bd) {
const int width = block_size_wide[bsize];
const int height = block_size_high[bsize];
// Implementation requires width to be a multiple of 8. It also requires
// height to be a multiple of 4, but this is always the case.
assert(height % 4 == 0);
if (width % 8 != 0) {
- return 0;
+ EdgeInfo ei = { .magnitude = 0, .x = 0, .y = 0 };
+ return ei;
}
return av1_edge_exists(ref->buf, ref->stride, width, height, high_bd, bd);
}
@@ -611,9 +612,14 @@
// should not be used. Use a value that will always succeed in the check.
if (cpi->sf.disable_wedge_search_edge_thresh == 0) {
x->edge_strength = UINT16_MAX;
+ x->edge_strength_x = UINT16_MAX;
+ x->edge_strength_y = UINT16_MAX;
} else {
- x->edge_strength =
- edge_strength(&x->plane[0].src, bsize, is_cur_buf_hbd(xd), xd->bd);
+ EdgeInfo ei =
+ edge_info(&x->plane[0].src, bsize, is_cur_buf_hbd(xd), xd->bd);
+ x->edge_strength = ei.magnitude;
+ x->edge_strength_x = ei.x;
+ x->edge_strength_y = ei.y;
}
// Save rdmult before it might be changed, so it can be restored later.
orig_rdmult = x->rdmult;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 28caad0..f5dfca0 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -13061,12 +13061,14 @@
}
}
-static uint16_t edge_probability(const uint8_t *input, int w, int h,
+static EdgeInfo edge_probability(const uint8_t *input, int w, int h,
bool high_bd, int bd) {
// The probability of an edge in the whole image is the same as the highest
// probability of an edge for any individual pixel. Use Sobel as the metric
// for finding an edge.
uint16_t highest = 0;
+ uint16_t highest_x = 0;
+ uint16_t highest_y = 0;
// Ignore the 1 pixel border around the image for the computation.
for (int j = 1; j < h - 1; ++j) {
for (int i = 1; i < w - 1; ++i) {
@@ -13076,18 +13078,22 @@
int16_t g_y = g.y >> (bd - 8);
uint16_t magnitude = (uint16_t)sqrt(g_x * g_x + g_y * g_y);
highest = AOMMAX(highest, magnitude);
+ highest_x = AOMMAX(highest_x, g_x);
+ highest_y = AOMMAX(highest_y, g_y);
}
}
- return highest;
+ EdgeInfo ei = { .magnitude = highest, .x = highest_x, .y = highest_y };
+ return ei;
}
/* Uses most of the Canny edge detection algorithm to find if there are any
* edges in the image.
*/
-uint16_t av1_edge_exists(const uint8_t *src, int src_stride, int w, int h,
+EdgeInfo av1_edge_exists(const uint8_t *src, int src_stride, int w, int h,
bool high_bd, int bd) {
if (w < 3 || h < 3) {
- return 0;
+ EdgeInfo n = { .magnitude = 0, .x = 0, .y = 0 };
+ return n;
}
uint8_t *blurred;
if (high_bd) {
@@ -13100,7 +13106,7 @@
// want a probability of an edge existing in the buffer, which is determined
// by the strongest edge in it -- we don't need to eliminate the weaker
// edges. Use Sobel for the edge detection.
- uint16_t prob = edge_probability(blurred, w, h, high_bd, bd);
+ EdgeInfo prob = edge_probability(blurred, w, h, high_bd, bd);
if (high_bd) {
aom_free(CONVERT_TO_SHORTPTR(blurred));
} else {
diff --git a/av1/encoder/rdopt.h b/av1/encoder/rdopt.h
index 983d385..0ce931a 100644
--- a/av1/encoder/rdopt.h
+++ b/av1/encoder/rdopt.h
@@ -128,13 +128,21 @@
struct macroblock *x, int mi_row, int mi_col, struct RD_STATS *rd_cost,
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, int64_t best_rd_so_far);
+// The best edge strength seen in the block, as well as the best x and y
+// components of edge strength seen.
+typedef struct {
+ uint16_t magnitude;
+ uint16_t x;
+ uint16_t y;
+} EdgeInfo;
+
/** Returns an integer indicating the strength of the edge.
* 0 means no edge found, 556 is the strength of a solid black/white edge,
* and the number may range higher if the signal is even stronger (e.g., on a
* corner). high_bd is a bool indicating the source should be treated
* as a 16-bit array. bd is the bit depth.
*/
-uint16_t av1_edge_exists(const uint8_t *src, int src_stride, int w, int h,
+EdgeInfo av1_edge_exists(const uint8_t *src, int src_stride, int w, int h,
bool high_bd, int bd);
/** Applies a Gaussian blur with sigma = 1.3. Used by av1_edge_exists and