GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/vc1_mc.c Lines: 659 749 88.0 %
Date: 2020-10-23 17:01:47 Branches: 362 467 77.5 %

Line Branch Exec 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
{
38
    int i, j;
39
    for (j = 0; j < k; j++) {
40
        for (i = 0; i < k; i++)
41
            srcY[i] = ((srcY[i] - 128) >> 1) + 128;
42
        srcY += linesize;
43
    }
44
}
45
46
static av_always_inline void vc1_scale_chroma(uint8_t *srcU, uint8_t *srcV,
47
                                              int k, int uvlinesize)
48
{
49
    int i, j;
50
    for (j = 0; j < k; j++) {
51
        for (i = 0; i < k; i++) {
52
            srcU[i] = ((srcU[i] - 128) >> 1) + 128;
53
            srcV[i] = ((srcV[i] - 128) >> 1) + 128;
54
        }
55
        srcU += uvlinesize;
56
        srcV += uvlinesize;
57
    }
58
}
59
60
3813
static av_always_inline void vc1_lut_scale_luma(uint8_t *srcY,
61
                                                uint8_t *lut1, uint8_t *lut2,
62
                                                int k, int linesize)
63
{
64
    int i, j;
65
66
37708
    for (j = 0; j < k; j += 2) {
67
746564
        for (i = 0; i < k; i++)
68
708856
            srcY[i] = lut1[srcY[i]];
69
37708
        srcY += linesize;
70
71
37708
        if (j + 1 == k)
72
3813
            break;
73
74
671148
        for (i = 0; i < k; i++)
75
637253
            srcY[i] = lut2[srcY[i]];
76
33895
        srcY += linesize;
77
    }
78
3813
}
79
80
3813
static av_always_inline void vc1_lut_scale_chroma(uint8_t *srcU, uint8_t *srcV,
81
                                                  uint8_t *lut1, uint8_t *lut2,
82
                                                  int k, int uvlinesize)
83
{
84
    int i, j;
85
86
19065
    for (j = 0; j < k; j += 2) {
87
190650
        for (i = 0; i < k; i++) {
88
171585
            srcU[i] = lut1[srcU[i]];
89
171585
            srcV[i] = lut1[srcV[i]];
90
        }
91
19065
        srcU += uvlinesize;
92
19065
        srcV += uvlinesize;
93
94
19065
        if (j + 1 == k)
95
3813
            break;
96
97
152520
        for (i = 0; i < k; i++) {
98
137268
            srcU[i] = lut2[srcU[i]];
99
137268
            srcV[i] = lut2[srcV[i]];
100
        }
101
15252
        srcU += uvlinesize;
102
15252
        srcV += uvlinesize;
103
    }
104
3813
}
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
23108
static av_always_inline int get_luma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty)
109
{
110
23108
    MpegEncContext *s = &v->s;
111
23108
    int idx = v->mv_f[dir][s->block_index[0] + v->blocks_off] |
112
23108
             (v->mv_f[dir][s->block_index[1] + v->blocks_off] << 1) |
113
23108
             (v->mv_f[dir][s->block_index[2] + v->blocks_off] << 2) |
114
23108
             (v->mv_f[dir][s->block_index[3] + v->blocks_off] << 3);
115
    static const uint8_t index2[16] = { 0, 0, 0, 0x23, 0, 0x13, 0x03, 0, 0, 0x12, 0x02, 0, 0x01, 0, 0, 0 };
116
23108
    int opp_count = popcount4[idx];
117
118

23108
    switch (opp_count) {
119
16111
    case 0:
120
    case 4:
121
16111
        *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
122
16111
        *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
123
16111
        break;
124
2829
    case 1:
125

2829
        *tx = mid_pred(s->mv[dir][idx < 2][0], s->mv[dir][1 + (idx < 4)][0], s->mv[dir][2 + (idx < 8)][0]);
126

2829
        *ty = mid_pred(s->mv[dir][idx < 2][1], s->mv[dir][1 + (idx < 4)][1], s->mv[dir][2 + (idx < 8)][1]);
127
2829
        break;
128
2560
    case 3:
129

2560
        *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
130

2560
        *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
131
2560
        break;
132
1608
    case 2:
133
1608
        *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
134
1608
        *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
135
1608
        break;
136
    }
137
23108
    return opp_count;
138
}
139
140
26576
static av_always_inline int get_chroma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty)
141
{
142
26576
    MpegEncContext *s = &v->s;
143
79728
    int idx = !v->mb_type[0][s->block_index[0]] |
144
26576
             (!v->mb_type[0][s->block_index[1]] << 1) |
145
26576
             (!v->mb_type[0][s->block_index[2]] << 2) |
146
26576
             (!v->mb_type[0][s->block_index[3]] << 3);
147
    static const uint8_t index2[16] = { 0, 0, 0, 0x01, 0, 0x02, 0x12, 0, 0, 0x03, 0x13, 0, 0x23, 0, 0, 0 };
148
26576
    int valid_count = popcount4[idx];
149
150

26576
    switch (valid_count) {
151
20627
    case 4:
152
20627
        *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]);
153
20627
        *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]);
154
20627
        break;
155
3043
    case 3:
156

3043
        *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]);
157

3043
        *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]);
158
3043
        break;
159
1688
    case 2:
160
1688
        *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2;
161
1688
        *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2;
162
1688
        break;
163
1218
    default:
164
1218
        return 0;
165
    }
166
25358
    return valid_count;
167
}
168
169
/** Do motion compensation over 1 macroblock
170
 * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
171
 */
