Coverage Report

Created: 2026-07-25 07:52

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
9.52M
{
38
9.52M
    int i, j;
39
129M
    for (j = 0; j < k; j++) {
40
1.71G
        for (i = 0; i < k; i++)
41
1.59G
            srcY[i] = ((srcY[i] - 128) >> 1) + 128;
42
119M
        srcY += linesize;
43
119M
    }
44
9.52M
}
45
46
static av_always_inline void vc1_scale_chroma(uint8_t *srcU, uint8_t *srcV,
47
                                              int k, int uvlinesize)
48
3.97M
{
49
3.97M
    int i, j;
50
39.7M
    for (j = 0; j < k; j++) {
51
357M
        for (i = 0; i < k; i++) {
52
321M
            srcU[i] = ((srcU[i] - 128) >> 1) + 128;
53
321M
            srcV[i] = ((srcV[i] - 128) >> 1) + 128;
54
321M
        }
55
35.7M
        srcU += uvlinesize;
56
35.7M
        srcV += uvlinesize;
57
35.7M
    }
58
3.97M
}
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
13.7M
{
64
13.7M
    int i, j;
65
66
101M
    for (j = 0; j < k; j += 2) {
67
1.59G
        for (i = 0; i < k; i++)
68
1.49G
            srcY[i] = lut1[srcY[i]];
69
101M
        srcY += linesize;
70
71
101M
        if (j + 1 == k)
72
13.7M
            break;
73
74
1.38G
        for (i = 0; i < k; i++)
75
1.30G
            srcY[i] = lut2[srcY[i]];
76
87.6M
        srcY += linesize;
77
87.6M
    }
78
13.7M
}
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
9.63M
{
84
9.63M
    int i, j;
85
86
41.4M
    for (j = 0; j < k; j += 2) {
87
373M
        for (i = 0; i < k; i++) {
88
332M
            srcU[i] = lut1[srcU[i]];
89
332M
            srcV[i] = lut1[srcV[i]];
90
332M
        }
91
41.4M
        srcU += uvlinesize;
92
41.4M
        srcV += uvlinesize;
93
94
41.4M
        if (j + 1 == k)
95
9.63M
            break;
96
97
290M
        for (i = 0; i < k; i++) {
98
259M
            srcU[i] = lut2[srcU[i]];
99
259M
            srcV[i] = lut2[srcV[i]];
100
259M
        }
101
31.7M
        srcU += uvlinesize;
102
31.7M
        srcV += uvlinesize;
103
31.7M
    }
104
9.63M
}
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
406k
{
110
406k
    MpegEncContext *s = &v->s;
111
406k
    int idx = v->mv_f[dir][s->block_index[0] + v->blocks_off] |
112
406k
             (v->mv_f[dir][s->block_index[1] + v->blocks_off] << 1) |
113
406k
             (v->mv_f[dir][s->block_index[2] + v->blocks_off] << 2) |
114
406k
             (v->mv_f[dir][s->block_index[3] + v->blocks_off] << 3);
115
406k
    static const uint8_t index2[16] = { 0, 0, 0, 0x23, 0, 0x13, 0x03, 0, 0, 0x12, 0x02, 0, 0x01, 0, 0, 0 };
116
406k
    int opp_count = popcount4[idx];
117
118
406k
    switch (opp_count) {
119
91.0k
    case 0:
120
165k
    case 4:
121
165k
        *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
122
165k
        *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
123
165k
        break;
124
84.2k
    case 1:
125
84.2k
        *tx = mid_pred(s->mv[dir][idx < 2][0], s->mv[dir][1 + (idx < 4)][0], s->mv[dir][2 + (idx < 8)][0]);
126
84.2k
        *ty = mid_pred(s->mv[dir][idx < 2][1], s->mv[dir][1 + (idx < 4)][1], s->mv[dir][2 + (idx < 8)][1]);
127
84.2k
        break;
128
86.4k
    case 3:
129
86.4k
        *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
130
86.4k
        *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
131
86.4k
        break;
132
69.6k
    case 2:
133
69.6k
        *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
134
69.6k
        *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
135
69.6k
        break;
136
406k
    }
137
406k
    return opp_count;
138
406k
}
139
140
static av_always_inline int get_chroma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty)
141
3.78M
{
142
3.78M
    MpegEncContext *s = &v->s;
143
3.78M
    int idx = !v->mb_type[s->block_index[0]] |
144
3.78M
             (!v->mb_type[s->block_index[1]] << 1) |
145
3.78M
             (!v->mb_type[s->block_index[2]] << 2) |
146
3.78M
             (!v->mb_type[s->block_index[3]] << 3);
147
3.78M
    static const uint8_t index2[16] = { 0, 0, 0, 0x01, 0, 0x02, 0x12, 0, 0, 0x03, 0x13, 0, 0x23, 0, 0, 0 };
148
3.78M
    int valid_count = popcount4[idx];
149
150
3.78M
    switch (valid_count) {
151
3.32M
    case 4:
152
3.32M
        *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
153
3.32M
        *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
154
3.32M
        break;
155
400k
    case 3:
156
400k
        *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
157
400k
        *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
158
400k
        break;
159
44.4k
    case 2:
160
44.4k
        *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
161
44.4k
        *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
162
44.4k
        break;
163
16.4k
    default:
164
16.4k
        return 0;
165
3.78M
    }
166
3.76M
    return valid_count;
167
3.78M
}
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
33.5M
{
174
33.5M
    MpegEncContext *s = &v->s;
175
33.5M
    H264ChromaContext *h264chroma = &v->h264chroma;
176
33.5M
    uint8_t *srcY, *srcU, *srcV;
177
33.5M
    int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
178
33.5M
    int v_edge_pos = s->v_edge_pos >> v->field_mode;
179
33.5M
    int i;
180
33.5M
    const uint8_t (*luty)[256], (*lutuv)[256];
181
33.5M
    int use_ic;
182
33.5M
    int interlace;
183
33.5M
    int linesize, uvlinesize;
184
185
33.5M
    if ((!v->field_mode ||
186
1.92M
         (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
187
32.3M
        !v->s.last_pic.data[0])
188
10.8M
        return;
189
190
22.7M
    linesize   = s->cur_pic.ptr->f->linesize[0];
191
22.7M
    uvlinesize = s->cur_pic.ptr->f->linesize[1];
192
193
22.7M
    mx = s->mv[dir][0][0];
194
22.7M
    my = s->mv[dir][0][1];
195
196
    // store motion vectors for further use in B-frames
197
22.7M
    if (s->pict_type == AV_PICTURE_TYPE_P) {
198
59.5M
        for (i = 0; i < 4; i++) {
199
47.6M
            s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
200
47.6M
            s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
201
47.6M
        }
202
11.9M
    }
203
204
22.7M
    uvmx = (mx + ((mx & 3) == 3)) >> 1;
205
22.7M
    uvmy = (my + ((my & 3) == 3)) >> 1;
206
22.7M
    v->luma_mv[s->mb_x][0] = uvmx;
207
22.7M
    v->luma_mv[s->mb_x][1] = uvmy;
208
209
22.7M
    if (v->field_mode &&
210
1.91M
        v->cur_field_type != v->ref_field_type[dir]) {
211
1.10M
        my   = my   - 2 + 4 * v->cur_field_type;
212
1.10M
        uvmy = uvmy - 2 + 4 * v->cur_field_type;
213
1.10M
    }
214
215
    // fastuvmc shall be ignored for interlaced frame picture
216
22.7M
    if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
217
5.83M
        uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
218
5.83M
        uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
219
5.83M
    }
220
22.7M
    if (!dir) {
221
19.4M
        if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
222
907k
            srcY = s->cur_pic.data[0];
223
907k
            srcU = s->cur_pic.data[1];
224
907k
            srcV = s->cur_pic.data[2];
225
907k
            luty  = v->curr_luty;
226
907k
            lutuv = v->curr_lutuv;
227
907k
            use_ic = *v->curr_use_ic;
228
907k
            interlace = 1;
229
18.5M
        } else {
230
18.5M
            srcY = s->last_pic.data[0];
231
18.5M
            srcU = s->last_pic.data[1];
232
18.5M
            srcV = s->last_pic.data[2];
233
18.5M
            luty  = v->last_luty;
234
18.5M
            lutuv = v->last_lutuv;
235
18.5M
            use_ic = v->last_use_ic;
236
18.5M
            interlace = v->last_interlaced;
237
18.5M
        }
238
19.4M
    } else {
239
3.23M
        srcY = s->next_pic.data[0];
240
3.23M
        srcU = s->next_pic.data[1];
241
3.23M
        srcV = s->next_pic.data[2];
242
3.23M
        luty  = v->next_luty;
243
3.23M
        lutuv = v->next_lutuv;
244
3.23M
        use_ic = v->next_use_ic;
245
3.23M
        interlace = v->next_interlaced;
246
3.23M
    }
247
248
22.7M
    if (!srcY || !srcU) {
249
13.9k
        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
250
13.9k
        return;
251
13.9k
    }
252
253
22.7M
    src_x   = s->mb_x * 16 + (mx   >> 2);
254
22.7M
    src_y   = s->mb_y * 16 + (my   >> 2);
255
22.7M
    uvsrc_x = s->mb_x *  8 + (uvmx >> 2);
256
22.7M
    uvsrc_y = s->mb_y *  8 + (uvmy >> 2);
257
258
22.7M
    if (v->profile != PROFILE_ADVANCED) {
259
9.14M
        src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
260
9.14M
        src_y   = av_clip(  src_y, -16, s->mb_height * 16);
261
9.14M
        uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
262
9.14M
        uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
263
13.5M
    } else {
264
13.5M
        src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
265
13.5M
        uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
266
13.5M
        if (v->fcm == ILACE_FRAME) {
267
8.18M
            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
268
8.18M
            uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
269
8.18M
        } else {
270
5.36M
            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
271
5.36M
            uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
272
5.36M
        }
273
13.5M
    }
274
275
22.7M
    srcY += src_y   * s->linesize   + src_x;
276
22.7M
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
277
22.7M
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
278
279
22.7M
    if (v->field_mode && v->ref_field_type[dir]) {
280
863k
        srcY += linesize;
281
863k
        srcU += uvlinesize;
282
863k
        srcV += uvlinesize;
283
863k
    }
284
285
    /* for grayscale we should not try to read from unknown area */
286
22.7M
    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
22.7M
    if (v->rangeredfrm || use_ic
292
16.5M
        || s->h_edge_pos < 22 || v_edge_pos < 22
293
14.9M
        || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
294
12.9M
        || (unsigned)(src_y - 1)        > v_edge_pos    - (my&3) - 16 - 3) {
295
11.4M
        uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
296
11.4M
        uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
297
11.4M
        const int k = 17 + s->mspel * 2;
298
299
11.4M
        srcY -= s->mspel * (1 + s->linesize);
300
11.4M
        if (interlace) {
301
1.03M
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
302
1.03M
                                     srcY,
303
1.03M
                                     linesize << 1,
304
1.03M
                                     linesize << 1,
305
1.03M
                                     k,
306
1.03M
                                     v->field_mode ? k : k + 1 >> 1,
307
1.03M
                                     src_x - s->mspel,
308
1.03M
                                     src_y - s->mspel >> !v->field_mode,
309
1.03M
                                     s->h_edge_pos,
310
1.03M
                                     s->v_edge_pos >> 1);
311
1.03M
            if (!v->field_mode)
312
703k
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize,
313
703k
                                         srcY + linesize,
314
703k
                                         linesize << 1,
315
703k
                                         linesize << 1,
316
703k
                                         k,
317
703k
                                         k >> 1,
318
703k
                                         src_x - s->mspel,
319
703k
                                         src_y - s->mspel + 1 >> 1,
320
703k
                                         s->h_edge_pos,
321
703k
                                         s->v_edge_pos >> 1);
322
1.03M
        } else
