Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1 | /* |
| 2 | * VC-1 and WMV3 decoder |
| 3 | * Copyright (c) 2011 Mashiat Sarker Shakkhar |
| 4 | * Copyright (c) 2006-2007 Konstantin Shishkov |
| 5 | * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer |
| 6 | * |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 7 | * This file is part of FFmpeg. |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 8 | * |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 9 | * FFmpeg is free software; you can redistribute it and/or |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 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 | * |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 14 | * FFmpeg is distributed in the hope that it will be useful, |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 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 |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 20 | * License along with FFmpeg; if not, write to the Free Software |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 22 | */ |
| 23 | |
| 24 | /** |
| 25 | * @file |
| 26 | * VC-1 and WMV3 block decoding routines |
| 27 | */ |
| 28 | |
| 29 | #include "avcodec.h" |
| 30 | #include "h264chroma.h" |
| 31 | #include "mathops.h" |
| 32 | #include "mpegvideo.h" |
| 33 | #include "vc1.h" |
| 34 | |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 35 | static av_always_inline void vc1_scale_luma(uint8_t *srcY, |
| 36 | int k, int linesize) |
| 37 | { |
| 38 | int i, j; |
| 39 | for (j = 0; j < k; j++) { |
| 40 | for (i = 0; i < k; i++) |
| 41 | srcY[i] = ((srcY[i] - 128) >> 1) + 128; |
| 42 | srcY += linesize; |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | static av_always_inline void vc1_scale_chroma(uint8_t *srcU, uint8_t *srcV, |
| 47 | int k, int uvlinesize) |
| 48 | { |
| 49 | int i, j; |
| 50 | for (j = 0; j < k; j++) { |
| 51 | for (i = 0; i < k; i++) { |
| 52 | srcU[i] = ((srcU[i] - 128) >> 1) + 128; |
| 53 | srcV[i] = ((srcV[i] - 128) >> 1) + 128; |
| 54 | } |
| 55 | srcU += uvlinesize; |
| 56 | srcV += uvlinesize; |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | static av_always_inline void vc1_lut_scale_luma(uint8_t *srcY, |
Andreas Rheinhardt | dda009b | 2023-10-04 19:33:18 | [diff] [blame] | 61 | const uint8_t *lut1, const uint8_t *lut2, |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 62 | int k, int linesize) |
| 63 | { |
| 64 | int i, j; |
| 65 | |
| 66 | for (j = 0; j < k; j += 2) { |
| 67 | for (i = 0; i < k; i++) |
| 68 | srcY[i] = lut1[srcY[i]]; |
| 69 | srcY += linesize; |
| 70 | |
| 71 | if (j + 1 == k) |
| 72 | break; |
| 73 | |
| 74 | for (i = 0; i < k; i++) |
| 75 | srcY[i] = lut2[srcY[i]]; |
| 76 | srcY += linesize; |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | static av_always_inline void vc1_lut_scale_chroma(uint8_t *srcU, uint8_t *srcV, |
Andreas Rheinhardt | dda009b | 2023-10-04 19:33:18 | [diff] [blame] | 81 | const uint8_t *lut1, const uint8_t *lut2, |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 82 | int k, int uvlinesize) |
| 83 | { |
| 84 | int i, j; |
| 85 | |
| 86 | for (j = 0; j < k; j += 2) { |
| 87 | for (i = 0; i < k; i++) { |
| 88 | srcU[i] = lut1[srcU[i]]; |
| 89 | srcV[i] = lut1[srcV[i]]; |
| 90 | } |
| 91 | srcU += uvlinesize; |
| 92 | srcV += uvlinesize; |
| 93 | |
| 94 | if (j + 1 == k) |
| 95 | break; |
| 96 | |
| 97 | for (i = 0; i < k; i++) { |
| 98 | srcU[i] = lut2[srcU[i]]; |
| 99 | srcV[i] = lut2[srcV[i]]; |
| 100 | } |
| 101 | srcU += uvlinesize; |
| 102 | srcV += uvlinesize; |
| 103 | } |
| 104 | } |
| 105 | |
zhaoxiu.zeng | 9d7e42e | 2015-03-07 15:17:53 | [diff] [blame] | 106 | static const uint8_t popcount4[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; |
| 107 | |
| 108 | static av_always_inline int get_luma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty) |
| 109 | { |
| 110 | MpegEncContext *s = &v->s; |
| 111 | int idx = v->mv_f[dir][s->block_index[0] + v->blocks_off] | |
| 112 | (v->mv_f[dir][s->block_index[1] + v->blocks_off] << 1) | |
| 113 | (v->mv_f[dir][s->block_index[2] + v->blocks_off] << 2) | |
| 114 | (v->mv_f[dir][s->block_index[3] + v->blocks_off] << 3); |
| 115 | static const uint8_t index2[16] = { 0, 0, 0, 0x23, 0, 0x13, 0x03, 0, 0, 0x12, 0x02, 0, 0x01, 0, 0, 0 }; |
| 116 | int opp_count = popcount4[idx]; |
| 117 | |
| 118 | switch (opp_count) { |
| 119 | case 0: |
| 120 | case 4: |
| 121 | *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]); |
| 122 | *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]); |
| 123 | break; |
| 124 | case 1: |
| 125 | *tx = mid_pred(s->mv[dir][idx < 2][0], s->mv[dir][1 + (idx < 4)][0], s->mv[dir][2 + (idx < 8)][0]); |
| 126 | *ty = mid_pred(s->mv[dir][idx < 2][1], s->mv[dir][1 + (idx < 4)][1], s->mv[dir][2 + (idx < 8)][1]); |
| 127 | break; |
| 128 | case 3: |
| 129 | *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]); |
| 130 | *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]); |
| 131 | break; |
| 132 | case 2: |
| 133 | *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2; |
| 134 | *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2; |
| 135 | break; |
| 136 | } |
| 137 | return opp_count; |
| 138 | } |
| 139 | |
| 140 | static av_always_inline int get_chroma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty) |
| 141 | { |
| 142 | MpegEncContext *s = &v->s; |
| 143 | int idx = !v->mb_type[0][s->block_index[0]] | |
| 144 | (!v->mb_type[0][s->block_index[1]] << 1) | |
| 145 | (!v->mb_type[0][s->block_index[2]] << 2) | |
| 146 | (!v->mb_type[0][s->block_index[3]] << 3); |
| 147 | static const uint8_t index2[16] = { 0, 0, 0, 0x01, 0, 0x02, 0x12, 0, 0, 0x03, 0x13, 0, 0x23, 0, 0, 0 }; |
| 148 | int valid_count = popcount4[idx]; |
| 149 | |
| 150 | switch (valid_count) { |
| 151 | case 4: |
| 152 | *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]); |
| 153 | *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]); |
| 154 | break; |
| 155 | case 3: |
| 156 | *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]); |
| 157 | *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]); |
| 158 | break; |
| 159 | case 2: |
| 160 | *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2; |
| 161 | *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2; |
| 162 | break; |
| 163 | default: |
| 164 | return 0; |
| 165 | } |
| 166 | return valid_count; |
| 167 | } |
| 168 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 169 | /** Do motion compensation over 1 macroblock |
| 170 | * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c |
| 171 | */ |
| 172 | void ff_vc1_mc_1mv(VC1Context *v, int dir) |
| 173 | { |
| 174 | MpegEncContext *s = &v->s; |
| 175 | H264ChromaContext *h264chroma = &v->h264chroma; |
| 176 | uint8_t *srcY, *srcU, *srcV; |
| 177 | int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; |
| 178 | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
| 179 | int i; |
Andreas Rheinhardt | dda009b | 2023-10-04 19:33:18 | [diff] [blame] | 180 | const uint8_t (*luty)[256], (*lutuv)[256]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 181 | int use_ic; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 182 | int interlace; |
| 183 | int linesize, uvlinesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 184 | |
| 185 | if ((!v->field_mode || |
| 186 | (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 187 | !v->s.last_pic.data[0]) |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 188 | return; |
| 189 | |
Andreas Rheinhardt | fe6037f | 2023-10-08 10:25:07 | [diff] [blame] | 190 | linesize = s->cur_pic.ptr->f->linesize[0]; |
| 191 | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 192 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 193 | mx = s->mv[dir][0][0]; |
| 194 | my = s->mv[dir][0][1]; |
| 195 | |
Vittorio Giovara | 41ed7ab | 2016-04-27 17:45:23 | [diff] [blame] | 196 | // store motion vectors for further use in B-frames |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 197 | if (s->pict_type == AV_PICTURE_TYPE_P) { |
| 198 | for (i = 0; i < 4; i++) { |
Andreas Rheinhardt | ec1eba7 | 2023-10-04 01:34:28 | [diff] [blame] | 199 | s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx; |
| 200 | s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][1] = my; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 201 | } |
| 202 | } |
| 203 | |
| 204 | uvmx = (mx + ((mx & 3) == 3)) >> 1; |
| 205 | uvmy = (my + ((my & 3) == 3)) >> 1; |
| 206 | v->luma_mv[s->mb_x][0] = uvmx; |
| 207 | v->luma_mv[s->mb_x][1] = uvmy; |
| 208 | |
| 209 | if (v->field_mode && |
| 210 | v->cur_field_type != v->ref_field_type[dir]) { |
| 211 | my = my - 2 + 4 * v->cur_field_type; |
| 212 | uvmy = uvmy - 2 + 4 * v->cur_field_type; |
| 213 | } |
| 214 | |
| 215 | // fastuvmc shall be ignored for interlaced frame picture |
| 216 | if (v->fastuvmc && (v->fcm != ILACE_FRAME)) { |
| 217 | uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); |
| 218 | uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); |
| 219 | } |
| 220 | if (!dir) { |
| 221 | if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 222 | srcY = s->cur_pic.data[0]; |
| 223 | srcU = s->cur_pic.data[1]; |
| 224 | srcV = s->cur_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 225 | luty = v->curr_luty; |
| 226 | lutuv = v->curr_lutuv; |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 227 | use_ic = *v->curr_use_ic; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 228 | interlace = 1; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 229 | } else { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 230 | srcY = s->last_pic.data[0]; |
| 231 | srcU = s->last_pic.data[1]; |
| 232 | srcV = s->last_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 233 | luty = v->last_luty; |
| 234 | lutuv = v->last_lutuv; |
| 235 | use_ic = v->last_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 236 | interlace = v->last_interlaced; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 237 | } |
| 238 | } else { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 239 | srcY = s->next_pic.data[0]; |
| 240 | srcU = s->next_pic.data[1]; |
| 241 | srcV = s->next_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 242 | luty = v->next_luty; |
| 243 | lutuv = v->next_lutuv; |
| 244 | use_ic = v->next_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 245 | interlace = v->next_interlaced; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 246 | } |
| 247 | |
| 248 | if (!srcY || !srcU) { |
| 249 | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
| 250 | return; |
| 251 | } |
| 252 | |
| 253 | src_x = s->mb_x * 16 + (mx >> 2); |
| 254 | src_y = s->mb_y * 16 + (my >> 2); |
| 255 | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
| 256 | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
| 257 | |
| 258 | if (v->profile != PROFILE_ADVANCED) { |
| 259 | src_x = av_clip( src_x, -16, s->mb_width * 16); |
| 260 | src_y = av_clip( src_y, -16, s->mb_height * 16); |
| 261 | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
| 262 | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
| 263 | } else { |
| 264 | src_x = av_clip( src_x, -17, s->avctx->coded_width); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 265 | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 266 | if (v->fcm == ILACE_FRAME) { |
| 267 | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
| 268 | uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); |
| 269 | } else { |
| 270 | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
| 271 | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
| 272 | } |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 273 | } |
| 274 | |
| 275 | srcY += src_y * s->linesize + src_x; |
| 276 | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 277 | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 278 | |
| 279 | if (v->field_mode && v->ref_field_type[dir]) { |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 280 | srcY += linesize; |
| 281 | srcU += uvlinesize; |
| 282 | srcV += uvlinesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 283 | } |
| 284 | |
| 285 | /* for grayscale we should not try to read from unknown area */ |
Michael Niedermayer | 94d68a4 | 2015-07-27 19:14:31 | [diff] [blame] | 286 | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) { |
Vittorio Giovara | da0c866 | 2015-05-31 13:49:52 | [diff] [blame] | 287 | srcU = s->sc.edge_emu_buffer + 18 * s->linesize; |
| 288 | srcV = s->sc.edge_emu_buffer + 18 * s->linesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 289 | } |
| 290 | |
| 291 | if (v->rangeredfrm || use_ic |
| 292 | || s->h_edge_pos < 22 || v_edge_pos < 22 |
| 293 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3 |
| 294 | || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 3) { |
Michael Niedermayer | db8ae37 | 2015-06-08 18:58:13 | [diff] [blame] | 295 | uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize; |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 296 | uint8_t *vbuf = ubuf + 9 * s->uvlinesize; |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 297 | const int k = 17 + s->mspel * 2; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 298 | |
| 299 | srcY -= s->mspel * (1 + s->linesize); |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 300 | if (interlace) { |
| 301 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 302 | srcY, |
| 303 | linesize << 1, |
| 304 | linesize << 1, |
| 305 | k, |
| 306 | v->field_mode ? k : k + 1 >> 1, |
| 307 | src_x - s->mspel, |
| 308 | src_y - s->mspel >> !v->field_mode, |
| 309 | s->h_edge_pos, |
| 310 | s->v_edge_pos >> 1); |
| 311 | if (!v->field_mode) |
| 312 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
| 313 | srcY + linesize, |
| 314 | linesize << 1, |
| 315 | linesize << 1, |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 316 | k, |
| 317 | k >> 1, |
| 318 | src_x - s->mspel, |
| 319 | src_y - s->mspel + 1 >> 1, |
| 320 | s->h_edge_pos, |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 321 | s->v_edge_pos >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 322 | } else |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 323 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 324 | srcY, |
| 325 | linesize, |
| 326 | linesize, |
| 327 | k, |
| 328 | v->field_mode ? (k << 1) - 1 : k, |
| 329 | src_x - s->mspel, |
| 330 | v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : |
| 331 | src_y - s->mspel, |
| 332 | s->h_edge_pos, |
| 333 | s->v_edge_pos); |
Vittorio Giovara | da0c866 | 2015-05-31 13:49:52 | [diff] [blame] | 334 | srcY = s->sc.edge_emu_buffer; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 335 | if (interlace) { |
| 336 | s->vdsp.emulated_edge_mc(ubuf, |
| 337 | srcU, |
| 338 | uvlinesize << 1, |
| 339 | uvlinesize << 1, |
| 340 | 9, |
| 341 | v->field_mode ? 9 : 5, |
| 342 | uvsrc_x, |
| 343 | uvsrc_y >> !v->field_mode, |
| 344 | s->h_edge_pos >> 1, |
| 345 | s->v_edge_pos >> 2); |
| 346 | s->vdsp.emulated_edge_mc(vbuf, |
| 347 | srcV, |
| 348 | uvlinesize << 1, |
| 349 | uvlinesize << 1, |
| 350 | 9, |
| 351 | v->field_mode ? 9 : 5, |
| 352 | uvsrc_x, |
| 353 | uvsrc_y >> !v->field_mode, |
| 354 | s->h_edge_pos >> 1, |
| 355 | s->v_edge_pos >> 2); |
| 356 | if (!v->field_mode) { |
| 357 | s->vdsp.emulated_edge_mc(ubuf + uvlinesize, |
| 358 | srcU + uvlinesize, |
| 359 | uvlinesize << 1, |
| 360 | uvlinesize << 1, |
| 361 | 9, |
| 362 | 4, |
| 363 | uvsrc_x, |
| 364 | uvsrc_y + 1 >> 1, |
| 365 | s->h_edge_pos >> 1, |
| 366 | s->v_edge_pos >> 2); |
| 367 | s->vdsp.emulated_edge_mc(vbuf + uvlinesize, |
| 368 | srcV + uvlinesize, |
| 369 | uvlinesize << 1, |
| 370 | uvlinesize << 1, |
| 371 | 9, |
| 372 | 4, |
| 373 | uvsrc_x, |
| 374 | uvsrc_y + 1 >> 1, |
| 375 | s->h_edge_pos >> 1, |
| 376 | s->v_edge_pos >> 2); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 377 | } |
| 378 | } else { |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 379 | s->vdsp.emulated_edge_mc(ubuf, |
| 380 | srcU, |
| 381 | uvlinesize, |
| 382 | uvlinesize, |
| 383 | 9, |
| 384 | v->field_mode ? 17 : 9, |
| 385 | uvsrc_x, |
| 386 | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, |
| 387 | s->h_edge_pos >> 1, |
| 388 | s->v_edge_pos >> 1); |
| 389 | s->vdsp.emulated_edge_mc(vbuf, |
| 390 | srcV, |
| 391 | uvlinesize, |
| 392 | uvlinesize, |
| 393 | 9, |
| 394 | v->field_mode ? 17 : 9, |
| 395 | uvsrc_x, |
| 396 | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, |
| 397 | s->h_edge_pos >> 1, |
| 398 | s->v_edge_pos >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 399 | } |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 400 | srcU = ubuf; |
| 401 | srcV = vbuf; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 402 | /* if we deal with range reduction we need to scale source blocks */ |
| 403 | if (v->rangeredfrm) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 404 | vc1_scale_luma(srcY, k, s->linesize); |
| 405 | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 406 | } |
| 407 | /* if we deal with intensity compensation we need to scale source blocks */ |
| 408 | if (use_ic) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 409 | vc1_lut_scale_luma(srcY, |
| 410 | luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)], |
| 411 | luty[v->field_mode ? v->ref_field_type[dir] : ((1 + src_y - s->mspel) & 1)], |
| 412 | k, s->linesize); |
| 413 | vc1_lut_scale_chroma(srcU, srcV, |
| 414 | lutuv[v->field_mode ? v->ref_field_type[dir] : ((0 + uvsrc_y) & 1)], |
| 415 | lutuv[v->field_mode ? v->ref_field_type[dir] : ((1 + uvsrc_y) & 1)], |
| 416 | 9, s->uvlinesize); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 417 | } |
| 418 | srcY += s->mspel * (1 + s->linesize); |
| 419 | } |
| 420 | |
| 421 | if (s->mspel) { |
| 422 | dxy = ((my & 3) << 2) | (mx & 3); |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 423 | v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 424 | } else { // hpel mc - always used for luma |
| 425 | dxy = (my & 2) | ((mx & 2) >> 1); |
| 426 | if (!v->rnd) |
| 427 | s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
| 428 | else |
| 429 | s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
| 430 | } |
| 431 | |
Michael Niedermayer | 94d68a4 | 2015-07-27 19:14:31 | [diff] [blame] | 432 | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
Vittorio Giovara | 848e86f | 2015-04-27 18:13:25 | [diff] [blame] | 433 | return; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 434 | /* Chroma MC always uses qpel bilinear */ |
| 435 | uvmx = (uvmx & 3) << 1; |
| 436 | uvmy = (uvmy & 3) << 1; |
| 437 | if (!v->rnd) { |
| 438 | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
| 439 | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
| 440 | } else { |
| 441 | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
| 442 | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
| 443 | } |
Jerome Borsboom | 79f8074 | 2018-04-23 18:59:13 | [diff] [blame] | 444 | if (v->field_mode) { |
| 445 | v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir]; |
| 446 | v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir]; |
| 447 | } |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 448 | } |
| 449 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 450 | /** Do motion compensation for 4-MV macroblock - luminance block |
| 451 | */ |
| 452 | void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) |
| 453 | { |
| 454 | MpegEncContext *s = &v->s; |
| 455 | uint8_t *srcY; |
| 456 | int dxy, mx, my, src_x, src_y; |
| 457 | int off; |
| 458 | int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0; |
| 459 | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
Andreas Rheinhardt | dda009b | 2023-10-04 19:33:18 | [diff] [blame] | 460 | const uint8_t (*luty)[256]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 461 | int use_ic; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 462 | int interlace; |
| 463 | int linesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 464 | |
| 465 | if ((!v->field_mode || |
| 466 | (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 467 | !v->s.last_pic.data[0]) |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 468 | return; |
| 469 | |
Andreas Rheinhardt | fe6037f | 2023-10-08 10:25:07 | [diff] [blame] | 470 | linesize = s->cur_pic.ptr->f->linesize[0]; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 471 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 472 | mx = s->mv[dir][n][0]; |
| 473 | my = s->mv[dir][n][1]; |
| 474 | |
| 475 | if (!dir) { |
| 476 | if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 477 | srcY = s->cur_pic.data[0]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 478 | luty = v->curr_luty; |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 479 | use_ic = *v->curr_use_ic; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 480 | interlace = 1; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 481 | } else { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 482 | srcY = s->last_pic.data[0]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 483 | luty = v->last_luty; |
| 484 | use_ic = v->last_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 485 | interlace = v->last_interlaced; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 486 | } |
| 487 | } else { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 488 | srcY = s->next_pic.data[0]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 489 | luty = v->next_luty; |
| 490 | use_ic = v->next_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 491 | interlace = v->next_interlaced; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 492 | } |
| 493 | |
| 494 | if (!srcY) { |
| 495 | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
| 496 | return; |
| 497 | } |
| 498 | |
| 499 | if (v->field_mode) { |
| 500 | if (v->cur_field_type != v->ref_field_type[dir]) |
| 501 | my = my - 2 + 4 * v->cur_field_type; |
| 502 | } |
| 503 | |
| 504 | if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) { |
zhaoxiu.zeng | 9d7e42e | 2015-03-07 15:17:53 | [diff] [blame] | 505 | int opp_count = get_luma_mv(v, 0, |
Andreas Rheinhardt | ec1eba7 | 2023-10-04 01:34:28 | [diff] [blame] | 506 | &s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0], |
| 507 | &s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1]); |
zhaoxiu.zeng | 9d7e42e | 2015-03-07 15:17:53 | [diff] [blame] | 508 | int k, f = opp_count > 2; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 509 | for (k = 0; k < 4; k++) |
| 510 | v->mv_f[1][s->block_index[k] + v->blocks_off] = f; |
| 511 | } |
| 512 | |
| 513 | if (v->fcm == ILACE_FRAME) { // not sure if needed for other types of picture |
| 514 | int qx, qy; |
| 515 | int width = s->avctx->coded_width; |
| 516 | int height = s->avctx->coded_height >> 1; |
| 517 | if (s->pict_type == AV_PICTURE_TYPE_P) { |
Andreas Rheinhardt | ec1eba7 | 2023-10-04 01:34:28 | [diff] [blame] | 518 | s->cur_pic.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx; |
| 519 | s->cur_pic.motion_val[1][s->block_index[n] + v->blocks_off][1] = my; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 520 | } |
| 521 | qx = (s->mb_x * 16) + (mx >> 2); |
| 522 | qy = (s->mb_y * 8) + (my >> 3); |
| 523 | |
| 524 | if (qx < -17) |
| 525 | mx -= 4 * (qx + 17); |
| 526 | else if (qx > width) |
| 527 | mx -= 4 * (qx - width); |
| 528 | if (qy < -18) |
| 529 | my -= 8 * (qy + 18); |
| 530 | else if (qy > height + 1) |
| 531 | my -= 8 * (qy - height - 1); |
| 532 | } |
| 533 | |
| 534 | if ((v->fcm == ILACE_FRAME) && fieldmv) |
| 535 | off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8; |
| 536 | else |
| 537 | off = s->linesize * 4 * (n & 2) + (n & 1) * 8; |
| 538 | |
| 539 | src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2); |
| 540 | if (!fieldmv) |
| 541 | src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2); |
| 542 | else |
| 543 | src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2); |
| 544 | |
| 545 | if (v->profile != PROFILE_ADVANCED) { |
| 546 | src_x = av_clip(src_x, -16, s->mb_width * 16); |
| 547 | src_y = av_clip(src_y, -16, s->mb_height * 16); |
| 548 | } else { |
| 549 | src_x = av_clip(src_x, -17, s->avctx->coded_width); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 550 | if (v->fcm == ILACE_FRAME) |
| 551 | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
| 552 | else |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 553 | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 554 | } |
| 555 | |
| 556 | srcY += src_y * s->linesize + src_x; |
| 557 | if (v->field_mode && v->ref_field_type[dir]) |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 558 | srcY += linesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 559 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 560 | if (v->rangeredfrm || use_ic |
| 561 | || s->h_edge_pos < 13 || v_edge_pos < 23 |
| 562 | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2 |
| 563 | || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 564 | const int k = 9 + s->mspel * 2; |
| 565 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 566 | srcY -= s->mspel * (1 + (s->linesize << fieldmv)); |
| 567 | /* check emulate edge stride and offset */ |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 568 | if (interlace) { |
| 569 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 570 | srcY, |
| 571 | linesize << 1, |
| 572 | linesize << 1, |
| 573 | k, |
| 574 | v->field_mode ? k : (k << fieldmv) + 1 >> 1, |
| 575 | src_x - s->mspel, |
| 576 | src_y - (s->mspel << fieldmv) >> !v->field_mode, |
| 577 | s->h_edge_pos, |
| 578 | s->v_edge_pos >> 1); |
| 579 | if (!v->field_mode && !fieldmv) |
| 580 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
| 581 | srcY + linesize, |
| 582 | linesize << 1, |
| 583 | linesize << 1, |
| 584 | k, |
| 585 | k >> 1, |
| 586 | src_x - s->mspel, |
| 587 | src_y - s->mspel + 1 >> 1, |
| 588 | s->h_edge_pos, |
| 589 | s->v_edge_pos >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 590 | } else |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 591 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 592 | srcY, |
| 593 | linesize, |
| 594 | linesize, |
| 595 | k, |
| 596 | v->field_mode ? (k << 1) - 1 : k << fieldmv, |
| 597 | src_x - s->mspel, |
| 598 | v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : |
| 599 | src_y - (s->mspel << fieldmv), |
| 600 | s->h_edge_pos, |
| 601 | s->v_edge_pos); |
Vittorio Giovara | da0c866 | 2015-05-31 13:49:52 | [diff] [blame] | 602 | srcY = s->sc.edge_emu_buffer; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 603 | /* if we deal with range reduction we need to scale source blocks */ |
| 604 | if (v->rangeredfrm) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 605 | vc1_scale_luma(srcY, k, s->linesize << fieldmv); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 606 | } |
| 607 | /* if we deal with intensity compensation we need to scale source blocks */ |
| 608 | if (use_ic) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 609 | vc1_lut_scale_luma(srcY, |
| 610 | luty[v->field_mode ? v->ref_field_type[dir] : (((0<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)], |
| 611 | luty[v->field_mode ? v->ref_field_type[dir] : (((1<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)], |
| 612 | k, s->linesize << fieldmv); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 613 | } |
| 614 | srcY += s->mspel * (1 + (s->linesize << fieldmv)); |
| 615 | } |
| 616 | |
| 617 | if (s->mspel) { |
| 618 | dxy = ((my & 3) << 2) | (mx & 3); |
| 619 | if (avg) |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 620 | v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 621 | else |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 622 | v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 623 | } else { // hpel mc - always used for luma |
| 624 | dxy = (my & 2) | ((mx & 2) >> 1); |
| 625 | if (!v->rnd) |
| 626 | s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); |
| 627 | else |
| 628 | s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); |
| 629 | } |
| 630 | } |
| 631 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 632 | /** Do motion compensation for 4-MV macroblock - both chroma blocks |
| 633 | */ |
| 634 | void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir) |
| 635 | { |
| 636 | MpegEncContext *s = &v->s; |
| 637 | H264ChromaContext *h264chroma = &v->h264chroma; |
| 638 | uint8_t *srcU, *srcV; |
| 639 | int uvmx, uvmy, uvsrc_x, uvsrc_y; |
zhaoxiu.zeng | 9d7e42e | 2015-03-07 15:17:53 | [diff] [blame] | 640 | int16_t tx, ty; |
| 641 | int chroma_ref_type; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 642 | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
Andreas Rheinhardt | dda009b | 2023-10-04 19:33:18 | [diff] [blame] | 643 | const uint8_t (*lutuv)[256]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 644 | int use_ic; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 645 | int interlace; |
| 646 | int uvlinesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 647 | |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 648 | if (!v->field_mode && !v->s.last_pic.data[0]) |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 649 | return; |
Michael Niedermayer | 94d68a4 | 2015-07-27 19:14:31 | [diff] [blame] | 650 | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 651 | return; |
| 652 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 653 | /* calculate chroma MV vector from four luma MVs */ |
zhaoxiu.zeng | 9d7e42e | 2015-03-07 15:17:53 | [diff] [blame] | 654 | if (!v->field_mode || !v->numref) { |
| 655 | int valid_count = get_chroma_mv(v, dir, &tx, &ty); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 656 | if (!valid_count) { |
Andreas Rheinhardt | ec1eba7 | 2023-10-04 01:34:28 | [diff] [blame] | 657 | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; |
| 658 | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 659 | v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; |
| 660 | return; //no need to do MC for intra blocks |
| 661 | } |
zhaoxiu.zeng | 9d7e42e | 2015-03-07 15:17:53 | [diff] [blame] | 662 | chroma_ref_type = v->ref_field_type[dir]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 663 | } else { |
zhaoxiu.zeng | 9d7e42e | 2015-03-07 15:17:53 | [diff] [blame] | 664 | int opp_count = get_luma_mv(v, dir, &tx, &ty); |
| 665 | chroma_ref_type = v->cur_field_type ^ (opp_count > 2); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 666 | } |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 667 | if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_pic.data[0]) |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 668 | return; |
Andreas Rheinhardt | ec1eba7 | 2023-10-04 01:34:28 | [diff] [blame] | 669 | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; |
| 670 | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 671 | |
Andreas Rheinhardt | fe6037f | 2023-10-08 10:25:07 | [diff] [blame] | 672 | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 673 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 674 | uvmx = (tx + ((tx & 3) == 3)) >> 1; |
| 675 | uvmy = (ty + ((ty & 3) == 3)) >> 1; |
| 676 | |
| 677 | v->luma_mv[s->mb_x][0] = uvmx; |
| 678 | v->luma_mv[s->mb_x][1] = uvmy; |
| 679 | |
| 680 | if (v->fastuvmc) { |
| 681 | uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); |
| 682 | uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); |
| 683 | } |
| 684 | // Field conversion bias |
| 685 | if (v->cur_field_type != chroma_ref_type) |
| 686 | uvmy += 2 - 4 * chroma_ref_type; |
| 687 | |
| 688 | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
| 689 | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
| 690 | |
| 691 | if (v->profile != PROFILE_ADVANCED) { |
| 692 | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
| 693 | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
| 694 | } else { |
| 695 | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
| 696 | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
| 697 | } |
| 698 | |
| 699 | if (!dir) { |
| 700 | if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 701 | srcU = s->cur_pic.data[1]; |
| 702 | srcV = s->cur_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 703 | lutuv = v->curr_lutuv; |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 704 | use_ic = *v->curr_use_ic; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 705 | interlace = 1; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 706 | } else { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 707 | srcU = s->last_pic.data[1]; |
| 708 | srcV = s->last_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 709 | lutuv = v->last_lutuv; |
| 710 | use_ic = v->last_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 711 | interlace = v->last_interlaced; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 712 | } |
| 713 | } else { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 714 | srcU = s->next_pic.data[1]; |
| 715 | srcV = s->next_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 716 | lutuv = v->next_lutuv; |
| 717 | use_ic = v->next_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 718 | interlace = v->next_interlaced; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 719 | } |
| 720 | |
| 721 | if (!srcU) { |
| 722 | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
| 723 | return; |
| 724 | } |
| 725 | |
| 726 | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 727 | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 728 | |
| 729 | if (v->field_mode) { |
| 730 | if (chroma_ref_type) { |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 731 | srcU += uvlinesize; |
| 732 | srcV += uvlinesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 733 | } |
| 734 | } |
| 735 | |
| 736 | if (v->rangeredfrm || use_ic |
| 737 | || s->h_edge_pos < 18 || v_edge_pos < 18 |
| 738 | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 |
| 739 | || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) { |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 740 | if (interlace) { |
| 741 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 742 | srcU, |
| 743 | uvlinesize << 1, |
| 744 | uvlinesize << 1, |
| 745 | 9, |
| 746 | v->field_mode ? 9 : 5, |
| 747 | uvsrc_x, |
| 748 | uvsrc_y >> !v->field_mode, |
| 749 | s->h_edge_pos >> 1, |
| 750 | s->v_edge_pos >> 2); |
| 751 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
| 752 | srcV, |
| 753 | uvlinesize << 1, |
| 754 | uvlinesize << 1, |
| 755 | 9, |
| 756 | v->field_mode ? 9 : 5, |
| 757 | uvsrc_x, |
| 758 | uvsrc_y >> !v->field_mode, |
| 759 | s->h_edge_pos >> 1, |
| 760 | s->v_edge_pos >> 2); |
| 761 | if (!v->field_mode) { |
| 762 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize, |
| 763 | srcU + uvlinesize, |
| 764 | uvlinesize << 1, |
| 765 | uvlinesize << 1, |
| 766 | 9, |
| 767 | 4, |
| 768 | uvsrc_x, |
| 769 | uvsrc_y + 1 >> 1, |
| 770 | s->h_edge_pos >> 1, |
| 771 | s->v_edge_pos >> 2); |
| 772 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize, |
| 773 | srcV + uvlinesize, |
| 774 | uvlinesize << 1, |
| 775 | uvlinesize << 1, |
| 776 | 9, |
| 777 | 4, |
| 778 | uvsrc_x, |
| 779 | uvsrc_y + 1 >> 1, |
| 780 | s->h_edge_pos >> 1, |
| 781 | s->v_edge_pos >> 2); |
| 782 | } |
| 783 | } else { |
| 784 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 785 | srcU, |
| 786 | uvlinesize, |
| 787 | uvlinesize, |
| 788 | 9, |
| 789 | v->field_mode ? 17 : 9, |
| 790 | uvsrc_x, |
| 791 | v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y, |
| 792 | s->h_edge_pos >> 1, |
| 793 | s->v_edge_pos >> 1); |
| 794 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
| 795 | srcV, |
| 796 | uvlinesize, |
| 797 | uvlinesize, |
| 798 | 9, |
| 799 | v->field_mode ? 17 : 9, |
| 800 | uvsrc_x, |
| 801 | v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y, |
| 802 | s->h_edge_pos >> 1, |
| 803 | s->v_edge_pos >> 1); |
| 804 | } |
Vittorio Giovara | da0c866 | 2015-05-31 13:49:52 | [diff] [blame] | 805 | srcU = s->sc.edge_emu_buffer; |
| 806 | srcV = s->sc.edge_emu_buffer + 16; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 807 | |
| 808 | /* if we deal with range reduction we need to scale source blocks */ |
| 809 | if (v->rangeredfrm) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 810 | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 811 | } |
| 812 | /* if we deal with intensity compensation we need to scale source blocks */ |
| 813 | if (use_ic) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 814 | vc1_lut_scale_chroma(srcU, srcV, |
| 815 | lutuv[v->field_mode ? chroma_ref_type : ((0 + uvsrc_y) & 1)], |
| 816 | lutuv[v->field_mode ? chroma_ref_type : ((1 + uvsrc_y) & 1)], |
| 817 | 9, s->uvlinesize); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 818 | } |
| 819 | } |
| 820 | |
| 821 | /* Chroma MC always uses qpel bilinear */ |
| 822 | uvmx = (uvmx & 3) << 1; |
| 823 | uvmy = (uvmy & 3) << 1; |
| 824 | if (!v->rnd) { |
| 825 | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
| 826 | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
| 827 | } else { |
| 828 | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
| 829 | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
| 830 | } |
Jerome Borsboom | 79f8074 | 2018-04-23 18:59:13 | [diff] [blame] | 831 | if (v->field_mode) { |
| 832 | v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != chroma_ref_type; |
| 833 | v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != chroma_ref_type; |
| 834 | } |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 835 | } |
| 836 | |
| 837 | /** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V) |
| 838 | */ |
| 839 | void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg) |
| 840 | { |
| 841 | MpegEncContext *s = &v->s; |
| 842 | H264ChromaContext *h264chroma = &v->h264chroma; |
| 843 | uint8_t *srcU, *srcV; |
| 844 | int uvsrc_x, uvsrc_y; |
| 845 | int uvmx_field[4], uvmy_field[4]; |
| 846 | int i, off, tx, ty; |
| 847 | int fieldmv = v->blk_mv_type[s->block_index[0]]; |
zhaoxiu.zeng | 9870c03 | 2015-03-07 14:47:18 | [diff] [blame] | 848 | static const uint8_t s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 }; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 849 | int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks |
| 850 | int v_edge_pos = s->v_edge_pos >> 1; |
| 851 | int use_ic; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 852 | int interlace; |
| 853 | int uvlinesize; |
Andreas Rheinhardt | dda009b | 2023-10-04 19:33:18 | [diff] [blame] | 854 | const uint8_t (*lutuv)[256]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 855 | |
Michael Niedermayer | 94d68a4 | 2015-07-27 19:14:31 | [diff] [blame] | 856 | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 857 | return; |
| 858 | |
Andreas Rheinhardt | fe6037f | 2023-10-08 10:25:07 | [diff] [blame] | 859 | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 860 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 861 | for (i = 0; i < 4; i++) { |
| 862 | int d = i < 2 ? dir: dir2; |
| 863 | tx = s->mv[d][i][0]; |
| 864 | uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1; |
| 865 | ty = s->mv[d][i][1]; |
| 866 | if (fieldmv) |
| 867 | uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF]; |
| 868 | else |
| 869 | uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1; |
| 870 | } |
| 871 | |
| 872 | for (i = 0; i < 4; i++) { |
| 873 | off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0); |
| 874 | uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2); |
| 875 | uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2); |
| 876 | // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack()) |
| 877 | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 878 | if (v->fcm == ILACE_FRAME) |
| 879 | uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); |
| 880 | else |
| 881 | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 882 | if (i < 2 ? dir : dir2) { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 883 | srcU = s->next_pic.data[1]; |
| 884 | srcV = s->next_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 885 | lutuv = v->next_lutuv; |
| 886 | use_ic = v->next_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 887 | interlace = v->next_interlaced; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 888 | } else { |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 889 | srcU = s->last_pic.data[1]; |
| 890 | srcV = s->last_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 891 | lutuv = v->last_lutuv; |
| 892 | use_ic = v->last_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 893 | interlace = v->last_interlaced; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 894 | } |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 895 | if (!srcU) |
| 896 | return; |
| 897 | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 898 | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 899 | uvmx_field[i] = (uvmx_field[i] & 3) << 1; |
| 900 | uvmy_field[i] = (uvmy_field[i] & 3) << 1; |
| 901 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 902 | if (use_ic |
| 903 | || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv) |
| 904 | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 |
| 905 | || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) { |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 906 | if (interlace) { |
| 907 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 908 | srcU, |
| 909 | uvlinesize << 1, |
| 910 | uvlinesize << 1, |
| 911 | 5, |
| 912 | (5 << fieldmv) + 1 >> 1, |
| 913 | uvsrc_x, |
| 914 | uvsrc_y >> 1, |
| 915 | s->h_edge_pos >> 1, |
| 916 | s->v_edge_pos >> 2); |
| 917 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
| 918 | srcV, |
| 919 | uvlinesize << 1, |
| 920 | uvlinesize << 1, |
| 921 | 5, |
| 922 | (5 << fieldmv) + 1 >> 1, |
| 923 | uvsrc_x, |
| 924 | uvsrc_y >> 1, |
| 925 | s->h_edge_pos >> 1, |
| 926 | s->v_edge_pos >> 2); |
| 927 | if (!fieldmv) { |
| 928 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize, |
| 929 | srcU + uvlinesize, |
| 930 | uvlinesize << 1, |
| 931 | uvlinesize << 1, |
| 932 | 5, |
| 933 | 2, |
| 934 | uvsrc_x, |
| 935 | uvsrc_y + 1 >> 1, |
| 936 | s->h_edge_pos >> 1, |
| 937 | s->v_edge_pos >> 2); |
| 938 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize, |
| 939 | srcV + uvlinesize, |
| 940 | uvlinesize << 1, |
| 941 | uvlinesize << 1, |
| 942 | 5, |
| 943 | 2, |
| 944 | uvsrc_x, |
| 945 | uvsrc_y + 1 >> 1, |
| 946 | s->h_edge_pos >> 1, |
| 947 | s->v_edge_pos >> 2); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 948 | } |
| 949 | } else { |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 950 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 951 | srcU, |
| 952 | uvlinesize, |
| 953 | uvlinesize, |
| 954 | 5, |
| 955 | 5 << fieldmv, |
| 956 | uvsrc_x, |
| 957 | uvsrc_y, |
| 958 | s->h_edge_pos >> 1, |
| 959 | s->v_edge_pos >> 1); |
| 960 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
| 961 | srcV, |
| 962 | uvlinesize, |
| 963 | uvlinesize, |
| 964 | 5, |
| 965 | 5 << fieldmv, |
| 966 | uvsrc_x, |
| 967 | uvsrc_y, |
| 968 | s->h_edge_pos >> 1, |
| 969 | s->v_edge_pos >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 970 | } |
Vittorio Giovara | da0c866 | 2015-05-31 13:49:52 | [diff] [blame] | 971 | srcU = s->sc.edge_emu_buffer; |
| 972 | srcV = s->sc.edge_emu_buffer + 16; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 973 | |
| 974 | /* if we deal with intensity compensation we need to scale source blocks */ |
| 975 | if (use_ic) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 976 | vc1_lut_scale_chroma(srcU, srcV, |
| 977 | lutuv[(uvsrc_y + (0 << fieldmv)) & 1], |
| 978 | lutuv[(uvsrc_y + (1 << fieldmv)) & 1], |
| 979 | 5, s->uvlinesize << fieldmv); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 980 | } |
| 981 | } |
| 982 | if (avg) { |
| 983 | if (!v->rnd) { |
| 984 | h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
| 985 | h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
| 986 | } else { |
| 987 | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
| 988 | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
| 989 | } |
| 990 | } else { |
| 991 | if (!v->rnd) { |
| 992 | h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
| 993 | h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
| 994 | } else { |
| 995 | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
| 996 | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
| 997 | } |
| 998 | } |
| 999 | } |
| 1000 | } |
| 1001 | |
| 1002 | /** Motion compensation for direct or interpolated blocks in B-frames |
| 1003 | */ |
| 1004 | void ff_vc1_interp_mc(VC1Context *v) |
| 1005 | { |
| 1006 | MpegEncContext *s = &v->s; |
| 1007 | H264ChromaContext *h264chroma = &v->h264chroma; |
| 1008 | uint8_t *srcY, *srcU, *srcV; |
| 1009 | int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1010 | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
| 1011 | int use_ic = v->next_use_ic; |
Andreas Rheinhardt | dac15a5 | 2024-05-04 14:20:42 | [diff] [blame] | 1012 | int interlace = v->next_interlaced; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 1013 | int linesize, uvlinesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1014 | |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 1015 | if (!v->field_mode && !v->s.next_pic.data[0]) |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1016 | return; |
| 1017 | |
Andreas Rheinhardt | fe6037f | 2023-10-08 10:25:07 | [diff] [blame] | 1018 | linesize = s->cur_pic.ptr->f->linesize[0]; |
| 1019 | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 1020 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1021 | mx = s->mv[1][0][0]; |
| 1022 | my = s->mv[1][0][1]; |
| 1023 | uvmx = (mx + ((mx & 3) == 3)) >> 1; |
| 1024 | uvmy = (my + ((my & 3) == 3)) >> 1; |
Vittorio Giovara | 28d82b7 | 2014-11-11 16:40:00 | [diff] [blame] | 1025 | if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) { |
| 1026 | my = my - 2 + 4 * v->cur_field_type; |
| 1027 | uvmy = uvmy - 2 + 4 * v->cur_field_type; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1028 | } |
| 1029 | if (v->fastuvmc) { |
| 1030 | uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1)); |
| 1031 | uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1)); |
| 1032 | } |
Andreas Rheinhardt | 7814dd7 | 2023-10-04 15:27:24 | [diff] [blame] | 1033 | srcY = s->next_pic.data[0]; |
| 1034 | srcU = s->next_pic.data[1]; |
| 1035 | srcV = s->next_pic.data[2]; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1036 | |
| 1037 | src_x = s->mb_x * 16 + (mx >> 2); |
| 1038 | src_y = s->mb_y * 16 + (my >> 2); |
| 1039 | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
| 1040 | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
| 1041 | |
| 1042 | if (v->profile != PROFILE_ADVANCED) { |
| 1043 | src_x = av_clip( src_x, -16, s->mb_width * 16); |
| 1044 | src_y = av_clip( src_y, -16, s->mb_height * 16); |
| 1045 | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
| 1046 | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
| 1047 | } else { |
| 1048 | src_x = av_clip( src_x, -17, s->avctx->coded_width); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1049 | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 1050 | if (v->fcm == ILACE_FRAME) { |
| 1051 | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
| 1052 | uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); |
| 1053 | } else { |
| 1054 | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
| 1055 | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
| 1056 | } |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1057 | } |
| 1058 | |
| 1059 | srcY += src_y * s->linesize + src_x; |
| 1060 | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 1061 | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
| 1062 | |
| 1063 | if (v->field_mode && v->ref_field_type[1]) { |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 1064 | srcY += linesize; |
| 1065 | srcU += uvlinesize; |
| 1066 | srcV += uvlinesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1067 | } |
| 1068 | |
| 1069 | /* for grayscale we should not try to read from unknown area */ |
Michael Niedermayer | 94d68a4 | 2015-07-27 19:14:31 | [diff] [blame] | 1070 | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) { |
Vittorio Giovara | da0c866 | 2015-05-31 13:49:52 | [diff] [blame] | 1071 | srcU = s->sc.edge_emu_buffer + 18 * s->linesize; |
| 1072 | srcV = s->sc.edge_emu_buffer + 18 * s->linesize; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1073 | } |
| 1074 | |
| 1075 | if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic |
| 1076 | || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3 |
| 1077 | || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) { |
Michael Niedermayer | db8ae37 | 2015-06-08 18:58:13 | [diff] [blame] | 1078 | uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize; |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 1079 | uint8_t *vbuf = ubuf + 9 * s->uvlinesize; |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 1080 | const int k = 17 + s->mspel * 2; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1081 | |
| 1082 | srcY -= s->mspel * (1 + s->linesize); |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 1083 | if (interlace) { |
| 1084 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 1085 | srcY, |
| 1086 | linesize << 1, |
| 1087 | linesize << 1, |
| 1088 | k, |
| 1089 | v->field_mode ? k : (k + 1 >> 1), |
| 1090 | src_x - s->mspel, |
| 1091 | src_y - s->mspel >> !v->field_mode, |
| 1092 | s->h_edge_pos, |
| 1093 | s->v_edge_pos >> 1); |
| 1094 | if (!v->field_mode) |
| 1095 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
| 1096 | srcY + linesize, |
| 1097 | linesize << 1, |
| 1098 | linesize << 1, |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 1099 | k, |
| 1100 | k >> 1, |
| 1101 | src_x - s->mspel, |
| 1102 | src_y - s->mspel + 1 >> 1, |
| 1103 | s->h_edge_pos, |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 1104 | s->v_edge_pos >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 1105 | } else |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 1106 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
| 1107 | srcY, |
| 1108 | linesize, |
| 1109 | linesize, |
| 1110 | k, |
| 1111 | v->field_mode ? (k << 1) - 1 : k, |
| 1112 | src_x - s->mspel, |
| 1113 | v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[1] : |
| 1114 | src_y - s->mspel, |
| 1115 | s->h_edge_pos, |
| 1116 | s->v_edge_pos); |
Vittorio Giovara | da0c866 | 2015-05-31 13:49:52 | [diff] [blame] | 1117 | srcY = s->sc.edge_emu_buffer; |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 1118 | if (interlace) { |
| 1119 | s->vdsp.emulated_edge_mc(ubuf, |
| 1120 | srcU, |
| 1121 | uvlinesize << 1, |
| 1122 | uvlinesize << 1, |
| 1123 | 9, |
| 1124 | v->field_mode ? 9 : 5, |
| 1125 | uvsrc_x, |
| 1126 | uvsrc_y >> !v->field_mode, |
| 1127 | s->h_edge_pos >> 1, |
| 1128 | s->v_edge_pos >> 2); |
| 1129 | s->vdsp.emulated_edge_mc(vbuf, |
| 1130 | srcV, |
| 1131 | uvlinesize << 1, |
| 1132 | uvlinesize << 1, |
| 1133 | 9, |
| 1134 | v->field_mode ? 9 : 5, |
| 1135 | uvsrc_x, |
| 1136 | uvsrc_y >> !v->field_mode, |
| 1137 | s->h_edge_pos >> 1, |
| 1138 | s->v_edge_pos >> 2); |
| 1139 | if (!v->field_mode) { |
| 1140 | s->vdsp.emulated_edge_mc(ubuf + uvlinesize, |
| 1141 | srcU + uvlinesize, |
| 1142 | uvlinesize << 1, |
| 1143 | uvlinesize << 1, |
| 1144 | 9, |
| 1145 | 4, |
| 1146 | uvsrc_x, |
| 1147 | uvsrc_y + 1 >> 1, |
| 1148 | s->h_edge_pos >> 1, |
| 1149 | s->v_edge_pos >> 2); |
| 1150 | s->vdsp.emulated_edge_mc(vbuf + uvlinesize, |
| 1151 | srcV + uvlinesize, |
| 1152 | uvlinesize << 1, |
| 1153 | uvlinesize << 1, |
| 1154 | 9, |
| 1155 | 4, |
| 1156 | uvsrc_x, |
| 1157 | uvsrc_y + 1 >> 1, |
| 1158 | s->h_edge_pos >> 1, |
| 1159 | s->v_edge_pos >> 2); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 1160 | } |
| 1161 | } else { |
Jerome Borsboom | f56a0b0 | 2018-05-29 12:26:17 | [diff] [blame] | 1162 | s->vdsp.emulated_edge_mc(ubuf, |
| 1163 | srcU, |
| 1164 | uvlinesize, |
| 1165 | uvlinesize, |
| 1166 | 9, |
| 1167 | v->field_mode ? 17 : 9, |
| 1168 | uvsrc_x, |
| 1169 | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[1] : uvsrc_y, |
| 1170 | s->h_edge_pos >> 1, |
| 1171 | s->v_edge_pos >> 1); |
| 1172 | s->vdsp.emulated_edge_mc(vbuf, |
| 1173 | srcV, |
| 1174 | uvlinesize, |
| 1175 | uvlinesize, |
| 1176 | 9, |
| 1177 | v->field_mode ? 17 : 9, |
| 1178 | uvsrc_x, |
| 1179 | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[1] : uvsrc_y, |
| 1180 | s->h_edge_pos >> 1, |
| 1181 | s->v_edge_pos >> 1); |
Jerome Borsboom | 362ce2d | 2018-04-23 18:59:41 | [diff] [blame] | 1182 | } |
Michael Niedermayer | d5a3cae | 2014-10-08 19:58:42 | [diff] [blame] | 1183 | srcU = ubuf; |
| 1184 | srcV = vbuf; |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1185 | /* if we deal with range reduction we need to scale source blocks */ |
| 1186 | if (v->rangeredfrm) { |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 1187 | vc1_scale_luma(srcY, k, s->linesize); |
| 1188 | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1189 | } |
| 1190 | |
| 1191 | if (use_ic) { |
Andreas Rheinhardt | dda009b | 2023-10-04 19:33:18 | [diff] [blame] | 1192 | const uint8_t (*luty )[256] = v->next_luty; |
| 1193 | const uint8_t (*lutuv)[256] = v->next_lutuv; |
zhaoxiu.zeng | bf99068 | 2015-02-16 16:38:53 | [diff] [blame] | 1194 | vc1_lut_scale_luma(srcY, |
| 1195 | luty[v->field_mode ? v->ref_field_type[1] : ((0+src_y - s->mspel) & 1)], |
| 1196 | luty[v->field_mode ? v->ref_field_type[1] : ((1+src_y - s->mspel) & 1)], |
| 1197 | k, s->linesize); |
| 1198 | vc1_lut_scale_chroma(srcU, srcV, |
| 1199 | lutuv[v->field_mode ? v->ref_field_type[1] : ((0+uvsrc_y) & 1)], |
| 1200 | lutuv[v->field_mode ? v->ref_field_type[1] : ((1+uvsrc_y) & 1)], |
| 1201 | 9, s->uvlinesize); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1202 | } |
| 1203 | srcY += s->mspel * (1 + s->linesize); |
| 1204 | } |
| 1205 | |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1206 | if (s->mspel) { |
| 1207 | dxy = ((my & 3) << 2) | (mx & 3); |
Zeng Zhaoxiu | 1be6054 | 2015-03-07 08:24:42 | [diff] [blame] | 1208 | v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1209 | } else { // hpel mc |
| 1210 | dxy = (my & 2) | ((mx & 2) >> 1); |
| 1211 | |
| 1212 | if (!v->rnd) |
Zeng Zhaoxiu | 1be6054 | 2015-03-07 08:24:42 | [diff] [blame] | 1213 | s->hdsp.avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1214 | else |
Zeng Zhaoxiu | 1be6054 | 2015-03-07 08:24:42 | [diff] [blame] | 1215 | s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0], srcY, s->linesize, 16); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1216 | } |
| 1217 | |
Michael Niedermayer | 94d68a4 | 2015-07-27 19:14:31 | [diff] [blame] | 1218 | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
Vittorio Giovara | 848e86f | 2015-04-27 18:13:25 | [diff] [blame] | 1219 | return; |
Vittorio Giovara | 41ed7ab | 2016-04-27 17:45:23 | [diff] [blame] | 1220 | /* Chroma MC always uses qpel bilinear */ |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1221 | uvmx = (uvmx & 3) << 1; |
| 1222 | uvmy = (uvmy & 3) << 1; |
| 1223 | if (!v->rnd) { |
Zeng Zhaoxiu | 1be6054 | 2015-03-07 08:24:42 | [diff] [blame] | 1224 | h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
| 1225 | h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1226 | } else { |
Zeng Zhaoxiu | 1be6054 | 2015-03-07 08:24:42 | [diff] [blame] | 1227 | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
| 1228 | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
Luca Barbato | 04d14c9 | 2014-07-16 18:18:20 | [diff] [blame] | 1229 | } |
| 1230 | } |