172
207434
void ff_vc1_mc_1mv(VC1Context *v, int dir)
173
{
174
207434
    MpegEncContext *s = &v->s;
175
207434
    H264ChromaContext *h264chroma = &v->h264chroma;
176
    uint8_t *srcY, *srcU, *srcV;
177
    int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
178
207434
    int v_edge_pos = s->v_edge_pos >> v->field_mode;
179
    int i;
180
    uint8_t (*luty)[256], (*lutuv)[256];
181
    int use_ic;
182
    int interlace;
183
    int linesize, uvlinesize;
184
185
207434
    if ((!v->field_mode ||
186

62489
         (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
187
150856
        !v->s.last_picture.f->data[0])
188
        return;
189
190
207434
    linesize = s->current_picture_ptr->f->linesize[0];
191
207434
    uvlinesize = s->current_picture_ptr->f->linesize[1];
192
193
207434
    mx = s->mv[dir][0][0];
194
207434
    my = s->mv[dir][0][1];
195
196
    // store motion vectors for further use in B-frames
197
207434
    if (s->pict_type == AV_PICTURE_TYPE_P) {
198
647435
        for (i = 0; i < 4; i++) {
199
517948
            s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
200
517948
            s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
201
        }
202
    }
203
204
207434
    uvmx = (mx + ((mx & 3) == 3)) >> 1;
205
207434
    uvmy = (my + ((my & 3) == 3)) >> 1;
206
207434
    v->luma_mv[s->mb_x][0] = uvmx;
207
207434
    v->luma_mv[s->mb_x][1] = uvmy;
208
209
207434
    if (v->field_mode &&
210
62489
        v->cur_field_type != v->ref_field_type[dir]) {
211
35969
        my   = my   - 2 + 4 * v->cur_field_type;
212
35969
        uvmy = uvmy - 2 + 4 * v->cur_field_type;
213
    }
214
215
    // fastuvmc shall be ignored for interlaced frame picture
216

207434
    if (v->fastuvmc && (v->fcm != ILACE_FRAME)) {
217
37054
        uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
218
37054
        uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
219
    }
220
207434
    if (!dir) {
221

181003
        if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
222
24294
            srcY = s->current_picture.f->data[0];
223
24294
            srcU = s->current_picture.f->data[1];
224
24294
            srcV = s->current_picture.f->data[2];
225
24294
            luty  = v->curr_luty;
226
24294
            lutuv = v->curr_lutuv;
227
24294
            use_ic = *v->curr_use_ic;
228
24294
            interlace = 1;
229
        } else {
230
156709
            srcY = s->last_picture.f->data[0];
231
156709
            srcU = s->last_picture.f->data[1];
232
156709
            srcV = s->last_picture.f->data[2];
233
156709
            luty  = v->last_luty;
234
156709
            lutuv = v->last_lutuv;
235
156709
            use_ic = v->last_use_ic;
236
156709
            interlace = s->last_picture.f->interlaced_frame;
237
        }
238
    } else {
239
26431
        srcY = s->next_picture.f->data[0];
240
26431
        srcU = s->next_picture.f->data[1];
241
26431
        srcV = s->next_picture.f->data[2];
242
26431
        luty  = v->next_luty;
243
26431
        lutuv = v->next_lutuv;
244
26431
        use_ic = v->next_use_ic;
245
26431
        interlace = s->next_picture.f->interlaced_frame;
246
    }
247
248

207434
    if (!srcY || !srcU) {
249
        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
250
        return;
251
    }
252
253
207434
    src_x   = s->mb_x * 16 + (mx   >> 2);
254
207434
    src_y   = s->mb_y * 16 + (my   >> 2);
255
207434
    uvsrc_x = s->mb_x *  8 + (uvmx >> 2);
256
207434
    uvsrc_y = s->mb_y *  8 + (uvmy >> 2);
257
258
207434
    if (v->profile != PROFILE_ADVANCED) {
259
88617
        src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
260
88617
        src_y   = av_clip(  src_y, -16, s->mb_height * 16);
261
88617
        uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
262
88617
        uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
263
    } else {
264
118817
        src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
265
118817
        uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
266
118817
        if (v->fcm == ILACE_FRAME) {
267
23152
            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
268
23152
            uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
269
        } else {
270
95665
            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
271
95665
            uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
272
        }
273
    }
274
275
207434
    srcY += src_y   * s->linesize   + src_x;
276
207434
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
277
207434
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
278
279

207434
    if (v->field_mode && v->ref_field_type[dir]) {
280
15788
        srcY += linesize;
281
15788
        srcU += uvlinesize;
282
15788
        srcV += uvlinesize;
283
    }
284
285
    /* for grayscale we should not try to read from unknown area */
286
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) {
287
        srcU = s->sc.edge_emu_buffer + 18 * s->linesize;
288
        srcV = s->sc.edge_emu_buffer + 18 * s->linesize;
289
    }
290
291

207434
    if (v->rangeredfrm || use_ic
292

203621
        || s->h_edge_pos < 22 || v_edge_pos < 22
293
203621
        || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
294
197045
        || (unsigned)(src_y - 1)        > v_edge_pos    - (my&3) - 16 - 3) {
295
24543
        uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
296
24543
        uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
297
24543
        const int k = 17 + s->mspel * 2;
298
299
24543
        srcY -= s->mspel * (1 + s->linesize);
300
24543
        if (interlace) {
301
5385
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
302
                                     srcY,
303
6916
                                     linesize << 1,
304
6916
                                     linesize << 1,
305
                                     k,
306
1531
                                     v->field_mode ? k : k + 1 >> 1,
307
6916
                                     src_x - s->mspel,
308
6916
                                     src_y - s->mspel >> !v->field_mode,
309
                                     s->h_edge_pos,
310
6916
                                     s->v_edge_pos >> 1);
311
6916
            if (!v->field_mode)
312
1531
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize,
313
1531
                                         srcY + linesize,
314
1531
                                         linesize << 1,
315
1531
                                         linesize << 1,
316
                                         k,
317
                                         k >> 1,
318
1531
                                         src_x - s->mspel,
319
1531
                                         src_y - s->mspel + 1 >> 1,
320
                                         s->h_edge_pos,
321
1531
                                         s->v_edge_pos >> 1);
322
        } else
323
17627
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
324
                                     srcY,
325
                                     linesize,
326
                                     linesize,
327
                                     k,
328
                                     v->field_mode ? (k << 1) - 1 : k,
329
17627
                                     src_x - s->mspel,
330
17627
                                     v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] :
331
17627
                                                     src_y - s->mspel,
332
                                     s->h_edge_pos,
333
                                     s->v_edge_pos);