323
10.4M
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
324
10.4M
                                     srcY,
325
10.4M
                                     linesize,
326
10.4M
                                     linesize,
327
10.4M
                                     k,
328
10.4M
                                     v->field_mode ? (k << 1) - 1 : k,
329
10.4M
                                     src_x - s->mspel,
330
10.4M
                                     v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] :
331
10.4M
                                                     src_y - s->mspel,
332
10.4M
                                     s->h_edge_pos,
333
10.4M
                                     s->v_edge_pos);
334
11.4M
        srcY = s->sc.edge_emu_buffer;
335
11.4M
        if (interlace) {
336
1.03M
            s->vdsp.emulated_edge_mc(ubuf,
337
1.03M
                                     srcU,
338
1.03M
                                     uvlinesize << 1,
339
1.03M
                                     uvlinesize << 1,
340
1.03M
                                     9,
341
1.03M
                                     v->field_mode ? 9 : 5,
342
1.03M
                                     uvsrc_x,
343
1.03M
                                     uvsrc_y >> !v->field_mode,
344
1.03M
                                     s->h_edge_pos >> 1,
345
1.03M
                                     s->v_edge_pos >> 2);
346
1.03M
            s->vdsp.emulated_edge_mc(vbuf,
347
1.03M
                                     srcV,
348
1.03M
                                     uvlinesize << 1,
349
1.03M
                                     uvlinesize << 1,
350
1.03M
                                     9,
351
1.03M
                                     v->field_mode ? 9 : 5,
352
1.03M
                                     uvsrc_x,
353
1.03M
                                     uvsrc_y >> !v->field_mode,
354
1.03M
                                     s->h_edge_pos >> 1,
355
1.03M
                                     s->v_edge_pos >> 2);
356
1.03M
            if (!v->field_mode) {
357
703k
                s->vdsp.emulated_edge_mc(ubuf + uvlinesize,
358
703k
                                         srcU + uvlinesize,
359
703k
                                         uvlinesize << 1,
360
703k
                                         uvlinesize << 1,
361
703k
                                         9,
362
703k
                                         4,
363
703k
                                         uvsrc_x,
364
703k
                                         uvsrc_y + 1 >> 1,
365
703k
                                         s->h_edge_pos >> 1,
366
703k
                                         s->v_edge_pos >> 2);
367
703k
                s->vdsp.emulated_edge_mc(vbuf + uvlinesize,
368
703k
                                         srcV + uvlinesize,
369
703k
                                         uvlinesize << 1,
370
703k
                                         uvlinesize << 1,
371
703k
                                         9,
372
703k
                                         4,
373
703k
                                         uvsrc_x,
374
703k
                                         uvsrc_y + 1 >> 1,
375
703k
                                         s->h_edge_pos >> 1,
376
703k
                                         s->v_edge_pos >> 2);
377
703k
            }
378
10.4M
        } else {
379
10.4M
            s->vdsp.emulated_edge_mc(ubuf,
380
10.4M
                                     srcU,
381
10.4M
                                     uvlinesize,
382
10.4M
                                     uvlinesize,
383
10.4M
                                     9,
384
10.4M
                                     v->field_mode ? 17 : 9,
385
10.4M
                                     uvsrc_x,
386
10.4M
                                     v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y,
387
10.4M
                                     s->h_edge_pos >> 1,
388
10.4M
                                     s->v_edge_pos >> 1);
389
10.4M
            s->vdsp.emulated_edge_mc(vbuf,
390
10.4M
                                     srcV,
391
10.4M
                                     uvlinesize,
392
10.4M
                                     uvlinesize,
393
10.4M
                                     9,
394
10.4M
                                     v->field_mode ? 17 : 9,
395
10.4M
                                     uvsrc_x,
396
10.4M
                                     v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y,
397
10.4M
                                     s->h_edge_pos >> 1,
398
10.4M
                                     s->v_edge_pos >> 1);
399
10.4M
        }
