20.13. modemv_data.h
---- Begin code block -------------------------------------- /* * Copyright (c) 2010, 2011, Google Inc. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be * found in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ static const unsigned char kf_y_mode_probs[] = { 145, 156, 163, 128}; static const unsigned char kf_uv_mode_probs[] = { 142, 114, 183}; static const unsigned char kf_b_mode_probs[10][10][9] = { { /* above mode 0 */ { /* left mode 0 */ 231, 120, 48, 89, 115, 113, 120, 152, 112}, { /* left mode 1 */ 152, 179, 64, 126, 170, 118, 46, 70, 95}, { /* left mode 2 */ 175, 69, 143, 80, 85, 82, 72, 155, 103}, { /* left mode 3 */ 56, 58, 10, 171, 218, 189, 17, 13, 152}, { /* left mode 4 */ 144, 71, 10, 38, 171, 213, 144, 34, 26}, { /* left mode 5 */ 114, 26, 17, 163, 44, 195, 21, 10, 173}, { /* left mode 6 */ 121, 24, 80, 195, 26, 62, 44, 64, 85}, { /* left mode 7 */ 170, 46, 55, 19, 136, 160, 33, 206, 71}, { /* left mode 8 */ 63, 20, 8, 114, 114, 208, 12, 9, 226}, { /* left mode 9 */ 81, 40, 11, 96, 182, 84, 29, 16, 36} }, { /* above mode 1 */ { /* left mode 0 */ 134, 183, 89, 137, 98, 101, 106, 165, 148}, { /* left mode 1 */ 72, 187, 100, 130, 157, 111, 32, 75, 80}, { /* left mode 2 */ 66, 102, 167, 99, 74, 62, 40, 234, 128}, { /* left mode 3 */ 41, 53, 9, 178, 241, 141, 26, 8, 107}, { /* left mode 4 */ 104, 79, 12, 27, 217, 255, 87, 17, 7}, { /* left mode 5 */ 74, 43, 26, 146, 73, 166, 49, 23, 157}, { /* left mode 6 */ 65, 38, 105, 160, 51, 52, 31, 115, 128}, { /* left mode 7 */ 87, 68, 71, 44, 114, 51, 15, 186, 23}, { /* left mode 8 */ 47, 41, 14, 110, 182, 183, 21, 17, 194}, { /* left mode 9 */ 66, 45, 25, 102, 197, 189, 23, 18, 22} }, { /* above mode 2 */ { /* left mode 0 */ 88, 88, 147, 150, 42, 46, 45, 196, 205}, { /* left mode 1 */ 43, 97, 183, 117, 85, 38, 35, 179, 61}, { /* left mode 2 */ 39, 53, 200, 87, 26, 21, 43, 232, 171}, { /* left mode 3 */ 56, 34, 51, 104, 114, 102, 29, 93, 77}, { /* left mode 4 */ 107, 54, 32, 26, 51, 1, 81, 43, 31},
{ /* left mode 5 */ 39, 28, 85, 171, 58, 165, 90, 98, 64}, { /* left mode 6 */ 34, 22, 116, 206, 23, 34, 43, 166, 73}, { /* left mode 7 */ 68, 25, 106, 22, 64, 171, 36, 225, 114}, { /* left mode 8 */ 34, 19, 21, 102, 132, 188, 16, 76, 124}, { /* left mode 9 */ 62, 18, 78, 95, 85, 57, 50, 48, 51} }, { /* above mode 3 */ { /* left mode 0 */ 193, 101, 35, 159, 215, 111, 89, 46, 111}, { /* left mode 1 */ 60, 148, 31, 172, 219, 228, 21, 18, 111}, { /* left mode 2 */ 112, 113, 77, 85, 179, 255, 38, 120, 114}, { /* left mode 3 */ 40, 42, 1, 196, 245, 209, 10, 25, 109}, { /* left mode 4 */ 100, 80, 8, 43, 154, 1, 51, 26, 71}, { /* left mode 5 */ 88, 43, 29, 140, 166, 213, 37, 43, 154}, { /* left mode 6 */ 61, 63, 30, 155, 67, 45, 68, 1, 209}, { /* left mode 7 */ 142, 78, 78, 16, 255, 128, 34, 197, 171}, { /* left mode 8 */ 41, 40, 5, 102, 211, 183, 4, 1, 221}, { /* left mode 9 */ 51, 50, 17, 168, 209, 192, 23, 25, 82} }, { /* above mode 4 */ { /* left mode 0 */ 125, 98, 42, 88, 104, 85, 117, 175, 82}, { /* left mode 1 */ 95, 84, 53, 89, 128, 100, 113, 101, 45}, { /* left mode 2 */ 75, 79, 123, 47, 51, 128, 81, 171, 1}, { /* left mode 3 */ 57, 17, 5, 71, 102, 57, 53, 41, 49}, { /* left mode 4 */ 115, 21, 2, 10, 102, 255, 166, 23, 6}, { /* left mode 5 */ 38, 33, 13, 121, 57, 73, 26, 1, 85}, { /* left mode 6 */ 41, 10, 67, 138, 77, 110, 90, 47, 114}, { /* left mode 7 */ 101, 29, 16, 10, 85, 128, 101, 196, 26}, { /* left mode 8 */ 57, 18, 10, 102, 102, 213, 34, 20, 43}, { /* left mode 9 */ 117, 20, 15, 36, 163, 128, 68, 1, 26} }, { /* above mode 5 */ { /* left mode 0 */ 138, 31, 36, 171, 27, 166, 38, 44, 229}, { /* left mode 1 */ 67, 87, 58, 169, 82, 115, 26, 59, 179}, { /* left mode 2 */ 63, 59, 90, 180, 59, 166, 93, 73, 154}, { /* left mode 3 */ 40, 40, 21, 116, 143, 209, 34, 39, 175}, { /* left mode 4 */ 57, 46, 22, 24, 128, 1, 54, 17, 37}, { /* left mode 5 */ 47, 15, 16, 183, 34, 223, 49, 45, 183}, { /* left mode 6 */ 46, 17, 33, 183, 6, 98, 15, 32, 183}, { /* left mode 7 */ 65, 32, 73, 115, 28, 128, 23, 128, 205}, { /* left mode 8 */ 40, 3, 9, 115, 51, 192, 18, 6, 223}, { /* left mode 9 */ 87, 37, 9, 115, 59, 77, 64, 21, 47} }, { /* above mode 6 */ { /* left mode 0 */ 104, 55, 44, 218, 9, 54, 53, 130, 226}, { /* left mode 1 */ 64, 90, 70, 205, 40, 41, 23, 26, 57}, { /* left mode 2 */ 54, 57, 112, 184, 5, 41, 38, 166, 213}, { /* left mode 3 */ 30, 34, 26, 133, 152, 116, 10, 32, 134}, { /* left mode 4 */ 75, 32, 12, 51, 192, 255, 160, 43, 51},
{ /* left mode 5 */ 39, 19, 53, 221, 26, 114, 32, 73, 255}, { /* left mode 6 */ 31, 9, 65, 234, 2, 15, 1, 118, 73}, { /* left mode 7 */ 88, 31, 35, 67, 102, 85, 55, 186, 85}, { /* left mode 8 */ 56, 21, 23, 111, 59, 205, 45, 37, 192}, { /* left mode 9 */ 55, 38, 70, 124, 73, 102, 1, 34, 98} }, { /* above mode 7 */ { /* left mode 0 */ 102, 61, 71, 37, 34, 53, 31, 243, 192}, { /* left mode 1 */ 69, 60, 71, 38, 73, 119, 28, 222, 37}, { /* left mode 2 */ 68, 45, 128, 34, 1, 47, 11, 245, 171}, { /* left mode 3 */ 62, 17, 19, 70, 146, 85, 55, 62, 70}, { /* left mode 4 */ 75, 15, 9, 9, 64, 255, 184, 119, 16}, { /* left mode 5 */ 37, 43, 37, 154, 100, 163, 85, 160, 1}, { /* left mode 6 */ 63, 9, 92, 136, 28, 64, 32, 201, 85}, { /* left mode 7 */ 86, 6, 28, 5, 64, 255, 25, 248, 1}, { /* left mode 8 */ 56, 8, 17, 132, 137, 255, 55, 116, 128}, { /* left mode 9 */ 58, 15, 20, 82, 135, 57, 26, 121, 40} }, { /* above mode 8 */ { /* left mode 0 */ 164, 50, 31, 137, 154, 133, 25, 35, 218}, { /* left mode 1 */ 51, 103, 44, 131, 131, 123, 31, 6, 158}, { /* left mode 2 */ 86, 40, 64, 135, 148, 224, 45, 183, 128}, { /* left mode 3 */ 22, 26, 17, 131, 240, 154, 14, 1, 209}, { /* left mode 4 */ 83, 12, 13, 54, 192, 255, 68, 47, 28}, { /* left mode 5 */ 45, 16, 21, 91, 64, 222, 7, 1, 197}, { /* left mode 6 */ 56, 21, 39, 155, 60, 138, 23, 102, 213}, { /* left mode 7 */ 85, 26, 85, 85, 128, 128, 32, 146, 171}, { /* left mode 8 */ 18, 11, 7, 63, 144, 171, 4, 4, 246}, { /* left mode 9 */ 35, 27, 10, 146, 174, 171, 12, 26, 128} }, { /* above mode 9 */ { /* left mode 0 */ 190, 80, 35, 99, 180, 80, 126, 54, 45}, { /* left mode 1 */ 85, 126, 47, 87, 176, 51, 41, 20, 32}, { /* left mode 2 */ 101, 75, 128, 139, 118, 146, 116, 128, 85}, { /* left mode 3 */ 56, 41, 15, 176, 236, 85, 37, 9, 62}, { /* left mode 4 */ 146, 36, 19, 30, 171, 255, 97, 27, 20}, { /* left mode 5 */ 71, 30, 17, 119, 118, 255, 17, 18, 138}, { /* left mode 6 */ 101, 38, 60, 138, 55, 70, 43, 26, 142}, { /* left mode 7 */ 138, 45, 61, 62, 219, 1, 81, 188, 64}, { /* left mode 8 */ 32, 41, 20, 117, 151, 142, 20, 21, 163}, { /* left mode 9 */ 112, 19, 12, 61, 195, 128, 48, 4, 24} } };
static const int kf_y_mode_tree[] = { -B_PRED, 2, 4, 6, -DC_PRED, -V_PRED, -H_PRED, -TM_PRED }; static const int y_mode_tree[] = { -DC_PRED, 2, 4, 6, -V_PRED, -H_PRED, -TM_PRED, -B_PRED }; static const int uv_mode_tree[6] = { -DC_PRED, 2, -V_PRED, 4, -H_PRED, -TM_PRED }; static const int b_mode_tree[18] = { -B_DC_PRED, 2, /* 0 = DC_NODE */ -B_TM_PRED, 4, /* 1 = TM_NODE */ -B_VE_PRED, 6, /* 2 = VE_NODE */ 8, 12, /* 3 = COM_NODE */ -B_HE_PRED, 10, /* 4 = HE_NODE */ -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ -B_LD_PRED, 14, /* 6 = LD_NODE */ -B_VL_PRED, 16, /* 7 = VL_NODE */ -B_HD_PRED, -B_HU_PRED /* 8 = HD_NODE */ }; static const int small_mv_tree[14] = { 2, 8, 4, 6, -0, -1, -2, -3, 10, 12, -4, -5, -6, -7 };
static const int mv_ref_tree[8] = { -ZEROMV, 2, -NEARESTMV, 4, -NEARMV, 6, -NEWMV, -SPLITMV }; static const int submv_ref_tree[6] = { -LEFT4X4, 2, -ABOVE4X4, 4, -ZERO4X4, -NEW4X4 }; static const int split_mv_tree[6] = { -3, 2, -2, 4, -0, -1 }; static const unsigned char default_b_mode_probs[] = { 120, 90, 79, 133, 87, 85, 80, 111, 151}; static const unsigned char mv_counts_to_probs[6][4] = { { 7, 1, 1, 143 }, { 14, 18, 14, 107 }, { 135, 64, 57, 68 }, { 60, 56, 128, 65 }, { 159, 134, 128, 34 }, { 234, 188, 128, 28 } }; static const unsigned char split_mv_probs[3] = { 110, 111, 150}; static const unsigned char submv_ref_probs2[5][3] = { { 147, 136, 18 }, { 106, 145, 1 }, { 179, 121, 1 }, { 223, 1, 34 }, { 208, 1, 1 } };
const static int mv_partitions[4][16] = { {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, {0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 }, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } }; ---- End code block ----------------------------------------20.14. predict.c
---- Begin code block -------------------------------------- /* * Copyright (c) 2010, 2011, Google Inc. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be * found in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "dixie.h" #include "predict.h" #include "idct_add.h" #include "mem.h" #include <assert.h> #include <string.h> enum { BORDER_PIXELS = 16, }; static const filter_t sixtap_filters[8] = { { 0, 0, 128, 0, 0, 0 }, { 0, -6, 123, 12, -1, 0 }, { 2, -11, 108, 36, -8, 1 }, { 0, -9, 93, 50, -6, 0 }, { 3, -16, 77, 77, -16, 3 }, { 0, -6, 50, 93, -9, 0 }, { 1, -8, 36, 108, -11, 2 }, { 0, -1, 12, 123, -6, 0 } };
static const filter_t bilinear_filters[8] = { { 0, 0, 128, 0, 0, 0 }, { 0, 0, 112, 16, 0, 0 }, { 0, 0, 96, 32, 0, 0 }, { 0, 0, 80, 48, 0, 0 }, { 0, 0, 64, 64, 0, 0 }, { 0, 0, 48, 80, 0, 0 }, { 0, 0, 32, 96, 0, 0 }, { 0, 0, 16, 112, 0, 0 } }; static void predict_h_nxn(unsigned char *predict, int stride, int n) { unsigned char *left = predict - 1; int i, j; for (i = 0; i < n; i++) for (j = 0; j < n; j++) predict[i *stride + j] = left[i * stride]; } static void predict_v_nxn(unsigned char *predict, int stride, int n) { unsigned char *above = predict - stride; int i, j; for (i = 0; i < n; i++) for (j = 0; j < n; j++) predict[i *stride + j] = above[j]; }
static void predict_tm_nxn(unsigned char *predict, int stride, int n) { /* Transposes the left column to the top row for later * consumption by the idct/recon stage */ unsigned char *left = predict - 1; unsigned char *above = predict - stride; unsigned char p = above[-1]; int i, j; for (j = 0; j < n; j++) { for (i = 0; i < n; i++) predict[i] = CLAMP_255(*left + above[i] - p); predict += stride; left += stride; } } static void predict_dc_nxn(unsigned char *predict, int stride, int n) { unsigned char *left = predict - 1; unsigned char *above = predict - stride; int i, j, dc = 0; for (i = 0; i < n; i++) { dc += *left + above[i]; left += stride; }
switch (n) { case 16: dc = (dc + 16) >> 5; break; case 8: dc = (dc + 8) >> 4; break; case 4: dc = (dc + 4) >> 3; break; } for (i = 0; i < n; i++) for (j = 0; j < n; j++) predict[i *stride + j] = dc; } static void predict_ve_4x4(unsigned char *predict, int stride) { unsigned char *above = predict - stride; int i, j; predict[0] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2; predict[1] = (above[ 0] + 2 * above[1] + above[2] + 2) >> 2; predict[2] = (above[ 1] + 2 * above[2] + above[3] + 2) >> 2; predict[3] = (above[ 2] + 2 * above[3] + above[4] + 2) >> 2; for (i = 1; i < 4; i++) for (j = 0; j < 4; j++) predict[i *stride + j] = predict[j]; }
static void predict_he_4x4(unsigned char *predict, int stride) { unsigned char *left = predict - 1; predict[0] = predict[1] = predict[2] = predict[3] = (left[-stride] + 2 * left[0] + left[stride] + 2) >> 2; predict += stride; left += stride; predict[0] = predict[1] = predict[2] = predict[3] = (left[-stride] + 2 * left[0] + left[stride] + 2) >> 2; predict += stride; left += stride; predict[0] = predict[1] = predict[2] = predict[3] = (left[-stride] + 2 * left[0] + left[stride] + 2) >> 2; predict += stride; left += stride; predict[0] = predict[1] = predict[2] = predict[3] = (left[-stride] + 2 * left[0] + left[0] + 2) >> 2; }
static void predict_ld_4x4(unsigned char *predict, int stride) { unsigned char *above = predict - stride; int pred0, pred1, pred2, pred3, pred4, pred5, pred6; predict[0] = pred0 = (above[0] + 2 * above[1] + above[2] + 2) >> 2; predict[1] = pred1 = (above[1] + 2 * above[2] + above[3] + 2) >> 2; predict[2] = pred2 = (above[2] + 2 * above[3] + above[4] + 2) >> 2; predict[3] = pred3 = (above[3] + 2 * above[4] + above[5] + 2) >> 2; predict += stride; predict[0] = pred1; predict[1] = pred2; predict[2] = pred3; predict[3] = pred4 = (above[4] + 2 * above[5] + above[6] + 2) >> 2; predict += stride; predict[0] = pred2; predict[1] = pred3; predict[2] = pred4; predict[3] = pred5 = (above[5] + 2 * above[6] + above[7] + 2) >> 2; predict += stride; predict[0] = pred3; predict[1] = pred4; predict[2] = pred5; predict[3] = pred6 = (above[6] + 2 * above[7] + above[7] + 2) >> 2; }
static void predict_rd_4x4(unsigned char *predict, int stride) { unsigned char *left = predict - 1; unsigned char *above = predict - stride; int pred0, pred1, pred2, pred3, pred4, pred5, pred6; predict[0] = pred0 = (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2; predict[1] = pred1 = (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2; predict[2] = pred2 = (above[ 0] + 2 * above[ 1] + above[2] + 2) >> 2; predict[3] = pred3 = (above[ 1] + 2 * above[ 2] + above[3] + 2) >> 2; predict += stride; predict[0] = pred4 = (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; predict[1] = pred0; predict[2] = pred1; predict[3] = pred2; predict += stride; predict[0] = pred5 = (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; predict[1] = pred4; predict[2] = pred0; predict[3] = pred1; predict += stride; predict[0] = pred6 = (left[stride*3] + 2 * left[stride*2] + left[stride] + 2) >> 2; predict[1] = pred5; predict[2] = pred4; predict[3] = pred0; }
static void predict_vr_4x4(unsigned char *predict, int stride) { unsigned char *left = predict - 1; unsigned char *above = predict - stride; int pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7, pred8, pred9; predict[0] = pred0 = (above[-1] + above[0] + 1) >> 1; predict[1] = pred1 = (above[ 0] + above[1] + 1) >> 1; predict[2] = pred2 = (above[ 1] + above[2] + 1) >> 1; predict[3] = pred3 = (above[ 2] + above[3] + 1) >> 1; predict += stride; predict[0] = pred4 = (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2; predict[1] = pred5 = (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2; predict[2] = pred6 = (above[ 0] + 2 * above[ 1] + above[2] + 2) >> 2; predict[3] = pred7 = (above[ 1] + 2 * above[ 2] + above[3] + 2) >> 2; predict += stride; predict[0] = pred8 = (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; predict[1] = pred0; predict[2] = pred1; predict[3] = pred2; predict += stride; predict[0] = pred9 = (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; predict[1] = pred4; predict[2] = pred5; predict[3] = pred6; }
static void predict_vl_4x4(unsigned char *predict, int stride) { unsigned char *above = predict - stride; int pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7, pred8, pred9; predict[0] = pred0 = (above[0] + above[1] + 1) >> 1; predict[1] = pred1 = (above[1] + above[2] + 1) >> 1; predict[2] = pred2 = (above[2] + above[3] + 1) >> 1; predict[3] = pred3 = (above[3] + above[4] + 1) >> 1; predict += stride; predict[0] = pred4 = (above[0] + 2 * above[1] + above[2] + 2) >> 2; predict[1] = pred5 = (above[1] + 2 * above[2] + above[3] + 2) >> 2; predict[2] = pred6 = (above[2] + 2 * above[3] + above[4] + 2) >> 2; predict[3] = pred7 = (above[3] + 2 * above[4] + above[5] + 2) >> 2; predict += stride; predict[0] = pred1; predict[1] = pred2; predict[2] = pred3; predict[3] = pred8 = (above[4] + 2 * above[5] + above[6] + 2) >> 2; predict += stride; predict[0] = pred5; predict[1] = pred6; predict[2] = pred7; predict[3] = pred9 = (above[5] + 2 * above[6] + above[7] + 2) >> 2; }
static void predict_hd_4x4(unsigned char *predict, int stride) { unsigned char *left = predict - 1; unsigned char *above = predict - stride; int pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7, pred8, pred9; predict[0] = pred0 = (left[ 0] + above[-1] + 1) >> 1; predict[1] = pred1 = (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2; predict[2] = pred2 = (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2; predict[3] = pred3 = (above[ 0] + 2 * above[ 1] + above[2] + 2) >> 2; predict += stride; predict[0] = pred4 = (left[stride] + left[0] + 1) >> 1; predict[1] = pred5 = (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; predict[2] = pred0; predict[3] = pred1; predict += stride; predict[0] = pred6 = (left[stride*2] + left[stride] + 1) >> 1; predict[1] = pred7 = (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; predict[2] = pred4; predict[3] = pred5; predict += stride; predict[0] = pred8 = (left[stride*3] + left[stride*2] + 1) >> 1; predict[1] = pred9 = (left[stride*3] + 2 * left[stride*2] + left[stride] + 2) >> 2; predict[2] = pred6; predict[3] = pred7; }
static void predict_hu_4x4(unsigned char *predict, int stride) { unsigned char *left = predict - 1; int pred0, pred1, pred2, pred3, pred4, pred5, pred6; predict[0] = pred0 = (left[stride*0] + left[stride*1] + 1) >> 1; predict[1] = pred1 = (left[stride*0] + 2 * left[stride*1] + left[stride*2] + 2) >> 2; predict[2] = pred2 = (left[stride*1] + left[stride*2] + 1) >> 1; predict[3] = pred3 = (left[stride*1] + 2 * left[stride*2] + left[stride*3] + 2) >> 2; predict += stride; predict[0] = pred2; predict[1] = pred3; predict[2] = pred4 = (left[stride*2] + left[stride*3] + 1) >> 1; predict[3] = pred5 = (left[stride*2] + 2 * left[stride*3] + left[stride*3] + 2) >> 2; predict += stride; predict[0] = pred4; predict[1] = pred5; predict[2] = pred6 = left[stride*3]; predict[3] = pred6; predict += stride; predict[0] = pred6; predict[1] = pred6; predict[2] = pred6; predict[3] = pred6; } static void predict_h_16x16(unsigned char *predict, int stride) { predict_h_nxn(predict, stride, 16); } static void predict_v_16x16(unsigned char *predict, int stride) { predict_v_nxn(predict, stride, 16); }
static void predict_tm_16x16(unsigned char *predict, int stride) { predict_tm_nxn(predict, stride, 16); } static void predict_h_8x8(unsigned char *predict, int stride) { predict_h_nxn(predict, stride, 8); } static void predict_v_8x8(unsigned char *predict, int stride) { predict_v_nxn(predict, stride, 8); } static void predict_tm_8x8(unsigned char *predict, int stride) { predict_tm_nxn(predict, stride, 8); } static void predict_tm_4x4(unsigned char *predict, int stride) { predict_tm_nxn(predict, stride, 4); } static void copy_down(unsigned char *recon, int stride) { /* Copy the four pixels above-right of subblock 3 to * above-right of subblocks 7, 11, and 15 */ uint32_t tmp, *copy = (void *)(recon + 16 - stride);
stride = stride / sizeof(unsigned int); tmp = *copy; copy += stride * 4; *copy = tmp; copy += stride * 4; *copy = tmp; copy += stride * 4; *copy = tmp; } static void b_pred(unsigned char *predict, int stride, struct mb_info *mbi, short *coeffs) { int i; copy_down(predict, stride); for (i = 0; i < 16; i++) { unsigned char *b_predict = predict + (i & 3) * 4; switch (mbi->split.modes[i]) { case B_DC_PRED: predict_dc_nxn(b_predict, stride, 4); break; case B_TM_PRED: predict_tm_4x4(b_predict, stride); break; case B_VE_PRED: predict_ve_4x4(b_predict, stride); break; case B_HE_PRED: predict_he_4x4(b_predict, stride); break; case B_LD_PRED: predict_ld_4x4(b_predict, stride); break; case B_RD_PRED: predict_rd_4x4(b_predict, stride); break; case B_VR_PRED: predict_vr_4x4(b_predict, stride); break;
case B_VL_PRED: predict_vl_4x4(b_predict, stride); break; case B_HD_PRED: predict_hd_4x4(b_predict, stride); break; case B_HU_PRED: predict_hu_4x4(b_predict, stride); break; default: assert(0); } vp8_dixie_idct_add(b_predict, b_predict, stride, coeffs); coeffs += 16; if ((i & 3) == 3) { predict += stride * 4; } } } static void fixup_dc_coeffs(struct mb_info *mbi, short *coeffs) { short y2[16]; int i; vp8_dixie_walsh(coeffs + 24 * 16, y2); for (i = 0; i < 16; i++) coeffs[i*16] = y2[i]; } static void predict_intra_luma(unsigned char *predict, int stride, struct mb_info *mbi, short *coeffs) { if (mbi->base.y_mode == B_PRED) b_pred(predict, stride, mbi, coeffs); else
{ int i; switch (mbi->base.y_mode) { case DC_PRED: predict_dc_nxn(predict, stride, 16); break; case V_PRED: predict_v_16x16(predict, stride); break; case H_PRED: predict_h_16x16(predict, stride); break; case TM_PRED: predict_tm_16x16(predict, stride); break; default: assert(0); } fixup_dc_coeffs(mbi, coeffs); for (i = 0; i < 16; i++) { vp8_dixie_idct_add(predict, predict, stride, coeffs); coeffs += 16; predict += 4; if ((i & 3) == 3) predict += stride * 4 - 16; } } } static void predict_intra_chroma(unsigned char *predict_u, unsigned char *predict_v, int stride, struct mb_info *mbi, short *coeffs) { int i;
switch (mbi->base.uv_mode) { case DC_PRED: predict_dc_nxn(predict_u, stride, 8); predict_dc_nxn(predict_v, stride, 8); break; case V_PRED: predict_v_8x8(predict_u, stride); predict_v_8x8(predict_v, stride); break; case H_PRED: predict_h_8x8(predict_u, stride); predict_h_8x8(predict_v, stride); break; case TM_PRED: predict_tm_8x8(predict_u, stride); predict_tm_8x8(predict_v, stride); break; default: assert(0); } coeffs += 16 * 16; for (i = 16; i < 20; i++) { vp8_dixie_idct_add(predict_u, predict_u, stride, coeffs); coeffs += 16; predict_u += 4; if (i & 1) predict_u += stride * 4 - 8; } for (i = 20; i < 24; i++) { vp8_dixie_idct_add(predict_v, predict_v, stride, coeffs); coeffs += 16; predict_v += 4; if (i & 1) predict_v += stride * 4 - 8; } }
static void sixtap_horiz(unsigned char *output, int output_stride, const unsigned char *reference, int reference_stride, int cols, int rows, const filter_t filter ) { int r, c, temp; for (r = 0; r < rows; r++) { for (c = 0; c < cols; c++) { temp = (reference[-2] * filter[0]) + (reference[-1] * filter[1]) + (reference[ 0] * filter[2]) + (reference[ 1] * filter[3]) + (reference[ 2] * filter[4]) + (reference[ 3] * filter[5]) + 64; temp >>= 7; output[c] = CLAMP_255(temp); reference++; } reference += reference_stride - cols; output += output_stride; } } static void sixtap_vert(unsigned char *output, int output_stride, const unsigned char *reference, int reference_stride, int cols, int rows, const filter_t filter ) { int r, c, temp; for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) { temp = (reference[-2*reference_stride] * filter[0]) + (reference[-1*reference_stride] * filter[1]) + (reference[ 0*reference_stride] * filter[2]) + (reference[ 1*reference_stride] * filter[3]) + (reference[ 2*reference_stride] * filter[4]) + (reference[ 3*reference_stride] * filter[5]) + 64; temp >>= 7; output[c] = CLAMP_255(temp); reference++; } reference += reference_stride - cols; output += output_stride; } } static void sixtap_2d(unsigned char *output, int output_stride, const unsigned char *reference, int reference_stride, int cols, int rows, int mx, int my, const filter_t filters[8] ) { DECLARE_ALIGNED(16, unsigned char, temp[16*(16+5)]); sixtap_horiz(temp, 16, reference - 2 * reference_stride, reference_stride, cols, rows + 5, filters[mx]); sixtap_vert(output, output_stride, temp + 2 * 16, 16, cols, rows, filters[my]); } struct img_index { unsigned char *y, *u, *v; int stride, uv_stride; };
static const unsigned char * filter_block(unsigned char *output, const unsigned char *reference, int stride, const union mv *mv, const filter_t filters[8]) { int mx, my; /* Handle 0,0 as a special case. TODO: Does this make it any * faster? */ if (!mv->raw) return reference; mx = mv->d.x & 7; my = mv->d.y & 7; reference += ((mv->d.y >> 3) * stride) + (mv->d.x >> 3); if (mx | my) { sixtap_2d(output, stride, reference, stride, 4, 4, mx, my, filters); reference = output; } return reference; } static void recon_1_block(unsigned char *output, const unsigned char *reference, int stride, const union mv *mv, const filter_t filters[8], short *coeffs, struct mb_info *mbi, int b ) { const unsigned char *predict; predict = filter_block(output, reference, stride, mv, filters); vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b); }
static mv_t calculate_chroma_splitmv(struct mb_info *mbi, int b, int full_pixel) { int temp; union mv mv; temp = mbi->split.mvs[b].d.x + mbi->split.mvs[b+1].d.x + mbi->split.mvs[b+4].d.x + mbi->split.mvs[b+5].d.x; if (temp < 0) temp -= 4; else temp += 4; mv.d.x = temp / 8; temp = mbi->split.mvs[b].d.y + mbi->split.mvs[b+1].d.y + mbi->split.mvs[b+4].d.y + mbi->split.mvs[b+5].d.y; if (temp < 0) temp -= 4; else temp += 4; mv.d.y = temp / 8; if (full_pixel) { mv.d.x &= ~7; mv.d.y &= ~7; } return mv; }
/* Note: We rely on the reconstructed border having the same stride * as the reference buffer because the filter_block can't adjust the * stride with its return value, only the reference pointer. */ static void build_mc_border(unsigned char *dst, const unsigned char *src, int stride, int x, int y, int b_w, int b_h, int w, int h ) { const unsigned char *ref_row; /* Get a pointer to the start of the real data for this row */ ref_row = src - x - y * stride; if (y >= h) ref_row += (h - 1) * stride; else if (y > 0) ref_row += y * stride; do { int left, right = 0, copy; left = x < 0 ? -x : 0; if (left > b_w) left = b_w; if (x + b_w > w) right = x + b_w - w; if (right > b_w) right = b_w;
copy = b_w - left - right; if (left) memset(dst, ref_row[0], left); if (copy) memcpy(dst + left, ref_row + x + left, copy); if (right) memset(dst + left + copy, ref_row[w-1], right); dst += stride; y++; if (y < h && y > 0) ref_row += stride; } while (--b_h); } static void recon_1_edge_block(unsigned char *output, unsigned char *emul_block, const unsigned char *reference, int stride, const union mv *mv, const filter_t filters[8], short *coeffs, struct mb_info *mbi, int x, int y, int w, int h, int start_b ) { const unsigned char *predict; int b = start_b; const int b_w = 4; const int b_h = 4; x += mv->d.x >> 3; y += mv->d.y >> 3;
/* Need two pixels left/above, 3 right/below for 6-tap */ if (x < 2 || x + b_w - 1 + 3 >= w || y < 2 || y + b_h - 1 + 3 >= h) { reference += (mv->d.x >> 3) + (mv->d.y >> 3) * stride; build_mc_border(emul_block, reference - 2 - 2 * stride, stride, x - 2, y - 2, b_w + 5, b_h + 5, w, h); reference = emul_block + 2 * stride + 2; reference -= (mv->d.x >> 3) + (mv->d.y >> 3) * stride; } predict = filter_block(output, reference, stride, mv, filters); vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b); } static void predict_inter_emulated_edge(struct vp8_decoder_ctx *ctx, struct img_index *img, short *coeffs, struct mb_info *mbi, int mb_col, int mb_row) { /* TODO: Move this into its own buffer. This only works because * we still have a border allocated. */ unsigned char *emul_block = ctx->frame_strg[0].img.img_data; unsigned char *reference; unsigned char *output; ptrdiff_t reference_offset; int w, h, x, y, b; union mv chroma_mv[4]; unsigned char *u = img->u, *v = img->v; int full_pixel = ctx->frame_hdr.version == 3; x = mb_col * 16; y = mb_row * 16; w = ctx->mb_cols * 16; h = ctx->mb_rows * 16; output = img->y; reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame]; reference = output + reference_offset;
if (mbi->base.y_mode != SPLITMV) { union mv uvmv; uvmv = mbi->base.mv; uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2; uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2; if (full_pixel) { uvmv.d.x &= ~7; uvmv.d.y &= ~7; } chroma_mv[0] = uvmv; chroma_mv[1] = uvmv; chroma_mv[2] = uvmv; chroma_mv[3] = uvmv; } else { chroma_mv[0] = calculate_chroma_splitmv(mbi, 0, full_pixel); chroma_mv[1] = calculate_chroma_splitmv(mbi, 2, full_pixel); chroma_mv[2] = calculate_chroma_splitmv(mbi, 8, full_pixel); chroma_mv[3] = calculate_chroma_splitmv(mbi, 10, full_pixel); } /* Luma */ for (b = 0; b < 16; b++) { union mv *ymv; if (mbi->base.y_mode != SPLITMV) ymv = &mbi->base.mv; else ymv = mbi->split.mvs + b; recon_1_edge_block(output, emul_block, reference, img->stride, ymv, ctx->subpixel_filters, coeffs, mbi, x, y, w, h, b); x += 4; output += 4; reference += 4;
if ((b & 3) == 3) { x -= 16; y += 4; output += 4 * img->stride - 16; reference += 4 * img->stride - 16; } } x = mb_col * 16; y = mb_row * 16; /* Chroma */ x >>= 1; y >>= 1; w >>= 1; h >>= 1; for (b = 0; b < 4; b++) { recon_1_edge_block(u, emul_block, u + reference_offset, img->uv_stride, &chroma_mv[b], ctx->subpixel_filters, coeffs, mbi, x, y, w, h, b + 16); recon_1_edge_block(v, emul_block, v + reference_offset, img->uv_stride, &chroma_mv[b], ctx->subpixel_filters, coeffs, mbi, x, y, w, h, b + 20); u += 4; v += 4; x += 4; if (b & 1) { x -= 8; y += 4; u += 4 * img->uv_stride - 8; v += 4 * img->uv_stride - 8; } } } static void predict_inter(struct vp8_decoder_ctx *ctx, struct img_index *img, short *coeffs, struct mb_info *mbi)
{ unsigned char *y = img->y; unsigned char *u = img->u; unsigned char *v = img->v; ptrdiff_t reference_offset; union mv chroma_mv[4]; int full_pixel = ctx->frame_hdr.version == 3; int b; if (mbi->base.y_mode != SPLITMV) { union mv uvmv; uvmv = mbi->base.mv; uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2; uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2; if (full_pixel) { uvmv.d.x &= ~7; uvmv.d.y &= ~7; } chroma_mv[0] = chroma_mv[1] = chroma_mv[2] = chroma_mv[3] = uvmv; } else { chroma_mv[0] = calculate_chroma_splitmv(mbi, 0, full_pixel); chroma_mv[1] = calculate_chroma_splitmv(mbi, 2, full_pixel); chroma_mv[2] = calculate_chroma_splitmv(mbi, 8, full_pixel); chroma_mv[3] = calculate_chroma_splitmv(mbi, 10, full_pixel); } reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame]; for (b = 0; b < 16; b++) { union mv *ymv; if (mbi->base.y_mode != SPLITMV) ymv = &mbi->base.mv; else ymv = mbi->split.mvs + b; recon_1_block(y, y + reference_offset, img->stride, ymv, ctx->subpixel_filters, coeffs, mbi, b);
y += 4; if ((b & 3) == 3) y += 4 * img->stride - 16; } for (b = 0; b < 4; b++) { recon_1_block(u, u + reference_offset, img->uv_stride, &chroma_mv[b], ctx->subpixel_filters, coeffs, mbi, b + 16); recon_1_block(v, v + reference_offset, img->uv_stride, &chroma_mv[b], ctx->subpixel_filters, coeffs, mbi, b + 20); u += 4; v += 4; if (b & 1) { u += 4 * img->uv_stride - 8; v += 4 * img->uv_stride - 8; } } } void vp8_dixie_release_ref_frame(struct ref_cnt_img *rcimg) { if (rcimg) { assert(rcimg->ref_cnt); rcimg->ref_cnt--; } } struct ref_cnt_img * vp8_dixie_ref_frame(struct ref_cnt_img *rcimg) { rcimg->ref_cnt++; return rcimg; }
struct ref_cnt_img * vp8_dixie_find_free_ref_frame(struct ref_cnt_img *frames) { int i; for (i = 0; i < NUM_REF_FRAMES; i++) if (frames[i].ref_cnt == 0) { frames[i].ref_cnt = 1; return &frames[i]; } assert(0); return NULL; } static void fixup_left(unsigned char *predict, int width, int stride, unsigned int row, enum prediction_mode mode) { /* The left column of out-of-frame pixels is taken to be 129, * unless we're doing DC_PRED, in which case we duplicate the * above row, unless this is also row 0, in which case we use * 129. */ unsigned char *left = predict - 1; int i; if (mode == DC_PRED && row) { unsigned char *above = predict - stride; for (i = 0; i < width; i++) { *left = above[i]; left += stride; } } else { /* Need to re-set the above row, in case the above MB was * DC_PRED. */ left -= stride;
for (i = -1; i < width; i++) { *left = 129; left += stride; } } } static void fixup_above(unsigned char *predict, int width, int stride, unsigned int col, enum prediction_mode mode) { /* The above row of out-of-frame pixels is taken to be 127, * unless we're doing DC_PRED, in which case we duplicate the * left col, unless this is also col 0, in which case we use * 127. */ unsigned char *above = predict - stride; int i; if (mode == DC_PRED && col) { unsigned char *left = predict - 1; for (i = 0; i < width; i++) { above[i] = *left; left += stride; } } else /* Need to re-set the left col, in case the last MB was * DC_PRED. */ memset(above - 1, 127, width + 1); memset(above + width, 127, 4); // for above-right subblock modes }
void vp8_dixie_predict_init(struct vp8_decoder_ctx *ctx) { int i; unsigned char *this_frame_base; if (ctx->frame_hdr.frame_size_updated) { for (i = 0; i < NUM_REF_FRAMES; i++) { unsigned int w = ctx->mb_cols * 16 + BORDER_PIXELS * 2; unsigned int h = ctx->mb_rows * 16 + BORDER_PIXELS * 2; vpx_img_free(&ctx->frame_strg[i].img); ctx->frame_strg[i].ref_cnt = 0; ctx->ref_frames[i] = NULL; if (!vpx_img_alloc(&ctx->frame_strg[i].img, IMG_FMT_I420, w, h, 16)) vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR, "Failed to allocate %dx%d" " framebuffer", w, h); vpx_img_set_rect(&ctx->frame_strg[i].img, BORDER_PIXELS, BORDER_PIXELS, ctx->frame_hdr.kf.w, ctx->frame_hdr.kf.h); } if (ctx->frame_hdr.version) ctx->subpixel_filters = bilinear_filters; else ctx->subpixel_filters = sixtap_filters; } /* Find a free framebuffer to predict into */ if (ctx->ref_frames[CURRENT_FRAME]) vp8_dixie_release_ref_frame(ctx->ref_frames[CURRENT_FRAME]); ctx->ref_frames[CURRENT_FRAME] = vp8_dixie_find_free_ref_frame(ctx->frame_strg); this_frame_base = ctx->ref_frames[CURRENT_FRAME]->img.img_data;
/* Calculate offsets to the other reference frames */ for (i = 0; i < NUM_REF_FRAMES; i++) { struct ref_cnt_img *ref = ctx->ref_frames[i]; ctx->ref_frame_offsets[i] = ref ? ref->img.img_data - this_frame_base : 0; } /* TODO: No need to do this on every frame... */ } void vp8_dixie_predict_destroy(struct vp8_decoder_ctx *ctx) { int i; for (i = 0; i < NUM_REF_FRAMES; i++) { vpx_img_free(&ctx->frame_strg[i].img); ctx->frame_strg[i].ref_cnt = 0; ctx->ref_frames[i] = NULL; } } void vp8_dixie_predict_process_row(struct vp8_decoder_ctx *ctx, unsigned int row, unsigned int start_col, unsigned int num_cols) { struct img_index img; struct mb_info *mbi; unsigned int col; short *coeffs;
/* Adjust pointers based on row, start_col */ img.stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; img.uv_stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_U]; img.y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; img.u = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_U]; img.v = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_V]; img.y += (img.stride * row + start_col) * 16; img.u += (img.uv_stride * row + start_col) * 8; img.v += (img.uv_stride * row + start_col) * 8; mbi = ctx->mb_info_rows[row] + start_col; coeffs = ctx->tokens[row & (ctx->token_hdr.partitions - 1)].coeffs + 25 * 16 * start_col; /* Fix up the out-of-frame pixels */ if (start_col == 0) { fixup_left(img.y, 16, img.stride, row, mbi->base.y_mode); fixup_left(img.u, 8, img.uv_stride, row, mbi->base.uv_mode); fixup_left(img.v, 8, img.uv_stride, row, mbi->base.uv_mode); if (row == 0) *(img.y - img.stride - 1) = 127; } for (col = start_col; col < start_col + num_cols; col++) { if (row == 0) { fixup_above(img.y, 16, img.stride, col, mbi->base.y_mode); fixup_above(img.u, 8, img.uv_stride, col, mbi->base.uv_mode); fixup_above(img.v, 8, img.uv_stride, col, mbi->base.uv_mode); } if (mbi->base.y_mode <= B_PRED) { predict_intra_luma(img.y, img.stride, mbi, coeffs); predict_intra_chroma(img.u, img.v, img.uv_stride, mbi, coeffs); }
else { if (mbi->base.y_mode != SPLITMV) // && != BPRED fixup_dc_coeffs(mbi, coeffs); if (mbi->base.need_mc_border) predict_inter_emulated_edge(ctx, &img, coeffs, mbi, col, row); else predict_inter(ctx, &img, coeffs, mbi); } /* Advance to the next macroblock */ mbi++; img.y += 16; img.u += 8; img.v += 8; coeffs += 25 * 16; } if (col == ctx->mb_cols) { /* Extend the last row by four pixels for intra-prediction. * This will be propagated later by copy_down. */ uint32_t *extend = (uint32_t *)(img.y + 15 * img.stride); uint32_t val = 0x01010101 * img.y[-1 + 15 * img.stride]; *extend = val; } } ---- End code block ----------------------------------------