334
24543
        srcY = s->sc.edge_emu_buffer;
335
24543
        if (interlace) {
336
6916
            s->vdsp.emulated_edge_mc(ubuf,
337
                                     srcU,
338
6916
                                     uvlinesize << 1,
339
6916
                                     uvlinesize << 1,
340
                                     9,
341
6916
                                     v->field_mode ? 9 : 5,
342
                                     uvsrc_x,
343
6916
                                     uvsrc_y >> !v->field_mode,
344
6916
                                     s->h_edge_pos >> 1,
345
6916
                                     s->v_edge_pos >> 2);
346
6916
            s->vdsp.emulated_edge_mc(vbuf,
347
                                     srcV,
348
6916
                                     uvlinesize << 1,
349
6916
                                     uvlinesize << 1,
350
                                     9,
351
6916
                                     v->field_mode ? 9 : 5,
352
                                     uvsrc_x,
353
6916
                                     uvsrc_y >> !v->field_mode,
354
6916
                                     s->h_edge_pos >> 1,
355
6916
                                     s->v_edge_pos >> 2);
356
6916
            if (!v->field_mode) {
357
1531
                s->vdsp.emulated_edge_mc(ubuf + uvlinesize,
358
1531
                                         srcU + uvlinesize,
359
1531
                                         uvlinesize << 1,
360
1531
                                         uvlinesize << 1,
361
                                         9,
362
                                         4,
363
                                         uvsrc_x,
364
1531
                                         uvsrc_y + 1 >> 1,
365
1531
                                         s->h_edge_pos >> 1,
366
1531
                                         s->v_edge_pos >> 2);
367
1531
                s->vdsp.emulated_edge_mc(vbuf + uvlinesize,
368
1531
                                         srcV + uvlinesize,
369
1531
                                         uvlinesize << 1,
370
1531
                                         uvlinesize << 1,
371
                                         9,
372
                                         4,
373
                                         uvsrc_x,
374
1531
                                         uvsrc_y + 1 >> 1,
375
1531
                                         s->h_edge_pos >> 1,
376
1531
                                         s->v_edge_pos >> 2);
377
            }
378
        } else {
379
35254
            s->vdsp.emulated_edge_mc(ubuf,
380
                                     srcU,
381
                                     uvlinesize,
382
                                     uvlinesize,
383
                                     9,
384
17627
                                     v->field_mode ? 17 : 9,
385
                                     uvsrc_x,
386
                                     v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y,
387
17627
                                     s->h_edge_pos >> 1,
388
17627
                                     s->v_edge_pos >> 1);
389
35254
            s->vdsp.emulated_edge_mc(vbuf,
390
                                     srcV,
391
                                     uvlinesize,
392
                                     uvlinesize,
393
                                     9,
394
17627
                                     v->field_mode ? 17 : 9,
395
                                     uvsrc_x,
396
                                     v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y,
397
17627
                                     s->h_edge_pos >> 1,
398
17627
                                     s->v_edge_pos >> 1);
399
        }
400
24543
        srcU = ubuf;
401
24543
        srcV = vbuf;
402
        /* if we deal with range reduction we need to scale source blocks */
403
24543
        if (v->rangeredfrm) {
404
            vc1_scale_luma(srcY, k, s->linesize);
405
            vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
406
        }
407
        /* if we deal with intensity compensation we need to scale source blocks */
408
24543
        if (use_ic) {
409
7626
            vc1_lut_scale_luma(srcY,
410
3813
                               luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)],
411
3813
                               luty[v->field_mode ? v->ref_field_type[dir] : ((1 + src_y - s->mspel) & 1)],
412
3813
                               k, s->linesize);
413
7626
            vc1_lut_scale_chroma(srcU, srcV,
414
3813
                                 lutuv[v->field_mode ? v->ref_field_type[dir] : ((0 + uvsrc_y) & 1)],
415
3813
                                 lutuv[v->field_mode ? v->ref_field_type[dir] : ((1 + uvsrc_y) & 1)],
416
3813
                                 9, s->uvlinesize);
417
        }
418
24543
        srcY += s->mspel * (1 + s->linesize);
419
    }
420
421
207434
    if (s->mspel) {
422
124012
        dxy = ((my & 3) << 2) | (mx & 3);
423
124012
        v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
424
    } else { // hpel mc - always used for luma
425
83422
        dxy = (my & 2) | ((mx & 2) >> 1);
426
83422
        if (!v->rnd)
427
34949
            s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
428
        else
429
48473
            s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
430
    }
431
432
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
433
        return;
434
    /* Chroma MC always uses qpel bilinear */
435
207434
    uvmx = (uvmx & 3) << 1;
436
207434
    uvmy = (uvmy & 3) << 1;
437
207434
    if (!v->rnd) {
438
104840
        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
439
104840
        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
440
    } else {
441
102594
        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
442
102594
        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
443
    }
444
207434
    if (v->field_mode) {
445
62489
        v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir];
446
62489
        v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir];
447
    }
448
}
449
450
/** Do motion compensation for 4-MV macroblock - luminance block
451
 */