400
11.4M
        srcU = ubuf;
401
11.4M
        srcV = vbuf;
402
        /* if we deal with range reduction we need to scale source blocks */
403
11.4M
        if (v->rangeredfrm) {
404
1.72M
            vc1_scale_luma(srcY, k, s->linesize);
405
1.72M
            vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
406
1.72M
        }
407
        /* if we deal with intensity compensation we need to scale source blocks */
408
11.4M
        if (use_ic) {
409
4.83M
            vc1_lut_scale_luma(srcY,
410
4.83M
                               luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)],
411
4.83M
                               luty[v->field_mode ? v->ref_field_type[dir] : ((1 + src_y - s->mspel) & 1)],
412
4.83M
                               k, s->linesize);
413
4.83M
            vc1_lut_scale_chroma(srcU, srcV,
414
4.83M
                                 lutuv[v->field_mode ? v->ref_field_type[dir] : ((0 + uvsrc_y) & 1)],
415
4.83M
                                 lutuv[v->field_mode ? v->ref_field_type[dir] : ((1 + uvsrc_y) & 1)],
416
4.83M
                                 9, s->uvlinesize);
417
4.83M
        }
418
11.4M
        srcY += s->mspel * (1 + s->linesize);
419
11.4M
    }
420
421
22.7M
    if (s->mspel) {
422
18.3M
        dxy = ((my & 3) << 2) | (mx & 3);
423
18.3M
        v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
424
18.3M
    } else { // hpel mc - always used for luma
425
4.30M
        dxy = (my & 2) | ((mx & 2) >> 1);
426
4.30M
        if (!v->rnd)
427
1.64M
            s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
428
2.65M
        else
429
2.65M
            s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
430
4.30M
    }
431
432
22.7M
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
433
0
        return;
434
    /* Chroma MC always uses qpel bilinear */
435
22.7M
    uvmx = (uvmx & 3) << 1;
436
22.7M
    uvmy = (uvmy & 3) << 1;
437
22.7M
    if (!v->rnd) {
438
7.61M
        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
439
7.61M
        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
440
15.0M
    } else {
441
15.0M
        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
442
15.0M
        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
443
15.0M
    }
444
22.7M
    if (v->field_mode) {
445
1.90M
        v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir];
446
1.90M
        v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir];
447
1.90M
    }
448
22.7M
}
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
46.9M
{
454
46.9M
    MpegEncContext *s = &v->s;
455
46.9M
    uint8_t *srcY;
456
46.9M
    int dxy, mx, my, src_x, src_y;
457
46.9M
    int off;
458
46.9M
    int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
459
46.9M
    int v_edge_pos = s->v_edge_pos >> v->field_mode;
460
46.9M
    const uint8_t (*luty)[256];
461
46.9M
    int use_ic;
462
46.9M
    int interlace;
463
46.9M
    int linesize;
464
465
46.9M
    if ((!v->field_mode ||
466
1.32M
         (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
467
46.1M
        !v->s.last_pic.data[0])
468
13.0M
        return;
469
470
33.9M
    linesize = s->cur_pic.ptr->f->linesize[0];
471
472
33.9M
    mx = s->mv[dir][n][0];
473
33.9M
    my = s->mv[dir][n][1];
474
475
33.9M
    if (!dir) {
476
27.0M
        if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
477
361k
            srcY = s->cur_pic.data[0];
478
361k
            luty = v->curr_luty;
479
361k
            use_ic = *v->curr_use_ic;
480
361k
            interlace = 1;
481
26.6M
        } else {
482
26.6M
            srcY = s->last_pic.data[0];
483
26.6M
            luty = v->last_luty;
484
26.6M
            use_ic = v->last_use_ic;
485
26.6M
            interlace = v->last_interlaced;
486
26.6M
        }
487
27.0M
    } else {
488
6.92M
        srcY = s->next_pic.data[0];
489
6.92M
        luty = v->next_luty;
490
6.92M
        use_ic = v->next_use_ic;
491
6.92M
        interlace = v->next_interlaced;
492
6.92M
    }
493
494
33.9M
    if (!srcY) {
495
19.3k
        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
496
19.3k
        return;
497
19.3k
    }
498
499
33.9M
    if (v->field_mode) {
500
1.29M
        if (v->cur_field_type != v->ref_field_type[dir])
501
617k
            my = my - 2 + 4 * v->cur_field_type;
502
1.29M
    }
503
504
33.9M
    if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
505
131k
        int opp_count = get_luma_mv(v, 0,
506
131k
                                    &s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0],
507
131k
                                    &s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1]);
