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