452
277224
void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
453
{
454
277224
    MpegEncContext *s = &v->s;
455
    uint8_t *srcY;
456
    int dxy, mx, my, src_x, src_y;
457
    int off;
458
277224
    int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
459
277224
    int v_edge_pos = s->v_edge_pos >> v->field_mode;
460
    uint8_t (*luty)[256];
461
    int use_ic;
462
    int interlace;
463
    int linesize;
464
465
277224
    if ((!v->field_mode ||
466

65032
         (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
467
224834
        !v->s.last_picture.f->data[0])
468
        return;
469
470
277224
    linesize = s->current_picture_ptr->f->linesize[0];
471
472
277224
    mx = s->mv[dir][n][0];
473
277224
    my = s->mv[dir][n][1];
474
475
277224
    if (!dir) {
476

220450
        if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
477
18181
            srcY = s->current_picture.f->data[0];
478
18181
            luty = v->curr_luty;
479
18181
            use_ic = *v->curr_use_ic;
480
18181
            interlace = 1;
481
        } else {
482
202269
            srcY = s->last_picture.f->data[0];
483
202269
            luty = v->last_luty;
484
202269
            use_ic = v->last_use_ic;
485
202269
            interlace = s->last_picture.f->interlaced_frame;
486
        }
487
    } else {
488
56774
        srcY = s->next_picture.f->data[0];
489
56774
        luty = v->next_luty;
490
56774
        use_ic = v->next_use_ic;
491
56774
        interlace = s->next_picture.f->interlaced_frame;
492
    }
493
494
277224
    if (!srcY) {
495
        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
496
        return;
497
    }
498
499
277224
    if (v->field_mode) {
500
65032
        if (v->cur_field_type != v->ref_field_type[dir])
501
32438
            my = my - 2 + 4 * v->cur_field_type;
502
    }
503
504

277224
    if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {
505
6850
        int opp_count = get_luma_mv(v, 0,
506
6850
                                    &s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
507
6850
                                    &s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1]);
508
6850
        int k, f = opp_count > 2;
509
34250
        for (k = 0; k < 4; k++)
510
27400
            v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
511
    }
512
513
277224
    if (v->fcm == ILACE_FRAME) {  // not sure if needed for other types of picture
514
        int qx, qy;
515
116452
        int width  = s->avctx->coded_width;
516
116452
        int height = s->avctx->coded_height >> 1;
517
116452
        if (s->pict_type == AV_PICTURE_TYPE_P) {
518
26340
            s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
519
26340
            s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
520
        }
521
116452
        qx = (s->mb_x * 16) + (mx >> 2);
522
116452
        qy = (s->mb_y *  8) + (my >> 3);
523
524
116452
        if (qx < -17)
525
244
            mx -= 4 * (qx + 17);
526
116208
        else if (qx > width)
527
704
            mx -= 4 * (qx - width);
528
116452
        if (qy < -18)
529
20
            my -= 8 * (qy + 18);
530
116432
        else if (qy > height + 1)
531
443
            my -= 8 * (qy - height - 1);
532
    }
533
534

277224
    if ((v->fcm == ILACE_FRAME) && fieldmv)
535
113636
        off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
536
    else
537
163588
        off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
538
539
277224
    src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
540
277224
    if (!fieldmv)
541
163588
        src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);
542
    else
543
113636
        src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);
544
545
277224
    if (v->profile != PROFILE_ADVANCED) {
546
19626
        src_x = av_clip(src_x, -16, s->mb_width  * 16);
547
19626
        src_y = av_clip(src_y, -16, s->mb_height * 16);
548
    } else {
549
257598
        src_x = av_clip(src_x, -17, s->avctx->coded_width);
550
257598
        if (v->fcm == ILACE_FRAME)
551
116452
            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
552
        else
553
141146
            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
554
    }
555
556
277224
    srcY += src_y * s->linesize + src_x;
557

277224
    if (v->field_mode && v->ref_field_type[dir])
558
24818
        srcY += linesize;
559
560

277224
    if (v->rangeredfrm || use_ic
561

277224
        || s->h_edge_pos < 13 || v_edge_pos < 23
562
277224
        || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
563
270763
        || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
564
16794
        const int k = 9 + s->mspel * 2;
565
566
16794
        srcY -= s->mspel * (1 + (s->linesize << fieldmv));
567
        /* check emulate edge stride and offset */
568
16794
        if (interlace) {
569
5672
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
570
                                     srcY,
571
11594
                                     linesize << 1,
572
11594
                                     linesize << 1,
573
                                     k,
574
5922
                                     v->field_mode ? k : (k << fieldmv) + 1 >> 1,
575
11594
                                     src_x - s->mspel,
576
11594
                                     src_y - (s->mspel << fieldmv) >> !v->field_mode,
577
                                     s->h_edge_pos,
578
11594
                                     s->v_edge_pos >> 1);
579

11594
            if (!v->field_mode && !fieldmv)
580
114
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize,
581
114
                                         srcY + linesize,
582
114
                                         linesize << 1,
583
114
                                         linesize << 1,
584
                                         k,
585
                                         k >> 1,
586
114
                                         src_x - s->mspel,
587
114
                                         src_y - s->mspel + 1 >> 1,
588
                                         s->h_edge_pos,
589
114
                                         s->v_edge_pos >> 1);
590
        } else
591
5200
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
592
                                     srcY,
593
                                     linesize,
594
                                     linesize,
595
                                     k,
596
                                     v->field_mode ? (k << 1) - 1 : k << fieldmv,
597
5200
                                     src_x - s->mspel,
598
5200
                                     v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] :
599
5200
                                                     src_y - (s->mspel << fieldmv),
600
                                     s->h_edge_pos,
601
                                     s->v_edge_pos);
602
16794
        srcY = s->sc.edge_emu_buffer;
603
        /* if we deal with range reduction we need to scale source blocks */
604
16794
        if (v->rangeredfrm) {
605
            vc1_scale_luma(srcY, k, s->linesize << fieldmv);
606
        }
607
        /* if we deal with intensity compensation we need to scale source blocks */