508
131k
        int k, f = opp_count > 2;
509
656k
        for (k = 0; k < 4; k++)
510
524k
            v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
511
131k
    }
512
513
33.9M
    if (v->fcm == ILACE_FRAME) {  // not sure if needed for other types of picture
514
18.2M
        int qx, qy;
515
18.2M
        int width  = s->avctx->coded_width;
516
18.2M
        int height = s->avctx->coded_height >> 1;
517
18.2M
        if (s->pict_type == AV_PICTURE_TYPE_P) {
518
5.37M
            s->cur_pic.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
519
5.37M
            s->cur_pic.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
520
5.37M
        }
521
18.2M
        qx = (s->mb_x * 16) + (mx >> 2);
522
18.2M
        qy = (s->mb_y *  8) + (my >> 3);
523
524
18.2M
        if (qx < -17)
525
99.7k
            mx -= 4 * (qx + 17);
526
18.1M
        else if (qx > width)
527
300k
            mx -= 4 * (qx - width);
528
18.2M
        if (qy < -18)
529
4.37k
            my -= 8 * (qy + 18);
530
18.2M
        else if (qy > height + 1)
531
90.6k
            my -= 8 * (qy - height - 1);
532
18.2M
    }
533
534
33.9M
    if ((v->fcm == ILACE_FRAME) && fieldmv)
535
18.1M
        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
33.9M
    src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
540
33.9M
    if (!fieldmv)
541
15.8M
        src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
542
18.1M
    else
543
18.1M
        src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
544
545
33.9M
    if (v->profile != PROFILE_ADVANCED) {
546
14.4M
        src_x = av_clip(src_x, -16, s->mb_width  * 16);
547
14.4M
        src_y = av_clip(src_y, -16, s->mb_height * 16);
548
19.4M
    } else {
549
19.4M
        src_x = av_clip(src_x, -17, s->avctx->coded_width);
550
19.4M
        if (v->fcm == ILACE_FRAME)
551
14.4M
            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
552
5.01M
        else
553
5.01M
            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
554
19.4M
    }
555
556
33.9M
    srcY += src_y * s->linesize + src_x;
557
33.9M
    if (v->field_mode && v->ref_field_type[dir])
558
670k
        srcY += linesize;
559
560
33.9M
    if (v->rangeredfrm || use_ic
561
21.4M
        || s->h_edge_pos < 13 || v_edge_pos < 23
562
20.5M
        || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
563
18.3M
        || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
564
17.9M
        const int k = 9 + s->mspel * 2;
565
566
17.9M
        srcY -= s->mspel * (1 + (s->linesize << fieldmv));
567
        /* check emulate edge stride and offset */
568
17.9M
        if (interlace) {
569
1.82M
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
570
1.82M
                                     srcY,
571
1.82M
                                     linesize << 1,
572
1.82M
                                     linesize << 1,
573
1.82M
                                     k,
574
1.82M
                                     v->field_mode ? k : (k << fieldmv) + 1 >> 1,
575
1.82M
                                     src_x - s->mspel,
576
1.82M
                                     src_y - (s->mspel << fieldmv) >> !v->field_mode,
577
1.82M
                                     s->h_edge_pos,
578
1.82M
                                     s->v_edge_pos >> 1);
579
1.82M
            if (!v->field_mode && !fieldmv)
580
66.5k
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize,
581
66.5k
                                         srcY + linesize,
582
66.5k
                                         linesize << 1,
583
66.5k
                                         linesize << 1,
584
66.5k
                                         k,
585
66.5k
                                         k >> 1,
586
66.5k
                                         src_x - s->mspel,
587
66.5k
                                         src_y - s->mspel + 1 >> 1,
588
66.5k
                                         s->h_edge_pos,
589
66.5k
                                         s->v_edge_pos >> 1);
590
1.82M
        } else
591
16.1M
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
592
16.1M
                                     srcY,
593
16.1M
                                     linesize,
594
16.1M
                                     linesize,
595
16.1M
                                     k,
596
16.1M
                                     v->field_mode ? (k << 1) - 1 : k << fieldmv,
597
16.1M
                                     src_x - s->mspel,
598
16.1M
                                     v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] :
599
16.1M
                                                     src_y - (s->mspel << fieldmv),
600
16.1M
                                     s->h_edge_pos,
601
16.1M
                                     s->v_edge_pos);
602
17.9M
        srcY = s->sc.edge_emu_buffer;
603
        /* if we deal with range reduction we need to scale source blocks */
604
17.9M
        if (v->rangeredfrm) {
605
7.50M
            vc1_scale_luma(srcY, k, s->linesize << fieldmv);
606
7.50M
        }
607
        /* if we deal with intensity compensation we need to scale source blocks */
