2 * VC-1 and WMV3 decoder
3 * Copyright (c) 2011 Mashiat Sarker Shakkhar
4 * Copyright (c) 2006-2007 Konstantin Shishkov
5 * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
7 * This file is part of Libav.
9 * Libav is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * Libav is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with Libav; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 * VC-1 and WMV3 block decoding routines
30 #include "mpegutils.h"
31 #include "mpegvideo.h"
36 static av_always_inline
int scaleforsame_x(VC1Context
*v
, int n
/* MV */, int dir
)
38 int scaledvalue
, refdist
;
39 int scalesame1
, scalesame2
;
40 int scalezone1_x
, zone1offset_x
;
41 int table_index
= dir
^ v
->second_field
;
43 if (v
->s
.pict_type
!= AV_PICTURE_TYPE_B
)
46 refdist
= dir
? v
->brfd
: v
->frfd
;
49 scalesame1
= ff_vc1_field_mvpred_scales
[table_index
][1][refdist
];
50 scalesame2
= ff_vc1_field_mvpred_scales
[table_index
][2][refdist
];
51 scalezone1_x
= ff_vc1_field_mvpred_scales
[table_index
][3][refdist
];
52 zone1offset_x
= ff_vc1_field_mvpred_scales
[table_index
][5][refdist
];
57 if (FFABS(n
) < scalezone1_x
)
58 scaledvalue
= (n
* scalesame1
) >> 8;
61 scaledvalue
= ((n
* scalesame2
) >> 8) - zone1offset_x
;
63 scaledvalue
= ((n
* scalesame2
) >> 8) + zone1offset_x
;
66 return av_clip(scaledvalue
, -v
->range_x
, v
->range_x
- 1);
69 static av_always_inline
int scaleforsame_y(VC1Context
*v
, int i
, int n
/* MV */, int dir
)
71 int scaledvalue
, refdist
;
72 int scalesame1
, scalesame2
;
73 int scalezone1_y
, zone1offset_y
;
74 int table_index
= dir
^ v
->second_field
;
76 if (v
->s
.pict_type
!= AV_PICTURE_TYPE_B
)
79 refdist
= dir
? v
->brfd
: v
->frfd
;
82 scalesame1
= ff_vc1_field_mvpred_scales
[table_index
][1][refdist
];
83 scalesame2
= ff_vc1_field_mvpred_scales
[table_index
][2][refdist
];
84 scalezone1_y
= ff_vc1_field_mvpred_scales
[table_index
][4][refdist
];
85 zone1offset_y
= ff_vc1_field_mvpred_scales
[table_index
][6][refdist
];
90 if (FFABS(n
) < scalezone1_y
)
91 scaledvalue
= (n
* scalesame1
) >> 8;
94 scaledvalue
= ((n
* scalesame2
) >> 8) - zone1offset_y
;
96 scaledvalue
= ((n
* scalesame2
) >> 8) + zone1offset_y
;
100 if (v
->cur_field_type
&& !v
->ref_field_type
[dir
])
101 return av_clip(scaledvalue
, -v
->range_y
/ 2 + 1, v
->range_y
/ 2);
103 return av_clip(scaledvalue
, -v
->range_y
/ 2, v
->range_y
/ 2 - 1);
106 static av_always_inline
int scaleforopp_x(VC1Context
*v
, int n
/* MV */)
108 int scalezone1_x
, zone1offset_x
;
109 int scaleopp1
, scaleopp2
, brfd
;
112 brfd
= FFMIN(v
->brfd
, 3);
113 scalezone1_x
= ff_vc1_b_field_mvpred_scales
[3][brfd
];
114 zone1offset_x
= ff_vc1_b_field_mvpred_scales
[5][brfd
];
115 scaleopp1
= ff_vc1_b_field_mvpred_scales
[1][brfd
];
116 scaleopp2
= ff_vc1_b_field_mvpred_scales
[2][brfd
];
121 if (FFABS(n
) < scalezone1_x
)
122 scaledvalue
= (n
* scaleopp1
) >> 8;
125 scaledvalue
= ((n
* scaleopp2
) >> 8) - zone1offset_x
;
127 scaledvalue
= ((n
* scaleopp2
) >> 8) + zone1offset_x
;
130 return av_clip(scaledvalue
, -v
->range_x
, v
->range_x
- 1);
133 static av_always_inline
int scaleforopp_y(VC1Context
*v
, int n
/* MV */, int dir
)
135 int scalezone1_y
, zone1offset_y
;
136 int scaleopp1
, scaleopp2
, brfd
;
139 brfd
= FFMIN(v
->brfd
, 3);
140 scalezone1_y
= ff_vc1_b_field_mvpred_scales
[4][brfd
];
141 zone1offset_y
= ff_vc1_b_field_mvpred_scales
[6][brfd
];
142 scaleopp1
= ff_vc1_b_field_mvpred_scales
[1][brfd
];
143 scaleopp2
= ff_vc1_b_field_mvpred_scales
[2][brfd
];
148 if (FFABS(n
) < scalezone1_y
)
149 scaledvalue
= (n
* scaleopp1
) >> 8;
152 scaledvalue
= ((n
* scaleopp2
) >> 8) - zone1offset_y
;
154 scaledvalue
= ((n
* scaleopp2
) >> 8) + zone1offset_y
;
157 if (v
->cur_field_type
&& !v
->ref_field_type
[dir
]) {
158 return av_clip(scaledvalue
, -v
->range_y
/ 2 + 1, v
->range_y
/ 2);
160 return av_clip(scaledvalue
, -v
->range_y
/ 2, v
->range_y
/ 2 - 1);
164 static av_always_inline
int scaleforsame(VC1Context
*v
, int i
, int n
/* MV */,
168 int hpel
= 1 - v
->s
.quarter_sample
;
171 if (v
->s
.pict_type
!= AV_PICTURE_TYPE_B
|| v
->second_field
|| !dir
) {
173 n
= scaleforsame_y(v
, i
, n
, dir
) << hpel
;
175 n
= scaleforsame_x(v
, n
, dir
) << hpel
;
178 brfd
= FFMIN(v
->brfd
, 3);
179 scalesame
= ff_vc1_b_field_mvpred_scales
[0][brfd
];
181 n
= (n
* scalesame
>> 8) << hpel
;
185 static av_always_inline
int scaleforopp(VC1Context
*v
, int n
/* MV */,
188 int refdist
, scaleopp
;
189 int hpel
= 1 - v
->s
.quarter_sample
;
192 if (v
->s
.pict_type
== AV_PICTURE_TYPE_B
&& !v
->second_field
&& dir
== 1) {
194 n
= scaleforopp_y(v
, n
, dir
) << hpel
;
196 n
= scaleforopp_x(v
, n
) << hpel
;
199 if (v
->s
.pict_type
!= AV_PICTURE_TYPE_B
)
200 refdist
= FFMIN(v
->refdist
, 3);
202 refdist
= dir
? v
->brfd
: v
->frfd
;
203 scaleopp
= ff_vc1_field_mvpred_scales
[dir
^ v
->second_field
][0][refdist
];
205 n
= (n
* scaleopp
>> 8) << hpel
;
209 /** Predict and set motion vector
211 void ff_vc1_pred_mv(VC1Context
*v
, int n
, int dmv_x
, int dmv_y
,
212 int mv1
, int r_x
, int r_y
, uint8_t* is_intra
,
213 int pred_flag
, int dir
)
215 MpegEncContext
*s
= &v
->s
;
216 int xy
, wrap
, off
= 0;
220 int mixedmv_pic
, num_samefield
= 0, num_oppfield
= 0;
221 int opposite
, a_f
, b_f
, c_f
;
222 int16_t field_predA
[2];
223 int16_t field_predB
[2];
224 int16_t field_predC
[2];
225 int a_valid
, b_valid
, c_valid
;
226 int hybridmv_thresh
, y_bias
= 0;
228 if (v
->mv_mode
== MV_PMODE_MIXED_MV
||
229 ((v
->mv_mode
== MV_PMODE_INTENSITY_COMP
) && (v
->mv_mode2
== MV_PMODE_MIXED_MV
)))
233 /* scale MV difference to be quad-pel */
234 dmv_x
<<= 1 - s
->quarter_sample
;
235 dmv_y
<<= 1 - s
->quarter_sample
;
238 xy
= s
->block_index
[n
];
241 s
->mv
[0][n
][0] = s
->current_picture
.motion_val
[0][xy
+ v
->blocks_off
][0] = 0;
242 s
->mv
[0][n
][1] = s
->current_picture
.motion_val
[0][xy
+ v
->blocks_off
][1] = 0;
243 s
->current_picture
.motion_val
[1][xy
+ v
->blocks_off
][0] = 0;
244 s
->current_picture
.motion_val
[1][xy
+ v
->blocks_off
][1] = 0;
245 if (mv1
) { /* duplicate motion data for 1-MV block */
246 s
->current_picture
.motion_val
[0][xy
+ 1 + v
->blocks_off
][0] = 0;
247 s
->current_picture
.motion_val
[0][xy
+ 1 + v
->blocks_off
][1] = 0;
248 s
->current_picture
.motion_val
[0][xy
+ wrap
+ v
->blocks_off
][0] = 0;
249 s
->current_picture
.motion_val
[0][xy
+ wrap
+ v
->blocks_off
][1] = 0;
250 s
->current_picture
.motion_val
[0][xy
+ wrap
+ 1 + v
->blocks_off
][0] = 0;
251 s
->current_picture
.motion_val
[0][xy
+ wrap
+ 1 + v
->blocks_off
][1] = 0;
252 v
->luma_mv
[s
->mb_x
][0] = v
->luma_mv
[s
->mb_x
][1] = 0;
253 s
->current_picture
.motion_val
[1][xy
+ 1 + v
->blocks_off
][0] = 0;
254 s
->current_picture
.motion_val
[1][xy
+ 1 + v
->blocks_off
][1] = 0;
255 s
->current_picture
.motion_val
[1][xy
+ wrap
][0] = 0;
256 s
->current_picture
.motion_val
[1][xy
+ wrap
+ v
->blocks_off
][1] = 0;
257 s
->current_picture
.motion_val
[1][xy
+ wrap
+ 1 + v
->blocks_off
][0] = 0;
258 s
->current_picture
.motion_val
[1][xy
+ wrap
+ 1 + v
->blocks_off
][1] = 0;
263 C
= s
->current_picture
.motion_val
[dir
][xy
- 1 + v
->blocks_off
];
264 A
= s
->current_picture
.motion_val
[dir
][xy
- wrap
+ v
->blocks_off
];
266 if (v
->field_mode
&& mixedmv_pic
)
267 off
= (s
->mb_x
== (s
->mb_width
- 1)) ? -2 : 2;
269 off
= (s
->mb_x
== (s
->mb_width
- 1)) ? -1 : 2;
271 //in 4-MV mode different blocks have different B predictor position
274 off
= (s
->mb_x
> 0) ? -1 : 1;
277 off
= (s
->mb_x
== (s
->mb_width
- 1)) ? -1 : 1;
286 B
= s
->current_picture
.motion_val
[dir
][xy
- wrap
+ off
+ v
->blocks_off
];
288 a_valid
= !s
->first_slice_line
|| (n
== 2 || n
== 3);
289 b_valid
= a_valid
&& (s
->mb_width
> 1);
290 c_valid
= s
->mb_x
|| (n
== 1 || n
== 3);
292 a_valid
= a_valid
&& !is_intra
[xy
- wrap
];
293 b_valid
= b_valid
&& !is_intra
[xy
- wrap
+ off
];
294 c_valid
= c_valid
&& !is_intra
[xy
- 1];
298 a_f
= v
->mv_f
[dir
][xy
- wrap
+ v
->blocks_off
];
300 num_samefield
+= 1 - a_f
;
301 field_predA
[0] = A
[0];
302 field_predA
[1] = A
[1];
304 field_predA
[0] = field_predA
[1] = 0;
308 b_f
= v
->mv_f
[dir
][xy
- wrap
+ off
+ v
->blocks_off
];
310 num_samefield
+= 1 - b_f
;
311 field_predB
[0] = B
[0];
312 field_predB
[1] = B
[1];
314 field_predB
[0] = field_predB
[1] = 0;
318 c_f
= v
->mv_f
[dir
][xy
- 1 + v
->blocks_off
];
320 num_samefield
+= 1 - c_f
;
321 field_predC
[0] = C
[0];
322 field_predC
[1] = C
[1];
324 field_predC
[0] = field_predC
[1] = 0;
330 // REFFIELD determines if the last field or the second-last field is
331 // to be used as reference
332 opposite
= 1 - v
->reffield
;
334 if (num_samefield
<= num_oppfield
)
335 opposite
= 1 - pred_flag
;
337 opposite
= pred_flag
;
342 if (a_valid
&& !a_f
) {
343 field_predA
[0] = scaleforopp(v
, field_predA
[0], 0, dir
);
344 field_predA
[1] = scaleforopp(v
, field_predA
[1], 1, dir
);
346 if (b_valid
&& !b_f
) {
347 field_predB
[0] = scaleforopp(v
, field_predB
[0], 0, dir
);
348 field_predB
[1] = scaleforopp(v
, field_predB
[1], 1, dir
);
350 if (c_valid
&& !c_f
) {
351 field_predC
[0] = scaleforopp(v
, field_predC
[0], 0, dir
);
352 field_predC
[1] = scaleforopp(v
, field_predC
[1], 1, dir
);
354 v
->mv_f
[dir
][xy
+ v
->blocks_off
] = 1;
355 v
->ref_field_type
[dir
] = !v
->cur_field_type
;
357 if (a_valid
&& a_f
) {
358 field_predA
[0] = scaleforsame(v
, n
, field_predA
[0], 0, dir
);
359 field_predA
[1] = scaleforsame(v
, n
, field_predA
[1], 1, dir
);
361 if (b_valid
&& b_f
) {
362 field_predB
[0] = scaleforsame(v
, n
, field_predB
[0], 0, dir
);
363 field_predB
[1] = scaleforsame(v
, n
, field_predB
[1], 1, dir
);
365 if (c_valid
&& c_f
) {
366 field_predC
[0] = scaleforsame(v
, n
, field_predC
[0], 0, dir
);
367 field_predC
[1] = scaleforsame(v
, n
, field_predC
[1], 1, dir
);
369 v
->mv_f
[dir
][xy
+ v
->blocks_off
] = 0;
370 v
->ref_field_type
[dir
] = v
->cur_field_type
;
376 } else if (c_valid
) {
379 } else if (b_valid
) {
387 if (num_samefield
+ num_oppfield
> 1) {
388 px
= mid_pred(field_predA
[0], field_predB
[0], field_predC
[0]);
389 py
= mid_pred(field_predA
[1], field_predB
[1], field_predC
[1]);
392 /* Pullback MV as specified in 8.3.5.3.4 */
393 if (!v
->field_mode
) {
395 qx
= (s
->mb_x
<< 6) + ((n
== 1 || n
== 3) ? 32 : 0);
396 qy
= (s
->mb_y
<< 6) + ((n
== 2 || n
== 3) ? 32 : 0);
397 X
= (s
->mb_width
<< 6) - 4;
398 Y
= (s
->mb_height
<< 6) - 4;
400 if (qx
+ px
< -60) px
= -60 - qx
;
401 if (qy
+ py
< -60) py
= -60 - qy
;
403 if (qx
+ px
< -28) px
= -28 - qx
;
404 if (qy
+ py
< -28) py
= -28 - qy
;
406 if (qx
+ px
> X
) px
= X
- qx
;
407 if (qy
+ py
> Y
) py
= Y
- qy
;
410 if (!v
->field_mode
|| s
->pict_type
!= AV_PICTURE_TYPE_B
) {
411 /* Calculate hybrid prediction as specified in 8.3.5.3.5 (also 10.3.5.4.3.5) */
412 hybridmv_thresh
= 32;
413 if (a_valid
&& c_valid
) {
414 if (is_intra
[xy
- wrap
])
415 sum
= FFABS(px
) + FFABS(py
);
417 sum
= FFABS(px
- field_predA
[0]) + FFABS(py
- field_predA
[1]);
418 if (sum
> hybridmv_thresh
) {
419 if (get_bits1(&s
->gb
)) { // read HYBRIDPRED bit
427 if (is_intra
[xy
- 1])
428 sum
= FFABS(px
) + FFABS(py
);
430 sum
= FFABS(px
- field_predC
[0]) + FFABS(py
- field_predC
[1]);
431 if (sum
> hybridmv_thresh
) {
432 if (get_bits1(&s
->gb
)) {
444 if (v
->field_mode
&& v
->numref
)
446 if (v
->field_mode
&& v
->cur_field_type
&& v
->ref_field_type
[dir
] == 0)
448 /* store MV using signed modulus of MV range defined in 4.11 */
449 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
;
450 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
;
451 if (mv1
) { /* duplicate motion data for 1-MV block */
452 s
->current_picture
.motion_val
[dir
][xy
+ 1 + v
->blocks_off
][0] = s
->current_picture
.motion_val
[dir
][xy
+ v
->blocks_off
][0];
453 s
->current_picture
.motion_val
[dir
][xy
+ 1 + v
->blocks_off
][1] = s
->current_picture
.motion_val
[dir
][xy
+ v
->blocks_off
][1];
454 s
->current_picture
.motion_val
[dir
][xy
+ wrap
+ v
->blocks_off
][0] = s
->current_picture
.motion_val
[dir
][xy
+ v
->blocks_off
][0];
455 s
->current_picture
.motion_val
[dir
][xy
+ wrap
+ v
->blocks_off
][1] = s
->current_picture
.motion_val
[dir
][xy
+ v
->blocks_off
][1];
456 s
->current_picture
.motion_val
[dir
][xy
+ wrap
+ 1 + v
->blocks_off
][0] = s
->current_picture
.motion_val
[dir
][xy
+ v
->blocks_off
][0];
457 s
->current_picture
.motion_val
[dir
][xy
+ wrap
+ 1 + v
->blocks_off
][1] = s
->current_picture
.motion_val
[dir
][xy
+ v
->blocks_off
][1];
458 v
->mv_f
[dir
][xy
+ 1 + v
->blocks_off
] = v
->mv_f
[dir
][xy
+ v
->blocks_off
];
459 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
];
463 /** Predict and set motion vector for interlaced frame picture MBs
465 void ff_vc1_pred_mv_intfr(VC1Context
*v
, int n
, int dmv_x
, int dmv_y
,
466 int mvn
, int r_x
, int r_y
, uint8_t* is_intra
, int dir
)
468 MpegEncContext
*s
= &v
->s
;
469 int xy
, wrap
, off
= 0;
470 int A
[2], B
[2], C
[2];
472 int a_valid
= 0, b_valid
= 0, c_valid
= 0;
473 int field_a
, field_b
, field_c
; // 0: same, 1: opposite
474 int total_valid
, num_samefield
, num_oppfield
;
475 int pos_c
, pos_b
, n_adj
;
478 xy
= s
->block_index
[n
];
481 s
->mv
[0][n
][0] = s
->current_picture
.motion_val
[0][xy
][0] = 0;
482 s
->mv
[0][n
][1] = s
->current_picture
.motion_val
[0][xy
][1] = 0;
483 s
->current_picture
.motion_val
[1][xy
][0] = 0;
484 s
->current_picture
.motion_val
[1][xy
][1] = 0;
485 if (mvn
== 1) { /* duplicate motion data for 1-MV block */
486 s
->current_picture
.motion_val
[0][xy
+ 1][0] = 0;
487 s
->current_picture
.motion_val
[0][xy
+ 1][1] = 0;
488 s
->current_picture
.motion_val
[0][xy
+ wrap
][0] = 0;
489 s
->current_picture
.motion_val
[0][xy
+ wrap
][1] = 0;
490 s
->current_picture
.motion_val
[0][xy
+ wrap
+ 1][0] = 0;
491 s
->current_picture
.motion_val
[0][xy
+ wrap
+ 1][1] = 0;
492 v
->luma_mv
[s
->mb_x
][0] = v
->luma_mv
[s
->mb_x
][1] = 0;
493 s
->current_picture
.motion_val
[1][xy
+ 1][0] = 0;
494 s
->current_picture
.motion_val
[1][xy
+ 1][1] = 0;
495 s
->current_picture
.motion_val
[1][xy
+ wrap
][0] = 0;
496 s
->current_picture
.motion_val
[1][xy
+ wrap
][1] = 0;
497 s
->current_picture
.motion_val
[1][xy
+ wrap
+ 1][0] = 0;
498 s
->current_picture
.motion_val
[1][xy
+ wrap
+ 1][1] = 0;
503 off
= ((n
== 0) || (n
== 1)) ? 1 : -1;
505 if (s
->mb_x
|| (n
== 1) || (n
== 3)) {
506 if ((v
->blk_mv_type
[xy
]) // current block (MB) has a field MV
507 || (!v
->blk_mv_type
[xy
] && !v
->blk_mv_type
[xy
- 1])) { // or both have frame MV
508 A
[0] = s
->current_picture
.motion_val
[dir
][xy
- 1][0];
509 A
[1] = s
->current_picture
.motion_val
[dir
][xy
- 1][1];
511 } else { // current block has frame mv and cand. has field MV (so average)
512 A
[0] = (s
->current_picture
.motion_val
[dir
][xy
- 1][0]
513 + s
->current_picture
.motion_val
[dir
][xy
- 1 + off
* wrap
][0] + 1) >> 1;
514 A
[1] = (s
->current_picture
.motion_val
[dir
][xy
- 1][1]
515 + s
->current_picture
.motion_val
[dir
][xy
- 1 + off
* wrap
][1] + 1) >> 1;
518 if (!(n
& 1) && v
->is_intra
[s
->mb_x
- 1]) {
524 /* Predict B and C */
525 B
[0] = B
[1] = C
[0] = C
[1] = 0;
526 if (n
== 0 || n
== 1 || v
->blk_mv_type
[xy
]) {
527 if (!s
->first_slice_line
) {
528 if (!v
->is_intra
[s
->mb_x
- s
->mb_stride
]) {
531 pos_b
= s
->block_index
[n_adj
] - 2 * wrap
;
532 if (v
->blk_mv_type
[pos_b
] && v
->blk_mv_type
[xy
]) {
533 n_adj
= (n
& 2) | (n
& 1);
535 B
[0] = s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
] - 2 * wrap
][0];
536 B
[1] = s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
] - 2 * wrap
][1];
537 if (v
->blk_mv_type
[pos_b
] && !v
->blk_mv_type
[xy
]) {
538 B
[0] = (B
[0] + s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
^ 2] - 2 * wrap
][0] + 1) >> 1;
539 B
[1] = (B
[1] + s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
^ 2] - 2 * wrap
][1] + 1) >> 1;
542 if (s
->mb_width
> 1) {
543 if (!v
->is_intra
[s
->mb_x
- s
->mb_stride
+ 1]) {
546 pos_c
= s
->block_index
[2] - 2 * wrap
+ 2;
547 if (v
->blk_mv_type
[pos_c
] && v
->blk_mv_type
[xy
]) {
550 C
[0] = s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
] - 2 * wrap
+ 2][0];
551 C
[1] = s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
] - 2 * wrap
+ 2][1];
552 if (v
->blk_mv_type
[pos_c
] && !v
->blk_mv_type
[xy
]) {
553 C
[0] = (1 + C
[0] + (s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
^ 2] - 2 * wrap
+ 2][0])) >> 1;
554 C
[1] = (1 + C
[1] + (s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
^ 2] - 2 * wrap
+ 2][1])) >> 1;
556 if (s
->mb_x
== s
->mb_width
- 1) {
557 if (!v
->is_intra
[s
->mb_x
- s
->mb_stride
- 1]) {
560 pos_c
= s
->block_index
[3] - 2 * wrap
- 2;
561 if (v
->blk_mv_type
[pos_c
] && v
->blk_mv_type
[xy
]) {
564 C
[0] = s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
] - 2 * wrap
- 2][0];
565 C
[1] = s
->current_picture
.motion_val
[dir
][s
->block_index
[n_adj
] - 2 * wrap
- 2][1];
566 if (v
->blk_mv_type
[pos_c
] && !v
->blk_mv_type
[xy
]) {
567 C
[0] = (1 + C
[0] + s
->current_picture
.motion_val
[dir
][s
->block_index
[1] - 2 * wrap
- 2][0]) >> 1;
568 C
[1] = (1 + C
[1] + s
->current_picture
.motion_val
[dir
][s
->block_index
[1] - 2 * wrap
- 2][1]) >> 1;
577 pos_b
= s
->block_index
[1];
579 B
[0] = s
->current_picture
.motion_val
[dir
][pos_b
][0];
580 B
[1] = s
->current_picture
.motion_val
[dir
][pos_b
][1];
581 pos_c
= s
->block_index
[0];
583 C
[0] = s
->current_picture
.motion_val
[dir
][pos_c
][0];
584 C
[1] = s
->current_picture
.motion_val
[dir
][pos_c
][1];
587 total_valid
= a_valid
+ b_valid
+ c_valid
;
588 // check if predictor A is out of bounds
589 if (!s
->mb_x
&& !(n
== 1 || n
== 3)) {
592 // check if predictor B is out of bounds
593 if ((s
->first_slice_line
&& v
->blk_mv_type
[xy
]) || (s
->first_slice_line
&& !(n
& 2))) {
594 B
[0] = B
[1] = C
[0] = C
[1] = 0;
596 if (!v
->blk_mv_type
[xy
]) {
597 if (s
->mb_width
== 1) {
601 if (total_valid
>= 2) {
602 px
= mid_pred(A
[0], B
[0], C
[0]);
603 py
= mid_pred(A
[1], B
[1], C
[1]);
604 } else if (total_valid
) {
605 if (a_valid
) { px
= A
[0]; py
= A
[1]; }
606 if (b_valid
) { px
= B
[0]; py
= B
[1]; }
607 if (c_valid
) { px
= C
[0]; py
= C
[1]; }
612 field_a
= (A
[1] & 4) ? 1 : 0;
616 field_b
= (B
[1] & 4) ? 1 : 0;
620 field_c
= (C
[1] & 4) ? 1 : 0;
624 num_oppfield
= field_a
+ field_b
+ field_c
;
625 num_samefield
= total_valid
- num_oppfield
;
626 if (total_valid
== 3) {
627 if ((num_samefield
== 3) || (num_oppfield
== 3)) {
628 px
= mid_pred(A
[0], B
[0], C
[0]);
629 py
= mid_pred(A
[1], B
[1], C
[1]);
630 } else if (num_samefield
>= num_oppfield
) {
631 /* take one MV from same field set depending on priority
632 the check for B may not be necessary */
633 px
= !field_a
? A
[0] : B
[0];
634 py
= !field_a
? A
[1] : B
[1];
636 px
= field_a
? A
[0] : B
[0];
637 py
= field_a
? A
[1] : B
[1];
639 } else if (total_valid
== 2) {
640 if (num_samefield
>= num_oppfield
) {
641 if (!field_a
&& a_valid
) {
644 } else if (!field_b
&& b_valid
) {
647 } else if (c_valid
) {
652 if (field_a
&& a_valid
) {
655 } else if (field_b
&& b_valid
) {
660 } else if (total_valid
== 1) {
661 px
= (a_valid
) ? A
[0] : ((b_valid
) ? B
[0] : C
[0]);
662 py
= (a_valid
) ? A
[1] : ((b_valid
) ? B
[1] : C
[1]);
666 /* store MV using signed modulus of MV range defined in 4.11 */
667 s
->mv
[dir
][n
][0] = s
->current_picture
.motion_val
[dir
][xy
][0] = ((px
+ dmv_x
+ r_x
) & ((r_x
<< 1) - 1)) - r_x
;
668 s
->mv
[dir
][n
][1] = s
->current_picture
.motion_val
[dir
][xy
][1] = ((py
+ dmv_y
+ r_y
) & ((r_y
<< 1) - 1)) - r_y
;
669 if (mvn
== 1) { /* duplicate motion data for 1-MV block */
670 s
->current_picture
.motion_val
[dir
][xy
+ 1 ][0] = s
->current_picture
.motion_val
[dir
][xy
][0];
671 s
->current_picture
.motion_val
[dir
][xy
+ 1 ][1] = s
->current_picture
.motion_val
[dir
][xy
][1];
672 s
->current_picture
.motion_val
[dir
][xy
+ wrap
][0] = s
->current_picture
.motion_val
[dir
][xy
][0];
673 s
->current_picture
.motion_val
[dir
][xy
+ wrap
][1] = s
->current_picture
.motion_val
[dir
][xy
][1];
674 s
->current_picture
.motion_val
[dir
][xy
+ wrap
+ 1][0] = s
->current_picture
.motion_val
[dir
][xy
][0];
675 s
->current_picture
.motion_val
[dir
][xy
+ wrap
+ 1][1] = s
->current_picture
.motion_val
[dir
][xy
][1];
676 } else if (mvn
== 2) { /* duplicate motion data for 2-Field MV block */
677 s
->current_picture
.motion_val
[dir
][xy
+ 1][0] = s
->current_picture
.motion_val
[dir
][xy
][0];
678 s
->current_picture
.motion_val
[dir
][xy
+ 1][1] = s
->current_picture
.motion_val
[dir
][xy
][1];
679 s
->mv
[dir
][n
+ 1][0] = s
->mv
[dir
][n
][0];
680 s
->mv
[dir
][n
+ 1][1] = s
->mv
[dir
][n
][1];
684 void ff_vc1_pred_b_mv(VC1Context
*v
, int dmv_x
[2], int dmv_y
[2],
685 int direct
, int mvtype
)
687 MpegEncContext
*s
= &v
->s
;
688 int xy
, wrap
, off
= 0;
693 const uint8_t *is_intra
= v
->mb_type
[0];
697 /* scale MV difference to be quad-pel */
698 dmv_x
[0] <<= 1 - s
->quarter_sample
;
699 dmv_y
[0] <<= 1 - s
->quarter_sample
;
700 dmv_x
[1] <<= 1 - s
->quarter_sample
;
701 dmv_y
[1] <<= 1 - s
->quarter_sample
;
704 xy
= s
->block_index
[0];
707 s
->current_picture
.motion_val
[0][xy
+ v
->blocks_off
][0] =
708 s
->current_picture
.motion_val
[0][xy
+ v
->blocks_off
][1] =
709 s
->current_picture
.motion_val
[1][xy
+ v
->blocks_off
][0] =
710 s
->current_picture
.motion_val
[1][xy
+ v
->blocks_off
][1] = 0;
713 if (!v
->field_mode
) {
714 s
->mv
[0][0][0] = scale_mv(s
->next_picture
.motion_val
[1][xy
][0], v
->bfraction
, 0, s
->quarter_sample
);
715 s
->mv
[0][0][1] = scale_mv(s
->next_picture
.motion_val
[1][xy
][1], v
->bfraction
, 0, s
->quarter_sample
);
716 s
->mv
[1][0][0] = scale_mv(s
->next_picture
.motion_val
[1][xy
][0], v
->bfraction
, 1, s
->quarter_sample
);
717 s
->mv
[1][0][1] = scale_mv(s
->next_picture
.motion_val
[1][xy
][1], v
->bfraction
, 1, s
->quarter_sample
);
719 /* Pullback predicted motion vectors as specified in 8.4.5.4 */
720 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));
721 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));
722 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));
723 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));
726 s
->current_picture
.motion_val
[0][xy
+ v
->blocks_off
][0] = s
->mv
[0][0][0];
727 s
->current_picture
.motion_val
[0][xy
+ v
->blocks_off
][1] = s
->mv
[0][0][1];
728 s
->current_picture
.motion_val
[1][xy
+ v
->blocks_off
][0] = s
->mv
[1][0][0];
729 s
->current_picture
.motion_val
[1][xy
+ v
->blocks_off
][1] = s
->mv
[1][0][1];
733 if ((mvtype
== BMV_TYPE_FORWARD
) || (mvtype
== BMV_TYPE_INTERPOLATED
)) {
734 C
= s
->current_picture
.motion_val
[0][xy
- 2];
735 A
= s
->current_picture
.motion_val
[0][xy
- wrap
* 2];
736 off
= (s
->mb_x
== (s
->mb_width
- 1)) ? -2 : 2;
737 B
= s
->current_picture
.motion_val
[0][xy
- wrap
* 2 + off
];
739 if (!s
->mb_x
) C
[0] = C
[1] = 0;
740 if (!s
->first_slice_line
) { // predictor A is not out of bounds
741 if (s
->mb_width
== 1) {
745 px
= mid_pred(A
[0], B
[0], C
[0]);
746 py
= mid_pred(A
[1], B
[1], C
[1]);
748 } else if (s
->mb_x
) { // predictor C is not out of bounds
754 /* Pullback MV as specified in 8.3.5.3.4 */
757 if (v
->profile
< PROFILE_ADVANCED
) {
760 X
= (s
->mb_width
<< 5) - 4;
761 Y
= (s
->mb_height
<< 5) - 4;
762 if (qx
+ px
< -28) px
= -28 - qx
;
763 if (qy
+ py
< -28) py
= -28 - qy
;
764 if (qx
+ px
> X
) px
= X
- qx
;
765 if (qy
+ py
> Y
) py
= Y
- qy
;
769 X
= (s
->mb_width
<< 6) - 4;
770 Y
= (s
->mb_height
<< 6) - 4;
771 if (qx
+ px
< -60) px
= -60 - qx
;
772 if (qy
+ py
< -60) py
= -60 - qy
;
773 if (qx
+ px
> X
) px
= X
- qx
;
774 if (qy
+ py
> Y
) py
= Y
- qy
;
777 /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
778 if (0 && !s
->first_slice_line
&& s
->mb_x
) {
779 if (is_intra
[xy
- wrap
])
780 sum
= FFABS(px
) + FFABS(py
);
782 sum
= FFABS(px
- A
[0]) + FFABS(py
- A
[1]);
784 if (get_bits1(&s
->gb
)) {
792 if (is_intra
[xy
- 2])
793 sum
= FFABS(px
) + FFABS(py
);
795 sum
= FFABS(px
- C
[0]) + FFABS(py
- C
[1]);
797 if (get_bits1(&s
->gb
)) {
807 /* store MV using signed modulus of MV range defined in 4.11 */
808 s
->mv
[0][0][0] = ((px
+ dmv_x
[0] + r_x
) & ((r_x
<< 1) - 1)) - r_x
;
809 s
->mv
[0][0][1] = ((py
+ dmv_y
[0] + r_y
) & ((r_y
<< 1) - 1)) - r_y
;
811 if ((mvtype
== BMV_TYPE_BACKWARD
) || (mvtype
== BMV_TYPE_INTERPOLATED
)) {
812 C
= s
->current_picture
.motion_val
[1][xy
- 2];
813 A
= s
->current_picture
.motion_val
[1][xy
- wrap
* 2];
814 off
= (s
->mb_x
== (s
->mb_width
- 1)) ? -2 : 2;
815 B
= s
->current_picture
.motion_val
[1][xy
- wrap
* 2 + off
];
819 if (!s
->first_slice_line
) { // predictor A is not out of bounds
820 if (s
->mb_width
== 1) {
824 px
= mid_pred(A
[0], B
[0], C
[0]);
825 py
= mid_pred(A
[1], B
[1], C
[1]);
827 } else if (s
->mb_x
) { // predictor C is not out of bounds
833 /* Pullback MV as specified in 8.3.5.3.4 */
836 if (v
->profile
< PROFILE_ADVANCED
) {
839 X
= (s
->mb_width
<< 5) - 4;
840 Y
= (s
->mb_height
<< 5) - 4;
841 if (qx
+ px
< -28) px
= -28 - qx
;
842 if (qy
+ py
< -28) py
= -28 - qy
;
843 if (qx
+ px
> X
) px
= X
- qx
;
844 if (qy
+ py
> Y
) py
= Y
- qy
;
848 X
= (s
->mb_width
<< 6) - 4;
849 Y
= (s
->mb_height
<< 6) - 4;
850 if (qx
+ px
< -60) px
= -60 - qx
;
851 if (qy
+ py
< -60) py
= -60 - qy
;
852 if (qx
+ px
> X
) px
= X
- qx
;
853 if (qy
+ py
> Y
) py
= Y
- qy
;
856 /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
857 if (0 && !s
->first_slice_line
&& s
->mb_x
) {
858 if (is_intra
[xy
- wrap
])
859 sum
= FFABS(px
) + FFABS(py
);
861 sum
= FFABS(px
- A
[0]) + FFABS(py
- A
[1]);
863 if (get_bits1(&s
->gb
)) {
871 if (is_intra
[xy
- 2])
872 sum
= FFABS(px
) + FFABS(py
);
874 sum
= FFABS(px
- C
[0]) + FFABS(py
- C
[1]);
876 if (get_bits1(&s
->gb
)) {
886 /* store MV using signed modulus of MV range defined in 4.11 */
888 s
->mv
[1][0][0] = ((px
+ dmv_x
[1] + r_x
) & ((r_x
<< 1) - 1)) - r_x
;
889 s
->mv
[1][0][1] = ((py
+ dmv_y
[1] + r_y
) & ((r_y
<< 1) - 1)) - r_y
;
891 s
->current_picture
.motion_val
[0][xy
][0] = s
->mv
[0][0][0];
892 s
->current_picture
.motion_val
[0][xy
][1] = s
->mv
[0][0][1];
893 s
->current_picture
.motion_val
[1][xy
][0] = s
->mv
[1][0][0];
894 s
->current_picture
.motion_val
[1][xy
][1] = s
->mv
[1][0][1];
897 void ff_vc1_pred_b_mv_intfi(VC1Context
*v
, int n
, int *dmv_x
, int *dmv_y
,
898 int mv1
, int *pred_flag
)
900 int dir
= (v
->bmvtype
== BMV_TYPE_BACKWARD
) ? 1 : 0;
901 MpegEncContext
*s
= &v
->s
;
902 int mb_pos
= s
->mb_x
+ s
->mb_y
* s
->mb_stride
;
904 if (v
->bmvtype
== BMV_TYPE_DIRECT
) {
906 if (s
->next_picture
.mb_type
[mb_pos
+ v
->mb_off
] != MB_TYPE_INTRA
) {
907 s
->mv
[0][0][0] = scale_mv(s
->next_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][0],
908 v
->bfraction
, 0, s
->quarter_sample
);
909 s
->mv
[0][0][1] = scale_mv(s
->next_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][1],
910 v
->bfraction
, 0, s
->quarter_sample
);
911 s
->mv
[1][0][0] = scale_mv(s
->next_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][0],
912 v
->bfraction
, 1, s
->quarter_sample
);
913 s
->mv
[1][0][1] = scale_mv(s
->next_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][1],
914 v
->bfraction
, 1, s
->quarter_sample
);
916 total_opp
= v
->mv_f_next
[0][s
->block_index
[0] + v
->blocks_off
]
917 + v
->mv_f_next
[0][s
->block_index
[1] + v
->blocks_off
]
918 + v
->mv_f_next
[0][s
->block_index
[2] + v
->blocks_off
]
919 + v
->mv_f_next
[0][s
->block_index
[3] + v
->blocks_off
];
920 f
= (total_opp
> 2) ? 1 : 0;
922 s
->mv
[0][0][0] = s
->mv
[0][0][1] = 0;
923 s
->mv
[1][0][0] = s
->mv
[1][0][1] = 0;
926 v
->ref_field_type
[0] = v
->ref_field_type
[1] = v
->cur_field_type
^ f
;
927 for (k
= 0; k
< 4; k
++) {
928 s
->current_picture
.motion_val
[0][s
->block_index
[k
] + v
->blocks_off
][0] = s
->mv
[0][0][0];
929 s
->current_picture
.motion_val
[0][s
->block_index
[k
] + v
->blocks_off
][1] = s
->mv
[0][0][1];
930 s
->current_picture
.motion_val
[1][s
->block_index
[k
] + v
->blocks_off
][0] = s
->mv
[1][0][0];
931 s
->current_picture
.motion_val
[1][s
->block_index
[k
] + v
->blocks_off
][1] = s
->mv
[1][0][1];
932 v
->mv_f
[0][s
->block_index
[k
] + v
->blocks_off
] = f
;
933 v
->mv_f
[1][s
->block_index
[k
] + v
->blocks_off
] = f
;
937 if (v
->bmvtype
== BMV_TYPE_INTERPOLATED
) {
938 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);
939 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);
942 if (dir
) { // backward
943 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);
945 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);
948 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);
950 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);