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 "h264chroma.h"
32 #include "mpegvideo.h"
35 /** Do motion compensation over 1 macroblock
36 * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
38 void ff_vc1_mc_1mv(VC1Context
*v
, int dir
)
40 MpegEncContext
*s
= &v
->s
;
41 H264ChromaContext
*h264chroma
= &v
->h264chroma
;
42 uint8_t *srcY
, *srcU
, *srcV
;
43 int dxy
, mx
, my
, uvmx
, uvmy
, src_x
, src_y
, uvsrc_x
, uvsrc_y
;
44 int v_edge_pos
= s
->v_edge_pos
>> v
->field_mode
;
46 uint8_t (*luty
)[256], (*lutuv
)[256];
49 if ((!v
->field_mode
||
50 (v
->ref_field_type
[dir
] == 1 && v
->cur_field_type
== 1)) &&
51 !v
->s
.last_picture
.f
->data
[0])
54 mx
= s
->mv
[dir
][0][0];
55 my
= s
->mv
[dir
][0][1];
57 // store motion vectors for further use in B-frames
58 if (s
->pict_type
== AV_PICTURE_TYPE_P
) {
59 for (i
= 0; i
< 4; i
++) {
60 s
->current_picture
.motion_val
[1][s
->block_index
[i
] + v
->blocks_off
][0] = mx
;
61 s
->current_picture
.motion_val
[1][s
->block_index
[i
] + v
->blocks_off
][1] = my
;
65 uvmx
= (mx
+ ((mx
& 3) == 3)) >> 1;
66 uvmy
= (my
+ ((my
& 3) == 3)) >> 1;
67 v
->luma_mv
[s
->mb_x
][0] = uvmx
;
68 v
->luma_mv
[s
->mb_x
][1] = uvmy
;
71 v
->cur_field_type
!= v
->ref_field_type
[dir
]) {
72 my
= my
- 2 + 4 * v
->cur_field_type
;
73 uvmy
= uvmy
- 2 + 4 * v
->cur_field_type
;
76 // fastuvmc shall be ignored for interlaced frame picture
77 if (v
->fastuvmc
&& (v
->fcm
!= ILACE_FRAME
)) {
78 uvmx
= uvmx
+ ((uvmx
< 0) ? (uvmx
& 1) : -(uvmx
& 1));
79 uvmy
= uvmy
+ ((uvmy
< 0) ? (uvmy
& 1) : -(uvmy
& 1));
82 if (v
->field_mode
&& (v
->cur_field_type
!= v
->ref_field_type
[dir
]) && v
->second_field
) {
83 srcY
= s
->current_picture
.f
->data
[0];
84 srcU
= s
->current_picture
.f
->data
[1];
85 srcV
= s
->current_picture
.f
->data
[2];
87 lutuv
= v
->curr_lutuv
;
88 use_ic
= v
->curr_use_ic
;
90 srcY
= s
->last_picture
.f
->data
[0];
91 srcU
= s
->last_picture
.f
->data
[1];
92 srcV
= s
->last_picture
.f
->data
[2];
94 lutuv
= v
->last_lutuv
;
95 use_ic
= v
->last_use_ic
;
98 srcY
= s
->next_picture
.f
->data
[0];
99 srcU
= s
->next_picture
.f
->data
[1];
100 srcV
= s
->next_picture
.f
->data
[2];
102 lutuv
= v
->next_lutuv
;
103 use_ic
= v
->next_use_ic
;
106 if (!srcY
|| !srcU
) {
107 av_log(v
->s
.avctx
, AV_LOG_ERROR
, "Referenced frame missing.\n");
111 src_x
= s
->mb_x
* 16 + (mx
>> 2);
112 src_y
= s
->mb_y
* 16 + (my
>> 2);
113 uvsrc_x
= s
->mb_x
* 8 + (uvmx
>> 2);
114 uvsrc_y
= s
->mb_y
* 8 + (uvmy
>> 2);
116 if (v
->profile
!= PROFILE_ADVANCED
) {
117 src_x
= av_clip( src_x
, -16, s
->mb_width
* 16);
118 src_y
= av_clip( src_y
, -16, s
->mb_height
* 16);
119 uvsrc_x
= av_clip(uvsrc_x
, -8, s
->mb_width
* 8);
120 uvsrc_y
= av_clip(uvsrc_y
, -8, s
->mb_height
* 8);
122 src_x
= av_clip( src_x
, -17, s
->avctx
->coded_width
);
123 src_y
= av_clip( src_y
, -18, s
->avctx
->coded_height
+ 1);
124 uvsrc_x
= av_clip(uvsrc_x
, -8, s
->avctx
->coded_width
>> 1);
125 uvsrc_y
= av_clip(uvsrc_y
, -8, s
->avctx
->coded_height
>> 1);
128 srcY
+= src_y
* s
->linesize
+ src_x
;
129 srcU
+= uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
130 srcV
+= uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
132 if (v
->field_mode
&& v
->ref_field_type
[dir
]) {
133 srcY
+= s
->current_picture_ptr
->f
->linesize
[0];
134 srcU
+= s
->current_picture_ptr
->f
->linesize
[1];
135 srcV
+= s
->current_picture_ptr
->f
->linesize
[2];
138 /* for grayscale we should not try to read from unknown area */
139 if (s
->avctx
->flags
& AV_CODEC_FLAG_GRAY
) {
140 srcU
= s
->sc
.edge_emu_buffer
+ 18 * s
->linesize
;
141 srcV
= s
->sc
.edge_emu_buffer
+ 18 * s
->linesize
;
144 if (v
->rangeredfrm
|| use_ic
145 || s
->h_edge_pos
< 22 || v_edge_pos
< 22
146 || (unsigned)(src_x
- s
->mspel
) > s
->h_edge_pos
- (mx
&3) - 16 - s
->mspel
* 3
147 || (unsigned)(src_y
- 1) > v_edge_pos
- (my
&3) - 16 - 3) {
148 uint8_t *uvbuf
= s
->sc
.edge_emu_buffer
+ 19 * s
->linesize
;
150 srcY
-= s
->mspel
* (1 + s
->linesize
);
151 s
->vdsp
.emulated_edge_mc(s
->sc
.edge_emu_buffer
, srcY
,
152 s
->linesize
, s
->linesize
,
153 17 + s
->mspel
* 2, 17 + s
->mspel
* 2,
154 src_x
- s
->mspel
, src_y
- s
->mspel
,
155 s
->h_edge_pos
, v_edge_pos
);
156 srcY
= s
->sc
.edge_emu_buffer
;
157 s
->vdsp
.emulated_edge_mc(uvbuf
, srcU
,
158 s
->uvlinesize
, s
->uvlinesize
,
160 uvsrc_x
, uvsrc_y
, s
->h_edge_pos
>> 1, v_edge_pos
>> 1);
161 s
->vdsp
.emulated_edge_mc(uvbuf
+ 16, srcV
,
162 s
->uvlinesize
, s
->uvlinesize
,
164 uvsrc_x
, uvsrc_y
, s
->h_edge_pos
>> 1, v_edge_pos
>> 1);
167 /* if we deal with range reduction we need to scale source blocks */
168 if (v
->rangeredfrm
) {
173 for (j
= 0; j
< 17 + s
->mspel
* 2; j
++) {
174 for (i
= 0; i
< 17 + s
->mspel
* 2; i
++)
175 src
[i
] = ((src
[i
] - 128) >> 1) + 128;
180 for (j
= 0; j
< 9; j
++) {
181 for (i
= 0; i
< 9; i
++) {
182 src
[i
] = ((src
[i
] - 128) >> 1) + 128;
183 src2
[i
] = ((src2
[i
] - 128) >> 1) + 128;
185 src
+= s
->uvlinesize
;
186 src2
+= s
->uvlinesize
;
189 /* if we deal with intensity compensation we need to scale source blocks */
195 for (j
= 0; j
< 17 + s
->mspel
* 2; j
++) {
196 int f
= v
->field_mode
? v
->ref_field_type
[dir
] : ((j
+ src_y
- s
->mspel
) & 1) ;
197 for (i
= 0; i
< 17 + s
->mspel
* 2; i
++)
198 src
[i
] = luty
[f
][src
[i
]];
203 for (j
= 0; j
< 9; j
++) {
204 int f
= v
->field_mode
? v
->ref_field_type
[dir
] : ((j
+ uvsrc_y
) & 1);
205 for (i
= 0; i
< 9; i
++) {
206 src
[i
] = lutuv
[f
][src
[i
]];
207 src2
[i
] = lutuv
[f
][src2
[i
]];
209 src
+= s
->uvlinesize
;
210 src2
+= s
->uvlinesize
;
213 srcY
+= s
->mspel
* (1 + s
->linesize
);
217 dxy
= ((my
& 3) << 2) | (mx
& 3);
218 v
->vc1dsp
.put_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] , srcY
, s
->linesize
, v
->rnd
);
219 v
->vc1dsp
.put_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + 8, srcY
+ 8, s
->linesize
, v
->rnd
);
220 srcY
+= s
->linesize
* 8;
221 v
->vc1dsp
.put_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + 8 * s
->linesize
, srcY
, s
->linesize
, v
->rnd
);
222 v
->vc1dsp
.put_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + 8 * s
->linesize
+ 8, srcY
+ 8, s
->linesize
, v
->rnd
);
223 } else { // hpel mc - always used for luma
224 dxy
= (my
& 2) | ((mx
& 2) >> 1);
226 s
->hdsp
.put_pixels_tab
[0][dxy
](s
->dest
[0], srcY
, s
->linesize
, 16);
228 s
->hdsp
.put_no_rnd_pixels_tab
[0][dxy
](s
->dest
[0], srcY
, s
->linesize
, 16);
231 if (s
->avctx
->flags
& AV_CODEC_FLAG_GRAY
)
233 /* Chroma MC always uses qpel bilinear */
234 uvmx
= (uvmx
& 3) << 1;
235 uvmy
= (uvmy
& 3) << 1;
237 h264chroma
->put_h264_chroma_pixels_tab
[0](s
->dest
[1], srcU
, s
->uvlinesize
, 8, uvmx
, uvmy
);
238 h264chroma
->put_h264_chroma_pixels_tab
[0](s
->dest
[2], srcV
, s
->uvlinesize
, 8, uvmx
, uvmy
);
240 v
->vc1dsp
.put_no_rnd_vc1_chroma_pixels_tab
[0](s
->dest
[1], srcU
, s
->uvlinesize
, 8, uvmx
, uvmy
);
241 v
->vc1dsp
.put_no_rnd_vc1_chroma_pixels_tab
[0](s
->dest
[2], srcV
, s
->uvlinesize
, 8, uvmx
, uvmy
);
245 static inline int median4(int a
, int b
, int c
, int d
)
248 if (c
< d
) return (FFMIN(b
, d
) + FFMAX(a
, c
)) / 2;
249 else return (FFMIN(b
, c
) + FFMAX(a
, d
)) / 2;
251 if (c
< d
) return (FFMIN(a
, d
) + FFMAX(b
, c
)) / 2;
252 else return (FFMIN(a
, c
) + FFMAX(b
, d
)) / 2;
256 /** Do motion compensation for 4-MV macroblock - luminance block
258 void ff_vc1_mc_4mv_luma(VC1Context
*v
, int n
, int dir
, int avg
)
260 MpegEncContext
*s
= &v
->s
;
262 int dxy
, mx
, my
, src_x
, src_y
;
264 int fieldmv
= (v
->fcm
== ILACE_FRAME
) ? v
->blk_mv_type
[s
->block_index
[n
]] : 0;
265 int v_edge_pos
= s
->v_edge_pos
>> v
->field_mode
;
266 uint8_t (*luty
)[256];
269 if ((!v
->field_mode
||
270 (v
->ref_field_type
[dir
] == 1 && v
->cur_field_type
== 1)) &&
271 !v
->s
.last_picture
.f
->data
[0])
274 mx
= s
->mv
[dir
][n
][0];
275 my
= s
->mv
[dir
][n
][1];
278 if (v
->field_mode
&& (v
->cur_field_type
!= v
->ref_field_type
[dir
]) && v
->second_field
) {
279 srcY
= s
->current_picture
.f
->data
[0];
281 use_ic
= v
->curr_use_ic
;
283 srcY
= s
->last_picture
.f
->data
[0];
285 use_ic
= v
->last_use_ic
;
288 srcY
= s
->next_picture
.f
->data
[0];
290 use_ic
= v
->next_use_ic
;
294 av_log(v
->s
.avctx
, AV_LOG_ERROR
, "Referenced frame missing.\n");
299 if (v
->cur_field_type
!= v
->ref_field_type
[dir
])
300 my
= my
- 2 + 4 * v
->cur_field_type
;
303 if (s
->pict_type
== AV_PICTURE_TYPE_P
&& n
== 3 && v
->field_mode
) {
304 int same_count
= 0, opp_count
= 0, k
;
305 int chosen_mv
[2][4][2], f
;
307 for (k
= 0; k
< 4; k
++) {
308 f
= v
->mv_f
[0][s
->block_index
[k
] + v
->blocks_off
];
309 chosen_mv
[f
][f
? opp_count
: same_count
][0] = s
->mv
[0][k
][0];
310 chosen_mv
[f
][f
? opp_count
: same_count
][1] = s
->mv
[0][k
][1];
314 f
= opp_count
> same_count
;
315 switch (f
? opp_count
: same_count
) {
317 tx
= median4(chosen_mv
[f
][0][0], chosen_mv
[f
][1][0],
318 chosen_mv
[f
][2][0], chosen_mv
[f
][3][0]);
319 ty
= median4(chosen_mv
[f
][0][1], chosen_mv
[f
][1][1],
320 chosen_mv
[f
][2][1], chosen_mv
[f
][3][1]);
323 tx
= mid_pred(chosen_mv
[f
][0][0], chosen_mv
[f
][1][0], chosen_mv
[f
][2][0]);
324 ty
= mid_pred(chosen_mv
[f
][0][1], chosen_mv
[f
][1][1], chosen_mv
[f
][2][1]);
327 tx
= (chosen_mv
[f
][0][0] + chosen_mv
[f
][1][0]) / 2;
328 ty
= (chosen_mv
[f
][0][1] + chosen_mv
[f
][1][1]) / 2;
331 s
->current_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][0] = tx
;
332 s
->current_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][1] = ty
;
333 for (k
= 0; k
< 4; k
++)
334 v
->mv_f
[1][s
->block_index
[k
] + v
->blocks_off
] = f
;
337 if (v
->fcm
== ILACE_FRAME
) { // not sure if needed for other types of picture
339 int width
= s
->avctx
->coded_width
;
340 int height
= s
->avctx
->coded_height
>> 1;
341 if (s
->pict_type
== AV_PICTURE_TYPE_P
) {
342 s
->current_picture
.motion_val
[1][s
->block_index
[n
] + v
->blocks_off
][0] = mx
;
343 s
->current_picture
.motion_val
[1][s
->block_index
[n
] + v
->blocks_off
][1] = my
;
345 qx
= (s
->mb_x
* 16) + (mx
>> 2);
346 qy
= (s
->mb_y
* 8) + (my
>> 3);
351 mx
-= 4 * (qx
- width
);
354 else if (qy
> height
+ 1)
355 my
-= 8 * (qy
- height
- 1);
358 if ((v
->fcm
== ILACE_FRAME
) && fieldmv
)
359 off
= ((n
> 1) ? s
->linesize
: 0) + (n
& 1) * 8;
361 off
= s
->linesize
* 4 * (n
& 2) + (n
& 1) * 8;
363 src_x
= s
->mb_x
* 16 + (n
& 1) * 8 + (mx
>> 2);
365 src_y
= s
->mb_y
* 16 + (n
& 2) * 4 + (my
>> 2);
367 src_y
= s
->mb_y
* 16 + ((n
> 1) ? 1 : 0) + (my
>> 2);
369 if (v
->profile
!= PROFILE_ADVANCED
) {
370 src_x
= av_clip(src_x
, -16, s
->mb_width
* 16);
371 src_y
= av_clip(src_y
, -16, s
->mb_height
* 16);
373 src_x
= av_clip(src_x
, -17, s
->avctx
->coded_width
);
374 if (v
->fcm
== ILACE_FRAME
) {
376 src_y
= av_clip(src_y
, -17, s
->avctx
->coded_height
+ 1);
378 src_y
= av_clip(src_y
, -18, s
->avctx
->coded_height
);
380 src_y
= av_clip(src_y
, -18, s
->avctx
->coded_height
+ 1);
384 srcY
+= src_y
* s
->linesize
+ src_x
;
385 if (v
->field_mode
&& v
->ref_field_type
[dir
])
386 srcY
+= s
->current_picture_ptr
->f
->linesize
[0];
388 if (fieldmv
&& !(src_y
& 1))
390 if (fieldmv
&& (src_y
& 1) && src_y
< 4)
392 if (v
->rangeredfrm
|| use_ic
393 || s
->h_edge_pos
< 13 || v_edge_pos
< 23
394 || (unsigned)(src_x
- s
->mspel
) > s
->h_edge_pos
- (mx
& 3) - 8 - s
->mspel
* 2
395 || (unsigned)(src_y
- (s
->mspel
<< fieldmv
)) > v_edge_pos
- (my
& 3) - ((8 + s
->mspel
* 2) << fieldmv
)) {
396 srcY
-= s
->mspel
* (1 + (s
->linesize
<< fieldmv
));
397 /* check emulate edge stride and offset */
398 s
->vdsp
.emulated_edge_mc(s
->sc
.edge_emu_buffer
, srcY
,
399 s
->linesize
, s
->linesize
,
400 9 + s
->mspel
* 2, (9 + s
->mspel
* 2) << fieldmv
,
401 src_x
- s
->mspel
, src_y
- (s
->mspel
<< fieldmv
),
402 s
->h_edge_pos
, v_edge_pos
);
403 srcY
= s
->sc
.edge_emu_buffer
;
404 /* if we deal with range reduction we need to scale source blocks */
405 if (v
->rangeredfrm
) {
410 for (j
= 0; j
< 9 + s
->mspel
* 2; j
++) {
411 for (i
= 0; i
< 9 + s
->mspel
* 2; i
++)
412 src
[i
] = ((src
[i
] - 128) >> 1) + 128;
413 src
+= s
->linesize
<< fieldmv
;
416 /* if we deal with intensity compensation we need to scale source blocks */
422 for (j
= 0; j
< 9 + s
->mspel
* 2; j
++) {
423 int f
= v
->field_mode
? v
->ref_field_type
[dir
] : (((j
<<fieldmv
)+src_y
- (s
->mspel
<< fieldmv
)) & 1);
424 for (i
= 0; i
< 9 + s
->mspel
* 2; i
++)
425 src
[i
] = luty
[f
][src
[i
]];
426 src
+= s
->linesize
<< fieldmv
;
429 srcY
+= s
->mspel
* (1 + (s
->linesize
<< fieldmv
));
433 dxy
= ((my
& 3) << 2) | (mx
& 3);
435 v
->vc1dsp
.avg_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + off
, srcY
, s
->linesize
<< fieldmv
, v
->rnd
);
437 v
->vc1dsp
.put_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + off
, srcY
, s
->linesize
<< fieldmv
, v
->rnd
);
438 } else { // hpel mc - always used for luma
439 dxy
= (my
& 2) | ((mx
& 2) >> 1);
441 s
->hdsp
.put_pixels_tab
[1][dxy
](s
->dest
[0] + off
, srcY
, s
->linesize
, 8);
443 s
->hdsp
.put_no_rnd_pixels_tab
[1][dxy
](s
->dest
[0] + off
, srcY
, s
->linesize
, 8);
447 static av_always_inline
int get_chroma_mv(int *mvx
, int *mvy
, int *a
, int flag
, int *tx
, int *ty
)
450 static const int count
[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
452 idx
= ((a
[3] != flag
) << 3)
453 | ((a
[2] != flag
) << 2)
454 | ((a
[1] != flag
) << 1)
457 *tx
= median4(mvx
[0], mvx
[1], mvx
[2], mvx
[3]);
458 *ty
= median4(mvy
[0], mvy
[1], mvy
[2], mvy
[3]);
460 } else if (count
[idx
] == 1) {
463 *tx
= mid_pred(mvx
[1], mvx
[2], mvx
[3]);
464 *ty
= mid_pred(mvy
[1], mvy
[2], mvy
[3]);
467 *tx
= mid_pred(mvx
[0], mvx
[2], mvx
[3]);
468 *ty
= mid_pred(mvy
[0], mvy
[2], mvy
[3]);
471 *tx
= mid_pred(mvx
[0], mvx
[1], mvx
[3]);
472 *ty
= mid_pred(mvy
[0], mvy
[1], mvy
[3]);
475 *tx
= mid_pred(mvx
[0], mvx
[1], mvx
[2]);
476 *ty
= mid_pred(mvy
[0], mvy
[1], mvy
[2]);
479 } else if (count
[idx
] == 2) {
481 for (i
= 0; i
< 3; i
++)
486 for (i
= t1
+ 1; i
< 4; i
++)
491 *tx
= (mvx
[t1
] + mvx
[t2
]) / 2;
492 *ty
= (mvy
[t1
] + mvy
[t2
]) / 2;
500 /** Do motion compensation for 4-MV macroblock - both chroma blocks
502 void ff_vc1_mc_4mv_chroma(VC1Context
*v
, int dir
)
504 MpegEncContext
*s
= &v
->s
;
505 H264ChromaContext
*h264chroma
= &v
->h264chroma
;
506 uint8_t *srcU
, *srcV
;
507 int uvmx
, uvmy
, uvsrc_x
, uvsrc_y
;
508 int k
, tx
= 0, ty
= 0;
509 int mvx
[4], mvy
[4], intra
[4], mv_f
[4];
511 int chroma_ref_type
= v
->cur_field_type
;
512 int v_edge_pos
= s
->v_edge_pos
>> v
->field_mode
;
513 uint8_t (*lutuv
)[256];
516 if (!v
->field_mode
&& !v
->s
.last_picture
.f
->data
[0])
518 if (s
->avctx
->flags
& AV_CODEC_FLAG_GRAY
)
521 for (k
= 0; k
< 4; k
++) {
522 mvx
[k
] = s
->mv
[dir
][k
][0];
523 mvy
[k
] = s
->mv
[dir
][k
][1];
524 intra
[k
] = v
->mb_type
[0][s
->block_index
[k
]];
526 mv_f
[k
] = v
->mv_f
[dir
][s
->block_index
[k
] + v
->blocks_off
];
529 /* calculate chroma MV vector from four luma MVs */
530 if (!v
->field_mode
|| (v
->field_mode
&& !v
->numref
)) {
531 valid_count
= get_chroma_mv(mvx
, mvy
, intra
, 0, &tx
, &ty
);
532 chroma_ref_type
= v
->reffield
;
534 s
->current_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][0] = 0;
535 s
->current_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][1] = 0;
536 v
->luma_mv
[s
->mb_x
][0] = v
->luma_mv
[s
->mb_x
][1] = 0;
537 return; //no need to do MC for intra blocks
541 if (mv_f
[0] + mv_f
[1] + mv_f
[2] + mv_f
[3] > 2)
543 valid_count
= get_chroma_mv(mvx
, mvy
, mv_f
, dominant
, &tx
, &ty
);
545 chroma_ref_type
= !v
->cur_field_type
;
547 if (v
->field_mode
&& chroma_ref_type
== 1 && v
->cur_field_type
== 1 && !v
->s
.last_picture
.f
->data
[0])
549 s
->current_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][0] = tx
;
550 s
->current_picture
.motion_val
[1][s
->block_index
[0] + v
->blocks_off
][1] = ty
;
551 uvmx
= (tx
+ ((tx
& 3) == 3)) >> 1;
552 uvmy
= (ty
+ ((ty
& 3) == 3)) >> 1;
554 v
->luma_mv
[s
->mb_x
][0] = uvmx
;
555 v
->luma_mv
[s
->mb_x
][1] = uvmy
;
558 uvmx
= uvmx
+ ((uvmx
< 0) ? (uvmx
& 1) : -(uvmx
& 1));
559 uvmy
= uvmy
+ ((uvmy
< 0) ? (uvmy
& 1) : -(uvmy
& 1));
561 // Field conversion bias
562 if (v
->cur_field_type
!= chroma_ref_type
)
563 uvmy
+= 2 - 4 * chroma_ref_type
;
565 uvsrc_x
= s
->mb_x
* 8 + (uvmx
>> 2);
566 uvsrc_y
= s
->mb_y
* 8 + (uvmy
>> 2);
568 if (v
->profile
!= PROFILE_ADVANCED
) {
569 uvsrc_x
= av_clip(uvsrc_x
, -8, s
->mb_width
* 8);
570 uvsrc_y
= av_clip(uvsrc_y
, -8, s
->mb_height
* 8);
572 uvsrc_x
= av_clip(uvsrc_x
, -8, s
->avctx
->coded_width
>> 1);
573 uvsrc_y
= av_clip(uvsrc_y
, -8, s
->avctx
->coded_height
>> 1);
577 if (v
->field_mode
&& (v
->cur_field_type
!= chroma_ref_type
) && v
->second_field
) {
578 srcU
= s
->current_picture
.f
->data
[1];
579 srcV
= s
->current_picture
.f
->data
[2];
580 lutuv
= v
->curr_lutuv
;
581 use_ic
= v
->curr_use_ic
;
583 srcU
= s
->last_picture
.f
->data
[1];
584 srcV
= s
->last_picture
.f
->data
[2];
585 lutuv
= v
->last_lutuv
;
586 use_ic
= v
->last_use_ic
;
589 srcU
= s
->next_picture
.f
->data
[1];
590 srcV
= s
->next_picture
.f
->data
[2];
591 lutuv
= v
->next_lutuv
;
592 use_ic
= v
->next_use_ic
;
596 av_log(v
->s
.avctx
, AV_LOG_ERROR
, "Referenced frame missing.\n");
600 srcU
+= uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
601 srcV
+= uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
604 if (chroma_ref_type
) {
605 srcU
+= s
->current_picture_ptr
->f
->linesize
[1];
606 srcV
+= s
->current_picture_ptr
->f
->linesize
[2];
610 if (v
->rangeredfrm
|| use_ic
611 || s
->h_edge_pos
< 18 || v_edge_pos
< 18
612 || (unsigned)uvsrc_x
> (s
->h_edge_pos
>> 1) - 9
613 || (unsigned)uvsrc_y
> (v_edge_pos
>> 1) - 9) {
614 s
->vdsp
.emulated_edge_mc(s
->sc
.edge_emu_buffer
, srcU
,
615 s
->uvlinesize
, s
->uvlinesize
,
616 8 + 1, 8 + 1, uvsrc_x
, uvsrc_y
,
617 s
->h_edge_pos
>> 1, v_edge_pos
>> 1);
618 s
->vdsp
.emulated_edge_mc(s
->sc
.edge_emu_buffer
+ 16, srcV
,
619 s
->uvlinesize
, s
->uvlinesize
,
620 8 + 1, 8 + 1, uvsrc_x
, uvsrc_y
,
621 s
->h_edge_pos
>> 1, v_edge_pos
>> 1);
622 srcU
= s
->sc
.edge_emu_buffer
;
623 srcV
= s
->sc
.edge_emu_buffer
+ 16;
625 /* if we deal with range reduction we need to scale source blocks */
626 if (v
->rangeredfrm
) {
632 for (j
= 0; j
< 9; j
++) {
633 for (i
= 0; i
< 9; i
++) {
634 src
[i
] = ((src
[i
] - 128) >> 1) + 128;
635 src2
[i
] = ((src2
[i
] - 128) >> 1) + 128;
637 src
+= s
->uvlinesize
;
638 src2
+= s
->uvlinesize
;
641 /* if we deal with intensity compensation we need to scale source blocks */
648 for (j
= 0; j
< 9; j
++) {
649 int f
= v
->field_mode
? chroma_ref_type
: ((j
+ uvsrc_y
) & 1);
650 for (i
= 0; i
< 9; i
++) {
651 src
[i
] = lutuv
[f
][src
[i
]];
652 src2
[i
] = lutuv
[f
][src2
[i
]];
654 src
+= s
->uvlinesize
;
655 src2
+= s
->uvlinesize
;
660 /* Chroma MC always uses qpel bilinear */
661 uvmx
= (uvmx
& 3) << 1;
662 uvmy
= (uvmy
& 3) << 1;
664 h264chroma
->put_h264_chroma_pixels_tab
[0](s
->dest
[1], srcU
, s
->uvlinesize
, 8, uvmx
, uvmy
);
665 h264chroma
->put_h264_chroma_pixels_tab
[0](s
->dest
[2], srcV
, s
->uvlinesize
, 8, uvmx
, uvmy
);
667 v
->vc1dsp
.put_no_rnd_vc1_chroma_pixels_tab
[0](s
->dest
[1], srcU
, s
->uvlinesize
, 8, uvmx
, uvmy
);
668 v
->vc1dsp
.put_no_rnd_vc1_chroma_pixels_tab
[0](s
->dest
[2], srcV
, s
->uvlinesize
, 8, uvmx
, uvmy
);
672 /** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
674 void ff_vc1_mc_4mv_chroma4(VC1Context
*v
, int dir
, int dir2
, int avg
)
676 MpegEncContext
*s
= &v
->s
;
677 H264ChromaContext
*h264chroma
= &v
->h264chroma
;
678 uint8_t *srcU
, *srcV
;
679 int uvsrc_x
, uvsrc_y
;
680 int uvmx_field
[4], uvmy_field
[4];
682 int fieldmv
= v
->blk_mv_type
[s
->block_index
[0]];
683 static const int s_rndtblfield
[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
684 int v_dist
= fieldmv
? 1 : 4; // vertical offset for lower sub-blocks
685 int v_edge_pos
= s
->v_edge_pos
>> 1;
687 uint8_t (*lutuv
)[256];
689 if (s
->avctx
->flags
& AV_CODEC_FLAG_GRAY
)
692 if (!s
->last_picture
.f
->data
[1]) {
693 av_log(s
->avctx
, AV_LOG_ERROR
, "Bad data in last picture frame.\n");
697 for (i
= 0; i
< 4; i
++) {
698 int d
= i
< 2 ? dir
: dir2
;
700 uvmx_field
[i
] = (tx
+ ((tx
& 3) == 3)) >> 1;
703 uvmy_field
[i
] = (ty
>> 4) * 8 + s_rndtblfield
[ty
& 0xF];
705 uvmy_field
[i
] = (ty
+ ((ty
& 3) == 3)) >> 1;
708 for (i
= 0; i
< 4; i
++) {
709 off
= (i
& 1) * 4 + ((i
& 2) ? v_dist
* s
->uvlinesize
: 0);
710 uvsrc_x
= s
->mb_x
* 8 + (i
& 1) * 4 + (uvmx_field
[i
] >> 2);
711 uvsrc_y
= s
->mb_y
* 8 + ((i
& 2) ? v_dist
: 0) + (uvmy_field
[i
] >> 2);
712 // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
713 uvsrc_x
= av_clip(uvsrc_x
, -8, s
->avctx
->coded_width
>> 1);
714 uvsrc_y
= av_clip(uvsrc_y
, -8, s
->avctx
->coded_height
>> 1);
715 if (i
< 2 ? dir
: dir2
) {
716 srcU
= s
->next_picture
.f
->data
[1] + uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
717 srcV
= s
->next_picture
.f
->data
[2] + uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
718 lutuv
= v
->next_lutuv
;
719 use_ic
= v
->next_use_ic
;
721 srcU
= s
->last_picture
.f
->data
[1] + uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
722 srcV
= s
->last_picture
.f
->data
[2] + uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
723 lutuv
= v
->last_lutuv
;
724 use_ic
= v
->last_use_ic
;
726 uvmx_field
[i
] = (uvmx_field
[i
] & 3) << 1;
727 uvmy_field
[i
] = (uvmy_field
[i
] & 3) << 1;
729 if (fieldmv
&& !(uvsrc_y
& 1))
731 if (fieldmv
&& (uvsrc_y
& 1) && uvsrc_y
< 2)
734 || s
->h_edge_pos
< 10 || v_edge_pos
< (5 << fieldmv
)
735 || (unsigned)uvsrc_x
> (s
->h_edge_pos
>> 1) - 5
736 || (unsigned)uvsrc_y
> v_edge_pos
- (5 << fieldmv
)) {
737 s
->vdsp
.emulated_edge_mc(s
->sc
.edge_emu_buffer
, srcU
,
738 s
->uvlinesize
, s
->uvlinesize
,
739 5, (5 << fieldmv
), uvsrc_x
, uvsrc_y
,
740 s
->h_edge_pos
>> 1, v_edge_pos
);
741 s
->vdsp
.emulated_edge_mc(s
->sc
.edge_emu_buffer
+ 16, srcV
,
742 s
->uvlinesize
, s
->uvlinesize
,
743 5, (5 << fieldmv
), uvsrc_x
, uvsrc_y
,
744 s
->h_edge_pos
>> 1, v_edge_pos
);
745 srcU
= s
->sc
.edge_emu_buffer
;
746 srcV
= s
->sc
.edge_emu_buffer
+ 16;
748 /* if we deal with intensity compensation we need to scale source blocks */
755 for (j
= 0; j
< 5; j
++) {
756 int f
= (uvsrc_y
+ (j
<< fieldmv
)) & 1;
757 for (i
= 0; i
< 5; i
++) {
758 src
[i
] = lutuv
[f
][src
[i
]];
759 src2
[i
] = lutuv
[f
][src2
[i
]];
761 src
+= s
->uvlinesize
<< fieldmv
;
762 src2
+= s
->uvlinesize
<< fieldmv
;
768 h264chroma
->avg_h264_chroma_pixels_tab
[1](s
->dest
[1] + off
, srcU
, s
->uvlinesize
<< fieldmv
, 4, uvmx_field
[i
], uvmy_field
[i
]);
769 h264chroma
->avg_h264_chroma_pixels_tab
[1](s
->dest
[2] + off
, srcV
, s
->uvlinesize
<< fieldmv
, 4, uvmx_field
[i
], uvmy_field
[i
]);
771 v
->vc1dsp
.avg_no_rnd_vc1_chroma_pixels_tab
[1](s
->dest
[1] + off
, srcU
, s
->uvlinesize
<< fieldmv
, 4, uvmx_field
[i
], uvmy_field
[i
]);
772 v
->vc1dsp
.avg_no_rnd_vc1_chroma_pixels_tab
[1](s
->dest
[2] + off
, srcV
, s
->uvlinesize
<< fieldmv
, 4, uvmx_field
[i
], uvmy_field
[i
]);
776 h264chroma
->put_h264_chroma_pixels_tab
[1](s
->dest
[1] + off
, srcU
, s
->uvlinesize
<< fieldmv
, 4, uvmx_field
[i
], uvmy_field
[i
]);
777 h264chroma
->put_h264_chroma_pixels_tab
[1](s
->dest
[2] + off
, srcV
, s
->uvlinesize
<< fieldmv
, 4, uvmx_field
[i
], uvmy_field
[i
]);
779 v
->vc1dsp
.put_no_rnd_vc1_chroma_pixels_tab
[1](s
->dest
[1] + off
, srcU
, s
->uvlinesize
<< fieldmv
, 4, uvmx_field
[i
], uvmy_field
[i
]);
780 v
->vc1dsp
.put_no_rnd_vc1_chroma_pixels_tab
[1](s
->dest
[2] + off
, srcV
, s
->uvlinesize
<< fieldmv
, 4, uvmx_field
[i
], uvmy_field
[i
]);
786 /** Motion compensation for direct or interpolated blocks in B-frames
788 void ff_vc1_interp_mc(VC1Context
*v
)
790 MpegEncContext
*s
= &v
->s
;
791 H264ChromaContext
*h264chroma
= &v
->h264chroma
;
792 uint8_t *srcY
, *srcU
, *srcV
;
793 int dxy
, mx
, my
, uvmx
, uvmy
, src_x
, src_y
, uvsrc_x
, uvsrc_y
;
795 int v_edge_pos
= s
->v_edge_pos
>> v
->field_mode
;
796 int use_ic
= v
->next_use_ic
;
798 if (!v
->field_mode
&& !v
->s
.next_picture
.f
->data
[0])
803 uvmx
= (mx
+ ((mx
& 3) == 3)) >> 1;
804 uvmy
= (my
+ ((my
& 3) == 3)) >> 1;
805 if (v
->field_mode
&& v
->cur_field_type
!= v
->ref_field_type
[1]) {
806 my
= my
- 2 + 4 * v
->cur_field_type
;
807 uvmy
= uvmy
- 2 + 4 * v
->cur_field_type
;
810 uvmx
= uvmx
+ ((uvmx
< 0) ? -(uvmx
& 1) : (uvmx
& 1));
811 uvmy
= uvmy
+ ((uvmy
< 0) ? -(uvmy
& 1) : (uvmy
& 1));
813 srcY
= s
->next_picture
.f
->data
[0];
814 srcU
= s
->next_picture
.f
->data
[1];
815 srcV
= s
->next_picture
.f
->data
[2];
817 src_x
= s
->mb_x
* 16 + (mx
>> 2);
818 src_y
= s
->mb_y
* 16 + (my
>> 2);
819 uvsrc_x
= s
->mb_x
* 8 + (uvmx
>> 2);
820 uvsrc_y
= s
->mb_y
* 8 + (uvmy
>> 2);
822 if (v
->profile
!= PROFILE_ADVANCED
) {
823 src_x
= av_clip( src_x
, -16, s
->mb_width
* 16);
824 src_y
= av_clip( src_y
, -16, s
->mb_height
* 16);
825 uvsrc_x
= av_clip(uvsrc_x
, -8, s
->mb_width
* 8);
826 uvsrc_y
= av_clip(uvsrc_y
, -8, s
->mb_height
* 8);
828 src_x
= av_clip( src_x
, -17, s
->avctx
->coded_width
);
829 src_y
= av_clip( src_y
, -18, s
->avctx
->coded_height
+ 1);
830 uvsrc_x
= av_clip(uvsrc_x
, -8, s
->avctx
->coded_width
>> 1);
831 uvsrc_y
= av_clip(uvsrc_y
, -8, s
->avctx
->coded_height
>> 1);
834 srcY
+= src_y
* s
->linesize
+ src_x
;
835 srcU
+= uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
836 srcV
+= uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
838 if (v
->field_mode
&& v
->ref_field_type
[1]) {
839 srcY
+= s
->current_picture_ptr
->f
->linesize
[0];
840 srcU
+= s
->current_picture_ptr
->f
->linesize
[1];
841 srcV
+= s
->current_picture_ptr
->f
->linesize
[2];
844 /* for grayscale we should not try to read from unknown area */
845 if (s
->avctx
->flags
& AV_CODEC_FLAG_GRAY
) {
846 srcU
= s
->sc
.edge_emu_buffer
+ 18 * s
->linesize
;
847 srcV
= s
->sc
.edge_emu_buffer
+ 18 * s
->linesize
;
850 if (v
->rangeredfrm
|| s
->h_edge_pos
< 22 || v_edge_pos
< 22 || use_ic
851 || (unsigned)(src_x
- 1) > s
->h_edge_pos
- (mx
& 3) - 16 - 3
852 || (unsigned)(src_y
- 1) > v_edge_pos
- (my
& 3) - 16 - 3) {
853 uint8_t *uvbuf
= s
->sc
.edge_emu_buffer
+ 19 * s
->linesize
;
855 srcY
-= s
->mspel
* (1 + s
->linesize
);
856 s
->vdsp
.emulated_edge_mc(s
->sc
.edge_emu_buffer
, srcY
,
857 s
->linesize
, s
->linesize
,
858 17 + s
->mspel
* 2, 17 + s
->mspel
* 2,
859 src_x
- s
->mspel
, src_y
- s
->mspel
,
860 s
->h_edge_pos
, v_edge_pos
);
861 srcY
= s
->sc
.edge_emu_buffer
;
862 s
->vdsp
.emulated_edge_mc(uvbuf
, srcU
,
863 s
->uvlinesize
, s
->uvlinesize
,
865 uvsrc_x
, uvsrc_y
, s
->h_edge_pos
>> 1, v_edge_pos
>> 1);
866 s
->vdsp
.emulated_edge_mc(uvbuf
+ 16, srcV
,
867 s
->uvlinesize
, s
->uvlinesize
,
869 uvsrc_x
, uvsrc_y
, s
->h_edge_pos
>> 1, v_edge_pos
>> 1);
872 /* if we deal with range reduction we need to scale source blocks */
873 if (v
->rangeredfrm
) {
878 for (j
= 0; j
< 17 + s
->mspel
* 2; j
++) {
879 for (i
= 0; i
< 17 + s
->mspel
* 2; i
++)
880 src
[i
] = ((src
[i
] - 128) >> 1) + 128;
885 for (j
= 0; j
< 9; j
++) {
886 for (i
= 0; i
< 9; i
++) {
887 src
[i
] = ((src
[i
] - 128) >> 1) + 128;
888 src2
[i
] = ((src2
[i
] - 128) >> 1) + 128;
890 src
+= s
->uvlinesize
;
891 src2
+= s
->uvlinesize
;
896 uint8_t (*luty
)[256] = v
->next_luty
;
897 uint8_t (*lutuv
)[256] = v
->next_lutuv
;
902 for (j
= 0; j
< 17 + s
->mspel
* 2; j
++) {
903 int f
= v
->field_mode
? v
->ref_field_type
[1] : ((j
+src_y
- s
->mspel
) & 1);
904 for (i
= 0; i
< 17 + s
->mspel
* 2; i
++)
905 src
[i
] = luty
[f
][src
[i
]];
910 for (j
= 0; j
< 9; j
++) {
911 int f
= v
->field_mode
? v
->ref_field_type
[1] : ((j
+uvsrc_y
) & 1);
912 for (i
= 0; i
< 9; i
++) {
913 src
[i
] = lutuv
[f
][src
[i
]];
914 src2
[i
] = lutuv
[f
][src2
[i
]];
916 src
+= s
->uvlinesize
;
917 src2
+= s
->uvlinesize
;
920 srcY
+= s
->mspel
* (1 + s
->linesize
);
927 dxy
= ((my
& 3) << 2) | (mx
& 3);
928 v
->vc1dsp
.avg_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + off
, srcY
, s
->linesize
, v
->rnd
);
929 v
->vc1dsp
.avg_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + off
+ 8, srcY
+ 8, s
->linesize
, v
->rnd
);
930 srcY
+= s
->linesize
* 8;
931 v
->vc1dsp
.avg_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + off
+ 8 * s
->linesize
, srcY
, s
->linesize
, v
->rnd
);
932 v
->vc1dsp
.avg_vc1_mspel_pixels_tab
[dxy
](s
->dest
[0] + off
+ 8 * s
->linesize
+ 8, srcY
+ 8, s
->linesize
, v
->rnd
);
934 dxy
= (my
& 2) | ((mx
& 2) >> 1);
937 s
->hdsp
.avg_pixels_tab
[0][dxy
](s
->dest
[0] + off
, srcY
, s
->linesize
, 16);
939 s
->hdsp
.avg_no_rnd_pixels_tab
[dxy
](s
->dest
[0] + off
, srcY
, s
->linesize
, 16);
942 if (s
->avctx
->flags
& AV_CODEC_FLAG_GRAY
)
944 /* Chroma MC always uses qpel bilinear */
945 uvmx
= (uvmx
& 3) << 1;
946 uvmy
= (uvmy
& 3) << 1;
948 h264chroma
->avg_h264_chroma_pixels_tab
[0](s
->dest
[1] + off_uv
, srcU
, s
->uvlinesize
, 8, uvmx
, uvmy
);
949 h264chroma
->avg_h264_chroma_pixels_tab
[0](s
->dest
[2] + off_uv
, srcV
, s
->uvlinesize
, 8, uvmx
, uvmy
);
951 v
->vc1dsp
.avg_no_rnd_vc1_chroma_pixels_tab
[0](s
->dest
[1] + off_uv
, srcU
, s
->uvlinesize
, 8, uvmx
, uvmy
);
952 v
->vc1dsp
.avg_no_rnd_vc1_chroma_pixels_tab
[0](s
->dest
[2] + off_uv
, srcV
, s
->uvlinesize
, 8, uvmx
, uvmy
);