608
17.9M
        if (use_ic) {
609
8.90M
            vc1_lut_scale_luma(srcY,
610
8.90M
                               luty[v->field_mode ? v->ref_field_type[dir] : (((0<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
611
8.90M
                               luty[v->field_mode ? v->ref_field_type[dir] : (((1<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
612
8.90M
                               k, s->linesize << fieldmv);
613
8.90M
        }
614
17.9M
        srcY += s->mspel * (1 + (s->linesize << fieldmv));
615
17.9M
    }
616
617
33.9M
    if (s->mspel) {
618
33.9M
        dxy = ((my & 3) << 2) | (mx & 3);
619
33.9M
        if (avg)
620
4.25M
            v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
621
29.6M
        else
622
29.6M
            v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
623
33.9M
    } 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
33.9M
}
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.36M
{
636
5.36M
    MpegEncContext *s = &v->s;
637
5.36M
    H264ChromaContext *h264chroma = &v->h264chroma;
638
5.36M
    uint8_t *srcU, *srcV;
639
5.36M
    int uvmx, uvmy, uvsrc_x, uvsrc_y;
640
5.36M
    int16_t tx, ty;
641
5.36M
    int chroma_ref_type;
642
5.36M
    int v_edge_pos = s->v_edge_pos >> v->field_mode;
643
5.36M
    const uint8_t (*lutuv)[256];
644
5.36M
    int use_ic;
645
5.36M
    int interlace;
646
5.36M
    int uvlinesize;
647
648
5.36M
    if (!v->field_mode && !v->s.last_pic.data[0])
649
1.30M
        return;
650
4.05M
    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.05M
    if (!v->field_mode || !v->numref) {
655
3.78M
        int valid_count = get_chroma_mv(v, dir, &tx, &ty);
656
3.78M
        if (!valid_count) {
657
16.4k
            s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
658
16.4k
            s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
659
16.4k
            v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
660
16.4k
            return; //no need to do MC for intra blocks
661
16.4k
        }
662
3.76M
        chroma_ref_type = v->ref_field_type[dir];
663
3.76M
    } else {
664
275k
        int opp_count = get_luma_mv(v, dir, &tx, &ty);
665
275k
        chroma_ref_type = v->cur_field_type ^ (opp_count > 2);
666
275k
    }
667
4.04M
    if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_pic.data[0])
668
4.72k
        return;
669
4.03M
    s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
670
4.03M
    s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
671
672
4.03M
    uvlinesize = s->cur_pic.ptr->f->linesize[1];
673
674
4.03M
    uvmx = (tx + ((tx & 3) == 3)) >> 1;
675
4.03M
    uvmy = (ty + ((ty & 3) == 3)) >> 1;
676
677
4.03M
    v->luma_mv[s->mb_x][0] = uvmx;
678
4.03M
    v->luma_mv[s->mb_x][1] = uvmy;
679
680
4.03M
    if (v->fastuvmc) {
681
2.92M
        uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
682
2.92M
        uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
683
2.92M
    }
684
    // Field conversion bias
685
4.03M
    if (v->cur_field_type != chroma_ref_type)
686
127k
        uvmy += 2 - 4 * chroma_ref_type;
687
688
4.03M
    uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
689
4.03M
    uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
690
691
4.03M
    if (v->profile != PROFILE_ADVANCED) {
692
2.75M
        uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width  * 8);
693
2.75M
        uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
694
2.75M
    } else {
695
1.27M
        uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
696
1.27M
        uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
697
1.27M
    }
698
699
4.03M
    if (!dir) {
700
3.91M
        if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
701
76.1k
            srcU = s->cur_pic.data[1];
702
76.1k
            srcV = s->cur_pic.data[2];
703
76.1k
            lutuv = v->curr_lutuv;
704
76.1k
            use_ic = *v->curr_use_ic;
705
76.1k
            interlace = 1;
706
3.84M
        } else {
707
3.84M
            srcU = s->last_pic.data[1];
708
3.84M
            srcV = s->last_pic.data[2];
709
3.84M
            lutuv = v->last_lutuv;
710
3.84M
            use_ic = v->last_use_ic;
711
3.84M
            interlace = v->last_interlaced;
712
3.84M
        }
713
3.91M
    } else {
714
119k
        srcU = s->next_pic.data[1];
715
119k
        srcV = s->next_pic.data[2];
716
119k
        lutuv = v->next_lutuv;
717
119k
        use_ic = v->next_use_ic;
718
119k
        interlace = v->next_interlaced;
719
119k
    }
720
721
4.03M
    if (!srcU) {
722
5.72k
        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
723
5.72k
        return;
724
5.72k
    }
725
726
4.03M
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
727
4.03M
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
728
729
4.03M
    if (v->field_mode) {
730
321k
        if (chroma_ref_type) {
731
183k
            srcU += uvlinesize;
732
183k
            srcV += uvlinesize;
733
183k
        }
734
321k
    }
735
736
4.03M
    if (v->rangeredfrm || use_ic
737
1.67M
        || s->h_edge_pos < 18 || v_edge_pos < 18
738
1.46M
        || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
739
2.76M
        || (unsigned)uvsrc_y > (v_edge_pos    >> 1) - 9) {
740
2.76M
        if (interlace) {
741
45.8k
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
742
45.8k
                                     srcU,
743
45.8k
                                     uvlinesize << 1,
744
45.8k
                                     uvlinesize << 1,
745
45.8k
                                     9,
746
45.8k
                                     v->field_mode ? 9 : 5,
747
45.8k
                                     uvsrc_x,
748
45.8k
                                     uvsrc_y >> !v->field_mode,
749
45.8k
                                     s->h_edge_pos >> 1,
750
45.8k
                                     s->v_edge_pos >> 2);
751
45.8k
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16,
752
45.8k
                                     srcV,
753
45.8k
                                     uvlinesize << 1,
754
45.8k
                                     uvlinesize << 1,
755
45.8k
                                     9,
756
45.8k
                                     v->field_mode ? 9 : 5,
757
45.8k
                                     uvsrc_x,
758
45.8k
                                     uvsrc_y >> !v->field_mode,
759
45.8k
                                     s->h_edge_pos >> 1,
760
45.8k
                                     s->v_edge_pos >> 2);
761
45.8k
            if (!v->field_mode) {
762
14.6k
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize,
763
14.6k
                                         srcU + uvlinesize,
764
14.6k
                                         uvlinesize << 1,
765
14.6k
                                         uvlinesize << 1,
766
14.6k
                                         9,
767
14.6k
                                         4,
768
14.6k
                                         uvsrc_x,
769
14.6k
                                         uvsrc_y + 1 >> 1,
770
14.6k
                                         s->h_edge_pos >> 1,
771
14.6k
                                         s->v_edge_pos >> 2);
772
14.6k
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize,
773
14.6k
                                         srcV + uvlinesize,
774
14.6k
                                         uvlinesize << 1,
775
14.6k
                                         uvlinesize << 1,
776
14.6k
                                         9,
777
14.6k
                                         4,
778
14.6k
                                         uvsrc_x,
779
14.6k
                                         uvsrc_y + 1 >> 1,
780
14.6k
                                         s->h_edge_pos >> 1,
781
14.6k
                                         s->v_edge_pos >> 2);
782
14.6k
            }
783
2.72M
        } else {
784
2.72M
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
785
2.72M
                                     srcU,
786
2.72M
                                     uvlinesize,
787
2.72M
                                     uvlinesize,
788
2.72M
                                     9,
789
2.72M
                                     v->field_mode ? 17 : 9,
790
2.72M
                                     uvsrc_x,
791
2.72M
                                     v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y,
792
2.72M
                                     s->h_edge_pos >> 1,
793
2.72M
                                     s->v_edge_pos >> 1);
794
2.72M
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16,
795
2.72M
                                     srcV,
796
2.72M
                                     uvlinesize,
797
2.72M
                                     uvlinesize,
798
2.72M
                                     9,
799
2.72M
                                     v->field_mode ? 17 : 9,
800
2.72M
                                     uvsrc_x,
801
2.72M
                                     v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y,
802
2.72M
                                     s->h_edge_pos >> 1,
803
2.72M
                                     s->v_edge_pos >> 1);