608
16794
        if (use_ic) {
609
            vc1_lut_scale_luma(srcY,
610
                               luty[v->field_mode ? v->ref_field_type[dir] : (((0<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
611
                               luty[v->field_mode ? v->ref_field_type[dir] : (((1<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)],
612
                               k, s->linesize << fieldmv);
613
        }
614
16794
        srcY += s->mspel * (1 + (s->linesize << fieldmv));
615
    }
616
617
277224
    if (s->mspel) {
618
277224
        dxy = ((my & 3) << 2) | (mx & 3);
619
277224
        if (avg)
620
20328
            v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
621
        else
622
256896
            v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
623
    } else { // hpel mc - always used for luma
624
        dxy = (my & 2) | ((mx & 2) >> 1);
625
        if (!v->rnd)
626
            s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
627
        else
628
            s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
629
    }
630
}
631
632
/** Do motion compensation for 4-MV macroblock - both chroma blocks
633
 */
634
42834
void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir)
635
{
636
42834
    MpegEncContext *s = &v->s;
637
42834
    H264ChromaContext *h264chroma = &v->h264chroma;
638
    uint8_t *srcU, *srcV;
639
    int uvmx, uvmy, uvsrc_x, uvsrc_y;
640
    int16_t tx, ty;
641
    int chroma_ref_type;
642
42834
    int v_edge_pos = s->v_edge_pos >> v->field_mode;
643
    uint8_t (*lutuv)[256];
644
    int use_ic;
645
    int interlace;
646
    int uvlinesize;
647
648

42834
    if (!v->field_mode && !v->s.last_picture.f->data[0])
649
1218
        return;
650
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
651
        return;
652
653
    /* calculate chroma MV vector from four luma MVs */
654

42834
    if (!v->field_mode || !v->numref) {
655
26576
        int valid_count = get_chroma_mv(v, dir, &tx, &ty);
656
26576
        if (!valid_count) {
657
1218
            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
658
1218
            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
659
1218
            v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
660
1218
            return; //no need to do MC for intra blocks
661
        }
662
25358
        chroma_ref_type = v->ref_field_type[dir];
663
    } else {
664
16258
        int opp_count = get_luma_mv(v, dir, &tx, &ty);
665
16258
        chroma_ref_type = v->cur_field_type ^ (opp_count > 2);
666
    }
667


41616
    if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f->data[0])
668
        return;
669
41616
    s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
670
41616
    s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
671
672
41616
    uvlinesize = s->current_picture_ptr->f->linesize[1];
673
674
41616
    uvmx = (tx + ((tx & 3) == 3)) >> 1;
675
41616
    uvmy = (ty + ((ty & 3) == 3)) >> 1;
676
677
41616
    v->luma_mv[s->mb_x][0] = uvmx;
678
41616
    v->luma_mv[s->mb_x][1] = uvmy;
679
680
41616
    if (v->fastuvmc) {
681
        uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
682
        uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
683
    }
684
    // Field conversion bias
685
41616
    if (v->cur_field_type != chroma_ref_type)
686
7493
        uvmy += 2 - 4 * chroma_ref_type;
687
688
41616
    uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
689
41616
    uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
690
691
41616
    if (v->profile != PROFILE_ADVANCED) {
692
5416
        uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width  * 8);
693
5416
        uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
694
    } else {
695
36200
        uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
696
36200
        uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
697
    }
698
699
41616
    if (!dir) {
700

37100
        if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
701
4366
            srcU = s->current_picture.f->data[1];
702
4366
            srcV = s->current_picture.f->data[2];
703
4366
            lutuv = v->curr_lutuv;
704
4366
            use_ic = *v->curr_use_ic;
705
4366
            interlace = 1;
706
        } else {
707
32734
            srcU = s->last_picture.f->data[1];
708
32734
            srcV = s->last_picture.f->data[2];
709
32734
            lutuv = v->last_lutuv;
710
32734
            use_ic = v->last_use_ic;
711
32734
            interlace = s->last_picture.f->interlaced_frame;
712
        }
713
    } else {
714
4516
        srcU = s->next_picture.f->data[1];
715
4516
        srcV = s->next_picture.f->data[2];
716
4516
        lutuv = v->next_lutuv;
717
4516
        use_ic = v->next_use_ic;
718
4516
        interlace = s->next_picture.f->interlaced_frame;
719
    }
720
721
41616
    if (!srcU) {
722
        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
723
        return;
724
    }
725
726
41616
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
727
41616
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
728
729
41616
    if (v->field_mode) {
730
16258
        if (chroma_ref_type) {
731
6083
            srcU += uvlinesize;
732
6083
            srcV += uvlinesize;
733
        }
734
    }
735
736

41616
    if (v->rangeredfrm || use_ic
737

41616
        || s->h_edge_pos < 18 || v_edge_pos < 18
738
41616
        || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
739
40502
        || (unsigned)uvsrc_y > (v_edge_pos    >> 1) - 9) {
740
3153
        if (interlace) {
741
1626
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
742
                                     srcU,
743
1626
                                     uvlinesize << 1,
744
1626
                                     uvlinesize << 1,
745
                                     9,
746
1626
                                     v->field_mode ? 9 : 5,
747
                                     uvsrc_x,
748
1626
                                     uvsrc_y >> !v->field_mode,
749
1626
                                     s->h_edge_pos >> 1,
750
1626
                                     s->v_edge_pos >> 2);
751
1626
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16,
752
                                     srcV,
753
1626
                                     uvlinesize << 1,
754
1626
                                     uvlinesize << 1,
755
                                     9,
756
1626
                                     v->field_mode ? 9 : 5,
757
                                     uvsrc_x,
758
1626
                                     uvsrc_y >> !v->field_mode,
759
1626
                                     s->h_edge_pos >> 1,
760
1626
                                     s->v_edge_pos >> 2);
761
1626
            if (!v->field_mode) {
762
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize,
763
                                         srcU + uvlinesize,
764
                                         uvlinesize << 1,
765
                                         uvlinesize << 1,
766
                                         9,
767
                                         4,
768
                                         uvsrc_x,
769
                                         uvsrc_y + 1 >> 1,
770
                                         s->h_edge_pos >> 1,
771
                                         s->v_edge_pos >> 2);
772
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize,
773
                                         srcV + uvlinesize,
774
                                         uvlinesize << 1,
775
                                         uvlinesize << 1,
776
                                         9,
777
                                         4,
778
                                         uvsrc_x,
779
                                         uvsrc_y + 1 >> 1,
780
                                         s->h_edge_pos >> 1,
781
                                         s->v_edge_pos >> 2);
782
            }
783
        } else {
784
3054
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
785
                                     srcU,
786
                                     uvlinesize,
787
                                     uvlinesize,
788
                                     9,
789
1527
                                     v->field_mode ? 17 : 9,
790
                                     uvsrc_x,
791
                                     v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y,
792
1527
                                     s->h_edge_pos >> 1,
793
1527
                                     s->v_edge_pos >> 1);
794
3054
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16,
795
                                     srcV,
796
                                     uvlinesize,
797
                                     uvlinesize,
