summaryrefslogtreecommitdiff
path: root/vp9/common/vp9_reconintra4x4.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/common/vp9_reconintra4x4.c')
-rw-r--r--vp9/common/vp9_reconintra4x4.c196
1 files changed, 125 insertions, 71 deletions
diff --git a/vp9/common/vp9_reconintra4x4.c b/vp9/common/vp9_reconintra4x4.c
index da607e81c..eab5ab495 100644
--- a/vp9/common/vp9_reconintra4x4.c
+++ b/vp9/common/vp9_reconintra4x4.c
@@ -15,17 +15,17 @@
#include "vp9_rtcd.h"
#if CONFIG_NEWBINTRAMODES
-static int find_grad_measure(uint8_t *x, int stride, int n, int t,
+static int find_grad_measure(uint8_t *x, int stride, int n, int tx, int ty,
int dx, int dy) {
int i, j;
int count = 0, gsum = 0, gdiv;
/* TODO: Make this code more efficient by breaking up into two loops */
- for (i = -t; i < n; ++i)
- for (j = -t; j < n; ++j) {
+ for (i = -ty; i < n; ++i)
+ for (j = -tx; j < n; ++j) {
int g;
if (i >= 0 && j >= 0) continue;
if (i + dy >= 0 && j + dx >= 0) continue;
- if (i + dy < -t || i + dy >= n || j + dx < -t || j + dx >= n) continue;
+ if (i + dy < -ty || i + dy >= n || j + dx < -tx || j + dx >= n) continue;
g = abs(x[(i + dy) * stride + j + dx] - x[i * stride + j]);
gsum += g * g;
count++;
@@ -36,14 +36,15 @@ static int find_grad_measure(uint8_t *x, int stride, int n, int t,
#if CONTEXT_PRED_REPLACEMENTS == 6
B_PREDICTION_MODE vp9_find_dominant_direction(uint8_t *ptr,
- int stride, int n) {
+ int stride, int n,
+ int tx, int ty) {
int g[8], i, imin, imax;
- g[1] = find_grad_measure(ptr, stride, n, 4, 2, 1);
- g[2] = find_grad_measure(ptr, stride, n, 4, 1, 1);
- g[3] = find_grad_measure(ptr, stride, n, 4, 1, 2);
- g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2);
- g[6] = find_grad_measure(ptr, stride, n, 4, -1, 1);
- g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1);
+ g[1] = find_grad_measure(ptr, stride, n, tx, ty, 2, 1);
+ g[2] = find_grad_measure(ptr, stride, n, tx, ty, 1, 1);
+ g[3] = find_grad_measure(ptr, stride, n, tx, ty, 1, 2);
+ g[5] = find_grad_measure(ptr, stride, n, tx, ty, -1, 2);
+ g[6] = find_grad_measure(ptr, stride, n, tx, ty, -1, 1);
+ g[7] = find_grad_measure(ptr, stride, n, tx, ty, -2, 1);
imin = 1;
for (i = 2; i < 8; i += 1 + (i == 3))
imin = (g[i] < g[imin] ? i : imin);
@@ -73,12 +74,13 @@ B_PREDICTION_MODE vp9_find_dominant_direction(uint8_t *ptr,
}
#elif CONTEXT_PRED_REPLACEMENTS == 4
B_PREDICTION_MODE vp9_find_dominant_direction(uint8_t *ptr,
- int stride, int n) {
+ int stride, int n,
+ int tx, int ty) {
int g[8], i, imin, imax;
- g[1] = find_grad_measure(ptr, stride, n, 4, 2, 1);
- g[3] = find_grad_measure(ptr, stride, n, 4, 1, 2);
- g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2);
- g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1);
+ g[1] = find_grad_measure(ptr, stride, n, tx, ty, 2, 1);
+ g[3] = find_grad_measure(ptr, stride, n, tx, ty, 1, 2);
+ g[5] = find_grad_measure(ptr, stride, n, tx, ty, -1, 2);
+ g[7] = find_grad_measure(ptr, stride, n, tx, ty, -2, 1);
imin = 1;
for (i = 3; i < 8; i+=2)
imin = (g[i] < g[imin] ? i : imin);
@@ -104,16 +106,17 @@ B_PREDICTION_MODE vp9_find_dominant_direction(uint8_t *ptr,
}
#elif CONTEXT_PRED_REPLACEMENTS == 0
B_PREDICTION_MODE vp9_find_dominant_direction(uint8_t *ptr,
- int stride, int n) {
+ int stride, int n,
+ int tx, int ty) {
int g[8], i, imin, imax;
- g[0] = find_grad_measure(ptr, stride, n, 4, 1, 0);
- g[1] = find_grad_measure(ptr, stride, n, 4, 2, 1);
- g[2] = find_grad_measure(ptr, stride, n, 4, 1, 1);
- g[3] = find_grad_measure(ptr, stride, n, 4, 1, 2);
- g[4] = find_grad_measure(ptr, stride, n, 4, 0, 1);
- g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2);
- g[6] = find_grad_measure(ptr, stride, n, 4, -1, 1);
- g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1);
+ g[0] = find_grad_measure(ptr, stride, n, tx, ty, 1, 0);
+ g[1] = find_grad_measure(ptr, stride, n, tx, ty, 2, 1);
+ g[2] = find_grad_measure(ptr, stride, n, tx, ty, 1, 1);
+ g[3] = find_grad_measure(ptr, stride, n, tx, ty, 1, 2);
+ g[4] = find_grad_measure(ptr, stride, n, tx, ty, 0, 1);
+ g[5] = find_grad_measure(ptr, stride, n, tx, ty, -1, 2);
+ g[6] = find_grad_measure(ptr, stride, n, tx, ty, -1, 1);
+ g[7] = find_grad_measure(ptr, stride, n, tx, ty, -2, 1);
imax = 0;
for (i = 1; i < 8; i++)
imax = (g[i] > g[imax] ? i : imax);
@@ -144,26 +147,113 @@ B_PREDICTION_MODE vp9_find_dominant_direction(uint8_t *ptr,
}
#endif
-B_PREDICTION_MODE vp9_find_bpred_context(BLOCKD *x) {
+B_PREDICTION_MODE vp9_find_bpred_context(MACROBLOCKD *xd, BLOCKD *x) {
+ const int block_idx = x - xd->block;
+ const int have_top = (block_idx >> 2) || xd->up_available;
+ const int have_left = (block_idx & 3) || xd->left_available;
uint8_t *ptr = *(x->base_dst) + x->dst;
int stride = x->dst_stride;
- return vp9_find_dominant_direction(ptr, stride, 4);
+ int tx = have_left ? 4 : 0;
+ int ty = have_top ? 4 : 0;
+ if (!have_left && !have_top)
+ return B_DC_PRED;
+ return vp9_find_dominant_direction(ptr, stride, 4, tx, ty);
}
#endif
-void vp9_intra4x4_predict(BLOCKD *x,
+void vp9_intra4x4_predict(MACROBLOCKD *xd,
+ BLOCKD *x,
int b_mode,
uint8_t *predictor) {
int i, r, c;
+ const int block_idx = x - xd->block;
+ const int have_top = (block_idx >> 2) || xd->up_available;
+ const int have_left = (block_idx & 3) || xd->left_available;
+ const int have_right = (block_idx & 3) != 3 || xd->right_available;
+ uint8_t left[4], above[8], top_left;
+ /*
+ * 127 127 127 .. 127 127 127 127 127 127
+ * 129 A B .. Y Z
+ * 129 C D .. W X
+ * 129 E F .. U V
+ * 129 G H .. S T T T T T
+ * ..
+ */
+
+ if (have_left) {
+ uint8_t *left_ptr = *(x->base_dst) + x->dst - 1;
+ const int stride = x->dst_stride;
+
+ left[0] = left_ptr[0 * stride];
+ left[1] = left_ptr[1 * stride];
+ left[2] = left_ptr[2 * stride];
+ left[3] = left_ptr[3 * stride];
+ } else {
+ left[0] = left[1] = left[2] = left[3] = 129;
+ }
+
+ if (have_top) {
+ uint8_t *above_ptr = *(x->base_dst) + x->dst - x->dst_stride;
- uint8_t *above = *(x->base_dst) + x->dst - x->dst_stride;
- uint8_t left[4];
- uint8_t top_left = above[-1];
+ if (have_left) {
+ top_left = above_ptr[-1];
+ } else {
+ top_left = 127;
+ }
- left[0] = (*(x->base_dst))[x->dst - 1];
- left[1] = (*(x->base_dst))[x->dst - 1 + x->dst_stride];
- left[2] = (*(x->base_dst))[x->dst - 1 + 2 * x->dst_stride];
- left[3] = (*(x->base_dst))[x->dst - 1 + 3 * x->dst_stride];
+ above[0] = above_ptr[0];
+ above[1] = above_ptr[1];
+ above[2] = above_ptr[2];
+ above[3] = above_ptr[3];
+ if (((block_idx & 3) != 3) ||
+ (have_right && block_idx == 3 &&
+ ((xd->mb_index != 3 && xd->sb_index != 3) ||
+ ((xd->mb_index & 1) == 0 && xd->sb_index == 3)))) {
+ above[4] = above_ptr[4];
+ above[5] = above_ptr[5];
+ above[6] = above_ptr[6];
+ above[7] = above_ptr[7];
+ } else if (have_right) {
+ uint8_t *above_right = above_ptr + 4;
+
+ if (xd->sb_index == 3 && (xd->mb_index & 1))
+ above_right -= 32 * x->dst_stride;
+ if (xd->mb_index == 3)
+ above_right -= 16 * x->dst_stride;
+ above_right -= (block_idx & ~3) * x->dst_stride;
+
+ /* use a more distant above-right (from closest available top-right
+ * corner), but with a "localized DC" (similar'ish to TM-pred):
+ *
+ * A B C D E F G H
+ * I J K L
+ * M N O P
+ * Q R S T
+ * U V W X x1 x2 x3 x4
+ *
+ * Where:
+ * x1 = clip_pixel(E + X - D)
+ * x2 = clip_pixel(F + X - D)
+ * x3 = clip_pixel(G + X - D)
+ * x4 = clip_pixel(H + X - D)
+ *
+ * This is applied anytime when we use a "distant" above-right edge
+ * that is not immediately top-right to the block that we're going
+ * to do intra prediction for.
+ */
+ above[4] = clip_pixel(above_right[0] + above_ptr[3] - above_right[-1]);
+ above[5] = clip_pixel(above_right[1] + above_ptr[3] - above_right[-1]);
+ above[6] = clip_pixel(above_right[2] + above_ptr[3] - above_right[-1]);
+ above[7] = clip_pixel(above_right[3] + above_ptr[3] - above_right[-1]);
+ } else {
+ // extend edge
+ above[4] = above[5] = above[6] = above[7] = above[3];
+ }
+ } else {
+ above[0] = above[1] = above[2] = above[3] = 127;
+ above[4] = above[5] = above[6] = above[7] = 127;
+ top_left = 127;
+ }
#if CONFIG_NEWBINTRAMODES
if (b_mode == B_CONTEXT_PRED)
@@ -411,39 +501,3 @@ void vp9_intra4x4_predict(BLOCKD *x,
#endif
}
}
-
-/* copy 4 bytes from the above right down so that the 4x4 prediction modes using pixels above and
- * to the right prediction have filled in pixels to use.
- */
-void vp9_intra_prediction_down_copy(MACROBLOCKD *xd) {
- int extend_edge = xd->mb_to_right_edge == 0 && xd->mb_index < 2;
- uint8_t *above_right = *(xd->block[0].base_dst) + xd->block[0].dst -
- xd->block[0].dst_stride + 16;
- uint32_t *dst_ptr0 = (uint32_t *)above_right;
- uint32_t *dst_ptr1 =
- (uint32_t *)(above_right + 4 * xd->block[0].dst_stride);
- uint32_t *dst_ptr2 =
- (uint32_t *)(above_right + 8 * xd->block[0].dst_stride);
- uint32_t *dst_ptr3 =
- (uint32_t *)(above_right + 12 * xd->block[0].dst_stride);
-
- uint32_t *src_ptr = (uint32_t *) above_right;
-
- if ((xd->sb_index >= 2 && xd->mb_to_right_edge == 0) ||
- (xd->sb_index == 3 && xd->mb_index & 1))
- src_ptr = (uint32_t *) (((uint8_t *) src_ptr) - 32 *
- xd->block[0].dst_stride);
- if (xd->mb_index == 3 ||
- (xd->mb_to_right_edge == 0 && xd->mb_index == 2))
- src_ptr = (uint32_t *) (((uint8_t *) src_ptr) - 16 *
- xd->block[0].dst_stride);
-
- if (extend_edge) {
- *src_ptr = ((uint8_t *) src_ptr)[-1] * 0x01010101U;
- }
-
- *dst_ptr0 = *src_ptr;
- *dst_ptr1 = *src_ptr;
- *dst_ptr2 = *src_ptr;
- *dst_ptr3 = *src_ptr;
-}