804
2.72M
        }
805
2.76M
        srcU = s->sc.edge_emu_buffer;
806
2.76M
        srcV = s->sc.edge_emu_buffer + 16;
807
808
        /* if we deal with range reduction we need to scale source blocks */
809
2.76M
        if (v->rangeredfrm) {
810
1.94M
            vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
811
1.94M
        }
812
        /* if we deal with intensity compensation we need to scale source blocks */
813
2.76M
        if (use_ic) {
814
1.40M
            vc1_lut_scale_chroma(srcU, srcV,
815
1.40M
                                 lutuv[v->field_mode ? chroma_ref_type : ((0 + uvsrc_y) & 1)],
816
1.40M
                                 lutuv[v->field_mode ? chroma_ref_type : ((1 + uvsrc_y) & 1)],
817
1.40M
                                 9, s->uvlinesize);
818
1.40M
        }
819
2.76M
    }
820
821
    /* Chroma MC always uses qpel bilinear */
822
4.03M
    uvmx = (uvmx & 3) << 1;
823
4.03M
    uvmy = (uvmy & 3) << 1;
824
4.03M
    if (!v->rnd) {
825
1.23M
        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
826
1.23M
        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
827
2.79M
    } else {
828
2.79M
        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
829
2.79M
        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
830
2.79M
    }
831
4.03M
    if (v->field_mode) {
832
321k
        v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != chroma_ref_type;
833
321k
        v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != chroma_ref_type;
834
321k
    }
835
4.03M
}
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
6.55M
{
841
6.55M
    MpegEncContext *s = &v->s;
842
6.55M
    H264ChromaContext *h264chroma = &v->h264chroma;
843
6.55M
    uint8_t *srcU, *srcV;
844
6.55M
    int uvsrc_x, uvsrc_y;
845
6.55M
    int uvmx_field[4], uvmy_field[4];
846
6.55M
    int i, off, tx, ty;
847
6.55M
    int fieldmv = v->blk_mv_type[s->block_index[0]];
848
6.55M
    static const uint8_t s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
849
6.55M
    int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
850
6.55M
    int v_edge_pos = s->v_edge_pos >> 1;
851
6.55M
    int use_ic;
852
6.55M
    int interlace;
853
6.55M
    int uvlinesize;
854
6.55M
    const uint8_t (*lutuv)[256];
855
856
6.55M
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
857
0
        return;
858
859
6.55M
    uvlinesize = s->cur_pic.ptr->f->linesize[1];
860
861
32.7M
    for (i = 0; i < 4; i++) {
862
26.2M
        int d = i < 2 ? dir: dir2;
863
26.2M
        tx = s->mv[d][i][0];
864
26.2M
        uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
865
26.2M
        ty = s->mv[d][i][1];
866
26.2M
        if (fieldmv)
867
25.9M
            uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
868
254k
        else
869
254k
            uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
870
26.2M
    }
871
872
26.0M
    for (i = 0; i < 4; i++) {
873
21.1M
        off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
874
21.1M
        uvsrc_x = s->mb_x * 8 +  (i & 1) * 4           + (uvmx_field[i] >> 2);
875
21.1M
        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
21.1M
        uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
878
21.1M
        if (v->fcm == ILACE_FRAME)
879
21.1M
            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
21.1M
        if (i < 2 ? dir : dir2) {
883
7.64M
            srcU = s->next_pic.data[1];
884
7.64M
            srcV = s->next_pic.data[2];
885
7.64M
            lutuv  = v->next_lutuv;
886
7.64M
            use_ic = v->next_use_ic;
887
7.64M
            interlace = v->next_interlaced;
888
13.5M
        } else {
889
13.5M
            srcU = s->last_pic.data[1];
890
13.5M
            srcV = s->last_pic.data[2];
891
13.5M
            lutuv  = v->last_lutuv;
892
13.5M
            use_ic = v->last_use_ic;
893
13.5M
            interlace = v->last_interlaced;
894
13.5M
        }
895
21.1M
        if (!srcU)
896
1.71M
            return;
897
19.4M
        srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
898
19.4M
        srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
899
19.4M
        uvmx_field[i] = (uvmx_field[i] & 3) << 1;
900
19.4M
        uvmy_field[i] = (uvmy_field[i] & 3) << 1;
901
902
19.4M
        if (use_ic
903
16.0M
            || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
904
15.7M
            || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
905
14.5M
            || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
906
5.95M
            if (interlace) {
907
1.14M
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
908
1.14M
                                         srcU,
909
1.14M
                                         uvlinesize << 1,
910
1.14M
                                         uvlinesize << 1,
911
1.14M
                                         5,
912
1.14M
                                         (5 << fieldmv) + 1 >> 1,
913
1.14M
                                         uvsrc_x,
914
1.14M
                                         uvsrc_y >> 1,
915
1.14M
                                         s->h_edge_pos >> 1,
916
1.14M
                                         s->v_edge_pos >> 2);
917
1.14M
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16,
918
1.14M
                                         srcV,
919
1.14M
                                         uvlinesize << 1,
920
1.14M
                                         uvlinesize << 1,
921
1.14M
                                         5,
922
1.14M
                                         (5 << fieldmv) + 1 >> 1,
923
1.14M
                                         uvsrc_x,
924
1.14M
                                         uvsrc_y >> 1,
925
1.14M
                                         s->h_edge_pos >> 1,
926
1.14M
                                         s->v_edge_pos >> 2);
927
1.14M
                if (!fieldmv) {
928
6.30k
                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize,
929
6.30k
                                             srcU + uvlinesize,
930
6.30k
                                             uvlinesize << 1,
931
6.30k
                                             uvlinesize << 1,
932
6.30k
                                             5,
933
6.30k
                                             2,
934
6.30k
                                             uvsrc_x,
935
6.30k
                                             uvsrc_y + 1 >> 1,
936
6.30k
                                             s->h_edge_pos >> 1,
937
6.30k
                                             s->v_edge_pos >> 2);
938
6.30k
                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize,
939
6.30k
                                             srcV + uvlinesize,
940
6.30k
                                             uvlinesize << 1,
941
6.30k
                                             uvlinesize << 1,
942
6.30k
                                             5,
943
6.30k
                                             2,
944
6.30k
                                             uvsrc_x,
945
6.30k
                                             uvsrc_y + 1 >> 1,
946
6.30k
                                             s->h_edge_pos >> 1,
947
6.30k
                                             s->v_edge_pos >> 2);
948
6.30k
                }