798
                                     9,
799
1527
                                     v->field_mode ? 17 : 9,
800
                                     uvsrc_x,
801
                                     v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y,
802
1527
                                     s->h_edge_pos >> 1,
803
1527
                                     s->v_edge_pos >> 1);
804
        }
805
3153
        srcU = s->sc.edge_emu_buffer;
806
3153
        srcV = s->sc.edge_emu_buffer + 16;
807
808
        /* if we deal with range reduction we need to scale source blocks */
809
3153
        if (v->rangeredfrm) {
810
            vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
811
        }
812
        /* if we deal with intensity compensation we need to scale source blocks */
813
3153
        if (use_ic) {
814
            vc1_lut_scale_chroma(srcU, srcV,
815
                                 lutuv[v->field_mode ? chroma_ref_type : ((0 + uvsrc_y) & 1)],
816
                                 lutuv[v->field_mode ? chroma_ref_type : ((1 + uvsrc_y) & 1)],
817
                                 9, s->uvlinesize);
818
        }
819
    }
820
821
    /* Chroma MC always uses qpel bilinear */
822
41616
    uvmx = (uvmx & 3) << 1;
823
41616
    uvmy = (uvmy & 3) << 1;
824
41616
    if (!v->rnd) {
825
22216
        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
826
22216
        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
827
    } else {
828
19400
        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
829
19400
        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
830
    }
831
41616
    if (v->field_mode) {
832
16258
        v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != chroma_ref_type;
833
16258
        v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != chroma_ref_type;
834
    }
835
}
836
837
/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
838
 */
839
29113
void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
840
{
841
29113
    MpegEncContext *s = &v->s;
842
29113
    H264ChromaContext *h264chroma = &v->h264chroma;
843
    uint8_t *srcU, *srcV;
844
    int uvsrc_x, uvsrc_y;
845
    int uvmx_field[4], uvmy_field[4];
846
    int i, off, tx, ty;
847
29113
    int fieldmv = v->blk_mv_type[s->block_index[0]];
848
    static const uint8_t s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
849
29113
    int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
850
29113
    int v_edge_pos = s->v_edge_pos >> 1;
851
    int use_ic;
852
    int interlace;
853
    int uvlinesize;
854
    uint8_t (*lutuv)[256];
855
856
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
857
        return;
858
859
29113
    uvlinesize = s->current_picture_ptr->f->linesize[1];
860
861
145565
    for (i = 0; i < 4; i++) {
862
116452
        int d = i < 2 ? dir: dir2;
863
116452
        tx = s->mv[d][i][0];
864
116452
        uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
865
116452
        ty = s->mv[d][i][1];
866
116452
        if (fieldmv)
867
113636
            uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
868
        else
869
2816
            uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1;
870
    }
871
872
145565
    for (i = 0; i < 4; i++) {
873
116452
        off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0);
874
116452
        uvsrc_x = s->mb_x * 8 +  (i & 1) * 4           + (uvmx_field[i] >> 2);
875
116452
        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
116452
        uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
878
116452
        if (v->fcm == ILACE_FRAME)
879
116452
            uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
880
        else
881
            uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
882

116452
        if (i < 2 ? dir : dir2) {
883
38710
            srcU = s->next_picture.f->data[1];
884
38710
            srcV = s->next_picture.f->data[2];
885
38710
            lutuv  = v->next_lutuv;
886
38710
            use_ic = v->next_use_ic;
887
38710
            interlace = s->next_picture.f->interlaced_frame;
888
        } else {
889
77742
            srcU = s->last_picture.f->data[1];
890
77742
            srcV = s->last_picture.f->data[2];
891
77742
            lutuv  = v->last_lutuv;
892
77742
            use_ic = v->last_use_ic;
893
77742
            interlace = s->last_picture.f->interlaced_frame;
894
        }
895
116452
        if (!srcU)
896
            return;
897
116452
        srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
898
116452
        srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
899
116452
        uvmx_field[i] = (uvmx_field[i] & 3) << 1;
900
116452
        uvmy_field[i] = (uvmy_field[i] & 3) << 1;
901
902
116452
        if (use_ic
903

116452
            || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
904
116452
            || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
905
113912
            || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
906
5427
            if (interlace) {
907
5427
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
908
                                         srcU,
909
5427
                                         uvlinesize << 1,
910
5427
                                         uvlinesize << 1,
911
                                         5,
912
5427
                                         (5 << fieldmv) + 1 >> 1,
913
                                         uvsrc_x,
914
                                         uvsrc_y >> 1,
915
5427
                                         s->h_edge_pos >> 1,
916
5427
                                         s->v_edge_pos >> 2);
917
5427
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16,
918
                                         srcV,
919
5427
                                         uvlinesize << 1,
920
5427
                                         uvlinesize << 1,
921
                                         5,
922
5427
                                         (5 << fieldmv) + 1 >> 1,
923
                                         uvsrc_x,
924
                                         uvsrc_y >> 1,
925
5427
                                         s->h_edge_pos >> 1,
926
5427
                                         s->v_edge_pos >> 2);
927
5427
                if (!fieldmv) {
928
108
                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize,
929
108
                                             srcU + uvlinesize,
930
108
                                             uvlinesize << 1,
931
108
                                             uvlinesize << 1,
932
                                             5,
933
                                             2,
934
                                             uvsrc_x,
935
108
                                             uvsrc_y + 1 >> 1,
936
108
                                             s->h_edge_pos >> 1,
937
108
                                             s->v_edge_pos >> 2);
938
108
                    s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize,
939
108
                                             srcV + uvlinesize,
940
108
                                             uvlinesize << 1,
941
108
                                             uvlinesize << 1,
942
                                             5,
943
                                             2,
944
                                             uvsrc_x,
945
108
                                             uvsrc_y + 1 >> 1,
946
108
                                             s->h_edge_pos >> 1,
947
108
                                             s->v_edge_pos >> 2);
948
                }
