Coverage Report

Created: 2026-05-16 07:49

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