949
4.81M
            } else {
950
4.81M
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
951
4.81M
                                         srcU,
952
4.81M
                                         uvlinesize,
953
4.81M
                                         uvlinesize,
954
4.81M
                                         5,
955
4.81M
                                         5 << fieldmv,
956
4.81M
                                         uvsrc_x,
957
4.81M
                                         uvsrc_y,
958
4.81M
                                         s->h_edge_pos >> 1,
959
4.81M
                                         s->v_edge_pos >> 1);
960
4.81M
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16,
961
4.81M
                                         srcV,
962
4.81M
                                         uvlinesize,
963
4.81M
                                         uvlinesize,
964
4.81M
                                         5,
965
4.81M
                                         5 << fieldmv,
966
4.81M
                                         uvsrc_x,
967
4.81M
                                         uvsrc_y,
968
4.81M
                                         s->h_edge_pos >> 1,
969
4.81M
                                         s->v_edge_pos >> 1);
970
4.81M
            }
971
5.95M
            srcU = s->sc.edge_emu_buffer;
972
5.95M
            srcV = s->sc.edge_emu_buffer + 16;
973
974
            /* if we deal with intensity compensation we need to scale source blocks */
975
5.95M
            if (use_ic) {
976
3.37M
                vc1_lut_scale_chroma(srcU, srcV,
977
3.37M
                                     lutuv[(uvsrc_y + (0 << fieldmv)) & 1],
978
3.37M
                                     lutuv[(uvsrc_y + (1 << fieldmv)) & 1],
979
3.37M
                                     5, s->uvlinesize << fieldmv);
980
3.37M
            }
981
5.95M
        }
982
19.4M
        if (avg) {
983
5.08M
            if (!v->rnd) {
984
997k
                h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
985
997k
                h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
986
4.08M
            } else {
987
4.08M
                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.08M
                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.08M
            }
990
14.3M
        } else {
991
14.3M
            if (!v->rnd) {
992
2.96M
                h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
993
2.96M
                h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
994
11.4M
            } else {
995
11.4M
                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
11.4M
                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
11.4M
            }
998
14.3M
        }
999
19.4M
    }
1000
6.55M
}
1001
1002
/** Motion compensation for direct or interpolated blocks in B-frames
1003
 */
1004
void ff_vc1_interp_mc(VC1Context *v)
1005
6.65M
{
1006
6.65M
    MpegEncContext *s = &v->s;
1007
6.65M
    H264ChromaContext *h264chroma = &v->h264chroma;
1008
6.65M
    uint8_t *srcY, *srcU, *srcV;
1009
6.65M
    int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
1010
6.65M
    int v_edge_pos = s->v_edge_pos >> v->field_mode;
1011
6.65M
    int use_ic = v->next_use_ic;
1012
6.65M
    int interlace = v->next_interlaced;
1013
6.65M
    int linesize, uvlinesize;
1014
1015
6.65M
    if (!v->field_mode && !v->s.next_pic.data[0])
1016
0
        return;
1017
1018
6.65M
    linesize   = s->cur_pic.ptr->f->linesize[0];
1019
6.65M
    uvlinesize = s->cur_pic.ptr->f->linesize[1];
1020
1021
6.65M
    mx   = s->mv[1][0][0];
1022
6.65M
    my   = s->mv[1][0][1];
1023
6.65M
    uvmx = (mx + ((mx & 3) == 3)) >> 1;
1024
6.65M
    uvmy = (my + ((my & 3) == 3)) >> 1;
1025
6.65M
    if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) {
1026
57.4k
        my   = my   - 2 + 4 * v->cur_field_type;
1027
57.4k
        uvmy = uvmy - 2 + 4 * v->cur_field_type;
1028
57.4k
    }
1029
6.65M
    if (v->fastuvmc) {
1030
2.05M
        uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
1031
2.05M
        uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
1032
2.05M
    }
1033
6.65M
    srcY = s->next_pic.data[0];
1034
6.65M
    srcU = s->next_pic.data[1];
1035
6.65M
    srcV = s->next_pic.data[2];
1036
1037
6.65M
    src_x   = s->mb_x * 16 + (mx   >> 2);
1038
6.65M
    src_y   = s->mb_y * 16 + (my   >> 2);
1039
6.65M
    uvsrc_x = s->mb_x *  8 + (uvmx >> 2);
1040
6.65M
    uvsrc_y = s->mb_y *  8 + (uvmy >> 2);
1041
1042
6.65M
    if (v->profile != PROFILE_ADVANCED) {
1043
3.94M
        src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
1044
3.94M
        src_y   = av_clip(  src_y, -16, s->mb_height * 16);
1045
3.94M
        uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
1046
3.94M
        uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
1047
3.94M
    } else {
1048
2.71M
        src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
1049
2.71M
        uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
1050
2.71M
        if (v->fcm == ILACE_FRAME) {
1051
1.92M
            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
1052
1.92M
            uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
1053
1.92M
        } else {
1054
793k
            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
1055
793k
            uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
1056
793k
        }
1057
2.71M
    }
1058
1059
6.65M
    srcY += src_y   * s->linesize   + src_x;
1060
6.65M
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
1061
6.65M
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
1062
1063
6.65M
    if (v->field_mode && v->ref_field_type[1]) {
1064
60.7k
        srcY += linesize;
1065
60.7k
        srcU += uvlinesize;
1066
60.7k
        srcV += uvlinesize;
1067
60.7k
    }