949
            } else {
950
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
951
                                         srcU,
952
                                         uvlinesize,
953
                                         uvlinesize,
954
                                         5,
955
                                         5 << fieldmv,
956
                                         uvsrc_x,
957
                                         uvsrc_y,
958
                                         s->h_edge_pos >> 1,
959
                                         s->v_edge_pos >> 1);
960
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16,
961
                                         srcV,
962
                                         uvlinesize,
963
                                         uvlinesize,
964
                                         5,
965
                                         5 << fieldmv,
966
                                         uvsrc_x,
967
                                         uvsrc_y,
968
                                         s->h_edge_pos >> 1,
969
                                         s->v_edge_pos >> 1);
970
            }
971
5427
            srcU = s->sc.edge_emu_buffer;
972
5427
            srcV = s->sc.edge_emu_buffer + 16;
973
974
            /* if we deal with intensity compensation we need to scale source blocks */
975
5427
            if (use_ic) {
976
                vc1_lut_scale_chroma(srcU, srcV,
977
                                     lutuv[(uvsrc_y + (0 << fieldmv)) & 1],
978
                                     lutuv[(uvsrc_y + (1 << fieldmv)) & 1],
979
                                     5, s->uvlinesize << fieldmv);
980
            }
981
        }
982
116452
        if (avg) {
983
20328
            if (!v->rnd) {
984
10832
                h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
985
10832
                h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
986
            } else {
987
9496
                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
9496
                v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
989
            }
990
        } else {
991
96124
            if (!v->rnd) {
992
53028
                h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
993
53028
                h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
994
            } else {
995
43096
                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
43096
                v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
997
            }
998
        }
999
    }
1000
}
1001
1002
/** Motion compensation for direct or interpolated blocks in B-frames
1003
 */
1004
28266
void ff_vc1_interp_mc(VC1Context *v)
1005
{
1006
28266
    MpegEncContext *s = &v->s;
1007
28266
    H264ChromaContext *h264chroma = &v->h264chroma;
1008
    uint8_t *srcY, *srcU, *srcV;
1009
    int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
1010
28266
    int v_edge_pos = s->v_edge_pos >> v->field_mode;
1011
28266
    int use_ic = v->next_use_ic;
1012
    int interlace;
1013
    int linesize, uvlinesize;
1014
1015

28266
    if (!v->field_mode && !v->s.next_picture.f->data[0])
1016
        return;
1017
1018
28266
    linesize = s->current_picture_ptr->f->linesize[0];
1019
28266
    uvlinesize = s->current_picture_ptr->f->linesize[1];
1020
1021
28266
    mx   = s->mv[1][0][0];
1022
28266
    my   = s->mv[1][0][1];
1023
28266
    uvmx = (mx + ((mx & 3) == 3)) >> 1;
1024
28266
    uvmy = (my + ((my & 3) == 3)) >> 1;
1025

28266
    if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) {
1026
5223
        my   = my   - 2 + 4 * v->cur_field_type;
1027
5223
        uvmy = uvmy - 2 + 4 * v->cur_field_type;
1028
    }
1029
28266
    if (v->fastuvmc) {
1030
        uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1));
1031
        uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1));
1032
    }
1033
28266
    srcY = s->next_picture.f->data[0];
1034
28266
    srcU = s->next_picture.f->data[1];
1035
28266
    srcV = s->next_picture.f->data[2];
1036
1037
28266
    interlace = s->next_picture.f->interlaced_frame;
1038
1039
28266
    src_x   = s->mb_x * 16 + (mx   >> 2);
1040
28266
    src_y   = s->mb_y * 16 + (my   >> 2);
1041
28266
    uvsrc_x = s->mb_x *  8 + (uvmx >> 2);
1042
28266
    uvsrc_y = s->mb_y *  8 + (uvmy >> 2);
1043
1044
28266
    if (v->profile != PROFILE_ADVANCED) {
1045
5166
        src_x   = av_clip(  src_x, -16, s->mb_width  * 16);
1046
5166
        src_y   = av_clip(  src_y, -16, s->mb_height * 16);
1047
5166
        uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);
1048
5166
        uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);
1049
    } else {
1050
23100
        src_x   = av_clip(  src_x, -17, s->avctx->coded_width);
1051
23100
        uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);
1052
23100
        if (v->fcm == ILACE_FRAME) {
1053
6884
            src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1));
1054
6884
            uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1));
1055
        } else {
1056
16216
            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);
1057
16216
            uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);
1058
        }
1059
    }
1060
1061
28266
    srcY += src_y   * s->linesize   + src_x;
1062
28266
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
1063
28266
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
1064
1065

28266
    if (v->field_mode && v->ref_field_type[1]) {
1066
4716
        srcY += linesize;
1067
4716
        srcU += uvlinesize;
1068
4716
        srcV += uvlinesize;
1069
    }
1070
1071
    /* for grayscale we should not try to read from unknown area */
1072
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) {
1073
        srcU = s->sc.edge_emu_buffer + 18 * s->linesize;
1074
        srcV = s->sc.edge_emu_buffer + 18 * s->linesize;
1075
    }
1076
1077


28266
    if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
1078
28266
        || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
1079
27224
        || (unsigned)(src_y - 1) > v_edge_pos    - (my & 3) - 16 - 3) {
1080
3476
        uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize;
1081
3476
        uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
1082
3476
        const int k = 17 + s->mspel * 2;
1083
1084
3476
        srcY -= s->mspel * (1 + s->linesize);
1085
3476
        if (interlace) {
1086
1601
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
1087
                                     srcY,
1088
2034
                                     linesize << 1,
1089
2034
                                     linesize << 1,
1090
                                     k,
1091
433
                                     v->field_mode ? k : (k + 1 >> 1),
1092
2034
                                     src_x - s->mspel,
1093
2034
                                     src_y - s->mspel >> !v->field_mode,
1094
                                     s->h_edge_pos,
1095
2034
                                     s->v_edge_pos >> 1);
1096
2034
            if (!v->field_mode)
1097
433
                s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize,
1098
433
                                         srcY + linesize,
1099
433
                                         linesize << 1,
1100
433
                                         linesize << 1,
1101
                                         k,
1102
                                         k >> 1,
1103
433
                                         src_x - s->mspel,
1104
433
                                         src_y - s->mspel + 1 >> 1,
1105
                                         s->h_edge_pos,
1106
433
                                         s->v_edge_pos >> 1);
