1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * VC-1 and WMV3 decoder
3cabdff1aSopenharmony_ci * Copyright (c) 2011 Mashiat Sarker Shakkhar
4cabdff1aSopenharmony_ci * Copyright (c) 2006-2007 Konstantin Shishkov
5cabdff1aSopenharmony_ci * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * This file is part of FFmpeg.
8cabdff1aSopenharmony_ci *
9cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
10cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
11cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
12cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
13cabdff1aSopenharmony_ci *
14cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
15cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
16cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17cabdff1aSopenharmony_ci * Lesser General Public License for more details.
18cabdff1aSopenharmony_ci *
19cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
20cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
21cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22cabdff1aSopenharmony_ci */
23cabdff1aSopenharmony_ci
24cabdff1aSopenharmony_ci/**
25cabdff1aSopenharmony_ci * @file
26cabdff1aSopenharmony_ci * VC-1 and WMV3 block decoding routines
27cabdff1aSopenharmony_ci */
28cabdff1aSopenharmony_ci
29cabdff1aSopenharmony_ci#include "mathops.h"
30cabdff1aSopenharmony_ci#include "mpegutils.h"
31cabdff1aSopenharmony_ci#include "mpegvideo.h"
32cabdff1aSopenharmony_ci#include "vc1.h"
33cabdff1aSopenharmony_ci#include "vc1_pred.h"
34cabdff1aSopenharmony_ci#include "vc1data.h"
35cabdff1aSopenharmony_ci
36cabdff1aSopenharmony_cistatic av_always_inline int scaleforsame_x(VC1Context *v, int n /* MV */, int dir)
37cabdff1aSopenharmony_ci{
38cabdff1aSopenharmony_ci    int scaledvalue, refdist;
39cabdff1aSopenharmony_ci    int scalesame1, scalesame2;
40cabdff1aSopenharmony_ci    int scalezone1_x, zone1offset_x;
41cabdff1aSopenharmony_ci    int table_index = dir ^ v->second_field;
42cabdff1aSopenharmony_ci
43cabdff1aSopenharmony_ci    if (v->s.pict_type != AV_PICTURE_TYPE_B)
44cabdff1aSopenharmony_ci        refdist = v->refdist;
45cabdff1aSopenharmony_ci    else
46cabdff1aSopenharmony_ci        refdist = dir ? v->brfd : v->frfd;
47cabdff1aSopenharmony_ci    if (refdist > 3)
48cabdff1aSopenharmony_ci        refdist = 3;
49cabdff1aSopenharmony_ci    scalesame1    = ff_vc1_field_mvpred_scales[table_index][1][refdist];
50cabdff1aSopenharmony_ci    scalesame2    = ff_vc1_field_mvpred_scales[table_index][2][refdist];
51cabdff1aSopenharmony_ci    scalezone1_x  = ff_vc1_field_mvpred_scales[table_index][3][refdist];
52cabdff1aSopenharmony_ci    zone1offset_x = ff_vc1_field_mvpred_scales[table_index][5][refdist];
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_ci    if (FFABS(n) > 255)
55cabdff1aSopenharmony_ci        scaledvalue = n;
56cabdff1aSopenharmony_ci    else {
57cabdff1aSopenharmony_ci        if (FFABS(n) < scalezone1_x)
58cabdff1aSopenharmony_ci            scaledvalue = (n * scalesame1) >> 8;
59cabdff1aSopenharmony_ci        else {
60cabdff1aSopenharmony_ci            if (n < 0)
61cabdff1aSopenharmony_ci                scaledvalue = ((n * scalesame2) >> 8) - zone1offset_x;
62cabdff1aSopenharmony_ci            else
63cabdff1aSopenharmony_ci                scaledvalue = ((n * scalesame2) >> 8) + zone1offset_x;
64cabdff1aSopenharmony_ci        }
65cabdff1aSopenharmony_ci    }
66cabdff1aSopenharmony_ci    return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
67cabdff1aSopenharmony_ci}
68cabdff1aSopenharmony_ci
69cabdff1aSopenharmony_cistatic av_always_inline int scaleforsame_y(VC1Context *v, int i, int n /* MV */, int dir)
70cabdff1aSopenharmony_ci{
71cabdff1aSopenharmony_ci    int scaledvalue, refdist;
72cabdff1aSopenharmony_ci    int scalesame1, scalesame2;
73cabdff1aSopenharmony_ci    int scalezone1_y, zone1offset_y;
74cabdff1aSopenharmony_ci    int table_index = dir ^ v->second_field;
75cabdff1aSopenharmony_ci
76cabdff1aSopenharmony_ci    if (v->s.pict_type != AV_PICTURE_TYPE_B)
77cabdff1aSopenharmony_ci        refdist = v->refdist;
78cabdff1aSopenharmony_ci    else
79cabdff1aSopenharmony_ci        refdist = dir ? v->brfd : v->frfd;
80cabdff1aSopenharmony_ci    if (refdist > 3)
81cabdff1aSopenharmony_ci        refdist = 3;
82cabdff1aSopenharmony_ci    scalesame1    = ff_vc1_field_mvpred_scales[table_index][1][refdist];
83cabdff1aSopenharmony_ci    scalesame2    = ff_vc1_field_mvpred_scales[table_index][2][refdist];
84cabdff1aSopenharmony_ci    scalezone1_y  = ff_vc1_field_mvpred_scales[table_index][4][refdist];
85cabdff1aSopenharmony_ci    zone1offset_y = ff_vc1_field_mvpred_scales[table_index][6][refdist];
86cabdff1aSopenharmony_ci
87cabdff1aSopenharmony_ci    if (FFABS(n) > 63)
88cabdff1aSopenharmony_ci        scaledvalue = n;
89cabdff1aSopenharmony_ci    else {
90cabdff1aSopenharmony_ci        if (FFABS(n) < scalezone1_y)
91cabdff1aSopenharmony_ci            scaledvalue = (n * scalesame1) >> 8;
92cabdff1aSopenharmony_ci        else {
93cabdff1aSopenharmony_ci            if (n < 0)
94cabdff1aSopenharmony_ci                scaledvalue = ((n * scalesame2) >> 8) - zone1offset_y;
95cabdff1aSopenharmony_ci            else
96cabdff1aSopenharmony_ci                scaledvalue = ((n * scalesame2) >> 8) + zone1offset_y;
97cabdff1aSopenharmony_ci        }
98cabdff1aSopenharmony_ci    }
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_ci    if (v->cur_field_type && !v->ref_field_type[dir])
101cabdff1aSopenharmony_ci        return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
102cabdff1aSopenharmony_ci    else
103cabdff1aSopenharmony_ci        return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
104cabdff1aSopenharmony_ci}
105cabdff1aSopenharmony_ci
106cabdff1aSopenharmony_cistatic av_always_inline int scaleforopp_x(VC1Context *v, int n /* MV */)
107cabdff1aSopenharmony_ci{
108cabdff1aSopenharmony_ci    int scalezone1_x, zone1offset_x;
109cabdff1aSopenharmony_ci    int scaleopp1, scaleopp2, brfd;
110cabdff1aSopenharmony_ci    int scaledvalue;
111cabdff1aSopenharmony_ci
112cabdff1aSopenharmony_ci    brfd = FFMIN(v->brfd, 3);
113cabdff1aSopenharmony_ci    scalezone1_x  = ff_vc1_b_field_mvpred_scales[3][brfd];
114cabdff1aSopenharmony_ci    zone1offset_x = ff_vc1_b_field_mvpred_scales[5][brfd];
115cabdff1aSopenharmony_ci    scaleopp1     = ff_vc1_b_field_mvpred_scales[1][brfd];
116cabdff1aSopenharmony_ci    scaleopp2     = ff_vc1_b_field_mvpred_scales[2][brfd];
117cabdff1aSopenharmony_ci
118cabdff1aSopenharmony_ci    if (FFABS(n) > 255)
119cabdff1aSopenharmony_ci        scaledvalue = n;
120cabdff1aSopenharmony_ci    else {
121cabdff1aSopenharmony_ci        if (FFABS(n) < scalezone1_x)
122cabdff1aSopenharmony_ci            scaledvalue = (n * scaleopp1) >> 8;
123cabdff1aSopenharmony_ci        else {
124cabdff1aSopenharmony_ci            if (n < 0)
125cabdff1aSopenharmony_ci                scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_x;
126cabdff1aSopenharmony_ci            else
127cabdff1aSopenharmony_ci                scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_x;
128cabdff1aSopenharmony_ci        }
129cabdff1aSopenharmony_ci    }
130cabdff1aSopenharmony_ci    return av_clip(scaledvalue, -v->range_x, v->range_x - 1);
131cabdff1aSopenharmony_ci}
132cabdff1aSopenharmony_ci
133cabdff1aSopenharmony_cistatic av_always_inline int scaleforopp_y(VC1Context *v, int n /* MV */, int dir)
134cabdff1aSopenharmony_ci{
135cabdff1aSopenharmony_ci    int scalezone1_y, zone1offset_y;
136cabdff1aSopenharmony_ci    int scaleopp1, scaleopp2, brfd;
137cabdff1aSopenharmony_ci    int scaledvalue;
138cabdff1aSopenharmony_ci
139cabdff1aSopenharmony_ci    brfd = FFMIN(v->brfd, 3);
140cabdff1aSopenharmony_ci    scalezone1_y  = ff_vc1_b_field_mvpred_scales[4][brfd];
141cabdff1aSopenharmony_ci    zone1offset_y = ff_vc1_b_field_mvpred_scales[6][brfd];
142cabdff1aSopenharmony_ci    scaleopp1     = ff_vc1_b_field_mvpred_scales[1][brfd];
143cabdff1aSopenharmony_ci    scaleopp2     = ff_vc1_b_field_mvpred_scales[2][brfd];
144cabdff1aSopenharmony_ci
145cabdff1aSopenharmony_ci    if (FFABS(n) > 63)
146cabdff1aSopenharmony_ci        scaledvalue = n;
147cabdff1aSopenharmony_ci    else {
148cabdff1aSopenharmony_ci        if (FFABS(n) < scalezone1_y)
149cabdff1aSopenharmony_ci            scaledvalue = (n * scaleopp1) >> 8;
150cabdff1aSopenharmony_ci        else {
151cabdff1aSopenharmony_ci            if (n < 0)
152cabdff1aSopenharmony_ci                scaledvalue = ((n * scaleopp2) >> 8) - zone1offset_y;
153cabdff1aSopenharmony_ci            else
154cabdff1aSopenharmony_ci                scaledvalue = ((n * scaleopp2) >> 8) + zone1offset_y;
155cabdff1aSopenharmony_ci        }
156cabdff1aSopenharmony_ci    }
157cabdff1aSopenharmony_ci    if (v->cur_field_type && !v->ref_field_type[dir]) {
158cabdff1aSopenharmony_ci        return av_clip(scaledvalue, -v->range_y / 2 + 1, v->range_y / 2);
159cabdff1aSopenharmony_ci    } else {
160cabdff1aSopenharmony_ci        return av_clip(scaledvalue, -v->range_y / 2, v->range_y / 2 - 1);
161cabdff1aSopenharmony_ci    }
162cabdff1aSopenharmony_ci}
163cabdff1aSopenharmony_ci
164cabdff1aSopenharmony_cistatic av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */,
165cabdff1aSopenharmony_ci                                         int dim, int dir)
166cabdff1aSopenharmony_ci{
167cabdff1aSopenharmony_ci    int brfd, scalesame;
168cabdff1aSopenharmony_ci    int hpel = 1 - v->s.quarter_sample;
169cabdff1aSopenharmony_ci
170cabdff1aSopenharmony_ci    n >>= hpel;
171cabdff1aSopenharmony_ci    if (v->s.pict_type != AV_PICTURE_TYPE_B || v->second_field || !dir) {
172cabdff1aSopenharmony_ci        if (dim)
173cabdff1aSopenharmony_ci            n = scaleforsame_y(v, i, n, dir) * (1 << hpel);
174cabdff1aSopenharmony_ci        else
175cabdff1aSopenharmony_ci            n = scaleforsame_x(v, n, dir) * (1 << hpel);
176cabdff1aSopenharmony_ci        return n;
177cabdff1aSopenharmony_ci    }
178cabdff1aSopenharmony_ci    brfd      = FFMIN(v->brfd, 3);
179cabdff1aSopenharmony_ci    scalesame = ff_vc1_b_field_mvpred_scales[0][brfd];
180cabdff1aSopenharmony_ci
181cabdff1aSopenharmony_ci    n = (n * scalesame >> 8) * (1 << hpel);
182cabdff1aSopenharmony_ci    return n;
183cabdff1aSopenharmony_ci}
184cabdff1aSopenharmony_ci
185cabdff1aSopenharmony_cistatic av_always_inline int scaleforopp(VC1Context *v, int n /* MV */,
186cabdff1aSopenharmony_ci                                        int dim, int dir)
187cabdff1aSopenharmony_ci{
188cabdff1aSopenharmony_ci    int refdist, scaleopp;
189cabdff1aSopenharmony_ci    int hpel = 1 - v->s.quarter_sample;
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_ci    n >>= hpel;
192cabdff1aSopenharmony_ci    if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) {
193cabdff1aSopenharmony_ci        if (dim)
194cabdff1aSopenharmony_ci            n = scaleforopp_y(v, n, dir) * (1 << hpel);
195cabdff1aSopenharmony_ci        else
196cabdff1aSopenharmony_ci            n = scaleforopp_x(v, n)      * (1 << hpel);
197cabdff1aSopenharmony_ci        return n;
198cabdff1aSopenharmony_ci    }
199cabdff1aSopenharmony_ci    if (v->s.pict_type != AV_PICTURE_TYPE_B)
200cabdff1aSopenharmony_ci        refdist = v->refdist;
201cabdff1aSopenharmony_ci    else
202cabdff1aSopenharmony_ci        refdist = dir ? v->brfd : v->frfd;
203cabdff1aSopenharmony_ci    refdist = FFMIN(refdist, 3);
204cabdff1aSopenharmony_ci    scaleopp = ff_vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist];
205cabdff1aSopenharmony_ci
206cabdff1aSopenharmony_ci    n = (n * scaleopp >> 8) * (1 << hpel);
207cabdff1aSopenharmony_ci    return n;
208cabdff1aSopenharmony_ci}
209cabdff1aSopenharmony_ci
210cabdff1aSopenharmony_ci/** Predict and set motion vector
211cabdff1aSopenharmony_ci */
212cabdff1aSopenharmony_civoid ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
213cabdff1aSopenharmony_ci                    int mv1, int r_x, int r_y, uint8_t* is_intra,
214cabdff1aSopenharmony_ci                    int pred_flag, int dir)
215cabdff1aSopenharmony_ci{
216cabdff1aSopenharmony_ci    MpegEncContext *s = &v->s;
217cabdff1aSopenharmony_ci    int xy, wrap, off = 0;
218cabdff1aSopenharmony_ci    int16_t *A, *B, *C;
219cabdff1aSopenharmony_ci    int px, py;
220cabdff1aSopenharmony_ci    int sum;
221cabdff1aSopenharmony_ci    int mixedmv_pic, num_samefield = 0, num_oppfield = 0;
222cabdff1aSopenharmony_ci    int opposite, a_f, b_f, c_f;
223cabdff1aSopenharmony_ci    int16_t field_predA[2];
224cabdff1aSopenharmony_ci    int16_t field_predB[2];
225cabdff1aSopenharmony_ci    int16_t field_predC[2];
226cabdff1aSopenharmony_ci    int a_valid, b_valid, c_valid;
227cabdff1aSopenharmony_ci    int hybridmv_thresh, y_bias = 0;
228cabdff1aSopenharmony_ci
229cabdff1aSopenharmony_ci    if (v->mv_mode == MV_PMODE_MIXED_MV ||
230cabdff1aSopenharmony_ci        ((v->mv_mode == MV_PMODE_INTENSITY_COMP) && (v->mv_mode2 == MV_PMODE_MIXED_MV)))
231cabdff1aSopenharmony_ci        mixedmv_pic = 1;
232cabdff1aSopenharmony_ci    else
233cabdff1aSopenharmony_ci        mixedmv_pic = 0;
234cabdff1aSopenharmony_ci    /* scale MV difference to be quad-pel */
235cabdff1aSopenharmony_ci    if (!s->quarter_sample) {
236cabdff1aSopenharmony_ci        dmv_x *= 2;
237cabdff1aSopenharmony_ci        dmv_y *= 2;
238cabdff1aSopenharmony_ci    }
239cabdff1aSopenharmony_ci
240cabdff1aSopenharmony_ci    wrap = s->b8_stride;
241cabdff1aSopenharmony_ci    xy   = s->block_index[n];
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_ci    if (s->mb_intra) {
244cabdff1aSopenharmony_ci        s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0;
245cabdff1aSopenharmony_ci        s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0;
246cabdff1aSopenharmony_ci        s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0;
247cabdff1aSopenharmony_ci        s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
248cabdff1aSopenharmony_ci        if (mv1) { /* duplicate motion data for 1-MV block */
249cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0]        = 0;
250cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1]        = 0;
251cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0]     = 0;
252cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1]     = 0;
253cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
254cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
255cabdff1aSopenharmony_ci            v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
256cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0]        = 0;
257cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1]        = 0;
258cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + wrap + v->blocks_off][0]     = 0;
259cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1]     = 0;
260cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
261cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
262cabdff1aSopenharmony_ci        }
263cabdff1aSopenharmony_ci        return;
264cabdff1aSopenharmony_ci    }
265cabdff1aSopenharmony_ci
266cabdff1aSopenharmony_ci    a_valid = !s->first_slice_line || (n == 2 || n == 3);
267cabdff1aSopenharmony_ci    b_valid = a_valid;
268cabdff1aSopenharmony_ci    c_valid = s->mb_x || (n == 1 || n == 3);
269cabdff1aSopenharmony_ci    if (mv1) {
270cabdff1aSopenharmony_ci        if (v->field_mode && mixedmv_pic)
271cabdff1aSopenharmony_ci            off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
272cabdff1aSopenharmony_ci        else
273cabdff1aSopenharmony_ci            off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
274cabdff1aSopenharmony_ci        b_valid = b_valid && s->mb_width > 1;
275cabdff1aSopenharmony_ci    } else {
276cabdff1aSopenharmony_ci        //in 4-MV mode different blocks have different B predictor position
277cabdff1aSopenharmony_ci        switch (n) {
278cabdff1aSopenharmony_ci        case 0:
279cabdff1aSopenharmony_ci            if (v->res_rtm_flag)
280cabdff1aSopenharmony_ci                off = s->mb_x ? -1 : 1;
281cabdff1aSopenharmony_ci            else
282cabdff1aSopenharmony_ci                off = s->mb_x ? -1 : 2 * s->mb_width - wrap - 1;
283cabdff1aSopenharmony_ci            break;
284cabdff1aSopenharmony_ci        case 1:
285cabdff1aSopenharmony_ci            off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
286cabdff1aSopenharmony_ci            break;
287cabdff1aSopenharmony_ci        case 2:
288cabdff1aSopenharmony_ci            off = 1;
289cabdff1aSopenharmony_ci            break;
290cabdff1aSopenharmony_ci        case 3:
291cabdff1aSopenharmony_ci            off = -1;
292cabdff1aSopenharmony_ci        }
293cabdff1aSopenharmony_ci        if (v->field_mode && s->mb_width == 1)
294cabdff1aSopenharmony_ci            b_valid = b_valid && c_valid;
295cabdff1aSopenharmony_ci    }
296cabdff1aSopenharmony_ci
297cabdff1aSopenharmony_ci    if (v->field_mode) {
298cabdff1aSopenharmony_ci        a_valid = a_valid && !is_intra[xy - wrap];
299cabdff1aSopenharmony_ci        b_valid = b_valid && !is_intra[xy - wrap + off];
300cabdff1aSopenharmony_ci        c_valid = c_valid && !is_intra[xy - 1];
301cabdff1aSopenharmony_ci    }
302cabdff1aSopenharmony_ci
303cabdff1aSopenharmony_ci    if (a_valid) {
304cabdff1aSopenharmony_ci        A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off];
305cabdff1aSopenharmony_ci        a_f = v->mv_f[dir][xy - wrap + v->blocks_off];
306cabdff1aSopenharmony_ci        num_oppfield  += a_f;
307cabdff1aSopenharmony_ci        num_samefield += 1 - a_f;
308cabdff1aSopenharmony_ci        field_predA[0] = A[0];
309cabdff1aSopenharmony_ci        field_predA[1] = A[1];
310cabdff1aSopenharmony_ci    } else {
311cabdff1aSopenharmony_ci        field_predA[0] = field_predA[1] = 0;
312cabdff1aSopenharmony_ci        a_f = 0;
313cabdff1aSopenharmony_ci    }
314cabdff1aSopenharmony_ci    if (b_valid) {
315cabdff1aSopenharmony_ci        B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off];
316cabdff1aSopenharmony_ci        b_f = v->mv_f[dir][xy - wrap + off + v->blocks_off];
317cabdff1aSopenharmony_ci        num_oppfield  += b_f;
318cabdff1aSopenharmony_ci        num_samefield += 1 - b_f;
319cabdff1aSopenharmony_ci        field_predB[0] = B[0];
320cabdff1aSopenharmony_ci        field_predB[1] = B[1];
321cabdff1aSopenharmony_ci    } else {
322cabdff1aSopenharmony_ci        field_predB[0] = field_predB[1] = 0;
323cabdff1aSopenharmony_ci        b_f = 0;
324cabdff1aSopenharmony_ci    }
325cabdff1aSopenharmony_ci    if (c_valid) {
326cabdff1aSopenharmony_ci        C = s->current_picture.motion_val[dir][xy - 1 + v->blocks_off];
327cabdff1aSopenharmony_ci        c_f = v->mv_f[dir][xy - 1 + v->blocks_off];
328cabdff1aSopenharmony_ci        num_oppfield  += c_f;
329cabdff1aSopenharmony_ci        num_samefield += 1 - c_f;
330cabdff1aSopenharmony_ci        field_predC[0] = C[0];
331cabdff1aSopenharmony_ci        field_predC[1] = C[1];
332cabdff1aSopenharmony_ci    } else {
333cabdff1aSopenharmony_ci        field_predC[0] = field_predC[1] = 0;
334cabdff1aSopenharmony_ci        c_f = 0;
335cabdff1aSopenharmony_ci    }
336cabdff1aSopenharmony_ci
337cabdff1aSopenharmony_ci    if (v->field_mode) {
338cabdff1aSopenharmony_ci        if (!v->numref)
339cabdff1aSopenharmony_ci            // REFFIELD determines if the last field or the second-last field is
340cabdff1aSopenharmony_ci            // to be used as reference
341cabdff1aSopenharmony_ci            opposite = 1 - v->reffield;
342cabdff1aSopenharmony_ci        else {
343cabdff1aSopenharmony_ci            if (num_samefield <= num_oppfield)
344cabdff1aSopenharmony_ci                opposite = 1 - pred_flag;
345cabdff1aSopenharmony_ci            else
346cabdff1aSopenharmony_ci                opposite = pred_flag;
347cabdff1aSopenharmony_ci        }
348cabdff1aSopenharmony_ci    } else
349cabdff1aSopenharmony_ci        opposite = 0;
350cabdff1aSopenharmony_ci    if (opposite) {
351cabdff1aSopenharmony_ci        v->mv_f[dir][xy + v->blocks_off] = 1;
352cabdff1aSopenharmony_ci        v->ref_field_type[dir] = !v->cur_field_type;
353cabdff1aSopenharmony_ci        if (a_valid && !a_f) {
354cabdff1aSopenharmony_ci            field_predA[0] = scaleforopp(v, field_predA[0], 0, dir);
355cabdff1aSopenharmony_ci            field_predA[1] = scaleforopp(v, field_predA[1], 1, dir);
356cabdff1aSopenharmony_ci        }
357cabdff1aSopenharmony_ci        if (b_valid && !b_f) {
358cabdff1aSopenharmony_ci            field_predB[0] = scaleforopp(v, field_predB[0], 0, dir);
359cabdff1aSopenharmony_ci            field_predB[1] = scaleforopp(v, field_predB[1], 1, dir);
360cabdff1aSopenharmony_ci        }
361cabdff1aSopenharmony_ci        if (c_valid && !c_f) {
362cabdff1aSopenharmony_ci            field_predC[0] = scaleforopp(v, field_predC[0], 0, dir);
363cabdff1aSopenharmony_ci            field_predC[1] = scaleforopp(v, field_predC[1], 1, dir);
364cabdff1aSopenharmony_ci        }
365cabdff1aSopenharmony_ci    } else {
366cabdff1aSopenharmony_ci        v->mv_f[dir][xy + v->blocks_off] = 0;
367cabdff1aSopenharmony_ci        v->ref_field_type[dir] = v->cur_field_type;
368cabdff1aSopenharmony_ci        if (a_valid && a_f) {
369cabdff1aSopenharmony_ci            field_predA[0] = scaleforsame(v, n, field_predA[0], 0, dir);
370cabdff1aSopenharmony_ci            field_predA[1] = scaleforsame(v, n, field_predA[1], 1, dir);
371cabdff1aSopenharmony_ci        }
372cabdff1aSopenharmony_ci        if (b_valid && b_f) {
373cabdff1aSopenharmony_ci            field_predB[0] = scaleforsame(v, n, field_predB[0], 0, dir);
374cabdff1aSopenharmony_ci            field_predB[1] = scaleforsame(v, n, field_predB[1], 1, dir);
375cabdff1aSopenharmony_ci        }
376cabdff1aSopenharmony_ci        if (c_valid && c_f) {
377cabdff1aSopenharmony_ci            field_predC[0] = scaleforsame(v, n, field_predC[0], 0, dir);
378cabdff1aSopenharmony_ci            field_predC[1] = scaleforsame(v, n, field_predC[1], 1, dir);
379cabdff1aSopenharmony_ci        }
380cabdff1aSopenharmony_ci    }
381cabdff1aSopenharmony_ci
382cabdff1aSopenharmony_ci    if (a_valid) {
383cabdff1aSopenharmony_ci        px = field_predA[0];
384cabdff1aSopenharmony_ci        py = field_predA[1];
385cabdff1aSopenharmony_ci    } else if (c_valid) {
386cabdff1aSopenharmony_ci        px = field_predC[0];
387cabdff1aSopenharmony_ci        py = field_predC[1];
388cabdff1aSopenharmony_ci    } else if (b_valid) {
389cabdff1aSopenharmony_ci        px = field_predB[0];
390cabdff1aSopenharmony_ci        py = field_predB[1];
391cabdff1aSopenharmony_ci    } else {
392cabdff1aSopenharmony_ci        px = 0;
393cabdff1aSopenharmony_ci        py = 0;
394cabdff1aSopenharmony_ci    }
395cabdff1aSopenharmony_ci
396cabdff1aSopenharmony_ci    if (num_samefield + num_oppfield > 1) {
397cabdff1aSopenharmony_ci        px = mid_pred(field_predA[0], field_predB[0], field_predC[0]);
398cabdff1aSopenharmony_ci        py = mid_pred(field_predA[1], field_predB[1], field_predC[1]);
399cabdff1aSopenharmony_ci    }
400cabdff1aSopenharmony_ci
401cabdff1aSopenharmony_ci    /* Pullback MV as specified in 8.3.5.3.4 */
402cabdff1aSopenharmony_ci    if (!v->field_mode) {
403cabdff1aSopenharmony_ci        int qx, qy, X, Y;
404cabdff1aSopenharmony_ci        int MV = mv1 ? -60 : -28;
405cabdff1aSopenharmony_ci        qx = (s->mb_x << 6) + ((n == 1 || n == 3) ? 32 : 0);
406cabdff1aSopenharmony_ci        qy = (s->mb_y << 6) + ((n == 2 || n == 3) ? 32 : 0);
407cabdff1aSopenharmony_ci        X  = (s->mb_width  << 6) - 4;
408cabdff1aSopenharmony_ci        Y  = (s->mb_height << 6) - 4;
409cabdff1aSopenharmony_ci        if (qx + px < MV) px = MV - qx;
410cabdff1aSopenharmony_ci        if (qy + py < MV) py = MV - qy;
411cabdff1aSopenharmony_ci        if (qx + px > X) px = X - qx;
412cabdff1aSopenharmony_ci        if (qy + py > Y) py = Y - qy;
413cabdff1aSopenharmony_ci    }
414cabdff1aSopenharmony_ci
415cabdff1aSopenharmony_ci    if (!v->field_mode || s->pict_type != AV_PICTURE_TYPE_B) {
416cabdff1aSopenharmony_ci        /* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */
417cabdff1aSopenharmony_ci        hybridmv_thresh = 32;
418cabdff1aSopenharmony_ci        if (a_valid && c_valid) {
419cabdff1aSopenharmony_ci            if (is_intra[xy - wrap])
420cabdff1aSopenharmony_ci                sum = FFABS(px) + FFABS(py);
421cabdff1aSopenharmony_ci            else
422cabdff1aSopenharmony_ci                sum = FFABS(px - field_predA[0]) + FFABS(py - field_predA[1]);
423cabdff1aSopenharmony_ci            if (sum > hybridmv_thresh) {
424cabdff1aSopenharmony_ci                if (get_bits1(&s->gb)) {     // read HYBRIDPRED bit
425cabdff1aSopenharmony_ci                    px = field_predA[0];
426cabdff1aSopenharmony_ci                    py = field_predA[1];
427cabdff1aSopenharmony_ci                } else {
428cabdff1aSopenharmony_ci                    px = field_predC[0];
429cabdff1aSopenharmony_ci                    py = field_predC[1];
430cabdff1aSopenharmony_ci                }
431cabdff1aSopenharmony_ci            } else {
432cabdff1aSopenharmony_ci                if (is_intra[xy - 1])
433cabdff1aSopenharmony_ci                    sum = FFABS(px) + FFABS(py);
434cabdff1aSopenharmony_ci                else
435cabdff1aSopenharmony_ci                    sum = FFABS(px - field_predC[0]) + FFABS(py - field_predC[1]);
436cabdff1aSopenharmony_ci                if (sum > hybridmv_thresh) {
437cabdff1aSopenharmony_ci                    if (get_bits1(&s->gb)) {
438cabdff1aSopenharmony_ci                        px = field_predA[0];
439cabdff1aSopenharmony_ci                        py = field_predA[1];
440cabdff1aSopenharmony_ci                    } else {
441cabdff1aSopenharmony_ci                        px = field_predC[0];
442cabdff1aSopenharmony_ci                        py = field_predC[1];
443cabdff1aSopenharmony_ci                    }
444cabdff1aSopenharmony_ci                }
445cabdff1aSopenharmony_ci            }
446cabdff1aSopenharmony_ci        }
447cabdff1aSopenharmony_ci    }
448cabdff1aSopenharmony_ci
449cabdff1aSopenharmony_ci    if (v->field_mode && v->numref)
450cabdff1aSopenharmony_ci        r_y >>= 1;
451cabdff1aSopenharmony_ci    if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
452cabdff1aSopenharmony_ci        y_bias = 1;
453cabdff1aSopenharmony_ci    /* store MV using signed modulus of MV range defined in 4.11 */
454cabdff1aSopenharmony_ci    s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
455cabdff1aSopenharmony_ci    s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
456cabdff1aSopenharmony_ci    if (mv1) { /* duplicate motion data for 1-MV block */
457cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy +    1 +     v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
458cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy +    1 +     v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
459cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + wrap +     v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
460cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + wrap +     v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
461cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
462cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
463cabdff1aSopenharmony_ci        v->mv_f[dir][xy +    1 + v->blocks_off] = v->mv_f[dir][xy +            v->blocks_off];
464cabdff1aSopenharmony_ci        v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
465cabdff1aSopenharmony_ci    }
466cabdff1aSopenharmony_ci}
467cabdff1aSopenharmony_ci
468cabdff1aSopenharmony_ci/** Predict and set motion vector for interlaced frame picture MBs
469cabdff1aSopenharmony_ci */
470cabdff1aSopenharmony_civoid ff_vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
471cabdff1aSopenharmony_ci                          int mvn, int r_x, int r_y, int dir)
472cabdff1aSopenharmony_ci{
473cabdff1aSopenharmony_ci    MpegEncContext *s = &v->s;
474cabdff1aSopenharmony_ci    int xy, wrap, off = 0;
475cabdff1aSopenharmony_ci    int A[2], B[2], C[2];
476cabdff1aSopenharmony_ci    int px = 0, py = 0;
477cabdff1aSopenharmony_ci    int a_valid = 0, b_valid = 0, c_valid = 0;
478cabdff1aSopenharmony_ci    int field_a, field_b, field_c; // 0: same, 1: opposite
479cabdff1aSopenharmony_ci    int total_valid, num_samefield, num_oppfield;
480cabdff1aSopenharmony_ci    int pos_c, pos_b, n_adj;
481cabdff1aSopenharmony_ci
482cabdff1aSopenharmony_ci    wrap = s->b8_stride;
483cabdff1aSopenharmony_ci    xy = s->block_index[n];
484cabdff1aSopenharmony_ci
485cabdff1aSopenharmony_ci    if (s->mb_intra) {
486cabdff1aSopenharmony_ci        s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
487cabdff1aSopenharmony_ci        s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
488cabdff1aSopenharmony_ci        s->current_picture.motion_val[1][xy][0] = 0;
489cabdff1aSopenharmony_ci        s->current_picture.motion_val[1][xy][1] = 0;
490cabdff1aSopenharmony_ci        if (mvn == 1) { /* duplicate motion data for 1-MV block */
491cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + 1][0]        = 0;
492cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + 1][1]        = 0;
493cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + wrap][0]     = 0;
494cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + wrap][1]     = 0;
495cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
496cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
497cabdff1aSopenharmony_ci            v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
498cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + 1][0]        = 0;
499cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + 1][1]        = 0;
500cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + wrap][0]     = 0;
501cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + wrap][1]     = 0;
502cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
503cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
504cabdff1aSopenharmony_ci        }
505cabdff1aSopenharmony_ci        return;
506cabdff1aSopenharmony_ci    }
507cabdff1aSopenharmony_ci
508cabdff1aSopenharmony_ci    off = ((n == 0) || (n == 1)) ? 1 : -1;
509cabdff1aSopenharmony_ci    /* predict A */
510cabdff1aSopenharmony_ci    if (s->mb_x || (n == 1) || (n == 3)) {
511cabdff1aSopenharmony_ci        if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
512cabdff1aSopenharmony_ci            || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
513cabdff1aSopenharmony_ci            A[0] = s->current_picture.motion_val[dir][xy - 1][0];
514cabdff1aSopenharmony_ci            A[1] = s->current_picture.motion_val[dir][xy - 1][1];
515cabdff1aSopenharmony_ci            a_valid = 1;
516cabdff1aSopenharmony_ci        } else { // current block has frame mv and cand. has field MV (so average)
517cabdff1aSopenharmony_ci            A[0] = (s->current_picture.motion_val[dir][xy - 1][0]
518cabdff1aSopenharmony_ci                    + s->current_picture.motion_val[dir][xy - 1 + off * wrap][0] + 1) >> 1;
519cabdff1aSopenharmony_ci            A[1] = (s->current_picture.motion_val[dir][xy - 1][1]
520cabdff1aSopenharmony_ci                    + s->current_picture.motion_val[dir][xy - 1 + off * wrap][1] + 1) >> 1;
521cabdff1aSopenharmony_ci            a_valid = 1;
522cabdff1aSopenharmony_ci        }
523cabdff1aSopenharmony_ci        if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
524cabdff1aSopenharmony_ci            a_valid = 0;
525cabdff1aSopenharmony_ci            A[0] = A[1] = 0;
526cabdff1aSopenharmony_ci        }
527cabdff1aSopenharmony_ci    } else
528cabdff1aSopenharmony_ci        A[0] = A[1] = 0;
529cabdff1aSopenharmony_ci    /* Predict B and C */
530cabdff1aSopenharmony_ci    B[0] = B[1] = C[0] = C[1] = 0;
531cabdff1aSopenharmony_ci    if (n == 0 || n == 1 || v->blk_mv_type[xy]) {
532cabdff1aSopenharmony_ci        if (!s->first_slice_line) {
533cabdff1aSopenharmony_ci            if (!v->is_intra[s->mb_x - s->mb_stride]) {
534cabdff1aSopenharmony_ci                b_valid = 1;
535cabdff1aSopenharmony_ci                n_adj   = n | 2;
536cabdff1aSopenharmony_ci                pos_b   = s->block_index[n_adj] - 2 * wrap;
537cabdff1aSopenharmony_ci                if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
538cabdff1aSopenharmony_ci                    n_adj = (n & 2) | (n & 1);
539cabdff1aSopenharmony_ci                }
540cabdff1aSopenharmony_ci                B[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][0];
541cabdff1aSopenharmony_ci                B[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][1];
542cabdff1aSopenharmony_ci                if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
543cabdff1aSopenharmony_ci                    B[0] = (B[0] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
544cabdff1aSopenharmony_ci                    B[1] = (B[1] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
545cabdff1aSopenharmony_ci                }
546cabdff1aSopenharmony_ci            }
547cabdff1aSopenharmony_ci            if (s->mb_width > 1) {
548cabdff1aSopenharmony_ci                if (!v->is_intra[s->mb_x - s->mb_stride + 1]) {
549cabdff1aSopenharmony_ci                    c_valid = 1;
550cabdff1aSopenharmony_ci                    n_adj   = 2;
551cabdff1aSopenharmony_ci                    pos_c   = s->block_index[2] - 2 * wrap + 2;
552cabdff1aSopenharmony_ci                    if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
553cabdff1aSopenharmony_ci                        n_adj = n & 2;
554cabdff1aSopenharmony_ci                    }
555cabdff1aSopenharmony_ci                    C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][0];
556cabdff1aSopenharmony_ci                    C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][1];
557cabdff1aSopenharmony_ci                    if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
558cabdff1aSopenharmony_ci                        C[0] = (1 + C[0] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
559cabdff1aSopenharmony_ci                        C[1] = (1 + C[1] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
560cabdff1aSopenharmony_ci                    }
561cabdff1aSopenharmony_ci                    if (s->mb_x == s->mb_width - 1) {
562cabdff1aSopenharmony_ci                        if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
563cabdff1aSopenharmony_ci                            c_valid = 1;
564cabdff1aSopenharmony_ci                            n_adj   = 3;
565cabdff1aSopenharmony_ci                            pos_c   = s->block_index[3] - 2 * wrap - 2;
566cabdff1aSopenharmony_ci                            if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
567cabdff1aSopenharmony_ci                                n_adj = n | 1;
568cabdff1aSopenharmony_ci                            }
569cabdff1aSopenharmony_ci                            C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][0];
570cabdff1aSopenharmony_ci                            C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][1];
571cabdff1aSopenharmony_ci                            if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
572cabdff1aSopenharmony_ci                                C[0] = (1 + C[0] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
573cabdff1aSopenharmony_ci                                C[1] = (1 + C[1] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
574cabdff1aSopenharmony_ci                            }
575cabdff1aSopenharmony_ci                        } else
576cabdff1aSopenharmony_ci                            c_valid = 0;
577cabdff1aSopenharmony_ci                    }
578cabdff1aSopenharmony_ci                }
579cabdff1aSopenharmony_ci            }
580cabdff1aSopenharmony_ci        }
581cabdff1aSopenharmony_ci    } else {
582cabdff1aSopenharmony_ci        pos_b   = s->block_index[1];
583cabdff1aSopenharmony_ci        b_valid = 1;
584cabdff1aSopenharmony_ci        B[0]    = s->current_picture.motion_val[dir][pos_b][0];
585cabdff1aSopenharmony_ci        B[1]    = s->current_picture.motion_val[dir][pos_b][1];
586cabdff1aSopenharmony_ci        pos_c   = s->block_index[0];
587cabdff1aSopenharmony_ci        c_valid = 1;
588cabdff1aSopenharmony_ci        C[0]    = s->current_picture.motion_val[dir][pos_c][0];
589cabdff1aSopenharmony_ci        C[1]    = s->current_picture.motion_val[dir][pos_c][1];
590cabdff1aSopenharmony_ci    }
591cabdff1aSopenharmony_ci
592cabdff1aSopenharmony_ci    total_valid = a_valid + b_valid + c_valid;
593cabdff1aSopenharmony_ci    // check if predictor A is out of bounds
594cabdff1aSopenharmony_ci    if (!s->mb_x && !(n == 1 || n == 3)) {
595cabdff1aSopenharmony_ci        A[0] = A[1] = 0;
596cabdff1aSopenharmony_ci    }
597cabdff1aSopenharmony_ci    // check if predictor B is out of bounds
598cabdff1aSopenharmony_ci    if ((s->first_slice_line && v->blk_mv_type[xy]) || (s->first_slice_line && !(n & 2))) {
599cabdff1aSopenharmony_ci        B[0] = B[1] = C[0] = C[1] = 0;
600cabdff1aSopenharmony_ci    }
601cabdff1aSopenharmony_ci    if (!v->blk_mv_type[xy]) {
602cabdff1aSopenharmony_ci        if (s->mb_width == 1) {
603cabdff1aSopenharmony_ci            px = B[0];
604cabdff1aSopenharmony_ci            py = B[1];
605cabdff1aSopenharmony_ci        } else {
606cabdff1aSopenharmony_ci            if (total_valid >= 2) {
607cabdff1aSopenharmony_ci                px = mid_pred(A[0], B[0], C[0]);
608cabdff1aSopenharmony_ci                py = mid_pred(A[1], B[1], C[1]);
609cabdff1aSopenharmony_ci            } else if (total_valid) {
610cabdff1aSopenharmony_ci                if      (a_valid) { px = A[0]; py = A[1]; }
611cabdff1aSopenharmony_ci                else if (b_valid) { px = B[0]; py = B[1]; }
612cabdff1aSopenharmony_ci                else              { px = C[0]; py = C[1]; }
613cabdff1aSopenharmony_ci            }
614cabdff1aSopenharmony_ci        }
615cabdff1aSopenharmony_ci    } else {
616cabdff1aSopenharmony_ci        if (a_valid)
617cabdff1aSopenharmony_ci            field_a = (A[1] & 4) ? 1 : 0;
618cabdff1aSopenharmony_ci        else
619cabdff1aSopenharmony_ci            field_a = 0;
620cabdff1aSopenharmony_ci        if (b_valid)
621cabdff1aSopenharmony_ci            field_b = (B[1] & 4) ? 1 : 0;
622cabdff1aSopenharmony_ci        else
623cabdff1aSopenharmony_ci            field_b = 0;
624cabdff1aSopenharmony_ci        if (c_valid)
625cabdff1aSopenharmony_ci            field_c = (C[1] & 4) ? 1 : 0;
626cabdff1aSopenharmony_ci        else
627cabdff1aSopenharmony_ci            field_c = 0;
628cabdff1aSopenharmony_ci
629cabdff1aSopenharmony_ci        num_oppfield  = field_a + field_b + field_c;
630cabdff1aSopenharmony_ci        num_samefield = total_valid - num_oppfield;
631cabdff1aSopenharmony_ci        if (total_valid == 3) {
632cabdff1aSopenharmony_ci            if ((num_samefield == 3) || (num_oppfield == 3)) {
633cabdff1aSopenharmony_ci                px = mid_pred(A[0], B[0], C[0]);
634cabdff1aSopenharmony_ci                py = mid_pred(A[1], B[1], C[1]);
635cabdff1aSopenharmony_ci            } else if (num_samefield >= num_oppfield) {
636cabdff1aSopenharmony_ci                /* take one MV from same field set depending on priority
637cabdff1aSopenharmony_ci                the check for B may not be necessary */
638cabdff1aSopenharmony_ci                px = !field_a ? A[0] : B[0];
639cabdff1aSopenharmony_ci                py = !field_a ? A[1] : B[1];
640cabdff1aSopenharmony_ci            } else {
641cabdff1aSopenharmony_ci                px =  field_a ? A[0] : B[0];
642cabdff1aSopenharmony_ci                py =  field_a ? A[1] : B[1];
643cabdff1aSopenharmony_ci            }
644cabdff1aSopenharmony_ci        } else if (total_valid == 2) {
645cabdff1aSopenharmony_ci            if (num_samefield >= num_oppfield) {
646cabdff1aSopenharmony_ci                if (!field_a && a_valid) {
647cabdff1aSopenharmony_ci                    px = A[0];
648cabdff1aSopenharmony_ci                    py = A[1];
649cabdff1aSopenharmony_ci                } else if (!field_b && b_valid) {
650cabdff1aSopenharmony_ci                    px = B[0];
651cabdff1aSopenharmony_ci                    py = B[1];
652cabdff1aSopenharmony_ci                } else /*if (c_valid)*/ {
653cabdff1aSopenharmony_ci                    av_assert1(c_valid);
654cabdff1aSopenharmony_ci                    px = C[0];
655cabdff1aSopenharmony_ci                    py = C[1];
656cabdff1aSopenharmony_ci                }
657cabdff1aSopenharmony_ci            } else {
658cabdff1aSopenharmony_ci                if (field_a && a_valid) {
659cabdff1aSopenharmony_ci                    px = A[0];
660cabdff1aSopenharmony_ci                    py = A[1];
661cabdff1aSopenharmony_ci                } else /*if (field_b && b_valid)*/ {
662cabdff1aSopenharmony_ci                    av_assert1(field_b && b_valid);
663cabdff1aSopenharmony_ci                    px = B[0];
664cabdff1aSopenharmony_ci                    py = B[1];
665cabdff1aSopenharmony_ci                }
666cabdff1aSopenharmony_ci            }
667cabdff1aSopenharmony_ci        } else if (total_valid == 1) {
668cabdff1aSopenharmony_ci            px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
669cabdff1aSopenharmony_ci            py = (a_valid) ? A[1] : ((b_valid) ? B[1] : C[1]);
670cabdff1aSopenharmony_ci        }
671cabdff1aSopenharmony_ci    }
672cabdff1aSopenharmony_ci
673cabdff1aSopenharmony_ci    /* store MV using signed modulus of MV range defined in 4.11 */
674cabdff1aSopenharmony_ci    s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
675cabdff1aSopenharmony_ci    s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
676cabdff1aSopenharmony_ci    if (mvn == 1) { /* duplicate motion data for 1-MV block */
677cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy +    1    ][0] = s->current_picture.motion_val[dir][xy][0];
678cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy +    1    ][1] = s->current_picture.motion_val[dir][xy][1];
679cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + wrap    ][0] = s->current_picture.motion_val[dir][xy][0];
680cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + wrap    ][1] = s->current_picture.motion_val[dir][xy][1];
681cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + wrap + 1][0] = s->current_picture.motion_val[dir][xy][0];
682cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + wrap + 1][1] = s->current_picture.motion_val[dir][xy][1];
683cabdff1aSopenharmony_ci    } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
684cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + 1][0] = s->current_picture.motion_val[dir][xy][0];
685cabdff1aSopenharmony_ci        s->current_picture.motion_val[dir][xy + 1][1] = s->current_picture.motion_val[dir][xy][1];
686cabdff1aSopenharmony_ci        s->mv[dir][n + 1][0] = s->mv[dir][n][0];
687cabdff1aSopenharmony_ci        s->mv[dir][n + 1][1] = s->mv[dir][n][1];
688cabdff1aSopenharmony_ci    }
689cabdff1aSopenharmony_ci}
690cabdff1aSopenharmony_ci
691cabdff1aSopenharmony_civoid ff_vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
692cabdff1aSopenharmony_ci                      int direct, int mvtype)
693cabdff1aSopenharmony_ci{
694cabdff1aSopenharmony_ci    MpegEncContext *s = &v->s;
695cabdff1aSopenharmony_ci    int xy, wrap, off = 0;
696cabdff1aSopenharmony_ci    int16_t *A, *B, *C;
697cabdff1aSopenharmony_ci    int px, py;
698cabdff1aSopenharmony_ci    int sum;
699cabdff1aSopenharmony_ci    int r_x, r_y;
700cabdff1aSopenharmony_ci    const uint8_t *is_intra = v->mb_type[0];
701cabdff1aSopenharmony_ci
702cabdff1aSopenharmony_ci    av_assert0(!v->field_mode);
703cabdff1aSopenharmony_ci
704cabdff1aSopenharmony_ci    r_x = v->range_x;
705cabdff1aSopenharmony_ci    r_y = v->range_y;
706cabdff1aSopenharmony_ci    /* scale MV difference to be quad-pel */
707cabdff1aSopenharmony_ci    if (!s->quarter_sample) {
708cabdff1aSopenharmony_ci        dmv_x[0] *= 2;
709cabdff1aSopenharmony_ci        dmv_y[0] *= 2;
710cabdff1aSopenharmony_ci        dmv_x[1] *= 2;
711cabdff1aSopenharmony_ci        dmv_y[1] *= 2;
712cabdff1aSopenharmony_ci    }
713cabdff1aSopenharmony_ci
714cabdff1aSopenharmony_ci    wrap = s->b8_stride;
715cabdff1aSopenharmony_ci    xy = s->block_index[0];
716cabdff1aSopenharmony_ci
717cabdff1aSopenharmony_ci    if (s->mb_intra) {
718cabdff1aSopenharmony_ci        s->current_picture.motion_val[0][xy][0] =
719cabdff1aSopenharmony_ci        s->current_picture.motion_val[0][xy][1] =
720cabdff1aSopenharmony_ci        s->current_picture.motion_val[1][xy][0] =
721cabdff1aSopenharmony_ci        s->current_picture.motion_val[1][xy][1] = 0;
722cabdff1aSopenharmony_ci        return;
723cabdff1aSopenharmony_ci    }
724cabdff1aSopenharmony_ci        if (direct && s->next_picture_ptr->field_picture)
725cabdff1aSopenharmony_ci            av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
726cabdff1aSopenharmony_ci
727cabdff1aSopenharmony_ci        s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
728cabdff1aSopenharmony_ci        s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
729cabdff1aSopenharmony_ci        s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
730cabdff1aSopenharmony_ci        s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
731cabdff1aSopenharmony_ci
732cabdff1aSopenharmony_ci        /* Pullback predicted motion vectors as specified in 8.4.5.4 */
733cabdff1aSopenharmony_ci        s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width  << 6) - 4 - (s->mb_x << 6));
734cabdff1aSopenharmony_ci        s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
735cabdff1aSopenharmony_ci        s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width  << 6) - 4 - (s->mb_x << 6));
736cabdff1aSopenharmony_ci        s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
737cabdff1aSopenharmony_ci    if (direct) {
738cabdff1aSopenharmony_ci        s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
739cabdff1aSopenharmony_ci        s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
740cabdff1aSopenharmony_ci        s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
741cabdff1aSopenharmony_ci        s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
742cabdff1aSopenharmony_ci        return;
743cabdff1aSopenharmony_ci    }
744cabdff1aSopenharmony_ci
745cabdff1aSopenharmony_ci    if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
746cabdff1aSopenharmony_ci        C   = s->current_picture.motion_val[0][xy - 2];
747cabdff1aSopenharmony_ci        A   = s->current_picture.motion_val[0][xy - wrap * 2];
748cabdff1aSopenharmony_ci        off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
749cabdff1aSopenharmony_ci        B   = s->current_picture.motion_val[0][xy - wrap * 2 + off];
750cabdff1aSopenharmony_ci
751cabdff1aSopenharmony_ci        if (!s->mb_x) C[0] = C[1] = 0;
752cabdff1aSopenharmony_ci        if (!s->first_slice_line) { // predictor A is not out of bounds
753cabdff1aSopenharmony_ci            if (s->mb_width == 1) {
754cabdff1aSopenharmony_ci                px = A[0];
755cabdff1aSopenharmony_ci                py = A[1];
756cabdff1aSopenharmony_ci            } else {
757cabdff1aSopenharmony_ci                px = mid_pred(A[0], B[0], C[0]);
758cabdff1aSopenharmony_ci                py = mid_pred(A[1], B[1], C[1]);
759cabdff1aSopenharmony_ci            }
760cabdff1aSopenharmony_ci        } else if (s->mb_x) { // predictor C is not out of bounds
761cabdff1aSopenharmony_ci            px = C[0];
762cabdff1aSopenharmony_ci            py = C[1];
763cabdff1aSopenharmony_ci        } else {
764cabdff1aSopenharmony_ci            px = py = 0;
765cabdff1aSopenharmony_ci        }
766cabdff1aSopenharmony_ci        /* Pullback MV as specified in 8.3.5.3.4 */
767cabdff1aSopenharmony_ci        {
768cabdff1aSopenharmony_ci            int qx, qy, X, Y;
769cabdff1aSopenharmony_ci            int sh = v->profile < PROFILE_ADVANCED ? 5 : 6;
770cabdff1aSopenharmony_ci            int MV = 4 - (1 << sh);
771cabdff1aSopenharmony_ci            qx = (s->mb_x << sh);
772cabdff1aSopenharmony_ci            qy = (s->mb_y << sh);
773cabdff1aSopenharmony_ci            X  = (s->mb_width  << sh) - 4;
774cabdff1aSopenharmony_ci            Y  = (s->mb_height << sh) - 4;
775cabdff1aSopenharmony_ci            if (qx + px < MV) px = MV - qx;
776cabdff1aSopenharmony_ci            if (qy + py < MV) py = MV - qy;
777cabdff1aSopenharmony_ci            if (qx + px > X) px = X - qx;
778cabdff1aSopenharmony_ci            if (qy + py > Y) py = Y - qy;
779cabdff1aSopenharmony_ci        }
780cabdff1aSopenharmony_ci        /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
781cabdff1aSopenharmony_ci        if (0 && !s->first_slice_line && s->mb_x) {
782cabdff1aSopenharmony_ci            if (is_intra[xy - wrap])
783cabdff1aSopenharmony_ci                sum = FFABS(px) + FFABS(py);
784cabdff1aSopenharmony_ci            else
785cabdff1aSopenharmony_ci                sum = FFABS(px - A[0]) + FFABS(py - A[1]);
786cabdff1aSopenharmony_ci            if (sum > 32) {
787cabdff1aSopenharmony_ci                if (get_bits1(&s->gb)) {
788cabdff1aSopenharmony_ci                    px = A[0];
789cabdff1aSopenharmony_ci                    py = A[1];
790cabdff1aSopenharmony_ci                } else {
791cabdff1aSopenharmony_ci                    px = C[0];
792cabdff1aSopenharmony_ci                    py = C[1];
793cabdff1aSopenharmony_ci                }
794cabdff1aSopenharmony_ci            } else {
795cabdff1aSopenharmony_ci                if (is_intra[xy - 2])
796cabdff1aSopenharmony_ci                    sum = FFABS(px) + FFABS(py);
797cabdff1aSopenharmony_ci                else
798cabdff1aSopenharmony_ci                    sum = FFABS(px - C[0]) + FFABS(py - C[1]);
799cabdff1aSopenharmony_ci                if (sum > 32) {
800cabdff1aSopenharmony_ci                    if (get_bits1(&s->gb)) {
801cabdff1aSopenharmony_ci                        px = A[0];
802cabdff1aSopenharmony_ci                        py = A[1];
803cabdff1aSopenharmony_ci                    } else {
804cabdff1aSopenharmony_ci                        px = C[0];
805cabdff1aSopenharmony_ci                        py = C[1];
806cabdff1aSopenharmony_ci                    }
807cabdff1aSopenharmony_ci                }
808cabdff1aSopenharmony_ci            }
809cabdff1aSopenharmony_ci        }
810cabdff1aSopenharmony_ci        /* store MV using signed modulus of MV range defined in 4.11 */
811cabdff1aSopenharmony_ci        s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x;
812cabdff1aSopenharmony_ci        s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
813cabdff1aSopenharmony_ci    }
814cabdff1aSopenharmony_ci    if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
815cabdff1aSopenharmony_ci        C   = s->current_picture.motion_val[1][xy - 2];
816cabdff1aSopenharmony_ci        A   = s->current_picture.motion_val[1][xy - wrap * 2];
817cabdff1aSopenharmony_ci        off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
818cabdff1aSopenharmony_ci        B   = s->current_picture.motion_val[1][xy - wrap * 2 + off];
819cabdff1aSopenharmony_ci
820cabdff1aSopenharmony_ci        if (!s->mb_x)
821cabdff1aSopenharmony_ci            C[0] = C[1] = 0;
822cabdff1aSopenharmony_ci        if (!s->first_slice_line) { // predictor A is not out of bounds
823cabdff1aSopenharmony_ci            if (s->mb_width == 1) {
824cabdff1aSopenharmony_ci                px = A[0];
825cabdff1aSopenharmony_ci                py = A[1];
826cabdff1aSopenharmony_ci            } else {
827cabdff1aSopenharmony_ci                px = mid_pred(A[0], B[0], C[0]);
828cabdff1aSopenharmony_ci                py = mid_pred(A[1], B[1], C[1]);
829cabdff1aSopenharmony_ci            }
830cabdff1aSopenharmony_ci        } else if (s->mb_x) { // predictor C is not out of bounds
831cabdff1aSopenharmony_ci            px = C[0];
832cabdff1aSopenharmony_ci            py = C[1];
833cabdff1aSopenharmony_ci        } else {
834cabdff1aSopenharmony_ci            px = py = 0;
835cabdff1aSopenharmony_ci        }
836cabdff1aSopenharmony_ci        /* Pullback MV as specified in 8.3.5.3.4 */
837cabdff1aSopenharmony_ci        {
838cabdff1aSopenharmony_ci            int qx, qy, X, Y;
839cabdff1aSopenharmony_ci            int sh = v->profile < PROFILE_ADVANCED ? 5 : 6;
840cabdff1aSopenharmony_ci            int MV = 4 - (1 << sh);
841cabdff1aSopenharmony_ci            qx = (s->mb_x << sh);
842cabdff1aSopenharmony_ci            qy = (s->mb_y << sh);
843cabdff1aSopenharmony_ci            X  = (s->mb_width  << sh) - 4;
844cabdff1aSopenharmony_ci            Y  = (s->mb_height << sh) - 4;
845cabdff1aSopenharmony_ci            if (qx + px < MV) px = MV - qx;
846cabdff1aSopenharmony_ci            if (qy + py < MV) py = MV - qy;
847cabdff1aSopenharmony_ci            if (qx + px > X) px = X - qx;
848cabdff1aSopenharmony_ci            if (qy + py > Y) py = Y - qy;
849cabdff1aSopenharmony_ci        }
850cabdff1aSopenharmony_ci        /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
851cabdff1aSopenharmony_ci        if (0 && !s->first_slice_line && s->mb_x) {
852cabdff1aSopenharmony_ci            if (is_intra[xy - wrap])
853cabdff1aSopenharmony_ci                sum = FFABS(px) + FFABS(py);
854cabdff1aSopenharmony_ci            else
855cabdff1aSopenharmony_ci                sum = FFABS(px - A[0]) + FFABS(py - A[1]);
856cabdff1aSopenharmony_ci            if (sum > 32) {
857cabdff1aSopenharmony_ci                if (get_bits1(&s->gb)) {
858cabdff1aSopenharmony_ci                    px = A[0];
859cabdff1aSopenharmony_ci                    py = A[1];
860cabdff1aSopenharmony_ci                } else {
861cabdff1aSopenharmony_ci                    px = C[0];
862cabdff1aSopenharmony_ci                    py = C[1];
863cabdff1aSopenharmony_ci                }
864cabdff1aSopenharmony_ci            } else {
865cabdff1aSopenharmony_ci                if (is_intra[xy - 2])
866cabdff1aSopenharmony_ci                    sum = FFABS(px) + FFABS(py);
867cabdff1aSopenharmony_ci                else
868cabdff1aSopenharmony_ci                    sum = FFABS(px - C[0]) + FFABS(py - C[1]);
869cabdff1aSopenharmony_ci                if (sum > 32) {
870cabdff1aSopenharmony_ci                    if (get_bits1(&s->gb)) {
871cabdff1aSopenharmony_ci                        px = A[0];
872cabdff1aSopenharmony_ci                        py = A[1];
873cabdff1aSopenharmony_ci                    } else {
874cabdff1aSopenharmony_ci                        px = C[0];
875cabdff1aSopenharmony_ci                        py = C[1];
876cabdff1aSopenharmony_ci                    }
877cabdff1aSopenharmony_ci                }
878cabdff1aSopenharmony_ci            }
879cabdff1aSopenharmony_ci        }
880cabdff1aSopenharmony_ci        /* store MV using signed modulus of MV range defined in 4.11 */
881cabdff1aSopenharmony_ci
882cabdff1aSopenharmony_ci        s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
883cabdff1aSopenharmony_ci        s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
884cabdff1aSopenharmony_ci    }
885cabdff1aSopenharmony_ci    s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
886cabdff1aSopenharmony_ci    s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
887cabdff1aSopenharmony_ci    s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
888cabdff1aSopenharmony_ci    s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
889cabdff1aSopenharmony_ci}
890cabdff1aSopenharmony_ci
891cabdff1aSopenharmony_civoid ff_vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y,
892cabdff1aSopenharmony_ci                            int mv1, int *pred_flag)
893cabdff1aSopenharmony_ci{
894cabdff1aSopenharmony_ci    int dir = (v->bmvtype == BMV_TYPE_BACKWARD) ? 1 : 0;
895cabdff1aSopenharmony_ci    MpegEncContext *s = &v->s;
896cabdff1aSopenharmony_ci    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
897cabdff1aSopenharmony_ci
898cabdff1aSopenharmony_ci    if (v->bmvtype == BMV_TYPE_DIRECT) {
899cabdff1aSopenharmony_ci        int total_opp, k, f;
900cabdff1aSopenharmony_ci        if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
901cabdff1aSopenharmony_ci            s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
902cabdff1aSopenharmony_ci                                      v->bfraction, 0, s->quarter_sample);
903cabdff1aSopenharmony_ci            s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
904cabdff1aSopenharmony_ci                                      v->bfraction, 0, s->quarter_sample);
905cabdff1aSopenharmony_ci            s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
906cabdff1aSopenharmony_ci                                      v->bfraction, 1, s->quarter_sample);
907cabdff1aSopenharmony_ci            s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
908cabdff1aSopenharmony_ci                                      v->bfraction, 1, s->quarter_sample);
909cabdff1aSopenharmony_ci
910cabdff1aSopenharmony_ci            total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off]
911cabdff1aSopenharmony_ci                      + v->mv_f_next[0][s->block_index[1] + v->blocks_off]
912cabdff1aSopenharmony_ci                      + v->mv_f_next[0][s->block_index[2] + v->blocks_off]
913cabdff1aSopenharmony_ci                      + v->mv_f_next[0][s->block_index[3] + v->blocks_off];
914cabdff1aSopenharmony_ci            f = (total_opp > 2) ? 1 : 0;
915cabdff1aSopenharmony_ci        } else {
916cabdff1aSopenharmony_ci            s->mv[0][0][0] = s->mv[0][0][1] = 0;
917cabdff1aSopenharmony_ci            s->mv[1][0][0] = s->mv[1][0][1] = 0;
918cabdff1aSopenharmony_ci            f = 0;
919cabdff1aSopenharmony_ci        }
920cabdff1aSopenharmony_ci        v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
921cabdff1aSopenharmony_ci        for (k = 0; k < 4; k++) {
922cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
923cabdff1aSopenharmony_ci            s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
924cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
925cabdff1aSopenharmony_ci            s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
926cabdff1aSopenharmony_ci            v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
927cabdff1aSopenharmony_ci            v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
928cabdff1aSopenharmony_ci        }
929cabdff1aSopenharmony_ci        return;
930cabdff1aSopenharmony_ci    }
931cabdff1aSopenharmony_ci    if (v->bmvtype == BMV_TYPE_INTERPOLATED) {
932cabdff1aSopenharmony_ci        ff_vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0],   1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
933cabdff1aSopenharmony_ci        ff_vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1],   1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
934cabdff1aSopenharmony_ci        return;
935cabdff1aSopenharmony_ci    }
936cabdff1aSopenharmony_ci    if (dir) { // backward
937cabdff1aSopenharmony_ci        ff_vc1_pred_mv(v, n, dmv_x[1], dmv_y[1], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[1], 1);
938cabdff1aSopenharmony_ci        if (n == 3 || mv1) {
939cabdff1aSopenharmony_ci            ff_vc1_pred_mv(v, 0, dmv_x[0], dmv_y[0],   1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
940cabdff1aSopenharmony_ci        }
941cabdff1aSopenharmony_ci    } else { // forward
942cabdff1aSopenharmony_ci        ff_vc1_pred_mv(v, n, dmv_x[0], dmv_y[0], mv1, v->range_x, v->range_y, v->mb_type[0], pred_flag[0], 0);
943cabdff1aSopenharmony_ci        if (n == 3 || mv1) {
944cabdff1aSopenharmony_ci            ff_vc1_pred_mv(v, 0, dmv_x[1], dmv_y[1],   1, v->range_x, v->range_y, v->mb_type[0], 0, 1);
945cabdff1aSopenharmony_ci        }
946cabdff1aSopenharmony_ci    }
947cabdff1aSopenharmony_ci}
948