1068
1069
    /* for grayscale we should not try to read from unknown area */
1070
6.65M
    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
6.65M
    if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
1076
5.61M
        || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
1077
4.96M
        || (unsigned)(src_y - 1) > v_edge_pos    - (my & 3) - 16 - 3) {
1078
2.31M
        uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
1079
2.31M
        uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
1080
2.31M
        const int k = 17 + s->mspel * 2;
1081
1082
2.31M
        srcY -= s->mspel * (1 + s->linesize);
1083
2.31M
        if (interlace) {
1084
795k
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
1085
795k
                                     srcY,
1086
795k
                                     linesize << 1,
1087
795k
                                     linesize << 1,
1088
795k
                                     k,
1089
795k
                                     v->field_mode ? k : (k + 1 >> 1),
1090
795k
                                     src_x - s->mspel,
1091
795k
                                     src_y - s->mspel >> !v->field_mode,
1092
795k
                                     s->h_edge_pos,
1093
795k
                                     s->v_edge_pos >> 1);
1094
795k
            if (!v->field_mode)
1095
773k
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize,
1096
773k
                                         srcY + linesize,
1097
773k
                                         linesize << 1,
1098
773k
                                         linesize << 1,
1099
773k
                                         k,
1100
773k
                                         k >> 1,
1101
773k
                                         src_x - s->mspel,
1102
773k
                                         src_y - s->mspel + 1 >> 1,
1103
773k
                                         s->h_edge_pos,
1104
773k
                                         s->v_edge_pos >> 1);
1105
795k
        } 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.31M
        srcY = s->sc.edge_emu_buffer;
1118
2.31M
        if (interlace) {
1119
795k
            s->vdsp.emulated_edge_mc(ubuf,
1120
795k
                                     srcU,
1121
795k
                                     uvlinesize << 1,
1122
795k
                                     uvlinesize << 1,
1123
795k
                                     9,
1124
795k
                                     v->field_mode ? 9 : 5,
1125
795k
                                     uvsrc_x,
1126
795k
                                     uvsrc_y >> !v->field_mode,
1127
795k
                                     s->h_edge_pos >> 1,
1128
795k
                                     s->v_edge_pos >> 2);
1129
795k
            s->vdsp.emulated_edge_mc(vbuf,
1130
795k
                                     srcV,
1131
795k
                                     uvlinesize << 1,
1132
795k
                                     uvlinesize << 1,
1133
795k
                                     9,
1134
795k
                                     v->field_mode ? 9 : 5,
1135
795k
                                     uvsrc_x,
1136
795k
                                     uvsrc_y >> !v->field_mode,
1137
795k
                                     s->h_edge_pos >> 1,
1138
795k
                                     s->v_edge_pos >> 2);
1139
795k
            if (!v->field_mode) {
1140
773k
                s->vdsp.emulated_edge_mc(ubuf + uvlinesize,
1141
773k
                                         srcU + uvlinesize,
1142
773k
                                         uvlinesize << 1,
1143
773k
                                         uvlinesize << 1,
1144
773k
                                         9,
1145
773k
                                         4,
1146
773k
                                         uvsrc_x,
1147
773k
                                         uvsrc_y + 1 >> 1,
1148
773k
                                         s->h_edge_pos >> 1,
1149
773k
                                         s->v_edge_pos >> 2);
1150
773k
                s->vdsp.emulated_edge_mc(vbuf + uvlinesize,
1151
773k
                                         srcV + uvlinesize,
1152
773k
                                         uvlinesize << 1,
1153
773k
                                         uvlinesize << 1,
1154
773k
                                         9,
1155
773k
                                         4,
1156
773k
                                         uvsrc_x,
1157
773k
                                         uvsrc_y + 1 >> 1,
1158
773k
                                         s->h_edge_pos >> 1,
1159
773k
                                         s->v_edge_pos >> 2);
1160
773k
            }
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.31M
        srcU = ubuf;
1184
2.31M
        srcV = vbuf;
1185
        /* if we deal with range reduction we need to scale source blocks */
1186
2.31M
        if (v->rangeredfrm) {
1187
292k
            vc1_scale_luma(srcY, k, s->linesize);
1188
292k
            vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
1189
292k
        }
1190
1191
2.31M
        if (use_ic) {
1192
18.0k
            const uint8_t (*luty )[256] = v->next_luty;
1193
18.0k
            const uint8_t (*lutuv)[256] = v->next_lutuv;
1194
18.0k
            vc1_lut_scale_luma(srcY,
1195
18.0k
                               luty[v->field_mode ? v->ref_field_type[1] : ((0+src_y - s->mspel) & 1)],
1196
18.0k
                               luty[v->field_mode ? v->ref_field_type[1] : ((1+src_y - s->mspel) & 1)],
1197
18.0k
                               k, s->linesize);
1198
18.0k
            vc1_lut_scale_chroma(srcU, srcV,
1199
18.0k
                                 lutuv[v->field_mode ? v->ref_field_type[1] : ((0+uvsrc_y) & 1)],
1200
18.0k
                                 lutuv[v->field_mode ? v->ref_field_type[1] : ((1+uvsrc_y) & 1)],
1201
18.0k
                                 9, s->uvlinesize);
1202
18.0k
        }
1203
2.31M
        srcY += s->mspel * (1 + s->linesize);
1204
2.31M
    }
1205
1206
6.65M
    if (s->mspel) {
1207
4.77M
        dxy = ((my & 3) << 2) | (mx & 3);
1208
4.77M
        v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
1209
4.77M
    } else { // hpel mc
1210
1.88M
        dxy = (my & 2) | ((mx & 2) >> 1);
1211
1212
1.88M
        if (!v->rnd)
1213
901k
            s->hdsp.avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
1214
979k
        else
1215
979k
            s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0], srcY, s->linesize, 16);
1216
1.88M
    }
1217
1218
6.65M
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
1219
0
        return;
1220
    /* Chroma MC always uses qpel bilinear */
1221
6.65M
    uvmx = (uvmx & 3) << 1;
1222
6.65M
    uvmy = (uvmy & 3) << 1;
1223
6.65M
    if (!v->rnd) {
1224
2.11M
        h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
1225
2.11M
        h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
1226
4.54M
    } else {
1227
4.54M
        v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
1228
4.54M
        v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
1229
4.54M
    }
1230
6.65M
}