1107
        } else
1108
1442
            s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer,
1109
                                     srcY,
1110
                                     linesize,
1111
                                     linesize,
1112
                                     k,
1113
                                     v->field_mode ? (k << 1) - 1 : k,
1114
1442
                                     src_x - s->mspel,
1115
1442
                                     v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[1] :
1116
1442
                                                     src_y - s->mspel,
1117
                                     s->h_edge_pos,
1118
                                     s->v_edge_pos);
1119
3476
        srcY = s->sc.edge_emu_buffer;
1120
3476
        if (interlace) {
1121
2034
            s->vdsp.emulated_edge_mc(ubuf,
1122
                                     srcU,
1123
2034
                                     uvlinesize << 1,
1124
2034
                                     uvlinesize << 1,
1125
                                     9,
1126
2034
                                     v->field_mode ? 9 : 5,
1127
                                     uvsrc_x,
1128
2034
                                     uvsrc_y >> !v->field_mode,
1129
2034
                                     s->h_edge_pos >> 1,
1130
2034
                                     s->v_edge_pos >> 2);
1131
2034
            s->vdsp.emulated_edge_mc(vbuf,
1132
                                     srcV,
1133
2034
                                     uvlinesize << 1,
1134
2034
                                     uvlinesize << 1,
1135
                                     9,
1136
2034
                                     v->field_mode ? 9 : 5,
1137
                                     uvsrc_x,
1138
2034
                                     uvsrc_y >> !v->field_mode,
1139
2034
                                     s->h_edge_pos >> 1,
1140
2034
                                     s->v_edge_pos >> 2);
1141
2034
            if (!v->field_mode) {
1142
433
                s->vdsp.emulated_edge_mc(ubuf + uvlinesize,
1143
433
                                         srcU + uvlinesize,
1144
433
                                         uvlinesize << 1,
1145
433
                                         uvlinesize << 1,
1146
                                         9,
1147
                                         4,
1148
                                         uvsrc_x,
1149
433
                                         uvsrc_y + 1 >> 1,
1150
433
                                         s->h_edge_pos >> 1,
1151
433
                                         s->v_edge_pos >> 2);
1152
433
                s->vdsp.emulated_edge_mc(vbuf + uvlinesize,
1153
433
                                         srcV + uvlinesize,
1154
433
                                         uvlinesize << 1,
1155
433
                                         uvlinesize << 1,
1156
                                         9,
1157
                                         4,
1158
                                         uvsrc_x,
1159
433
                                         uvsrc_y + 1 >> 1,
1160
433
                                         s->h_edge_pos >> 1,
1161
433
                                         s->v_edge_pos >> 2);
1162
            }
1163
        } else {
1164
2884
            s->vdsp.emulated_edge_mc(ubuf,
1165
                                     srcU,
1166
                                     uvlinesize,
1167
                                     uvlinesize,
1168
                                     9,
1169
1442
                                     v->field_mode ? 17 : 9,
1170
                                     uvsrc_x,
1171
                                     v->field_mode ? 2 * uvsrc_y + v->ref_field_type[1] : uvsrc_y,
1172
1442
                                     s->h_edge_pos >> 1,
1173
1442
                                     s->v_edge_pos >> 1);
1174
2884
            s->vdsp.emulated_edge_mc(vbuf,
1175
                                     srcV,
1176
                                     uvlinesize,
1177
                                     uvlinesize,
1178
                                     9,
1179
1442
                                     v->field_mode ? 17 : 9,
1180
                                     uvsrc_x,
1181
                                     v->field_mode ? 2 * uvsrc_y + v->ref_field_type[1] : uvsrc_y,
1182
1442
                                     s->h_edge_pos >> 1,
1183
1442
                                     s->v_edge_pos >> 1);
1184
        }
1185
3476
        srcU = ubuf;
1186
3476
        srcV = vbuf;
1187
        /* if we deal with range reduction we need to scale source blocks */
1188
3476
        if (v->rangeredfrm) {
1189
            vc1_scale_luma(srcY, k, s->linesize);
1190
            vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize);
1191
        }
1192
1193
3476
        if (use_ic) {
1194
            uint8_t (*luty )[256] = v->next_luty;
1195
            uint8_t (*lutuv)[256] = v->next_lutuv;
1196
            vc1_lut_scale_luma(srcY,
1197
                               luty[v->field_mode ? v->ref_field_type[1] : ((0+src_y - s->mspel) & 1)],
1198
                               luty[v->field_mode ? v->ref_field_type[1] : ((1+src_y - s->mspel) & 1)],
1199
                               k, s->linesize);
1200
            vc1_lut_scale_chroma(srcU, srcV,
1201
                                 lutuv[v->field_mode ? v->ref_field_type[1] : ((0+uvsrc_y) & 1)],
1202
                                 lutuv[v->field_mode ? v->ref_field_type[1] : ((1+uvsrc_y) & 1)],
1203
                                 9, s->uvlinesize);
1204
        }
1205
3476
        srcY += s->mspel * (1 + s->linesize);
1206
    }
1207
1208
28266
    if (s->mspel) {
1209
21617
        dxy = ((my & 3) << 2) | (mx & 3);
1210
21617
        v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd);
1211
    } else { // hpel mc
1212
6649
        dxy = (my & 2) | ((mx & 2) >> 1);
1213
1214
6649
        if (!v->rnd)
1215
3673
            s->hdsp.avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
1216
        else
1217
2976
            s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0], srcY, s->linesize, 16);
1218
    }
1219
1220
    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
1221
        return;
1222
    /* Chroma MC always uses qpel bilinear */
1223
28266
    uvmx = (uvmx & 3) << 1;
1224
28266
    uvmy = (uvmy & 3) << 1;
1225
28266
    if (!v->rnd) {
1226
17299
        h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
1227
17299
        h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
1228
    } else {
1229
10967
        v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
1230
10967
        v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
1231
    }
1232
}