| File: | root/firefox-clang/media/ffvpx/libavcodec/vp9_mc_template.c |
| Warning: | line 426, column 13 Array access (via field 'data') results in an undefined pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | ||||
| 2 | * VP9 compatible video decoder | ||||
| 3 | * | ||||
| 4 | * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com> | ||||
| 5 | * Copyright (C) 2013 Clément Bœsch <u pkh me> | ||||
| 6 | * | ||||
| 7 | * This file is part of FFmpeg. | ||||
| 8 | * | ||||
| 9 | * FFmpeg is free software; you can redistribute it and/or | ||||
| 10 | * modify it under the terms of the GNU Lesser General Public | ||||
| 11 | * License as published by the Free Software Foundation; either | ||||
| 12 | * version 2.1 of the License, or (at your option) any later version. | ||||
| 13 | * | ||||
| 14 | * FFmpeg is distributed in the hope that it will be useful, | ||||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| 17 | * Lesser General Public License for more details. | ||||
| 18 | * | ||||
| 19 | * You should have received a copy of the GNU Lesser General Public | ||||
| 20 | * License along with FFmpeg; if not, write to the Free Software | ||||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
| 22 | */ | ||||
| 23 | |||||
| 24 | #include "libavutil/avassert.h" | ||||
| 25 | #include "libavutil/frame.h" | ||||
| 26 | #include "libavutil/mem_internal.h" | ||||
| 27 | |||||
| 28 | #include "progressframe.h" | ||||
| 29 | #include "videodsp.h" | ||||
| 30 | #include "vp9data.h" | ||||
| 31 | #include "vp9dec.h" | ||||
| 32 | |||||
| 33 | static av_always_inline__attribute__((always_inline)) inline int check_intra_mode(VP9TileData *td, int mode, uint8_t **a, | ||||
| 34 | uint8_t *dst_edge, ptrdiff_t stride_edge, | ||||
| 35 | uint8_t *dst_inner, ptrdiff_t stride_inner, | ||||
| 36 | uint8_t *l, int col, int x, int w, | ||||
| 37 | int row, int y, enum TxfmMode tx, | ||||
| 38 | int p, int ss_h, int ss_v, int bytesperpixel) | ||||
| 39 | { | ||||
| 40 | const VP9Context *s = td->s; | ||||
| 41 | int have_top = row > 0 || y > 0; | ||||
| 42 | int have_left = col > td->tile_col_start || x > 0; | ||||
| 43 | int have_right = x < w - 1; | ||||
| 44 | int bpp = s->s.h.bpp; | ||||
| 45 | static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { | ||||
| 46 | [VERT_PRED] = { { DC_127_PRED, VERT_PRED }, | ||||
| 47 | { DC_127_PRED, VERT_PRED } }, | ||||
| 48 | [HOR_PRED] = { { DC_129_PRED, DC_129_PRED }, | ||||
| 49 | { HOR_PRED, HOR_PRED } }, | ||||
| 50 | [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED }, | ||||
| 51 | { LEFT_DC_PRED, DC_PRED } }, | ||||
| 52 | [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED }, | ||||
| 53 | { DC_127_PRED, DIAG_DOWN_LEFT_PRED } }, | ||||
| 54 | [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED }, | ||||
| 55 | { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } }, | ||||
| 56 | [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED }, | ||||
| 57 | { VERT_RIGHT_PRED, VERT_RIGHT_PRED } }, | ||||
| 58 | [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED }, | ||||
| 59 | { HOR_DOWN_PRED, HOR_DOWN_PRED } }, | ||||
| 60 | [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED }, | ||||
| 61 | { DC_127_PRED, VERT_LEFT_PRED } }, | ||||
| 62 | [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED }, | ||||
| 63 | { HOR_UP_PRED, HOR_UP_PRED } }, | ||||
| 64 | [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED }, | ||||
| 65 | { HOR_PRED, TM_VP8_PRED } }, | ||||
| 66 | }; | ||||
| 67 | static const struct { | ||||
| 68 | uint8_t needs_left:1; | ||||
| 69 | uint8_t needs_top:1; | ||||
| 70 | uint8_t needs_topleft:1; | ||||
| 71 | uint8_t needs_topright:1; | ||||
| 72 | uint8_t invert_left:1; | ||||
| 73 | } edges[N_INTRA_PRED_MODES] = { | ||||
| 74 | [VERT_PRED] = { .needs_top = 1 }, | ||||
| 75 | [HOR_PRED] = { .needs_left = 1 }, | ||||
| 76 | [DC_PRED] = { .needs_top = 1, .needs_left = 1 }, | ||||
| 77 | [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, | ||||
| 78 | [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, | ||||
| 79 | .needs_topleft = 1 }, | ||||
| 80 | [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, | ||||
| 81 | .needs_topleft = 1 }, | ||||
| 82 | [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, | ||||
| 83 | .needs_topleft = 1 }, | ||||
| 84 | [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 }, | ||||
| 85 | [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 }, | ||||
| 86 | [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, | ||||
| 87 | .needs_topleft = 1 }, | ||||
| 88 | [LEFT_DC_PRED] = { .needs_left = 1 }, | ||||
| 89 | [TOP_DC_PRED] = { .needs_top = 1 }, | ||||
| 90 | [DC_128_PRED] = { 0 }, | ||||
| 91 | [DC_127_PRED] = { 0 }, | ||||
| 92 | [DC_129_PRED] = { 0 } | ||||
| 93 | }; | ||||
| 94 | |||||
| 95 | av_assert2(mode >= 0 && mode < 10)do { if (!(mode >= 0 && mode < 10)) { av_log((( void*)0), 0, "Assertion %s failed at %s:%d\n", "mode >= 0 && mode < 10" , "/root/firefox-clang/media/ffvpx/libavcodec/vp9recon.c", 95 ); abort(); } } while (0); | ||||
| 96 | mode = mode_conv[mode][have_left][have_top]; | ||||
| 97 | if (edges[mode].needs_top) { | ||||
| 98 | uint8_t *top, *topleft; | ||||
| 99 | int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4; | ||||
| 100 | int n_px_need_tr = 0; | ||||
| 101 | |||||
| 102 | if (tx == TX_4X4 && edges[mode].needs_topright && have_right) | ||||
| 103 | n_px_need_tr = 4; | ||||
| 104 | |||||
| 105 | // if top of sb64-row, use s->intra_pred_data[] instead of | ||||
| 106 | // dst[-stride] for intra prediction (it contains pre- instead of | ||||
| 107 | // post-loopfilter data) | ||||
| 108 | if (have_top) { | ||||
| 109 | top = !(row & 7) && !y ? | ||||
| 110 | s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : | ||||
| 111 | y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner]; | ||||
| 112 | if (have_left) | ||||
| 113 | topleft = !(row & 7) && !y ? | ||||
| 114 | s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel : | ||||
| 115 | y == 0 || x == 0 ? &dst_edge[-stride_edge] : | ||||
| 116 | &dst_inner[-stride_inner]; | ||||
| 117 | } | ||||
| 118 | |||||
| 119 | if (have_top && | ||||
| 120 | (!edges[mode].needs_topleft || (have_left && top == topleft)) && | ||||
| 121 | (tx != TX_4X4 || !edges[mode].needs_topright || have_right) && | ||||
| 122 | n_px_need + n_px_need_tr <= n_px_have) { | ||||
| 123 | *a = top; | ||||
| 124 | } else { | ||||
| 125 | if (have_top) { | ||||
| 126 | if (n_px_need <= n_px_have) { | ||||
| 127 | memcpy(*a, top, n_px_need * bytesperpixel); | ||||
| 128 | } else { | ||||
| 129 | #define memset_bpp(c, i1, v, i2, num)do { if (bytesperpixel == 1) { memset(&(c)[(i1)], (v)[(i2 )], (num)); } else { int n, val = (((const av_alias16*)(& (v)[(i2) * 2]))->u16); for (n = 0; n < (num); n++) { (( (av_alias16*)(&(c)[((i1) + n) * 2]))->u16 = (val)); } } } while (0) do { \ | ||||
| 130 | if (bytesperpixel == 1) { \ | ||||
| 131 | memset(&(c)[(i1)], (v)[(i2)], (num)); \ | ||||
| 132 | } else { \ | ||||
| 133 | int n, val = AV_RN16A(&(v)[(i2) * 2])(((const av_alias16*)(&(v)[(i2) * 2]))->u16); \ | ||||
| 134 | for (n = 0; n < (num); n++) { \ | ||||
| 135 | AV_WN16A(&(c)[((i1) + n) * 2], val)(((av_alias16*)(&(c)[((i1) + n) * 2]))->u16 = (val)); \ | ||||
| 136 | } \ | ||||
| 137 | } \ | ||||
| 138 | } while (0) | ||||
| 139 | memcpy(*a, top, n_px_have * bytesperpixel); | ||||
| 140 | memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have)do { if (bytesperpixel == 1) { memset(&(*a)[(n_px_have)], ((*a))[(n_px_have - 1)], (n_px_need - n_px_have)); } else { int n, val = (((const av_alias16*)(&((*a))[(n_px_have - 1) * 2]))->u16); for (n = 0; n < (n_px_need - n_px_have); n ++) { (((av_alias16*)(&(*a)[((n_px_have) + n) * 2]))-> u16 = (val)); } } } while (0); | ||||
| 141 | } | ||||
| 142 | } else { | ||||
| 143 | #define memset_val(c, val, num)do { if (bytesperpixel == 1) { memset((c), (val), (num)); } else { int n; for (n = 0; n < (num); n++) { (((av_alias16*)(& (c)[n * 2]))->u16 = ((val))); } } } while (0) do { \ | ||||
| 144 | if (bytesperpixel == 1) { \ | ||||
| 145 | memset((c), (val), (num)); \ | ||||
| 146 | } else { \ | ||||
| 147 | int n; \ | ||||
| 148 | for (n = 0; n < (num); n++) { \ | ||||
| 149 | AV_WN16A(&(c)[n * 2], (val))(((av_alias16*)(&(c)[n * 2]))->u16 = ((val))); \ | ||||
| 150 | } \ | ||||
| 151 | } \ | ||||
| 152 | } while (0) | ||||
| 153 | memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need)do { if (bytesperpixel == 1) { memset((*a), ((128 << (bpp - 8)) - 1), (n_px_need)); } else { int n; for (n = 0; n < (n_px_need); n++) { (((av_alias16*)(&(*a)[n * 2]))->u16 = (((128 << (bpp - 8)) - 1))); } } } while (0); | ||||
| 154 | } | ||||
| 155 | if (edges[mode].needs_topleft) { | ||||
| 156 | if (have_left && have_top) { | ||||
| 157 | #define assign_bpp(c, i1, v, i2)do { if (bytesperpixel == 1) { (c)[(i1)] = (v)[(i2)]; } else { (((av_alias16*)(&(c)[(i1) * 2]))->u16 = ((const av_alias16 *)(&(v)[(i2) * 2]))->u16); } } while (0) do { \ | ||||
| 158 | if (bytesperpixel == 1) { \ | ||||
| 159 | (c)[(i1)] = (v)[(i2)]; \ | ||||
| 160 | } else { \ | ||||
| 161 | AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2])(((av_alias16*)(&(c)[(i1) * 2]))->u16 = ((const av_alias16 *)(&(v)[(i2) * 2]))->u16); \ | ||||
| 162 | } \ | ||||
| 163 | } while (0) | ||||
| 164 | assign_bpp(*a, -1, topleft, -1)do { if (bytesperpixel == 1) { (*a)[(-1)] = (topleft)[(-1)]; } else { (((av_alias16*)(&(*a)[(-1) * 2]))->u16 = ((const av_alias16*)(&(topleft)[(-1) * 2]))->u16); } } while ( 0); | ||||
| 165 | } else { | ||||
| 166 | #define assign_val(c, i, v)do { if (bytesperpixel == 1) { (c)[(i)] = (v); } else { (((av_alias16 *)(&(c)[(i) * 2]))->u16 = ((v))); } } while (0) do { \ | ||||
| 167 | if (bytesperpixel == 1) { \ | ||||
| 168 | (c)[(i)] = (v); \ | ||||
| 169 | } else { \ | ||||
| 170 | AV_WN16A(&(c)[(i) * 2], (v))(((av_alias16*)(&(c)[(i) * 2]))->u16 = ((v))); \ | ||||
| 171 | } \ | ||||
| 172 | } while (0) | ||||
| 173 | assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1))do { if (bytesperpixel == 1) { ((*a))[(-1)] = ((128 << ( bpp - 8)) + (have_top ? +1 : -1)); } else { (((av_alias16*)(& ((*a))[(-1) * 2]))->u16 = (((128 << (bpp - 8)) + (have_top ? +1 : -1)))); } } while (0); | ||||
| 174 | } | ||||
| 175 | } | ||||
| 176 | if (tx == TX_4X4 && edges[mode].needs_topright) { | ||||
| 177 | if (have_top && have_right && | ||||
| 178 | n_px_need + n_px_need_tr <= n_px_have) { | ||||
| 179 | memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel); | ||||
| 180 | } else { | ||||
| 181 | memset_bpp(*a, 4, *a, 3, 4)do { if (bytesperpixel == 1) { memset(&(*a)[(4)], (*a)[(3 )], (4)); } else { int n, val = (((const av_alias16*)(&(* a)[(3) * 2]))->u16); for (n = 0; n < (4); n++) { (((av_alias16 *)(&(*a)[((4) + n) * 2]))->u16 = (val)); } } } while ( 0); | ||||
| 182 | } | ||||
| 183 | } | ||||
| 184 | } | ||||
| 185 | } | ||||
| 186 | if (edges[mode].needs_left) { | ||||
| 187 | if (have_left) { | ||||
| 188 | int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4; | ||||
| 189 | uint8_t *dst = x == 0 ? dst_edge : dst_inner; | ||||
| 190 | ptrdiff_t stride = x == 0 ? stride_edge : stride_inner; | ||||
| 191 | |||||
| 192 | if (edges[mode].invert_left) { | ||||
| 193 | if (n_px_need <= n_px_have) { | ||||
| 194 | for (i = 0; i < n_px_need; i++) | ||||
| 195 | assign_bpp(l, i, &dst[i * stride], -1)do { if (bytesperpixel == 1) { (l)[(i)] = (&dst[i * stride ])[(-1)]; } else { (((av_alias16*)(&(l)[(i) * 2]))->u16 = ((const av_alias16*)(&(&dst[i * stride])[(-1) * 2] ))->u16); } } while (0); | ||||
| 196 | } else { | ||||
| 197 | for (i = 0; i < n_px_have; i++) | ||||
| 198 | assign_bpp(l, i, &dst[i * stride], -1)do { if (bytesperpixel == 1) { (l)[(i)] = (&dst[i * stride ])[(-1)]; } else { (((av_alias16*)(&(l)[(i) * 2]))->u16 = ((const av_alias16*)(&(&dst[i * stride])[(-1) * 2] ))->u16); } } while (0); | ||||
| 199 | memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have)do { if (bytesperpixel == 1) { memset(&(l)[(n_px_have)], ( l)[(n_px_have - 1)], (n_px_need - n_px_have)); } else { int n , val = (((const av_alias16*)(&(l)[(n_px_have - 1) * 2])) ->u16); for (n = 0; n < (n_px_need - n_px_have); n++) { (((av_alias16*)(&(l)[((n_px_have) + n) * 2]))->u16 = ( val)); } } } while (0); | ||||
| 200 | } | ||||
| 201 | } else { | ||||
| 202 | if (n_px_need <= n_px_have) { | ||||
| 203 | for (i = 0; i < n_px_need; i++) | ||||
| 204 | assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1)do { if (bytesperpixel == 1) { (l)[(n_px_need - 1 - i)] = (& dst[i * stride])[(-1)]; } else { (((av_alias16*)(&(l)[(n_px_need - 1 - i) * 2]))->u16 = ((const av_alias16*)(&(&dst [i * stride])[(-1) * 2]))->u16); } } while (0); | ||||
| 205 | } else { | ||||
| 206 | for (i = 0; i < n_px_have; i++) | ||||
| 207 | assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1)do { if (bytesperpixel == 1) { (l)[(n_px_need - 1 - i)] = (& dst[i * stride])[(-1)]; } else { (((av_alias16*)(&(l)[(n_px_need - 1 - i) * 2]))->u16 = ((const av_alias16*)(&(&dst [i * stride])[(-1) * 2]))->u16); } } while (0); | ||||
| 208 | memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have)do { if (bytesperpixel == 1) { memset(&(l)[(0)], (l)[(n_px_need - n_px_have)], (n_px_need - n_px_have)); } else { int n, val = (((const av_alias16*)(&(l)[(n_px_need - n_px_have) * 2 ]))->u16); for (n = 0; n < (n_px_need - n_px_have); n++ ) { (((av_alias16*)(&(l)[((0) + n) * 2]))->u16 = (val) ); } } } while (0); | ||||
| 209 | } | ||||
| 210 | } | ||||
| 211 | } else { | ||||
| 212 | memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx)do { if (bytesperpixel == 1) { memset((l), ((128 << (bpp - 8)) + 1), (4 << tx)); } else { int n; for (n = 0; n < (4 << tx); n++) { (((av_alias16*)(&(l)[n * 2]))-> u16 = (((128 << (bpp - 8)) + 1))); } } } while (0); | ||||
| 213 | } | ||||
| 214 | } | ||||
| 215 | |||||
| 216 | return mode; | ||||
| 217 | } | ||||
| 218 | |||||
| 219 | static av_always_inline__attribute__((always_inline)) inline void intra_recon(VP9TileData *td, ptrdiff_t y_off, | ||||
| 220 | ptrdiff_t uv_off, int bytesperpixel) | ||||
| 221 | { | ||||
| 222 | const VP9Context *s = td->s; | ||||
| 223 | VP9Block *b = td->b; | ||||
| 224 | int row = td->row, col = td->col; | ||||
| 225 | int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; | ||||
| 226 | int h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); | ||||
| 227 | int end_x = FFMIN(2 * (s->cols - col), w4)((2 * (s->cols - col)) > (w4) ? (w4) : (2 * (s->cols - col))); | ||||
| 228 | int end_y = FFMIN(2 * (s->rows - row), h4)((2 * (s->rows - row)) > (h4) ? (h4) : (2 * (s->rows - row))); | ||||
| 229 | int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; | ||||
| 230 | int uvstep1d = 1 << b->uvtx, p; | ||||
| 231 | uint8_t *dst = td->dst[0], *dst_r = s->s.frames[CUR_FRAME0].tf.f->data[0] + y_off; | ||||
| 232 | LOCAL_ALIGNED_32(uint8_t, a_buf, [96])_Alignas(32) uint8_t la_a_buf [96] ; uint8_t (*a_buf) = la_a_buf; | ||||
| 233 | LOCAL_ALIGNED_32(uint8_t, l, [64])_Alignas(32) uint8_t la_l [64] ; uint8_t (*l) = la_l; | ||||
| 234 | |||||
| 235 | for (n = 0, y = 0; y < end_y; y += step1d) { | ||||
| 236 | uint8_t *ptr = dst, *ptr_r = dst_r; | ||||
| 237 | for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, | ||||
| 238 | ptr_r += 4 * step1d * bytesperpixel, n += step) { | ||||
| 239 | int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ? | ||||
| 240 | y * 2 + x : 0]; | ||||
| 241 | uint8_t *a = &a_buf[32]; | ||||
| 242 | enum TxfmType txtp = ff_vp9_intra_txfm_type[mode]; | ||||
| 243 | int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&td->eob[n])(((const av_alias16*)(&td->eob[n]))->u16) : td->eob[n]; | ||||
| 244 | |||||
| 245 | mode = check_intra_mode(td, mode, &a, ptr_r, | ||||
| 246 | s->s.frames[CUR_FRAME0].tf.f->linesize[0], | ||||
| 247 | ptr, td->y_stride, l, | ||||
| 248 | col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); | ||||
| 249 | s->dsp.intra_pred[b->tx][mode](ptr, td->y_stride, l, a); | ||||
| 250 | if (eob) | ||||
| 251 | s->dsp.itxfm_add[tx][txtp](ptr, td->y_stride, | ||||
| 252 | td->block + 16 * n * bytesperpixel, eob); | ||||
| 253 | } | ||||
| 254 | dst_r += 4 * step1d * s->s.frames[CUR_FRAME0].tf.f->linesize[0]; | ||||
| 255 | dst += 4 * step1d * td->y_stride; | ||||
| 256 | } | ||||
| 257 | |||||
| 258 | // U/V | ||||
| 259 | w4 >>= s->ss_h; | ||||
| 260 | end_x >>= s->ss_h; | ||||
| 261 | end_y >>= s->ss_v; | ||||
| 262 | step = 1 << (b->uvtx * 2); | ||||
| 263 | for (p = 0; p < 2; p++) { | ||||
| 264 | dst = td->dst[1 + p]; | ||||
| 265 | dst_r = s->s.frames[CUR_FRAME0].tf.f->data[1 + p] + uv_off; | ||||
| 266 | for (n = 0, y = 0; y < end_y; y += uvstep1d) { | ||||
| 267 | uint8_t *ptr = dst, *ptr_r = dst_r; | ||||
| 268 | for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, | ||||
| 269 | ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { | ||||
| 270 | int mode = b->uvmode; | ||||
| 271 | uint8_t *a = &a_buf[32]; | ||||
| 272 | int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&td->uveob[p][n])(((const av_alias16*)(&td->uveob[p][n]))->u16) : td->uveob[p][n]; | ||||
| 273 | |||||
| 274 | mode = check_intra_mode(td, mode, &a, ptr_r, | ||||
| 275 | s->s.frames[CUR_FRAME0].tf.f->linesize[1], | ||||
| 276 | ptr, td->uv_stride, l, col, x, w4, row, y, | ||||
| 277 | b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); | ||||
| 278 | s->dsp.intra_pred[b->uvtx][mode](ptr, td->uv_stride, l, a); | ||||
| 279 | if (eob) | ||||
| 280 | s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, | ||||
| 281 | td->uvblock[p] + 16 * n * bytesperpixel, eob); | ||||
| 282 | } | ||||
| 283 | dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME0].tf.f->linesize[1]; | ||||
| 284 | dst += 4 * uvstep1d * td->uv_stride; | ||||
| 285 | } | ||||
| 286 | } | ||||
| 287 | } | ||||
| 288 | |||||
| 289 | void ff_vp9_intra_recon_8bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) | ||||
| 290 | { | ||||
| 291 | intra_recon(td, y_off, uv_off, 1); | ||||
| 292 | } | ||||
| 293 | |||||
| 294 | void ff_vp9_intra_recon_16bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) | ||||
| 295 | { | ||||
| 296 | intra_recon(td, y_off, uv_off, 2); | ||||
| 297 | } | ||||
| 298 | |||||
| 299 | static av_always_inline__attribute__((always_inline)) inline void mc_luma_unscaled(VP9TileData *td, const vp9_mc_func (*mc)[2], | ||||
| 300 | uint8_t *dst, ptrdiff_t dst_stride, | ||||
| 301 | const uint8_t *ref, ptrdiff_t ref_stride, | ||||
| 302 | const ProgressFrame *ref_frame, | ||||
| 303 | ptrdiff_t y, ptrdiff_t x, const VP9mv *mv, | ||||
| 304 | int bw, int bh, int w, int h, int bytesperpixel) | ||||
| 305 | { | ||||
| 306 | const VP9Context *s = td->s; | ||||
| 307 | int mx = mv->x, my = mv->y, th; | ||||
| 308 | |||||
| 309 | y += my >> 3; | ||||
| 310 | x += mx >> 3; | ||||
| 311 | ref += y * ref_stride + x * bytesperpixel; | ||||
| 312 | mx &= 7; | ||||
| 313 | my &= 7; | ||||
| 314 | // FIXME bilinear filter only needs 0/1 pixels, not 3/4 | ||||
| 315 | // we use +7 because the last 7 pixels of each sbrow can be changed in | ||||
| 316 | // the longest loopfilter of the next sbrow | ||||
| 317 | th = (y + bh + 4 * !!my + 7) >> 6; | ||||
| 318 | ff_progress_frame_await(ref_frame, FFMAX(th, 0)((th) > (0) ? (th) : (0))); | ||||
| 319 | // The arm/aarch64 _hv filters read one more row than what actually is | ||||
| 320 | // needed, so switch to emulated edge one pixel sooner vertically | ||||
| 321 | // (!!my * 5) than horizontally (!!mx * 4). | ||||
| 322 | // The arm/aarch64 _h filters read one more pixel than what actually is | ||||
| 323 | // needed, so switch to emulated edge if that would read beyond the bottom | ||||
| 324 | // right block. | ||||
| 325 | if (x < !!mx * 3 || y < !!my * 3 || | ||||
| 326 | ((ARCH_AARCH640 || ARCH_ARM0) && (x + !!mx * 5 > w - bw) && (y + !!my * 5 + 1 > h - bh)) || | ||||
| 327 | x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { | ||||
| 328 | s->vdsp.emulated_edge_mc(td->edge_emu_buffer, | ||||
| 329 | ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, | ||||
| 330 | 160, ref_stride, | ||||
| 331 | bw + !!mx * 7, bh + !!my * 7, | ||||
| 332 | x - !!mx * 3, y - !!my * 3, w, h); | ||||
| 333 | ref = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; | ||||
| 334 | ref_stride = 160; | ||||
| 335 | } | ||||
| 336 | mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); | ||||
| 337 | } | ||||
| 338 | |||||
| 339 | static av_always_inline__attribute__((always_inline)) inline void mc_chroma_unscaled(VP9TileData *td, const vp9_mc_func (*mc)[2], | ||||
| 340 | uint8_t *dst_u, uint8_t *dst_v, | ||||
| 341 | ptrdiff_t dst_stride, | ||||
| 342 | const uint8_t *ref_u, ptrdiff_t src_stride_u, | ||||
| 343 | const uint8_t *ref_v, ptrdiff_t src_stride_v, | ||||
| 344 | const ProgressFrame *ref_frame, | ||||
| 345 | ptrdiff_t y, ptrdiff_t x, const VP9mv *mv, | ||||
| 346 | int bw, int bh, int w, int h, int bytesperpixel) | ||||
| 347 | { | ||||
| 348 | const VP9Context *s = td->s; | ||||
| 349 | int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; | ||||
| 350 | |||||
| 351 | y += my >> 4; | ||||
| 352 | x += mx >> 4; | ||||
| 353 | ref_u += y * src_stride_u + x * bytesperpixel; | ||||
| 354 | ref_v += y * src_stride_v + x * bytesperpixel; | ||||
| 355 | mx &= 15; | ||||
| 356 | my &= 15; | ||||
| 357 | // FIXME bilinear filter only needs 0/1 pixels, not 3/4 | ||||
| 358 | // we use +7 because the last 7 pixels of each sbrow can be changed in | ||||
| 359 | // the longest loopfilter of the next sbrow | ||||
| 360 | th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v); | ||||
| 361 | ff_progress_frame_await(ref_frame, FFMAX(th, 0)((th) > (0) ? (th) : (0))); | ||||
| 362 | // The arm/aarch64 _hv filters read one more row than what actually is | ||||
| 363 | // needed, so switch to emulated edge one pixel sooner vertically | ||||
| 364 | // (!!my * 5) than horizontally (!!mx * 4). | ||||
| 365 | // The arm/aarch64 _h filters read one more pixel than what actually is | ||||
| 366 | // needed, so switch to emulated edge if that would read beyond the bottom | ||||
| 367 | // right block. | ||||
| 368 | if (x < !!mx * 3 || y < !!my * 3 || | ||||
| 369 | ((ARCH_AARCH640 || ARCH_ARM0) && (x + !!mx * 5 > w - bw) && (y + !!my * 5 + 1 > h - bh)) || | ||||
| 370 | x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { | ||||
| 371 | s->vdsp.emulated_edge_mc(td->edge_emu_buffer, | ||||
| 372 | ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, | ||||
| 373 | 160, src_stride_u, | ||||
| 374 | bw + !!mx * 7, bh + !!my * 7, | ||||
| 375 | x - !!mx * 3, y - !!my * 3, w, h); | ||||
| 376 | ref_u = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; | ||||
| 377 | mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); | ||||
| 378 | |||||
| 379 | s->vdsp.emulated_edge_mc(td->edge_emu_buffer, | ||||
| 380 | ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, | ||||
| 381 | 160, src_stride_v, | ||||
| 382 | bw + !!mx * 7, bh + !!my * 7, | ||||
| 383 | x - !!mx * 3, y - !!my * 3, w, h); | ||||
| 384 | ref_v = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; | ||||
| 385 | mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); | ||||
| 386 | } else { | ||||
| 387 | mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); | ||||
| 388 | mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my); | ||||
| 389 | } | ||||
| 390 | } | ||||
| 391 | |||||
| 392 | #define mc_luma_dir(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ | ||||
| 393 | px, py, pw, ph, bw, bh, w, h, i) \ | ||||
| 394 | mc_luma_unscaled(td, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ | ||||
| 395 | mv, bw, bh, w, h, bytesperpixel) | ||||
| 396 | #define mc_chroma_dir(td, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ | ||||
| 397 | row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ | ||||
| 398 | mc_chroma_unscaled(td, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ | ||||
| 399 | row, col, mv, bw, bh, w, h, bytesperpixel) | ||||
| 400 | #define SCALED 0 | ||||
| 401 | #define FN(x) x##_8bpp | ||||
| 402 | #define BYTES_PER_PIXEL 1 | ||||
| 403 | #include "vp9_mc_template.c" | ||||
| 404 | #undef FN | ||||
| 405 | #undef BYTES_PER_PIXEL | ||||
| 406 | #define FN(x) x##_16bpp | ||||
| 407 | #define BYTES_PER_PIXEL 2 | ||||
| 408 | #include "vp9_mc_template.c" | ||||
| 409 | #undef mc_luma_dir | ||||
| 410 | #undef mc_chroma_dir | ||||
| 411 | #undef FN | ||||
| 412 | #undef BYTES_PER_PIXEL | ||||
| 413 | #undef SCALED | ||||
| 414 | |||||
| 415 | static av_always_inline__attribute__((always_inline)) inline void mc_luma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, | ||||
| 416 | const vp9_mc_func (*mc)[2], | ||||
| 417 | uint8_t *dst, ptrdiff_t dst_stride, | ||||
| 418 | const uint8_t *ref, ptrdiff_t ref_stride, | ||||
| 419 | const ProgressFrame *ref_frame, | ||||
| 420 | ptrdiff_t y, ptrdiff_t x, const VP9mv *in_mv, | ||||
| 421 | int px, int py, int pw, int ph, | ||||
| 422 | int bw, int bh, int w, int h, int bytesperpixel, | ||||
| 423 | const uint16_t *scale, const uint8_t *step) | ||||
| 424 | { | ||||
| 425 | const VP9Context *s = td->s; | ||||
| 426 | if (s->s.frames[CUR_FRAME0].tf.f->width == ref_frame->f->width && | ||||
| 427 | s->s.frames[CUR_FRAME0].tf.f->height == ref_frame->f->height) { | ||||
| 428 | mc_luma_unscaled(td, mc, dst, dst_stride, ref, ref_stride, ref_frame, | ||||
| 429 | y, x, in_mv, bw, bh, w, h, bytesperpixel); | ||||
| 430 | } else { | ||||
| 431 | #define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) | ||||
| 432 | int mx, my; | ||||
| 433 | int refbw_m1, refbh_m1; | ||||
| 434 | int th; | ||||
| 435 | VP9mv mv; | ||||
| 436 | |||||
| 437 | mv.x = av_clipav_clip_c(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); | ||||
| 438 | mv.y = av_clipav_clip_c(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); | ||||
| 439 | // BUG libvpx seems to scale the two components separately. This introduces | ||||
| 440 | // rounding errors but we have to reproduce them to be exactly compatible | ||||
| 441 | // with the output from libvpx... | ||||
| 442 | mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); | ||||
| 443 | my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); | ||||
| 444 | |||||
| 445 | y = my >> 4; | ||||
| 446 | x = mx >> 4; | ||||
| 447 | ref += y * ref_stride + x * bytesperpixel; | ||||
| 448 | mx &= 15; | ||||
| 449 | my &= 15; | ||||
| 450 | refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; | ||||
| 451 | refbh_m1 = ((bh - 1) * step[1] + my) >> 4; | ||||
| 452 | // FIXME bilinear filter only needs 0/1 pixels, not 3/4 | ||||
| 453 | // we use +7 because the last 7 pixels of each sbrow can be changed in | ||||
| 454 | // the longest loopfilter of the next sbrow | ||||
| 455 | th = (y + refbh_m1 + 4 + 7) >> 6; | ||||
| 456 | ff_progress_frame_await(ref_frame, FFMAX(th, 0)((th) > (0) ? (th) : (0))); | ||||
| 457 | // The arm/aarch64 _hv filters read one more row than what actually is | ||||
| 458 | // needed, so switch to emulated edge one pixel sooner vertically | ||||
| 459 | // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). | ||||
| 460 | if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { | ||||
| 461 | s->vdsp.emulated_edge_mc(td->edge_emu_buffer, | ||||
| 462 | ref - 3 * ref_stride - 3 * bytesperpixel, | ||||
| 463 | 288, ref_stride, | ||||
| 464 | refbw_m1 + 8, refbh_m1 + 8, | ||||
| 465 | x - 3, y - 3, w, h); | ||||
| 466 | ref = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; | ||||
| 467 | ref_stride = 288; | ||||
| 468 | } | ||||
| 469 | smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); | ||||
| 470 | } | ||||
| 471 | } | ||||
| 472 | |||||
| 473 | static av_always_inline__attribute__((always_inline)) inline void mc_chroma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, | ||||
| 474 | const vp9_mc_func (*mc)[2], | ||||
| 475 | uint8_t *dst_u, uint8_t *dst_v, | ||||
| 476 | ptrdiff_t dst_stride, | ||||
| 477 | const uint8_t *ref_u, ptrdiff_t src_stride_u, | ||||
| 478 | const uint8_t *ref_v, ptrdiff_t src_stride_v, | ||||
| 479 | const ProgressFrame *ref_frame, | ||||
| 480 | ptrdiff_t y, ptrdiff_t x, const VP9mv *in_mv, | ||||
| 481 | int px, int py, int pw, int ph, | ||||
| 482 | int bw, int bh, int w, int h, int bytesperpixel, | ||||
| 483 | const uint16_t *scale, const uint8_t *step) | ||||
| 484 | { | ||||
| 485 | const VP9Context *s = td->s; | ||||
| 486 | if (s->s.frames[CUR_FRAME0].tf.f->width == ref_frame->f->width && | ||||
| 487 | s->s.frames[CUR_FRAME0].tf.f->height == ref_frame->f->height) { | ||||
| 488 | mc_chroma_unscaled(td, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, | ||||
| 489 | ref_v, src_stride_v, ref_frame, | ||||
| 490 | y, x, in_mv, bw, bh, w, h, bytesperpixel); | ||||
| 491 | } else { | ||||
| 492 | int mx, my; | ||||
| 493 | int refbw_m1, refbh_m1; | ||||
| 494 | int th; | ||||
| 495 | VP9mv mv; | ||||
| 496 | |||||
| 497 | if (s->ss_h) { | ||||
| 498 | // BUG https://code.google.com/p/webm/issues/detail?id=820 | ||||
| 499 | mv.x = av_clipav_clip_c(in_mv->x, -(x + pw - px + 4) * 16, (s->cols * 4 - x + px + 3) * 16); | ||||
| 500 | mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); | ||||
| 501 | } else { | ||||
| 502 | mv.x = av_clipav_clip_c(in_mv->x, -(x + pw - px + 4) * 8, (s->cols * 8 - x + px + 3) * 8); | ||||
| 503 | mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); | ||||
| 504 | } | ||||
| 505 | if (s->ss_v) { | ||||
| 506 | // BUG https://code.google.com/p/webm/issues/detail?id=820 | ||||
| 507 | mv.y = av_clipav_clip_c(in_mv->y, -(y + ph - py + 4) * 16, (s->rows * 4 - y + py + 3) * 16); | ||||
| 508 | my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); | ||||
| 509 | } else { | ||||
| 510 | mv.y = av_clipav_clip_c(in_mv->y, -(y + ph - py + 4) * 8, (s->rows * 8 - y + py + 3) * 8); | ||||
| 511 | my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); | ||||
| 512 | } | ||||
| 513 | #undef scale_mv | ||||
| 514 | y = my >> 4; | ||||
| 515 | x = mx >> 4; | ||||
| 516 | ref_u += y * src_stride_u + x * bytesperpixel; | ||||
| 517 | ref_v += y * src_stride_v + x * bytesperpixel; | ||||
| 518 | mx &= 15; | ||||
| 519 | my &= 15; | ||||
| 520 | refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; | ||||
| 521 | refbh_m1 = ((bh - 1) * step[1] + my) >> 4; | ||||
| 522 | // FIXME bilinear filter only needs 0/1 pixels, not 3/4 | ||||
| 523 | // we use +7 because the last 7 pixels of each sbrow can be changed in | ||||
| 524 | // the longest loopfilter of the next sbrow | ||||
| 525 | th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v); | ||||
| 526 | ff_progress_frame_await(ref_frame, FFMAX(th, 0)((th) > (0) ? (th) : (0))); | ||||
| 527 | // The arm/aarch64 _hv filters read one more row than what actually is | ||||
| 528 | // needed, so switch to emulated edge one pixel sooner vertically | ||||
| 529 | // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). | ||||
| 530 | if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { | ||||
| 531 | s->vdsp.emulated_edge_mc(td->edge_emu_buffer, | ||||
| 532 | ref_u - 3 * src_stride_u - 3 * bytesperpixel, | ||||
| 533 | 288, src_stride_u, | ||||
| 534 | refbw_m1 + 8, refbh_m1 + 8, | ||||
| 535 | x - 3, y - 3, w, h); | ||||
| 536 | ref_u = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; | ||||
| 537 | smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); | ||||
| 538 | |||||
| 539 | s->vdsp.emulated_edge_mc(td->edge_emu_buffer, | ||||
| 540 | ref_v - 3 * src_stride_v - 3 * bytesperpixel, | ||||
| 541 | 288, src_stride_v, | ||||
| 542 | refbw_m1 + 8, refbh_m1 + 8, | ||||
| 543 | x - 3, y - 3, w, h); | ||||
| 544 | ref_v = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; | ||||
| 545 | smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); | ||||
| 546 | } else { | ||||
| 547 | smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); | ||||
| 548 | smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]); | ||||
| 549 | } | ||||
| 550 | } | ||||
| 551 | } | ||||
| 552 | |||||
| 553 | #define mc_luma_dir(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ | ||||
| 554 | px, py, pw, ph, bw, bh, w, h, i) \ | ||||
| 555 | mc_luma_scaled(td, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ | ||||
| 556 | mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ | ||||
| 557 | s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) | ||||
| 558 | #define mc_chroma_dir(td, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ | ||||
| 559 | row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ | ||||
| 560 | mc_chroma_scaled(td, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ | ||||
| 561 | row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ | ||||
| 562 | s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) | ||||
| 563 | #define SCALED 1 | ||||
| 564 | #define FN(x) x##_scaled_8bpp | ||||
| 565 | #define BYTES_PER_PIXEL 1 | ||||
| 566 | #include "vp9_mc_template.c" | ||||
| 567 | #undef FN | ||||
| 568 | #undef BYTES_PER_PIXEL | ||||
| 569 | #define FN(x) x##_scaled_16bpp | ||||
| 570 | #define BYTES_PER_PIXEL 2 | ||||
| 571 | #include "vp9_mc_template.c" | ||||
| 572 | #undef mc_luma_dir | ||||
| 573 | #undef mc_chroma_dir | ||||
| 574 | #undef FN | ||||
| 575 | #undef BYTES_PER_PIXEL | ||||
| 576 | #undef SCALED | ||||
| 577 | |||||
| 578 | static av_always_inline__attribute__((always_inline)) inline void inter_recon(VP9TileData *td, int bytesperpixel) | ||||
| 579 | { | ||||
| 580 | const VP9Context *s = td->s; | ||||
| 581 | VP9Block *b = td->b; | ||||
| 582 | int row = td->row, col = td->col; | ||||
| 583 | |||||
| 584 | if (s->mvscale[b->ref[0]][0] == REF_INVALID_SCALE0xFFFF || | ||||
| 585 | (b->comp && s->mvscale[b->ref[1]][0] == REF_INVALID_SCALE0xFFFF)) { | ||||
| 586 | if (!s->td->error_info) { | ||||
| 587 | s->td->error_info = AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | (( unsigned)('A') << 24))); | ||||
| 588 | av_log(NULL((void*)0), AV_LOG_ERROR16, "Bitstream not supported, " | ||||
| 589 | "reference frame has invalid dimensions\n"); | ||||
| 590 | } | ||||
| 591 | return; | ||||
| 592 | } | ||||
| 593 | |||||
| 594 | if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { | ||||
| 595 | if (bytesperpixel
| ||||
| 596 | inter_pred_scaled_8bpp(td); | ||||
| 597 | } else { | ||||
| 598 | inter_pred_scaled_16bpp(td); | ||||
| 599 | } | ||||
| 600 | } else { | ||||
| 601 | if (bytesperpixel == 1) { | ||||
| 602 | inter_pred_8bpp(td); | ||||
| 603 | } else { | ||||
| 604 | inter_pred_16bpp(td); | ||||
| 605 | } | ||||
| 606 | } | ||||
| 607 | |||||
| 608 | if (!b->skip) { | ||||
| 609 | /* mostly copied intra_recon() */ | ||||
| 610 | |||||
| 611 | int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; | ||||
| 612 | int h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); | ||||
| 613 | int end_x = FFMIN(2 * (s->cols - col), w4)((2 * (s->cols - col)) > (w4) ? (w4) : (2 * (s->cols - col))); | ||||
| 614 | int end_y = FFMIN(2 * (s->rows - row), h4)((2 * (s->rows - row)) > (h4) ? (h4) : (2 * (s->rows - row))); | ||||
| 615 | int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; | ||||
| 616 | int uvstep1d = 1 << b->uvtx, p; | ||||
| 617 | uint8_t *dst = td->dst[0]; | ||||
| 618 | |||||
| 619 | // y itxfm add | ||||
| 620 | for (n = 0, y = 0; y < end_y; y += step1d) { | ||||
| 621 | uint8_t *ptr = dst; | ||||
| 622 | for (x = 0; x < end_x; x += step1d, | ||||
| 623 | ptr += 4 * step1d * bytesperpixel, n += step) { | ||||
| 624 | int eob = b->tx > TX_8X8 ? AV_RN16A(&td->eob[n])(((const av_alias16*)(&td->eob[n]))->u16) : td->eob[n]; | ||||
| 625 | |||||
| 626 | if (eob) | ||||
| 627 | s->dsp.itxfm_add[tx][DCT_DCT](ptr, td->y_stride, | ||||
| 628 | td->block + 16 * n * bytesperpixel, eob); | ||||
| 629 | } | ||||
| 630 | dst += 4 * td->y_stride * step1d; | ||||
| 631 | } | ||||
| 632 | |||||
| 633 | // uv itxfm add | ||||
| 634 | end_x >>= s->ss_h; | ||||
| 635 | end_y >>= s->ss_v; | ||||
| 636 | step = 1 << (b->uvtx * 2); | ||||
| 637 | for (p = 0; p < 2; p++) { | ||||
| 638 | dst = td->dst[p + 1]; | ||||
| 639 | for (n = 0, y = 0; y < end_y; y += uvstep1d) { | ||||
| 640 | uint8_t *ptr = dst; | ||||
| 641 | for (x = 0; x < end_x; x += uvstep1d, | ||||
| 642 | ptr += 4 * uvstep1d * bytesperpixel, n += step) { | ||||
| 643 | int eob = b->uvtx > TX_8X8 ? AV_RN16A(&td->uveob[p][n])(((const av_alias16*)(&td->uveob[p][n]))->u16) : td->uveob[p][n]; | ||||
| 644 | |||||
| 645 | if (eob) | ||||
| 646 | s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, | ||||
| 647 | td->uvblock[p] + 16 * n * bytesperpixel, eob); | ||||
| 648 | } | ||||
| 649 | dst += 4 * uvstep1d * td->uv_stride; | ||||
| 650 | } | ||||
| 651 | } | ||||
| 652 | } | ||||
| 653 | } | ||||
| 654 | |||||
| 655 | void ff_vp9_inter_recon_8bpp(VP9TileData *td) | ||||
| 656 | { | ||||
| 657 | inter_recon(td, 1); | ||||
| 658 | } | ||||
| 659 | |||||
| 660 | void ff_vp9_inter_recon_16bpp(VP9TileData *td) | ||||
| 661 | { | ||||
| 662 | inter_recon(td, 2); | ||||
| |||||
| 663 | } |
| 1 | /* | ||||
| 2 | * VP9 compatible video decoder | ||||
| 3 | * | ||||
| 4 | * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com> | ||||
| 5 | * Copyright (C) 2013 Clément Bœsch <u pkh me> | ||||
| 6 | * | ||||
| 7 | * This file is part of FFmpeg. | ||||
| 8 | * | ||||
| 9 | * FFmpeg is free software; you can redistribute it and/or | ||||
| 10 | * modify it under the terms of the GNU Lesser General Public | ||||
| 11 | * License as published by the Free Software Foundation; either | ||||
| 12 | * version 2.1 of the License, or (at your option) any later version. | ||||
| 13 | * | ||||
| 14 | * FFmpeg is distributed in the hope that it will be useful, | ||||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
| 17 | * Lesser General Public License for more details. | ||||
| 18 | * | ||||
| 19 | * You should have received a copy of the GNU Lesser General Public | ||||
| 20 | * License along with FFmpeg; if not, write to the Free Software | ||||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
| 22 | */ | ||||
| 23 | |||||
| 24 | #define ROUNDED_DIV_MVx2(a, b)(VP9mv) { .x = (((a.x + b.x)>=0 ? (a.x + b.x) + ((2)>> 1) : (a.x + b.x) - ((2)>>1))/(2)), .y = (((a.y + b.y)>= 0 ? (a.y + b.y) + ((2)>>1) : (a.y + b.y) - ((2)>> 1))/(2)) } \ | ||||
| 25 | (VP9mv) { .x = ROUNDED_DIV(a.x + b.x, 2)(((a.x + b.x)>=0 ? (a.x + b.x) + ((2)>>1) : (a.x + b .x) - ((2)>>1))/(2)), .y = ROUNDED_DIV(a.y + b.y, 2)(((a.y + b.y)>=0 ? (a.y + b.y) + ((2)>>1) : (a.y + b .y) - ((2)>>1))/(2)) } | ||||
| 26 | #define ROUNDED_DIV_MVx4(a, b, c, d)(VP9mv) { .x = (((a.x + b.x + c.x + d.x)>=0 ? (a.x + b.x + c.x + d.x) + ((4)>>1) : (a.x + b.x + c.x + d.x) - ((4) >>1))/(4)), .y = (((a.y + b.y + c.y + d.y)>=0 ? (a.y + b.y + c.y + d.y) + ((4)>>1) : (a.y + b.y + c.y + d.y ) - ((4)>>1))/(4)) } \ | ||||
| 27 | (VP9mv) { .x = ROUNDED_DIV(a.x + b.x + c.x + d.x, 4)(((a.x + b.x + c.x + d.x)>=0 ? (a.x + b.x + c.x + d.x) + ( (4)>>1) : (a.x + b.x + c.x + d.x) - ((4)>>1))/(4) ), \ | ||||
| 28 | .y = ROUNDED_DIV(a.y + b.y + c.y + d.y, 4)(((a.y + b.y + c.y + d.y)>=0 ? (a.y + b.y + c.y + d.y) + ( (4)>>1) : (a.y + b.y + c.y + d.y) - ((4)>>1))/(4) ) } | ||||
| 29 | |||||
| 30 | static void FN(inter_pred)(VP9TileData *td) | ||||
| 31 | { | ||||
| 32 | static const uint8_t bwlog_tab[2][N_BS_SIZES] = { | ||||
| 33 | { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, | ||||
| 34 | { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, | ||||
| 35 | }; | ||||
| 36 | const VP9Context *s = td->s; | ||||
| 37 | VP9Block *b = td->b; | ||||
| 38 | int row = td->row, col = td->col; | ||||
| 39 | const ProgressFrame *tref1 = &s->s.refs[s->s.h.refidx[b->ref[0]]], *tref2; | ||||
| 40 | const AVFrame *ref1 = tref1->f, *ref2; | ||||
| 41 | int w1 = ref1->width, h1 = ref1->height, w2, h2; | ||||
| 42 | ptrdiff_t ls_y = td->y_stride, ls_uv = td->uv_stride; | ||||
| 43 | int bytesperpixel = BYTES_PER_PIXEL; | ||||
| 44 | |||||
| 45 | if (b->comp
| ||||
| 46 | tref2 = &s->s.refs[s->s.h.refidx[b->ref[1]]]; | ||||
| 47 | ref2 = tref2->f; | ||||
| 48 | w2 = ref2->width; | ||||
| 49 | h2 = ref2->height; | ||||
| 50 | } | ||||
| 51 | |||||
| 52 | // y inter pred | ||||
| 53 | if (b->bs > BS_8x8) { | ||||
| 54 | VP9mv uvmv; | ||||
| 55 | |||||
| 56 | #if SCALED == 0 | ||||
| 57 | if (b->bs == BS_8x4) { | ||||
| 58 | mc_luma_dir(td, mc[3][b->filter][0], td->dst[0], ls_y, | ||||
| 59 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 60 | row << 3, col << 3, &b->mv[0][0],,,,, 8, 4, w1, h1, 0); | ||||
| 61 | mc_luma_dir(td, mc[3][b->filter][0], | ||||
| 62 | td->dst[0] + 4 * ls_y, ls_y, | ||||
| 63 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 64 | (row << 3) + 4, col << 3, &b->mv[2][0],,,,, 8, 4, w1, h1, 0); | ||||
| 65 | w1 = (w1 + s->ss_h) >> s->ss_h; | ||||
| 66 | if (s->ss_v) { | ||||
| 67 | h1 = (h1 + 1) >> 1; | ||||
| 68 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0])(VP9mv) { .x = (((b->mv[0][0].x + b->mv[2][0].x)>=0 ? (b->mv[0][0].x + b->mv[2][0].x) + ((2)>>1) : (b-> mv[0][0].x + b->mv[2][0].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][0].y + b->mv[2][0].y)>=0 ? (b->mv[0][0 ].y + b->mv[2][0].y) + ((2)>>1) : (b->mv[0][0].y + b->mv[2][0].y) - ((2)>>1))/(2)) }; | ||||
| 69 | mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], | ||||
| 70 | td->dst[1], td->dst[2], ls_uv, | ||||
| 71 | ref1->data[1], ref1->linesize[1], | ||||
| 72 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 73 | row << 2, col << (3 - s->ss_h), | ||||
| 74 | &uvmv,,,,, 8 >> s->ss_h, 4, w1, h1, 0); | ||||
| 75 | } else { | ||||
| 76 | mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], | ||||
| 77 | td->dst[1], td->dst[2], ls_uv, | ||||
| 78 | ref1->data[1], ref1->linesize[1], | ||||
| 79 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 80 | row << 3, col << (3 - s->ss_h), | ||||
| 81 | &b->mv[0][0],,,,, 8 >> s->ss_h, 4, w1, h1, 0); | ||||
| 82 | // BUG for 4:2:2 bs=8x4, libvpx uses the wrong block index | ||||
| 83 | // to get the motion vector for the bottom 4x4 block | ||||
| 84 | // https://code.google.com/p/webm/issues/detail?id=993 | ||||
| 85 | if (s->ss_h == 0) { | ||||
| 86 | uvmv = b->mv[2][0]; | ||||
| 87 | } else { | ||||
| 88 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0])(VP9mv) { .x = (((b->mv[0][0].x + b->mv[2][0].x)>=0 ? (b->mv[0][0].x + b->mv[2][0].x) + ((2)>>1) : (b-> mv[0][0].x + b->mv[2][0].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][0].y + b->mv[2][0].y)>=0 ? (b->mv[0][0 ].y + b->mv[2][0].y) + ((2)>>1) : (b->mv[0][0].y + b->mv[2][0].y) - ((2)>>1))/(2)) }; | ||||
| 89 | } | ||||
| 90 | mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], | ||||
| 91 | td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, | ||||
| 92 | ref1->data[1], ref1->linesize[1], | ||||
| 93 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 94 | (row << 3) + 4, col << (3 - s->ss_h), | ||||
| 95 | &uvmv,,,,, 8 >> s->ss_h, 4, w1, h1, 0); | ||||
| 96 | } | ||||
| 97 | |||||
| 98 | if (b->comp) { | ||||
| 99 | mc_luma_dir(td, mc[3][b->filter][1], td->dst[0], ls_y, | ||||
| 100 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 101 | row << 3, col << 3, &b->mv[0][1],,,,, 8, 4, w2, h2, 1); | ||||
| 102 | mc_luma_dir(td, mc[3][b->filter][1], | ||||
| 103 | td->dst[0] + 4 * ls_y, ls_y, | ||||
| 104 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 105 | (row << 3) + 4, col << 3, &b->mv[2][1],,,,, 8, 4, w2, h2, 1); | ||||
| 106 | w2 = (w2 + s->ss_h) >> s->ss_h; | ||||
| 107 | if (s->ss_v) { | ||||
| 108 | h2 = (h2 + 1) >> 1; | ||||
| 109 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1])(VP9mv) { .x = (((b->mv[0][1].x + b->mv[2][1].x)>=0 ? (b->mv[0][1].x + b->mv[2][1].x) + ((2)>>1) : (b-> mv[0][1].x + b->mv[2][1].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][1].y + b->mv[2][1].y)>=0 ? (b->mv[0][1 ].y + b->mv[2][1].y) + ((2)>>1) : (b->mv[0][1].y + b->mv[2][1].y) - ((2)>>1))/(2)) }; | ||||
| 110 | mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], | ||||
| 111 | td->dst[1], td->dst[2], ls_uv, | ||||
| 112 | ref2->data[1], ref2->linesize[1], | ||||
| 113 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 114 | row << 2, col << (3 - s->ss_h), | ||||
| 115 | &uvmv,,,,, 8 >> s->ss_h, 4, w2, h2, 1); | ||||
| 116 | } else { | ||||
| 117 | mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], | ||||
| 118 | td->dst[1], td->dst[2], ls_uv, | ||||
| 119 | ref2->data[1], ref2->linesize[1], | ||||
| 120 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 121 | row << 3, col << (3 - s->ss_h), | ||||
| 122 | &b->mv[0][1],,,,, 8 >> s->ss_h, 4, w2, h2, 1); | ||||
| 123 | // BUG for 4:2:2 bs=8x4, libvpx uses the wrong block index | ||||
| 124 | // to get the motion vector for the bottom 4x4 block | ||||
| 125 | // https://code.google.com/p/webm/issues/detail?id=993 | ||||
| 126 | if (s->ss_h == 0) { | ||||
| 127 | uvmv = b->mv[2][1]; | ||||
| 128 | } else { | ||||
| 129 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1])(VP9mv) { .x = (((b->mv[0][1].x + b->mv[2][1].x)>=0 ? (b->mv[0][1].x + b->mv[2][1].x) + ((2)>>1) : (b-> mv[0][1].x + b->mv[2][1].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][1].y + b->mv[2][1].y)>=0 ? (b->mv[0][1 ].y + b->mv[2][1].y) + ((2)>>1) : (b->mv[0][1].y + b->mv[2][1].y) - ((2)>>1))/(2)) }; | ||||
| 130 | } | ||||
| 131 | mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], | ||||
| 132 | td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, | ||||
| 133 | ref2->data[1], ref2->linesize[1], | ||||
| 134 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 135 | (row << 3) + 4, col << (3 - s->ss_h), | ||||
| 136 | &uvmv,,,,, 8 >> s->ss_h, 4, w2, h2, 1); | ||||
| 137 | } | ||||
| 138 | } | ||||
| 139 | } else if (b->bs == BS_4x8) { | ||||
| 140 | mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, | ||||
| 141 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 142 | row << 3, col << 3, &b->mv[0][0],,,,, 4, 8, w1, h1, 0); | ||||
| 143 | mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, | ||||
| 144 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 145 | row << 3, (col << 3) + 4, &b->mv[1][0],,,,, 4, 8, w1, h1, 0); | ||||
| 146 | h1 = (h1 + s->ss_v) >> s->ss_v; | ||||
| 147 | if (s->ss_h) { | ||||
| 148 | w1 = (w1 + 1) >> 1; | ||||
| 149 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0])(VP9mv) { .x = (((b->mv[0][0].x + b->mv[1][0].x)>=0 ? (b->mv[0][0].x + b->mv[1][0].x) + ((2)>>1) : (b-> mv[0][0].x + b->mv[1][0].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][0].y + b->mv[1][0].y)>=0 ? (b->mv[0][0 ].y + b->mv[1][0].y) + ((2)>>1) : (b->mv[0][0].y + b->mv[1][0].y) - ((2)>>1))/(2)) }; | ||||
| 150 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 151 | td->dst[1], td->dst[2], ls_uv, | ||||
| 152 | ref1->data[1], ref1->linesize[1], | ||||
| 153 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 154 | row << (3 - s->ss_v), col << 2, | ||||
| 155 | &uvmv,,,,, 4, 8 >> s->ss_v, w1, h1, 0); | ||||
| 156 | } else { | ||||
| 157 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 158 | td->dst[1], td->dst[2], ls_uv, | ||||
| 159 | ref1->data[1], ref1->linesize[1], | ||||
| 160 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 161 | row << (3 - s->ss_v), col << 3, | ||||
| 162 | &b->mv[0][0],,,,, 4, 8 >> s->ss_v, w1, h1, 0); | ||||
| 163 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 164 | td->dst[1] + 4 * bytesperpixel, | ||||
| 165 | td->dst[2] + 4 * bytesperpixel, ls_uv, | ||||
| 166 | ref1->data[1], ref1->linesize[1], | ||||
| 167 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 168 | row << (3 - s->ss_v), (col << 3) + 4, | ||||
| 169 | &b->mv[1][0],,,,, 4, 8 >> s->ss_v, w1, h1, 0); | ||||
| 170 | } | ||||
| 171 | |||||
| 172 | if (b->comp) { | ||||
| 173 | mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, | ||||
| 174 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 175 | row << 3, col << 3, &b->mv[0][1],,,,, 4, 8, w2, h2, 1); | ||||
| 176 | mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, | ||||
| 177 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 178 | row << 3, (col << 3) + 4, &b->mv[1][1],,,,, 4, 8, w2, h2, 1); | ||||
| 179 | h2 = (h2 + s->ss_v) >> s->ss_v; | ||||
| 180 | if (s->ss_h) { | ||||
| 181 | w2 = (w2 + 1) >> 1; | ||||
| 182 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1])(VP9mv) { .x = (((b->mv[0][1].x + b->mv[1][1].x)>=0 ? (b->mv[0][1].x + b->mv[1][1].x) + ((2)>>1) : (b-> mv[0][1].x + b->mv[1][1].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][1].y + b->mv[1][1].y)>=0 ? (b->mv[0][1 ].y + b->mv[1][1].y) + ((2)>>1) : (b->mv[0][1].y + b->mv[1][1].y) - ((2)>>1))/(2)) }; | ||||
| 183 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 184 | td->dst[1], td->dst[2], ls_uv, | ||||
| 185 | ref2->data[1], ref2->linesize[1], | ||||
| 186 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 187 | row << (3 - s->ss_v), col << 2, | ||||
| 188 | &uvmv,,,,, 4, 8 >> s->ss_v, w2, h2, 1); | ||||
| 189 | } else { | ||||
| 190 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 191 | td->dst[1], td->dst[2], ls_uv, | ||||
| 192 | ref2->data[1], ref2->linesize[1], | ||||
| 193 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 194 | row << (3 - s->ss_v), col << 3, | ||||
| 195 | &b->mv[0][1],,,,, 4, 8 >> s->ss_v, w2, h2, 1); | ||||
| 196 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 197 | td->dst[1] + 4 * bytesperpixel, | ||||
| 198 | td->dst[2] + 4 * bytesperpixel, ls_uv, | ||||
| 199 | ref2->data[1], ref2->linesize[1], | ||||
| 200 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 201 | row << (3 - s->ss_v), (col << 3) + 4, | ||||
| 202 | &b->mv[1][1],,,,, 4, 8 >> s->ss_v, w2, h2, 1); | ||||
| 203 | } | ||||
| 204 | } | ||||
| 205 | } else | ||||
| 206 | #endif | ||||
| 207 | { | ||||
| 208 | #if SCALED == 0 | ||||
| 209 | av_assert2(b->bs == BS_4x4)do { if (!(b->bs == BS_4x4)) { av_log(((void*)0), 0, "Assertion %s failed at %s:%d\n" , "b->bs == BS_4x4", "/root/firefox-clang/media/ffvpx/libavcodec/vp9_mc_template.c" , 209); abort(); } } while (0); | ||||
| 210 | #endif | ||||
| 211 | |||||
| 212 | // FIXME if two horizontally adjacent blocks have the same MV, | ||||
| 213 | // do a w8 instead of a w4 call | ||||
| 214 | mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, | ||||
| 215 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 216 | row << 3, col << 3, &b->mv[0][0], | ||||
| 217 | 0, 0, 8, 8, 4, 4, w1, h1, 0); | ||||
| 218 | mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, | ||||
| 219 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 220 | row << 3, (col << 3) + 4, &b->mv[1][0], | ||||
| 221 | 4, 0, 8, 8, 4, 4, w1, h1, 0); | ||||
| 222 | mc_luma_dir(td, mc[4][b->filter][0], | ||||
| 223 | td->dst[0] + 4 * ls_y, ls_y, | ||||
| 224 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 225 | (row << 3) + 4, col << 3, &b->mv[2][0], | ||||
| 226 | 0, 4, 8, 8, 4, 4, w1, h1, 0); | ||||
| 227 | mc_luma_dir(td, mc[4][b->filter][0], | ||||
| 228 | td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, | ||||
| 229 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 230 | (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], | ||||
| 231 | 4, 4, 8, 8, 4, 4, w1, h1, 0); | ||||
| 232 | if (s->ss_v) { | ||||
| 233 | h1 = (h1 + 1) >> 1; | ||||
| 234 | if (s->ss_h) { | ||||
| 235 | w1 = (w1 + 1) >> 1; | ||||
| 236 | uvmv = ROUNDED_DIV_MVx4(b->mv[0][0], b->mv[1][0],(VP9mv) { .x = (((b->mv[0][0].x + b->mv[1][0].x + b-> mv[2][0].x + b->mv[3][0].x)>=0 ? (b->mv[0][0].x + b-> mv[1][0].x + b->mv[2][0].x + b->mv[3][0].x) + ((4)>> 1) : (b->mv[0][0].x + b->mv[1][0].x + b->mv[2][0].x + b->mv[3][0].x) - ((4)>>1))/(4)), .y = (((b->mv[0 ][0].y + b->mv[1][0].y + b->mv[2][0].y + b->mv[3][0] .y)>=0 ? (b->mv[0][0].y + b->mv[1][0].y + b->mv[2 ][0].y + b->mv[3][0].y) + ((4)>>1) : (b->mv[0][0] .y + b->mv[1][0].y + b->mv[2][0].y + b->mv[3][0].y) - ((4)>>1))/(4)) } | ||||
| 237 | b->mv[2][0], b->mv[3][0])(VP9mv) { .x = (((b->mv[0][0].x + b->mv[1][0].x + b-> mv[2][0].x + b->mv[3][0].x)>=0 ? (b->mv[0][0].x + b-> mv[1][0].x + b->mv[2][0].x + b->mv[3][0].x) + ((4)>> 1) : (b->mv[0][0].x + b->mv[1][0].x + b->mv[2][0].x + b->mv[3][0].x) - ((4)>>1))/(4)), .y = (((b->mv[0 ][0].y + b->mv[1][0].y + b->mv[2][0].y + b->mv[3][0] .y)>=0 ? (b->mv[0][0].y + b->mv[1][0].y + b->mv[2 ][0].y + b->mv[3][0].y) + ((4)>>1) : (b->mv[0][0] .y + b->mv[1][0].y + b->mv[2][0].y + b->mv[3][0].y) - ((4)>>1))/(4)) }; | ||||
| 238 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 239 | td->dst[1], td->dst[2], ls_uv, | ||||
| 240 | ref1->data[1], ref1->linesize[1], | ||||
| 241 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 242 | row << 2, col << 2, | ||||
| 243 | &uvmv, 0, 0, 4, 4, 4, 4, w1, h1, 0); | ||||
| 244 | } else { | ||||
| 245 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0])(VP9mv) { .x = (((b->mv[0][0].x + b->mv[2][0].x)>=0 ? (b->mv[0][0].x + b->mv[2][0].x) + ((2)>>1) : (b-> mv[0][0].x + b->mv[2][0].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][0].y + b->mv[2][0].y)>=0 ? (b->mv[0][0 ].y + b->mv[2][0].y) + ((2)>>1) : (b->mv[0][0].y + b->mv[2][0].y) - ((2)>>1))/(2)) }; | ||||
| 246 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 247 | td->dst[1], td->dst[2], ls_uv, | ||||
| 248 | ref1->data[1], ref1->linesize[1], | ||||
| 249 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 250 | row << 2, col << 3, | ||||
| 251 | &uvmv, 0, 0, 8, 4, 4, 4, w1, h1, 0); | ||||
| 252 | uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[3][0])(VP9mv) { .x = (((b->mv[1][0].x + b->mv[3][0].x)>=0 ? (b->mv[1][0].x + b->mv[3][0].x) + ((2)>>1) : (b-> mv[1][0].x + b->mv[3][0].x) - ((2)>>1))/(2)), .y = ( ((b->mv[1][0].y + b->mv[3][0].y)>=0 ? (b->mv[1][0 ].y + b->mv[3][0].y) + ((2)>>1) : (b->mv[1][0].y + b->mv[3][0].y) - ((2)>>1))/(2)) }; | ||||
| 253 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 254 | td->dst[1] + 4 * bytesperpixel, | ||||
| 255 | td->dst[2] + 4 * bytesperpixel, ls_uv, | ||||
| 256 | ref1->data[1], ref1->linesize[1], | ||||
| 257 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 258 | row << 2, (col << 3) + 4, | ||||
| 259 | &uvmv, 4, 0, 8, 4, 4, 4, w1, h1, 0); | ||||
| 260 | } | ||||
| 261 | } else { | ||||
| 262 | if (s->ss_h) { | ||||
| 263 | w1 = (w1 + 1) >> 1; | ||||
| 264 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0])(VP9mv) { .x = (((b->mv[0][0].x + b->mv[1][0].x)>=0 ? (b->mv[0][0].x + b->mv[1][0].x) + ((2)>>1) : (b-> mv[0][0].x + b->mv[1][0].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][0].y + b->mv[1][0].y)>=0 ? (b->mv[0][0 ].y + b->mv[1][0].y) + ((2)>>1) : (b->mv[0][0].y + b->mv[1][0].y) - ((2)>>1))/(2)) }; | ||||
| 265 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 266 | td->dst[1], td->dst[2], ls_uv, | ||||
| 267 | ref1->data[1], ref1->linesize[1], | ||||
| 268 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 269 | row << 3, col << 2, | ||||
| 270 | &uvmv, 0, 0, 4, 8, 4, 4, w1, h1, 0); | ||||
| 271 | // BUG libvpx uses wrong block index for 4:2:2 bs=4x4 | ||||
| 272 | // bottom block | ||||
| 273 | // https://code.google.com/p/webm/issues/detail?id=993 | ||||
| 274 | uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[2][0])(VP9mv) { .x = (((b->mv[1][0].x + b->mv[2][0].x)>=0 ? (b->mv[1][0].x + b->mv[2][0].x) + ((2)>>1) : (b-> mv[1][0].x + b->mv[2][0].x) - ((2)>>1))/(2)), .y = ( ((b->mv[1][0].y + b->mv[2][0].y)>=0 ? (b->mv[1][0 ].y + b->mv[2][0].y) + ((2)>>1) : (b->mv[1][0].y + b->mv[2][0].y) - ((2)>>1))/(2)) }; | ||||
| 275 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 276 | td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, | ||||
| 277 | ref1->data[1], ref1->linesize[1], | ||||
| 278 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 279 | (row << 3) + 4, col << 2, | ||||
| 280 | &uvmv, 0, 4, 4, 8, 4, 4, w1, h1, 0); | ||||
| 281 | } else { | ||||
| 282 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 283 | td->dst[1], td->dst[2], ls_uv, | ||||
| 284 | ref1->data[1], ref1->linesize[1], | ||||
| 285 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 286 | row << 3, col << 3, | ||||
| 287 | &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); | ||||
| 288 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 289 | td->dst[1] + 4 * bytesperpixel, | ||||
| 290 | td->dst[2] + 4 * bytesperpixel, ls_uv, | ||||
| 291 | ref1->data[1], ref1->linesize[1], | ||||
| 292 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 293 | row << 3, (col << 3) + 4, | ||||
| 294 | &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); | ||||
| 295 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 296 | td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, | ||||
| 297 | ref1->data[1], ref1->linesize[1], | ||||
| 298 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 299 | (row << 3) + 4, col << 3, | ||||
| 300 | &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); | ||||
| 301 | mc_chroma_dir(td, mc[4][b->filter][0], | ||||
| 302 | td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, | ||||
| 303 | td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, | ||||
| 304 | ref1->data[1], ref1->linesize[1], | ||||
| 305 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 306 | (row << 3) + 4, (col << 3) + 4, | ||||
| 307 | &b->mv[3][0], 4, 4, 8, 8, 4, 4, w1, h1, 0); | ||||
| 308 | } | ||||
| 309 | } | ||||
| 310 | |||||
| 311 | if (b->comp) { | ||||
| 312 | mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, | ||||
| 313 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 314 | row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); | ||||
| 315 | mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, | ||||
| 316 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 317 | row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); | ||||
| 318 | mc_luma_dir(td, mc[4][b->filter][1], | ||||
| 319 | td->dst[0] + 4 * ls_y, ls_y, | ||||
| 320 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 321 | (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); | ||||
| 322 | mc_luma_dir(td, mc[4][b->filter][1], | ||||
| 323 | td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, | ||||
| 324 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 325 | (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, 8, 8, 4, 4, w2, h2, 1); | ||||
| 326 | if (s->ss_v) { | ||||
| 327 | h2 = (h2 + 1) >> 1; | ||||
| 328 | if (s->ss_h) { | ||||
| 329 | w2 = (w2 + 1) >> 1; | ||||
| 330 | uvmv = ROUNDED_DIV_MVx4(b->mv[0][1], b->mv[1][1],(VP9mv) { .x = (((b->mv[0][1].x + b->mv[1][1].x + b-> mv[2][1].x + b->mv[3][1].x)>=0 ? (b->mv[0][1].x + b-> mv[1][1].x + b->mv[2][1].x + b->mv[3][1].x) + ((4)>> 1) : (b->mv[0][1].x + b->mv[1][1].x + b->mv[2][1].x + b->mv[3][1].x) - ((4)>>1))/(4)), .y = (((b->mv[0 ][1].y + b->mv[1][1].y + b->mv[2][1].y + b->mv[3][1] .y)>=0 ? (b->mv[0][1].y + b->mv[1][1].y + b->mv[2 ][1].y + b->mv[3][1].y) + ((4)>>1) : (b->mv[0][1] .y + b->mv[1][1].y + b->mv[2][1].y + b->mv[3][1].y) - ((4)>>1))/(4)) } | ||||
| 331 | b->mv[2][1], b->mv[3][1])(VP9mv) { .x = (((b->mv[0][1].x + b->mv[1][1].x + b-> mv[2][1].x + b->mv[3][1].x)>=0 ? (b->mv[0][1].x + b-> mv[1][1].x + b->mv[2][1].x + b->mv[3][1].x) + ((4)>> 1) : (b->mv[0][1].x + b->mv[1][1].x + b->mv[2][1].x + b->mv[3][1].x) - ((4)>>1))/(4)), .y = (((b->mv[0 ][1].y + b->mv[1][1].y + b->mv[2][1].y + b->mv[3][1] .y)>=0 ? (b->mv[0][1].y + b->mv[1][1].y + b->mv[2 ][1].y + b->mv[3][1].y) + ((4)>>1) : (b->mv[0][1] .y + b->mv[1][1].y + b->mv[2][1].y + b->mv[3][1].y) - ((4)>>1))/(4)) }; | ||||
| 332 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 333 | td->dst[1], td->dst[2], ls_uv, | ||||
| 334 | ref2->data[1], ref2->linesize[1], | ||||
| 335 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 336 | row << 2, col << 2, | ||||
| 337 | &uvmv, 0, 0, 4, 4, 4, 4, w2, h2, 1); | ||||
| 338 | } else { | ||||
| 339 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1])(VP9mv) { .x = (((b->mv[0][1].x + b->mv[2][1].x)>=0 ? (b->mv[0][1].x + b->mv[2][1].x) + ((2)>>1) : (b-> mv[0][1].x + b->mv[2][1].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][1].y + b->mv[2][1].y)>=0 ? (b->mv[0][1 ].y + b->mv[2][1].y) + ((2)>>1) : (b->mv[0][1].y + b->mv[2][1].y) - ((2)>>1))/(2)) }; | ||||
| 340 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 341 | td->dst[1], td->dst[2], ls_uv, | ||||
| 342 | ref2->data[1], ref2->linesize[1], | ||||
| 343 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 344 | row << 2, col << 3, | ||||
| 345 | &uvmv, 0, 0, 8, 4, 4, 4, w2, h2, 1); | ||||
| 346 | uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[3][1])(VP9mv) { .x = (((b->mv[1][1].x + b->mv[3][1].x)>=0 ? (b->mv[1][1].x + b->mv[3][1].x) + ((2)>>1) : (b-> mv[1][1].x + b->mv[3][1].x) - ((2)>>1))/(2)), .y = ( ((b->mv[1][1].y + b->mv[3][1].y)>=0 ? (b->mv[1][1 ].y + b->mv[3][1].y) + ((2)>>1) : (b->mv[1][1].y + b->mv[3][1].y) - ((2)>>1))/(2)) }; | ||||
| 347 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 348 | td->dst[1] + 4 * bytesperpixel, | ||||
| 349 | td->dst[2] + 4 * bytesperpixel, ls_uv, | ||||
| 350 | ref2->data[1], ref2->linesize[1], | ||||
| 351 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 352 | row << 2, (col << 3) + 4, | ||||
| 353 | &uvmv, 4, 0, 8, 4, 4, 4, w2, h2, 1); | ||||
| 354 | } | ||||
| 355 | } else { | ||||
| 356 | if (s->ss_h) { | ||||
| 357 | w2 = (w2 + 1) >> 1; | ||||
| 358 | uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1])(VP9mv) { .x = (((b->mv[0][1].x + b->mv[1][1].x)>=0 ? (b->mv[0][1].x + b->mv[1][1].x) + ((2)>>1) : (b-> mv[0][1].x + b->mv[1][1].x) - ((2)>>1))/(2)), .y = ( ((b->mv[0][1].y + b->mv[1][1].y)>=0 ? (b->mv[0][1 ].y + b->mv[1][1].y) + ((2)>>1) : (b->mv[0][1].y + b->mv[1][1].y) - ((2)>>1))/(2)) }; | ||||
| 359 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 360 | td->dst[1], td->dst[2], ls_uv, | ||||
| 361 | ref2->data[1], ref2->linesize[1], | ||||
| 362 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 363 | row << 3, col << 2, | ||||
| 364 | &uvmv, 0, 0, 4, 8, 4, 4, w2, h2, 1); | ||||
| 365 | // BUG libvpx uses wrong block index for 4:2:2 bs=4x4 | ||||
| 366 | // bottom block | ||||
| 367 | // https://code.google.com/p/webm/issues/detail?id=993 | ||||
| 368 | uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[2][1])(VP9mv) { .x = (((b->mv[1][1].x + b->mv[2][1].x)>=0 ? (b->mv[1][1].x + b->mv[2][1].x) + ((2)>>1) : (b-> mv[1][1].x + b->mv[2][1].x) - ((2)>>1))/(2)), .y = ( ((b->mv[1][1].y + b->mv[2][1].y)>=0 ? (b->mv[1][1 ].y + b->mv[2][1].y) + ((2)>>1) : (b->mv[1][1].y + b->mv[2][1].y) - ((2)>>1))/(2)) }; | ||||
| 369 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 370 | td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, | ||||
| 371 | ref2->data[1], ref2->linesize[1], | ||||
| 372 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 373 | (row << 3) + 4, col << 2, | ||||
| 374 | &uvmv, 0, 4, 4, 8, 4, 4, w2, h2, 1); | ||||
| 375 | } else { | ||||
| 376 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 377 | td->dst[1], td->dst[2], ls_uv, | ||||
| 378 | ref2->data[1], ref2->linesize[1], | ||||
| 379 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 380 | row << 3, col << 3, | ||||
| 381 | &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); | ||||
| 382 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 383 | td->dst[1] + 4 * bytesperpixel, | ||||
| 384 | td->dst[2] + 4 * bytesperpixel, ls_uv, | ||||
| 385 | ref2->data[1], ref2->linesize[1], | ||||
| 386 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 387 | row << 3, (col << 3) + 4, | ||||
| 388 | &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); | ||||
| 389 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 390 | td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, | ||||
| 391 | ref2->data[1], ref2->linesize[1], | ||||
| 392 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 393 | (row << 3) + 4, col << 3, | ||||
| 394 | &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); | ||||
| 395 | mc_chroma_dir(td, mc[4][b->filter][1], | ||||
| 396 | td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, | ||||
| 397 | td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, | ||||
| 398 | ref2->data[1], ref2->linesize[1], | ||||
| 399 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 400 | (row << 3) + 4, (col << 3) + 4, | ||||
| 401 | &b->mv[3][1], 4, 4, 8, 8, 4, 4, w2, h2, 1); | ||||
| 402 | } | ||||
| 403 | } | ||||
| 404 | } | ||||
| 405 | } | ||||
| 406 | } else { | ||||
| 407 | int bwl = bwlog_tab[0][b->bs]; | ||||
| 408 | int bw = ff_vp9_bwh_tab[0][b->bs][0] * 4; | ||||
| 409 | int bh = ff_vp9_bwh_tab[0][b->bs][1] * 4; | ||||
| 410 | int uvbw = ff_vp9_bwh_tab[s->ss_h][b->bs][0] * 4; | ||||
| 411 | int uvbh = ff_vp9_bwh_tab[s->ss_v][b->bs][1] * 4; | ||||
| 412 | |||||
| 413 | mc_luma_dir(td, mc[bwl][b->filter][0], td->dst[0], ls_y, | ||||
| 414 | ref1->data[0], ref1->linesize[0], tref1, | ||||
| 415 | row << 3, col << 3, &b->mv[0][0], 0, 0, bw, bh, bw, bh, w1, h1, 0); | ||||
| 416 | w1 = (w1 + s->ss_h) >> s->ss_h; | ||||
| 417 | h1 = (h1 + s->ss_v) >> s->ss_v; | ||||
| 418 | mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][0], | ||||
| 419 | td->dst[1], td->dst[2], ls_uv, | ||||
| 420 | ref1->data[1], ref1->linesize[1], | ||||
| 421 | ref1->data[2], ref1->linesize[2], tref1, | ||||
| 422 | row << (3 - s->ss_v), col << (3 - s->ss_h), | ||||
| 423 | &b->mv[0][0], 0, 0, uvbw, uvbh, uvbw, uvbh, w1, h1, 0); | ||||
| 424 | |||||
| 425 | if (b->comp) { | ||||
| 426 | mc_luma_dir(td, mc[bwl][b->filter][1], td->dst[0], ls_y, | ||||
| |||||
| 427 | ref2->data[0], ref2->linesize[0], tref2, | ||||
| 428 | row << 3, col << 3, &b->mv[0][1], 0, 0, bw, bh, bw, bh, w2, h2, 1); | ||||
| 429 | w2 = (w2 + s->ss_h) >> s->ss_h; | ||||
| 430 | h2 = (h2 + s->ss_v) >> s->ss_v; | ||||
| 431 | mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][1], | ||||
| 432 | td->dst[1], td->dst[2], ls_uv, | ||||
| 433 | ref2->data[1], ref2->linesize[1], | ||||
| 434 | ref2->data[2], ref2->linesize[2], tref2, | ||||
| 435 | row << (3 - s->ss_v), col << (3 - s->ss_h), | ||||
| 436 | &b->mv[0][1], 0, 0, uvbw, uvbh, uvbw, uvbh, w2, h2, 1); | ||||
| 437 | } | ||||
| 438 | } | ||||
| 439 | } |