/src/ffmpeg/libavcodec/vc1_mc.c
Line | Count | Source |
1 | | /* |
2 | | * VC-1 and WMV3 decoder |
3 | | * Copyright (c) 2011 Mashiat Sarker Shakkhar |
4 | | * Copyright (c) 2006-2007 Konstantin Shishkov |
5 | | * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer |
6 | | * |
7 | | * This file is part of FFmpeg. |
8 | | * |
9 | | * FFmpeg is free software; you can redistribute it and/or |
10 | | * modify it under the terms of the GNU Lesser General Public |
11 | | * License as published by the Free Software Foundation; either |
12 | | * version 2.1 of the License, or (at your option) any later version. |
13 | | * |
14 | | * FFmpeg is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | | * Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public |
20 | | * License along with FFmpeg; if not, write to the Free Software |
21 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | | */ |
23 | | |
24 | | /** |
25 | | * @file |
26 | | * VC-1 and WMV3 block decoding routines |
27 | | */ |
28 | | |
29 | | #include "avcodec.h" |
30 | | #include "h264chroma.h" |
31 | | #include "mathops.h" |
32 | | #include "mpegvideo.h" |
33 | | #include "vc1.h" |
34 | | |
35 | | static av_always_inline void vc1_scale_luma(uint8_t *srcY, |
36 | | int k, int linesize) |
37 | 8.60M | { |
38 | 8.60M | int i, j; |
39 | 117M | for (j = 0; j < k; j++) { |
40 | 1.58G | for (i = 0; i < k; i++) |
41 | 1.47G | srcY[i] = ((srcY[i] - 128) >> 1) + 128; |
42 | 109M | srcY += linesize; |
43 | 109M | } |
44 | 8.60M | } |
45 | | |
46 | | static av_always_inline void vc1_scale_chroma(uint8_t *srcU, uint8_t *srcV, |
47 | | int k, int uvlinesize) |
48 | 3.67M | { |
49 | 3.67M | int i, j; |
50 | 36.7M | for (j = 0; j < k; j++) { |
51 | 330M | for (i = 0; i < k; i++) { |
52 | 297M | srcU[i] = ((srcU[i] - 128) >> 1) + 128; |
53 | 297M | srcV[i] = ((srcV[i] - 128) >> 1) + 128; |
54 | 297M | } |
55 | 33.0M | srcU += uvlinesize; |
56 | 33.0M | srcV += uvlinesize; |
57 | 33.0M | } |
58 | 3.67M | } |
59 | | |
60 | | static av_always_inline void vc1_lut_scale_luma(uint8_t *srcY, |
61 | | const uint8_t *lut1, const uint8_t *lut2, |
62 | | int k, int linesize) |
63 | 18.0M | { |
64 | 18.0M | int i, j; |
65 | | |
66 | 134M | for (j = 0; j < k; j += 2) { |
67 | 2.13G | for (i = 0; i < k; i++) |
68 | 2.00G | srcY[i] = lut1[srcY[i]]; |
69 | 134M | srcY += linesize; |
70 | | |
71 | 134M | if (j + 1 == k) |
72 | 18.0M | break; |
73 | | |
74 | 1.86G | for (i = 0; i < k; i++) |
75 | 1.75G | srcY[i] = lut2[srcY[i]]; |
76 | 116M | srcY += linesize; |
77 | 116M | } |
78 | 18.0M | } |
79 | | |
80 | | static av_always_inline void vc1_lut_scale_chroma(uint8_t *srcU, uint8_t *srcV, |
81 | | const uint8_t *lut1, const uint8_t *lut2, |
82 | | int k, int uvlinesize) |
83 | 14.6M | { |
84 | 14.6M | int i, j; |
85 | | |
86 | 59.7M | for (j = 0; j < k; j += 2) { |
87 | 515M | for (i = 0; i < k; i++) { |
88 | 455M | srcU[i] = lut1[srcU[i]]; |
89 | 455M | srcV[i] = lut1[srcV[i]]; |
90 | 455M | } |
91 | 59.7M | srcU += uvlinesize; |
92 | 59.7M | srcV += uvlinesize; |
93 | | |
94 | 59.7M | if (j + 1 == k) |
95 | 14.6M | break; |
96 | | |
97 | 395M | for (i = 0; i < k; i++) { |
98 | 350M | srcU[i] = lut2[srcU[i]]; |
99 | 350M | srcV[i] = lut2[srcV[i]]; |
100 | 350M | } |
101 | 45.0M | srcU += uvlinesize; |
102 | 45.0M | srcV += uvlinesize; |
103 | 45.0M | } |
104 | 14.6M | } |
105 | | |
106 | | static const uint8_t popcount4[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; |
107 | | |
108 | | static av_always_inline int get_luma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty) |
109 | 545k | { |
110 | 545k | MpegEncContext *s = &v->s; |
111 | 545k | int idx = v->mv_f[dir][s->block_index[0] + v->blocks_off] | |
112 | 545k | (v->mv_f[dir][s->block_index[1] + v->blocks_off] << 1) | |
113 | 545k | (v->mv_f[dir][s->block_index[2] + v->blocks_off] << 2) | |
114 | 545k | (v->mv_f[dir][s->block_index[3] + v->blocks_off] << 3); |
115 | 545k | static const uint8_t index2[16] = { 0, 0, 0, 0x23, 0, 0x13, 0x03, 0, 0, 0x12, 0x02, 0, 0x01, 0, 0, 0 }; |
116 | 545k | int opp_count = popcount4[idx]; |
117 | | |
118 | 545k | switch (opp_count) { |
119 | 105k | case 0: |
120 | 200k | case 4: |
121 | 200k | *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]); |
122 | 200k | *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]); |
123 | 200k | break; |
124 | 118k | case 1: |
125 | 118k | *tx = mid_pred(s->mv[dir][idx < 2][0], s->mv[dir][1 + (idx < 4)][0], s->mv[dir][2 + (idx < 8)][0]); |
126 | 118k | *ty = mid_pred(s->mv[dir][idx < 2][1], s->mv[dir][1 + (idx < 4)][1], s->mv[dir][2 + (idx < 8)][1]); |
127 | 118k | break; |
128 | 125k | case 3: |
129 | 125k | *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]); |
130 | 125k | *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]); |
131 | 125k | break; |
132 | 100k | case 2: |
133 | 100k | *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2; |
134 | 100k | *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2; |
135 | 100k | break; |
136 | 545k | } |
137 | 545k | return opp_count; |
138 | 545k | } |
139 | | |
140 | | static av_always_inline int get_chroma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty) |
141 | 3.68M | { |
142 | 3.68M | MpegEncContext *s = &v->s; |
143 | 3.68M | int idx = !v->mb_type[s->block_index[0]] | |
144 | 3.68M | (!v->mb_type[s->block_index[1]] << 1) | |
145 | 3.68M | (!v->mb_type[s->block_index[2]] << 2) | |
146 | 3.68M | (!v->mb_type[s->block_index[3]] << 3); |
147 | 3.68M | static const uint8_t index2[16] = { 0, 0, 0, 0x01, 0, 0x02, 0x12, 0, 0, 0x03, 0x13, 0, 0x23, 0, 0, 0 }; |
148 | 3.68M | int valid_count = popcount4[idx]; |
149 | | |
150 | 3.68M | switch (valid_count) { |
151 | 3.29M | case 4: |
152 | 3.29M | *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]); |
153 | 3.29M | *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]); |
154 | 3.29M | break; |
155 | 324k | case 3: |
156 | 324k | *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]); |
157 | 324k | *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]); |
158 | 324k | break; |
159 | 46.7k | case 2: |
160 | 46.7k | *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2; |
161 | 46.7k | *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2; |
162 | 46.7k | break; |
163 | 22.8k | default: |
164 | 22.8k | return 0; |
165 | 3.68M | } |
166 | 3.66M | return valid_count; |
167 | 3.68M | } |
168 | | |
169 | | /** Do motion compensation over 1 macroblock |
170 | | * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c |
171 | | */ |
172 | | void ff_vc1_mc_1mv(VC1Context *v, int dir) |
173 | 40.8M | { |
174 | 40.8M | MpegEncContext *s = &v->s; |
175 | 40.8M | H264ChromaContext *h264chroma = &v->h264chroma; |
176 | 40.8M | uint8_t *srcY, *srcU, *srcV; |
177 | 40.8M | int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; |
178 | 40.8M | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
179 | 40.8M | int i; |
180 | 40.8M | const uint8_t (*luty)[256], (*lutuv)[256]; |
181 | 40.8M | int use_ic; |
182 | 40.8M | int interlace; |
183 | 40.8M | int linesize, uvlinesize; |
184 | | |
185 | 40.8M | if ((!v->field_mode || |
186 | 2.26M | (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && |
187 | 39.4M | !v->s.last_pic.data[0]) |
188 | 12.5M | return; |
189 | | |
190 | 28.3M | linesize = s->cur_pic.ptr->f->linesize[0]; |
191 | 28.3M | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
192 | | |
193 | 28.3M | mx = s->mv[dir][0][0]; |
194 | 28.3M | my = s->mv[dir][0][1]; |
195 | | |
196 | | // store motion vectors for further use in B-frames |
197 | 28.3M | if (s->pict_type == AV_PICTURE_TYPE_P) { |
198 | 71.0M | for (i = 0; i < 4; i++) { |
199 | 56.8M | s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx; |
200 | 56.8M | s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][1] = my; |
201 | 56.8M | } |
202 | 14.2M | } |
203 | | |
204 | 28.3M | uvmx = (mx + ((mx & 3) == 3)) >> 1; |
205 | 28.3M | uvmy = (my + ((my & 3) == 3)) >> 1; |
206 | 28.3M | v->luma_mv[s->mb_x][0] = uvmx; |
207 | 28.3M | v->luma_mv[s->mb_x][1] = uvmy; |
208 | | |
209 | 28.3M | if (v->field_mode && |
210 | 2.25M | v->cur_field_type != v->ref_field_type[dir]) { |
211 | 1.27M | my = my - 2 + 4 * v->cur_field_type; |
212 | 1.27M | uvmy = uvmy - 2 + 4 * v->cur_field_type; |
213 | 1.27M | } |
214 | | |
215 | | // fastuvmc shall be ignored for interlaced frame picture |
216 | 28.3M | if (v->fastuvmc && (v->fcm != ILACE_FRAME)) { |
217 | 7.59M | uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); |
218 | 7.59M | uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); |
219 | 7.59M | } |
220 | 28.3M | if (!dir) { |
221 | 23.4M | if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { |
222 | 1.07M | srcY = s->cur_pic.data[0]; |
223 | 1.07M | srcU = s->cur_pic.data[1]; |
224 | 1.07M | srcV = s->cur_pic.data[2]; |
225 | 1.07M | luty = v->curr_luty; |
226 | 1.07M | lutuv = v->curr_lutuv; |
227 | 1.07M | use_ic = *v->curr_use_ic; |
228 | 1.07M | interlace = 1; |
229 | 22.4M | } else { |
230 | 22.4M | srcY = s->last_pic.data[0]; |
231 | 22.4M | srcU = s->last_pic.data[1]; |
232 | 22.4M | srcV = s->last_pic.data[2]; |
233 | 22.4M | luty = v->last_luty; |
234 | 22.4M | lutuv = v->last_lutuv; |
235 | 22.4M | use_ic = v->last_use_ic; |
236 | 22.4M | interlace = v->last_interlaced; |
237 | 22.4M | } |
238 | 23.4M | } else { |
239 | 4.86M | srcY = s->next_pic.data[0]; |
240 | 4.86M | srcU = s->next_pic.data[1]; |
241 | 4.86M | srcV = s->next_pic.data[2]; |
242 | 4.86M | luty = v->next_luty; |
243 | 4.86M | lutuv = v->next_lutuv; |
244 | 4.86M | use_ic = v->next_use_ic; |
245 | 4.86M | interlace = v->next_interlaced; |
246 | 4.86M | } |
247 | | |
248 | 28.3M | if (!srcY || !srcU) { |
249 | 14.3k | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
250 | 14.3k | return; |
251 | 14.3k | } |
252 | | |
253 | 28.3M | src_x = s->mb_x * 16 + (mx >> 2); |
254 | 28.3M | src_y = s->mb_y * 16 + (my >> 2); |
255 | 28.3M | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
256 | 28.3M | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
257 | | |
258 | 28.3M | if (v->profile != PROFILE_ADVANCED) { |
259 | 10.1M | src_x = av_clip( src_x, -16, s->mb_width * 16); |
260 | 10.1M | src_y = av_clip( src_y, -16, s->mb_height * 16); |
261 | 10.1M | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
262 | 10.1M | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
263 | 18.1M | } else { |
264 | 18.1M | src_x = av_clip( src_x, -17, s->avctx->coded_width); |
265 | 18.1M | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
266 | 18.1M | if (v->fcm == ILACE_FRAME) { |
267 | 10.7M | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
268 | 10.7M | uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); |
269 | 10.7M | } else { |
270 | 7.39M | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
271 | 7.39M | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
272 | 7.39M | } |
273 | 18.1M | } |
274 | | |
275 | 28.3M | srcY += src_y * s->linesize + src_x; |
276 | 28.3M | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
277 | 28.3M | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
278 | | |
279 | 28.3M | if (v->field_mode && v->ref_field_type[dir]) { |
280 | 1.04M | srcY += linesize; |
281 | 1.04M | srcU += uvlinesize; |
282 | 1.04M | srcV += uvlinesize; |
283 | 1.04M | } |
284 | | |
285 | | /* for grayscale we should not try to read from unknown area */ |
286 | 28.3M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) { |
287 | 0 | srcU = s->sc.edge_emu_buffer + 18 * s->linesize; |
288 | 0 | srcV = s->sc.edge_emu_buffer + 18 * s->linesize; |
289 | 0 | } |
290 | | |
291 | 28.3M | if (v->rangeredfrm || use_ic |
292 | 20.2M | || s->h_edge_pos < 22 || v_edge_pos < 22 |
293 | 18.6M | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3 |
294 | 16.3M | || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 3) { |
295 | 13.6M | uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize; |
296 | 13.6M | uint8_t *vbuf = ubuf + 9 * s->uvlinesize; |
297 | 13.6M | const int k = 17 + s->mspel * 2; |
298 | | |
299 | 13.6M | srcY -= s->mspel * (1 + s->linesize); |
300 | 13.6M | if (interlace) { |
301 | 1.15M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
302 | 1.15M | srcY, |
303 | 1.15M | linesize << 1, |
304 | 1.15M | linesize << 1, |
305 | 1.15M | k, |
306 | 1.15M | v->field_mode ? k : k + 1 >> 1, |
307 | 1.15M | src_x - s->mspel, |
308 | 1.15M | src_y - s->mspel >> !v->field_mode, |
309 | 1.15M | s->h_edge_pos, |
310 | 1.15M | s->v_edge_pos >> 1); |
311 | 1.15M | if (!v->field_mode) |
312 | 808k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
313 | 808k | srcY + linesize, |
314 | 808k | linesize << 1, |
315 | 808k | linesize << 1, |
316 | 808k | k, |
317 | 808k | k >> 1, |
318 | 808k | src_x - s->mspel, |
319 | 808k | src_y - s->mspel + 1 >> 1, |
320 | 808k | s->h_edge_pos, |
321 | 808k | s->v_edge_pos >> 1); |
322 | 1.15M | } else |
323 | 12.5M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
324 | 12.5M | srcY, |
325 | 12.5M | linesize, |
326 | 12.5M | linesize, |
327 | 12.5M | k, |
328 | 12.5M | v->field_mode ? (k << 1) - 1 : k, |
329 | 12.5M | src_x - s->mspel, |
330 | 12.5M | v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : |
331 | 12.5M | src_y - s->mspel, |
332 | 12.5M | s->h_edge_pos, |
333 | 12.5M | s->v_edge_pos); |
334 | 13.6M | srcY = s->sc.edge_emu_buffer; |
335 | 13.6M | if (interlace) { |
336 | 1.15M | s->vdsp.emulated_edge_mc(ubuf, |
337 | 1.15M | srcU, |
338 | 1.15M | uvlinesize << 1, |
339 | 1.15M | uvlinesize << 1, |
340 | 1.15M | 9, |
341 | 1.15M | v->field_mode ? 9 : 5, |
342 | 1.15M | uvsrc_x, |
343 | 1.15M | uvsrc_y >> !v->field_mode, |
344 | 1.15M | s->h_edge_pos >> 1, |
345 | 1.15M | s->v_edge_pos >> 2); |
346 | 1.15M | s->vdsp.emulated_edge_mc(vbuf, |
347 | 1.15M | srcV, |
348 | 1.15M | uvlinesize << 1, |
349 | 1.15M | uvlinesize << 1, |
350 | 1.15M | 9, |
351 | 1.15M | v->field_mode ? 9 : 5, |
352 | 1.15M | uvsrc_x, |
353 | 1.15M | uvsrc_y >> !v->field_mode, |
354 | 1.15M | s->h_edge_pos >> 1, |
355 | 1.15M | s->v_edge_pos >> 2); |
356 | 1.15M | if (!v->field_mode) { |
357 | 808k | s->vdsp.emulated_edge_mc(ubuf + uvlinesize, |
358 | 808k | srcU + uvlinesize, |
359 | 808k | uvlinesize << 1, |
360 | 808k | uvlinesize << 1, |
361 | 808k | 9, |
362 | 808k | 4, |
363 | 808k | uvsrc_x, |
364 | 808k | uvsrc_y + 1 >> 1, |
365 | 808k | s->h_edge_pos >> 1, |
366 | 808k | s->v_edge_pos >> 2); |
367 | 808k | s->vdsp.emulated_edge_mc(vbuf + uvlinesize, |
368 | 808k | srcV + uvlinesize, |
369 | 808k | uvlinesize << 1, |
370 | 808k | uvlinesize << 1, |
371 | 808k | 9, |
372 | 808k | 4, |
373 | 808k | uvsrc_x, |
374 | 808k | uvsrc_y + 1 >> 1, |
375 | 808k | s->h_edge_pos >> 1, |
376 | 808k | s->v_edge_pos >> 2); |
377 | 808k | } |
378 | 12.5M | } else { |
379 | 12.5M | s->vdsp.emulated_edge_mc(ubuf, |
380 | 12.5M | srcU, |
381 | 12.5M | uvlinesize, |
382 | 12.5M | uvlinesize, |
383 | 12.5M | 9, |
384 | 12.5M | v->field_mode ? 17 : 9, |
385 | 12.5M | uvsrc_x, |
386 | 12.5M | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, |
387 | 12.5M | s->h_edge_pos >> 1, |
388 | 12.5M | s->v_edge_pos >> 1); |
389 | 12.5M | s->vdsp.emulated_edge_mc(vbuf, |
390 | 12.5M | srcV, |
391 | 12.5M | uvlinesize, |
392 | 12.5M | uvlinesize, |
393 | 12.5M | 9, |
394 | 12.5M | v->field_mode ? 17 : 9, |
395 | 12.5M | uvsrc_x, |
396 | 12.5M | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, |
397 | 12.5M | s->h_edge_pos >> 1, |
398 | 12.5M | s->v_edge_pos >> 1); |
399 | 12.5M | } |
400 | 13.6M | srcU = ubuf; |
401 | 13.6M | srcV = vbuf; |
402 | | /* if we deal with range reduction we need to scale source blocks */ |
403 | 13.6M | if (v->rangeredfrm) { |
404 | 1.71M | vc1_scale_luma(srcY, k, s->linesize); |
405 | 1.71M | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
406 | 1.71M | } |
407 | | /* if we deal with intensity compensation we need to scale source blocks */ |
408 | 13.6M | if (use_ic) { |
409 | 6.69M | vc1_lut_scale_luma(srcY, |
410 | 6.69M | luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)], |
411 | 6.69M | luty[v->field_mode ? v->ref_field_type[dir] : ((1 + src_y - s->mspel) & 1)], |
412 | 6.69M | k, s->linesize); |
413 | 6.69M | vc1_lut_scale_chroma(srcU, srcV, |
414 | 6.69M | lutuv[v->field_mode ? v->ref_field_type[dir] : ((0 + uvsrc_y) & 1)], |
415 | 6.69M | lutuv[v->field_mode ? v->ref_field_type[dir] : ((1 + uvsrc_y) & 1)], |
416 | 6.69M | 9, s->uvlinesize); |
417 | 6.69M | } |
418 | 13.6M | srcY += s->mspel * (1 + s->linesize); |
419 | 13.6M | } |
420 | | |
421 | 28.3M | if (s->mspel) { |
422 | 23.7M | dxy = ((my & 3) << 2) | (mx & 3); |
423 | 23.7M | v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd); |
424 | 23.7M | } else { // hpel mc - always used for luma |
425 | 4.59M | dxy = (my & 2) | ((mx & 2) >> 1); |
426 | 4.59M | if (!v->rnd) |
427 | 2.07M | s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
428 | 2.51M | else |
429 | 2.51M | s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
430 | 4.59M | } |
431 | | |
432 | 28.3M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
433 | 0 | return; |
434 | | /* Chroma MC always uses qpel bilinear */ |
435 | 28.3M | uvmx = (uvmx & 3) << 1; |
436 | 28.3M | uvmy = (uvmy & 3) << 1; |
437 | 28.3M | if (!v->rnd) { |
438 | 11.7M | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
439 | 11.7M | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
440 | 16.5M | } else { |
441 | 16.5M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
442 | 16.5M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
443 | 16.5M | } |
444 | 28.3M | if (v->field_mode) { |
445 | 2.23M | v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir]; |
446 | 2.23M | v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir]; |
447 | 2.23M | } |
448 | 28.3M | } |
449 | | |
450 | | /** Do motion compensation for 4-MV macroblock - luminance block |
451 | | */ |
452 | | void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg) |
453 | 56.2M | { |
454 | 56.2M | MpegEncContext *s = &v->s; |
455 | 56.2M | uint8_t *srcY; |
456 | 56.2M | int dxy, mx, my, src_x, src_y; |
457 | 56.2M | int off; |
458 | 56.2M | int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0; |
459 | 56.2M | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
460 | 56.2M | const uint8_t (*luty)[256]; |
461 | 56.2M | int use_ic; |
462 | 56.2M | int interlace; |
463 | 56.2M | int linesize; |
464 | | |
465 | 56.2M | if ((!v->field_mode || |
466 | 1.56M | (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && |
467 | 55.3M | !v->s.last_pic.data[0]) |
468 | 15.3M | return; |
469 | | |
470 | 40.8M | linesize = s->cur_pic.ptr->f->linesize[0]; |
471 | | |
472 | 40.8M | mx = s->mv[dir][n][0]; |
473 | 40.8M | my = s->mv[dir][n][1]; |
474 | | |
475 | 40.8M | if (!dir) { |
476 | 31.9M | if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { |
477 | 509k | srcY = s->cur_pic.data[0]; |
478 | 509k | luty = v->curr_luty; |
479 | 509k | use_ic = *v->curr_use_ic; |
480 | 509k | interlace = 1; |
481 | 31.4M | } else { |
482 | 31.4M | srcY = s->last_pic.data[0]; |
483 | 31.4M | luty = v->last_luty; |
484 | 31.4M | use_ic = v->last_use_ic; |
485 | 31.4M | interlace = v->last_interlaced; |
486 | 31.4M | } |
487 | 31.9M | } else { |
488 | 8.92M | srcY = s->next_pic.data[0]; |
489 | 8.92M | luty = v->next_luty; |
490 | 8.92M | use_ic = v->next_use_ic; |
491 | 8.92M | interlace = v->next_interlaced; |
492 | 8.92M | } |
493 | | |
494 | 40.8M | if (!srcY) { |
495 | 18.4k | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
496 | 18.4k | return; |
497 | 18.4k | } |
498 | | |
499 | 40.8M | if (v->field_mode) { |
500 | 1.53M | if (v->cur_field_type != v->ref_field_type[dir]) |
501 | 746k | my = my - 2 + 4 * v->cur_field_type; |
502 | 1.53M | } |
503 | | |
504 | 40.8M | if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) { |
505 | 207k | int opp_count = get_luma_mv(v, 0, |
506 | 207k | &s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0], |
507 | 207k | &s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1]); |
508 | 207k | int k, f = opp_count > 2; |
509 | 1.03M | for (k = 0; k < 4; k++) |
510 | 828k | v->mv_f[1][s->block_index[k] + v->blocks_off] = f; |
511 | 207k | } |
512 | | |
513 | 40.8M | if (v->fcm == ILACE_FRAME) { // not sure if needed for other types of picture |
514 | 25.2M | int qx, qy; |
515 | 25.2M | int width = s->avctx->coded_width; |
516 | 25.2M | int height = s->avctx->coded_height >> 1; |
517 | 25.2M | if (s->pict_type == AV_PICTURE_TYPE_P) { |
518 | 8.69M | s->cur_pic.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx; |
519 | 8.69M | s->cur_pic.motion_val[1][s->block_index[n] + v->blocks_off][1] = my; |
520 | 8.69M | } |
521 | 25.2M | qx = (s->mb_x * 16) + (mx >> 2); |
522 | 25.2M | qy = (s->mb_y * 8) + (my >> 3); |
523 | | |
524 | 25.2M | if (qx < -17) |
525 | 120k | mx -= 4 * (qx + 17); |
526 | 25.1M | else if (qx > width) |
527 | 349k | mx -= 4 * (qx - width); |
528 | 25.2M | if (qy < -18) |
529 | 5.74k | my -= 8 * (qy + 18); |
530 | 25.2M | else if (qy > height + 1) |
531 | 99.5k | my -= 8 * (qy - height - 1); |
532 | 25.2M | } |
533 | | |
534 | 40.8M | if ((v->fcm == ILACE_FRAME) && fieldmv) |
535 | 25.0M | off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8; |
536 | 15.8M | else |
537 | 15.8M | off = s->linesize * 4 * (n & 2) + (n & 1) * 8; |
538 | | |
539 | 40.8M | src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2); |
540 | 40.8M | if (!fieldmv) |
541 | 15.8M | src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2); |
542 | 25.0M | else |
543 | 25.0M | src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2); |
544 | | |
545 | 40.8M | if (v->profile != PROFILE_ADVANCED) { |
546 | 15.0M | src_x = av_clip(src_x, -16, s->mb_width * 16); |
547 | 15.0M | src_y = av_clip(src_y, -16, s->mb_height * 16); |
548 | 25.7M | } else { |
549 | 25.7M | src_x = av_clip(src_x, -17, s->avctx->coded_width); |
550 | 25.7M | if (v->fcm == ILACE_FRAME) |
551 | 20.0M | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
552 | 5.69M | else |
553 | 5.69M | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
554 | 25.7M | } |
555 | | |
556 | 40.8M | srcY += src_y * s->linesize + src_x; |
557 | 40.8M | if (v->field_mode && v->ref_field_type[dir]) |
558 | 810k | srcY += linesize; |
559 | | |
560 | 40.8M | if (v->rangeredfrm || use_ic |
561 | 26.0M | || s->h_edge_pos < 13 || v_edge_pos < 23 |
562 | 25.2M | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2 |
563 | 22.9M | || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) { |
564 | 20.4M | const int k = 9 + s->mspel * 2; |
565 | | |
566 | 20.4M | srcY -= s->mspel * (1 + (s->linesize << fieldmv)); |
567 | | /* check emulate edge stride and offset */ |
568 | 20.4M | if (interlace) { |
569 | 1.79M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
570 | 1.79M | srcY, |
571 | 1.79M | linesize << 1, |
572 | 1.79M | linesize << 1, |
573 | 1.79M | k, |
574 | 1.79M | v->field_mode ? k : (k << fieldmv) + 1 >> 1, |
575 | 1.79M | src_x - s->mspel, |
576 | 1.79M | src_y - (s->mspel << fieldmv) >> !v->field_mode, |
577 | 1.79M | s->h_edge_pos, |
578 | 1.79M | s->v_edge_pos >> 1); |
579 | 1.79M | if (!v->field_mode && !fieldmv) |
580 | 41.6k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
581 | 41.6k | srcY + linesize, |
582 | 41.6k | linesize << 1, |
583 | 41.6k | linesize << 1, |
584 | 41.6k | k, |
585 | 41.6k | k >> 1, |
586 | 41.6k | src_x - s->mspel, |
587 | 41.6k | src_y - s->mspel + 1 >> 1, |
588 | 41.6k | s->h_edge_pos, |
589 | 41.6k | s->v_edge_pos >> 1); |
590 | 1.79M | } else |
591 | 18.6M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
592 | 18.6M | srcY, |
593 | 18.6M | linesize, |
594 | 18.6M | linesize, |
595 | 18.6M | k, |
596 | 18.6M | v->field_mode ? (k << 1) - 1 : k << fieldmv, |
597 | 18.6M | src_x - s->mspel, |
598 | 18.6M | v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : |
599 | 18.6M | src_y - (s->mspel << fieldmv), |
600 | 18.6M | s->h_edge_pos, |
601 | 18.6M | s->v_edge_pos); |
602 | 20.4M | srcY = s->sc.edge_emu_buffer; |
603 | | /* if we deal with range reduction we need to scale source blocks */ |
604 | 20.4M | if (v->rangeredfrm) { |
605 | 6.63M | vc1_scale_luma(srcY, k, s->linesize << fieldmv); |
606 | 6.63M | } |
607 | | /* if we deal with intensity compensation we need to scale source blocks */ |
608 | 20.4M | if (use_ic) { |
609 | 11.2M | vc1_lut_scale_luma(srcY, |
610 | 11.2M | luty[v->field_mode ? v->ref_field_type[dir] : (((0<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)], |
611 | 11.2M | luty[v->field_mode ? v->ref_field_type[dir] : (((1<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)], |
612 | 11.2M | k, s->linesize << fieldmv); |
613 | 11.2M | } |
614 | 20.4M | srcY += s->mspel * (1 + (s->linesize << fieldmv)); |
615 | 20.4M | } |
616 | | |
617 | 40.8M | if (s->mspel) { |
618 | 40.8M | dxy = ((my & 3) << 2) | (mx & 3); |
619 | 40.8M | if (avg) |
620 | 5.28M | v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd); |
621 | 35.5M | else |
622 | 35.5M | v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd); |
623 | 40.8M | } else { // hpel mc - always used for luma |
624 | 0 | dxy = (my & 2) | ((mx & 2) >> 1); |
625 | 0 | if (!v->rnd) |
626 | 0 | s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); |
627 | 0 | else |
628 | 0 | s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); |
629 | 0 | } |
630 | 40.8M | } |
631 | | |
632 | | /** Do motion compensation for 4-MV macroblock - both chroma blocks |
633 | | */ |
634 | | void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir) |
635 | 5.35M | { |
636 | 5.35M | MpegEncContext *s = &v->s; |
637 | 5.35M | H264ChromaContext *h264chroma = &v->h264chroma; |
638 | 5.35M | uint8_t *srcU, *srcV; |
639 | 5.35M | int uvmx, uvmy, uvsrc_x, uvsrc_y; |
640 | 5.35M | int16_t tx, ty; |
641 | 5.35M | int chroma_ref_type; |
642 | 5.35M | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
643 | 5.35M | const uint8_t (*lutuv)[256]; |
644 | 5.35M | int use_ic; |
645 | 5.35M | int interlace; |
646 | 5.35M | int uvlinesize; |
647 | | |
648 | 5.35M | if (!v->field_mode && !v->s.last_pic.data[0]) |
649 | 1.32M | return; |
650 | 4.02M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
651 | 0 | return; |
652 | | |
653 | | /* calculate chroma MV vector from four luma MVs */ |
654 | 4.02M | if (!v->field_mode || !v->numref) { |
655 | 3.68M | int valid_count = get_chroma_mv(v, dir, &tx, &ty); |
656 | 3.68M | if (!valid_count) { |
657 | 22.8k | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; |
658 | 22.8k | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; |
659 | 22.8k | v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; |
660 | 22.8k | return; //no need to do MC for intra blocks |
661 | 22.8k | } |
662 | 3.66M | chroma_ref_type = v->ref_field_type[dir]; |
663 | 3.66M | } else { |
664 | 337k | int opp_count = get_luma_mv(v, dir, &tx, &ty); |
665 | 337k | chroma_ref_type = v->cur_field_type ^ (opp_count > 2); |
666 | 337k | } |
667 | 4.00M | if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_pic.data[0]) |
668 | 3.47k | return; |
669 | 3.99M | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; |
670 | 3.99M | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; |
671 | | |
672 | 3.99M | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
673 | | |
674 | 3.99M | uvmx = (tx + ((tx & 3) == 3)) >> 1; |
675 | 3.99M | uvmy = (ty + ((ty & 3) == 3)) >> 1; |
676 | | |
677 | 3.99M | v->luma_mv[s->mb_x][0] = uvmx; |
678 | 3.99M | v->luma_mv[s->mb_x][1] = uvmy; |
679 | | |
680 | 3.99M | if (v->fastuvmc) { |
681 | 2.99M | uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); |
682 | 2.99M | uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); |
683 | 2.99M | } |
684 | | // Field conversion bias |
685 | 3.99M | if (v->cur_field_type != chroma_ref_type) |
686 | 153k | uvmy += 2 - 4 * chroma_ref_type; |
687 | | |
688 | 3.99M | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
689 | 3.99M | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
690 | | |
691 | 3.99M | if (v->profile != PROFILE_ADVANCED) { |
692 | 2.54M | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
693 | 2.54M | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
694 | 2.54M | } else { |
695 | 1.45M | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
696 | 1.45M | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
697 | 1.45M | } |
698 | | |
699 | 3.99M | if (!dir) { |
700 | 3.88M | if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) { |
701 | 105k | srcU = s->cur_pic.data[1]; |
702 | 105k | srcV = s->cur_pic.data[2]; |
703 | 105k | lutuv = v->curr_lutuv; |
704 | 105k | use_ic = *v->curr_use_ic; |
705 | 105k | interlace = 1; |
706 | 3.78M | } else { |
707 | 3.78M | srcU = s->last_pic.data[1]; |
708 | 3.78M | srcV = s->last_pic.data[2]; |
709 | 3.78M | lutuv = v->last_lutuv; |
710 | 3.78M | use_ic = v->last_use_ic; |
711 | 3.78M | interlace = v->last_interlaced; |
712 | 3.78M | } |
713 | 3.88M | } else { |
714 | 112k | srcU = s->next_pic.data[1]; |
715 | 112k | srcV = s->next_pic.data[2]; |
716 | 112k | lutuv = v->next_lutuv; |
717 | 112k | use_ic = v->next_use_ic; |
718 | 112k | interlace = v->next_interlaced; |
719 | 112k | } |
720 | | |
721 | 3.99M | if (!srcU) { |
722 | 5.55k | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
723 | 5.55k | return; |
724 | 5.55k | } |
725 | | |
726 | 3.99M | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
727 | 3.99M | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
728 | | |
729 | 3.99M | if (v->field_mode) { |
730 | 381k | if (chroma_ref_type) { |
731 | 225k | srcU += uvlinesize; |
732 | 225k | srcV += uvlinesize; |
733 | 225k | } |
734 | 381k | } |
735 | | |
736 | 3.99M | if (v->rangeredfrm || use_ic |
737 | 1.94M | || s->h_edge_pos < 18 || v_edge_pos < 18 |
738 | 1.73M | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 |
739 | 2.46M | || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) { |
740 | 2.46M | if (interlace) { |
741 | 38.2k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
742 | 38.2k | srcU, |
743 | 38.2k | uvlinesize << 1, |
744 | 38.2k | uvlinesize << 1, |
745 | 38.2k | 9, |
746 | 38.2k | v->field_mode ? 9 : 5, |
747 | 38.2k | uvsrc_x, |
748 | 38.2k | uvsrc_y >> !v->field_mode, |
749 | 38.2k | s->h_edge_pos >> 1, |
750 | 38.2k | s->v_edge_pos >> 2); |
751 | 38.2k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
752 | 38.2k | srcV, |
753 | 38.2k | uvlinesize << 1, |
754 | 38.2k | uvlinesize << 1, |
755 | 38.2k | 9, |
756 | 38.2k | v->field_mode ? 9 : 5, |
757 | 38.2k | uvsrc_x, |
758 | 38.2k | uvsrc_y >> !v->field_mode, |
759 | 38.2k | s->h_edge_pos >> 1, |
760 | 38.2k | s->v_edge_pos >> 2); |
761 | 38.2k | if (!v->field_mode) { |
762 | 8.53k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize, |
763 | 8.53k | srcU + uvlinesize, |
764 | 8.53k | uvlinesize << 1, |
765 | 8.53k | uvlinesize << 1, |
766 | 8.53k | 9, |
767 | 8.53k | 4, |
768 | 8.53k | uvsrc_x, |
769 | 8.53k | uvsrc_y + 1 >> 1, |
770 | 8.53k | s->h_edge_pos >> 1, |
771 | 8.53k | s->v_edge_pos >> 2); |
772 | 8.53k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize, |
773 | 8.53k | srcV + uvlinesize, |
774 | 8.53k | uvlinesize << 1, |
775 | 8.53k | uvlinesize << 1, |
776 | 8.53k | 9, |
777 | 8.53k | 4, |
778 | 8.53k | uvsrc_x, |
779 | 8.53k | uvsrc_y + 1 >> 1, |
780 | 8.53k | s->h_edge_pos >> 1, |
781 | 8.53k | s->v_edge_pos >> 2); |
782 | 8.53k | } |
783 | 2.43M | } else { |
784 | 2.43M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
785 | 2.43M | srcU, |
786 | 2.43M | uvlinesize, |
787 | 2.43M | uvlinesize, |
788 | 2.43M | 9, |
789 | 2.43M | v->field_mode ? 17 : 9, |
790 | 2.43M | uvsrc_x, |
791 | 2.43M | v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y, |
792 | 2.43M | s->h_edge_pos >> 1, |
793 | 2.43M | s->v_edge_pos >> 1); |
794 | 2.43M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
795 | 2.43M | srcV, |
796 | 2.43M | uvlinesize, |
797 | 2.43M | uvlinesize, |
798 | 2.43M | 9, |
799 | 2.43M | v->field_mode ? 17 : 9, |
800 | 2.43M | uvsrc_x, |
801 | 2.43M | v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y, |
802 | 2.43M | s->h_edge_pos >> 1, |
803 | 2.43M | s->v_edge_pos >> 1); |
804 | 2.43M | } |
805 | 2.46M | srcU = s->sc.edge_emu_buffer; |
806 | 2.46M | srcV = s->sc.edge_emu_buffer + 16; |
807 | | |
808 | | /* if we deal with range reduction we need to scale source blocks */ |
809 | 2.46M | if (v->rangeredfrm) { |
810 | 1.70M | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
811 | 1.70M | } |
812 | | /* if we deal with intensity compensation we need to scale source blocks */ |
813 | 2.46M | if (use_ic) { |
814 | 1.14M | vc1_lut_scale_chroma(srcU, srcV, |
815 | 1.14M | lutuv[v->field_mode ? chroma_ref_type : ((0 + uvsrc_y) & 1)], |
816 | 1.14M | lutuv[v->field_mode ? chroma_ref_type : ((1 + uvsrc_y) & 1)], |
817 | 1.14M | 9, s->uvlinesize); |
818 | 1.14M | } |
819 | 2.46M | } |
820 | | |
821 | | /* Chroma MC always uses qpel bilinear */ |
822 | 3.99M | uvmx = (uvmx & 3) << 1; |
823 | 3.99M | uvmy = (uvmy & 3) << 1; |
824 | 3.99M | if (!v->rnd) { |
825 | 1.52M | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
826 | 1.52M | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
827 | 2.47M | } else { |
828 | 2.47M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
829 | 2.47M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
830 | 2.47M | } |
831 | 3.99M | if (v->field_mode) { |
832 | 381k | v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != chroma_ref_type; |
833 | 381k | v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != chroma_ref_type; |
834 | 381k | } |
835 | 3.99M | } |
836 | | |
837 | | /** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V) |
838 | | */ |
839 | | void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg) |
840 | 8.86M | { |
841 | 8.86M | MpegEncContext *s = &v->s; |
842 | 8.86M | H264ChromaContext *h264chroma = &v->h264chroma; |
843 | 8.86M | uint8_t *srcU, *srcV; |
844 | 8.86M | int uvsrc_x, uvsrc_y; |
845 | 8.86M | int uvmx_field[4], uvmy_field[4]; |
846 | 8.86M | int i, off, tx, ty; |
847 | 8.86M | int fieldmv = v->blk_mv_type[s->block_index[0]]; |
848 | 8.86M | static const uint8_t s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 }; |
849 | 8.86M | int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks |
850 | 8.86M | int v_edge_pos = s->v_edge_pos >> 1; |
851 | 8.86M | int use_ic; |
852 | 8.86M | int interlace; |
853 | 8.86M | int uvlinesize; |
854 | 8.86M | const uint8_t (*lutuv)[256]; |
855 | | |
856 | 8.86M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
857 | 0 | return; |
858 | | |
859 | 8.86M | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
860 | | |
861 | 44.3M | for (i = 0; i < 4; i++) { |
862 | 35.4M | int d = i < 2 ? dir: dir2; |
863 | 35.4M | tx = s->mv[d][i][0]; |
864 | 35.4M | uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1; |
865 | 35.4M | ty = s->mv[d][i][1]; |
866 | 35.4M | if (fieldmv) |
867 | 35.0M | uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF]; |
868 | 412k | else |
869 | 412k | uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1; |
870 | 35.4M | } |
871 | | |
872 | 35.5M | for (i = 0; i < 4; i++) { |
873 | 28.8M | off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0); |
874 | 28.8M | uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2); |
875 | 28.8M | uvsrc_y = s->mb_y * 8 + ((i & 2) ? v_dist : 0) + (uvmy_field[i] >> 2); |
876 | | // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack()) |
877 | 28.8M | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
878 | 28.8M | if (v->fcm == ILACE_FRAME) |
879 | 28.8M | uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); |
880 | 0 | else |
881 | 0 | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
882 | 28.8M | if (i < 2 ? dir : dir2) { |
883 | 9.84M | srcU = s->next_pic.data[1]; |
884 | 9.84M | srcV = s->next_pic.data[2]; |
885 | 9.84M | lutuv = v->next_lutuv; |
886 | 9.84M | use_ic = v->next_use_ic; |
887 | 9.84M | interlace = v->next_interlaced; |
888 | 19.0M | } else { |
889 | 19.0M | srcU = s->last_pic.data[1]; |
890 | 19.0M | srcV = s->last_pic.data[2]; |
891 | 19.0M | lutuv = v->last_lutuv; |
892 | 19.0M | use_ic = v->last_use_ic; |
893 | 19.0M | interlace = v->last_interlaced; |
894 | 19.0M | } |
895 | 28.8M | if (!srcU) |
896 | 2.23M | return; |
897 | 26.6M | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
898 | 26.6M | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
899 | 26.6M | uvmx_field[i] = (uvmx_field[i] & 3) << 1; |
900 | 26.6M | uvmy_field[i] = (uvmy_field[i] & 3) << 1; |
901 | | |
902 | 26.6M | if (use_ic |
903 | 19.8M | || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv) |
904 | 19.4M | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 |
905 | 18.3M | || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) { |
906 | 9.43M | if (interlace) { |
907 | 1.13M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
908 | 1.13M | srcU, |
909 | 1.13M | uvlinesize << 1, |
910 | 1.13M | uvlinesize << 1, |
911 | 1.13M | 5, |
912 | 1.13M | (5 << fieldmv) + 1 >> 1, |
913 | 1.13M | uvsrc_x, |
914 | 1.13M | uvsrc_y >> 1, |
915 | 1.13M | s->h_edge_pos >> 1, |
916 | 1.13M | s->v_edge_pos >> 2); |
917 | 1.13M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
918 | 1.13M | srcV, |
919 | 1.13M | uvlinesize << 1, |
920 | 1.13M | uvlinesize << 1, |
921 | 1.13M | 5, |
922 | 1.13M | (5 << fieldmv) + 1 >> 1, |
923 | 1.13M | uvsrc_x, |
924 | 1.13M | uvsrc_y >> 1, |
925 | 1.13M | s->h_edge_pos >> 1, |
926 | 1.13M | s->v_edge_pos >> 2); |
927 | 1.13M | if (!fieldmv) { |
928 | 6.49k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize, |
929 | 6.49k | srcU + uvlinesize, |
930 | 6.49k | uvlinesize << 1, |
931 | 6.49k | uvlinesize << 1, |
932 | 6.49k | 5, |
933 | 6.49k | 2, |
934 | 6.49k | uvsrc_x, |
935 | 6.49k | uvsrc_y + 1 >> 1, |
936 | 6.49k | s->h_edge_pos >> 1, |
937 | 6.49k | s->v_edge_pos >> 2); |
938 | 6.49k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize, |
939 | 6.49k | srcV + uvlinesize, |
940 | 6.49k | uvlinesize << 1, |
941 | 6.49k | uvlinesize << 1, |
942 | 6.49k | 5, |
943 | 6.49k | 2, |
944 | 6.49k | uvsrc_x, |
945 | 6.49k | uvsrc_y + 1 >> 1, |
946 | 6.49k | s->h_edge_pos >> 1, |
947 | 6.49k | s->v_edge_pos >> 2); |
948 | 6.49k | } |
949 | 8.29M | } else { |
950 | 8.29M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
951 | 8.29M | srcU, |
952 | 8.29M | uvlinesize, |
953 | 8.29M | uvlinesize, |
954 | 8.29M | 5, |
955 | 8.29M | 5 << fieldmv, |
956 | 8.29M | uvsrc_x, |
957 | 8.29M | uvsrc_y, |
958 | 8.29M | s->h_edge_pos >> 1, |
959 | 8.29M | s->v_edge_pos >> 1); |
960 | 8.29M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
961 | 8.29M | srcV, |
962 | 8.29M | uvlinesize, |
963 | 8.29M | uvlinesize, |
964 | 8.29M | 5, |
965 | 8.29M | 5 << fieldmv, |
966 | 8.29M | uvsrc_x, |
967 | 8.29M | uvsrc_y, |
968 | 8.29M | s->h_edge_pos >> 1, |
969 | 8.29M | s->v_edge_pos >> 1); |
970 | 8.29M | } |
971 | 9.43M | srcU = s->sc.edge_emu_buffer; |
972 | 9.43M | srcV = s->sc.edge_emu_buffer + 16; |
973 | | |
974 | | /* if we deal with intensity compensation we need to scale source blocks */ |
975 | 9.43M | if (use_ic) { |
976 | 6.80M | vc1_lut_scale_chroma(srcU, srcV, |
977 | 6.80M | lutuv[(uvsrc_y + (0 << fieldmv)) & 1], |
978 | 6.80M | lutuv[(uvsrc_y + (1 << fieldmv)) & 1], |
979 | 6.80M | 5, s->uvlinesize << fieldmv); |
980 | 6.80M | } |
981 | 9.43M | } |
982 | 26.6M | if (avg) { |
983 | 6.24M | if (!v->rnd) { |
984 | 1.68M | h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
985 | 1.68M | h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
986 | 4.56M | } else { |
987 | 4.56M | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
988 | 4.56M | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
989 | 4.56M | } |
990 | 20.4M | } else { |
991 | 20.4M | if (!v->rnd) { |
992 | 7.88M | h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
993 | 7.88M | h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
994 | 12.5M | } else { |
995 | 12.5M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
996 | 12.5M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
997 | 12.5M | } |
998 | 20.4M | } |
999 | 26.6M | } |
1000 | 8.86M | } |
1001 | | |
1002 | | /** Motion compensation for direct or interpolated blocks in B-frames |
1003 | | */ |
1004 | | void ff_vc1_interp_mc(VC1Context *v) |
1005 | 8.84M | { |
1006 | 8.84M | MpegEncContext *s = &v->s; |
1007 | 8.84M | H264ChromaContext *h264chroma = &v->h264chroma; |
1008 | 8.84M | uint8_t *srcY, *srcU, *srcV; |
1009 | 8.84M | int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; |
1010 | 8.84M | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
1011 | 8.84M | int use_ic = v->next_use_ic; |
1012 | 8.84M | int interlace = v->next_interlaced; |
1013 | 8.84M | int linesize, uvlinesize; |
1014 | | |
1015 | 8.84M | if (!v->field_mode && !v->s.next_pic.data[0]) |
1016 | 0 | return; |
1017 | | |
1018 | 8.84M | linesize = s->cur_pic.ptr->f->linesize[0]; |
1019 | 8.84M | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
1020 | | |
1021 | 8.84M | mx = s->mv[1][0][0]; |
1022 | 8.84M | my = s->mv[1][0][1]; |
1023 | 8.84M | uvmx = (mx + ((mx & 3) == 3)) >> 1; |
1024 | 8.84M | uvmy = (my + ((my & 3) == 3)) >> 1; |
1025 | 8.84M | if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) { |
1026 | 59.4k | my = my - 2 + 4 * v->cur_field_type; |
1027 | 59.4k | uvmy = uvmy - 2 + 4 * v->cur_field_type; |
1028 | 59.4k | } |
1029 | 8.84M | if (v->fastuvmc) { |
1030 | 2.42M | uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1)); |
1031 | 2.42M | uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1)); |
1032 | 2.42M | } |
1033 | 8.84M | srcY = s->next_pic.data[0]; |
1034 | 8.84M | srcU = s->next_pic.data[1]; |
1035 | 8.84M | srcV = s->next_pic.data[2]; |
1036 | | |
1037 | 8.84M | src_x = s->mb_x * 16 + (mx >> 2); |
1038 | 8.84M | src_y = s->mb_y * 16 + (my >> 2); |
1039 | 8.84M | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
1040 | 8.84M | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
1041 | | |
1042 | 8.84M | if (v->profile != PROFILE_ADVANCED) { |
1043 | 5.19M | src_x = av_clip( src_x, -16, s->mb_width * 16); |
1044 | 5.19M | src_y = av_clip( src_y, -16, s->mb_height * 16); |
1045 | 5.19M | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
1046 | 5.19M | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
1047 | 5.19M | } else { |
1048 | 3.64M | src_x = av_clip( src_x, -17, s->avctx->coded_width); |
1049 | 3.64M | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
1050 | 3.64M | if (v->fcm == ILACE_FRAME) { |
1051 | 2.43M | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
1052 | 2.43M | uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); |
1053 | 2.43M | } else { |
1054 | 1.21M | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
1055 | 1.21M | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
1056 | 1.21M | } |
1057 | 3.64M | } |
1058 | | |
1059 | 8.84M | srcY += src_y * s->linesize + src_x; |
1060 | 8.84M | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
1061 | 8.84M | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
1062 | | |
1063 | 8.84M | if (v->field_mode && v->ref_field_type[1]) { |
1064 | 64.5k | srcY += linesize; |
1065 | 64.5k | srcU += uvlinesize; |
1066 | 64.5k | srcV += uvlinesize; |
1067 | 64.5k | } |
1068 | | |
1069 | | /* for grayscale we should not try to read from unknown area */ |
1070 | 8.84M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) { |
1071 | 0 | srcU = s->sc.edge_emu_buffer + 18 * s->linesize; |
1072 | 0 | srcV = s->sc.edge_emu_buffer + 18 * s->linesize; |
1073 | 0 | } |
1074 | | |
1075 | 8.84M | if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic |
1076 | 7.82M | || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3 |
1077 | 7.10M | || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) { |
1078 | 2.41M | uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize; |
1079 | 2.41M | uint8_t *vbuf = ubuf + 9 * s->uvlinesize; |
1080 | 2.41M | const int k = 17 + s->mspel * 2; |
1081 | | |
1082 | 2.41M | srcY -= s->mspel * (1 + s->linesize); |
1083 | 2.41M | if (interlace) { |
1084 | 893k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
1085 | 893k | srcY, |
1086 | 893k | linesize << 1, |
1087 | 893k | linesize << 1, |
1088 | 893k | k, |
1089 | 893k | v->field_mode ? k : (k + 1 >> 1), |
1090 | 893k | src_x - s->mspel, |
1091 | 893k | src_y - s->mspel >> !v->field_mode, |
1092 | 893k | s->h_edge_pos, |
1093 | 893k | s->v_edge_pos >> 1); |
1094 | 893k | if (!v->field_mode) |
1095 | 870k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
1096 | 870k | srcY + linesize, |
1097 | 870k | linesize << 1, |
1098 | 870k | linesize << 1, |
1099 | 870k | k, |
1100 | 870k | k >> 1, |
1101 | 870k | src_x - s->mspel, |
1102 | 870k | src_y - s->mspel + 1 >> 1, |
1103 | 870k | s->h_edge_pos, |
1104 | 870k | s->v_edge_pos >> 1); |
1105 | 893k | } else |
1106 | 1.51M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
1107 | 1.51M | srcY, |
1108 | 1.51M | linesize, |
1109 | 1.51M | linesize, |
1110 | 1.51M | k, |
1111 | 1.51M | v->field_mode ? (k << 1) - 1 : k, |
1112 | 1.51M | src_x - s->mspel, |
1113 | 1.51M | v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[1] : |
1114 | 1.51M | src_y - s->mspel, |
1115 | 1.51M | s->h_edge_pos, |
1116 | 1.51M | s->v_edge_pos); |
1117 | 2.41M | srcY = s->sc.edge_emu_buffer; |
1118 | 2.41M | if (interlace) { |
1119 | 893k | s->vdsp.emulated_edge_mc(ubuf, |
1120 | 893k | srcU, |
1121 | 893k | uvlinesize << 1, |
1122 | 893k | uvlinesize << 1, |
1123 | 893k | 9, |
1124 | 893k | v->field_mode ? 9 : 5, |
1125 | 893k | uvsrc_x, |
1126 | 893k | uvsrc_y >> !v->field_mode, |
1127 | 893k | s->h_edge_pos >> 1, |
1128 | 893k | s->v_edge_pos >> 2); |
1129 | 893k | s->vdsp.emulated_edge_mc(vbuf, |
1130 | 893k | srcV, |
1131 | 893k | uvlinesize << 1, |
1132 | 893k | uvlinesize << 1, |
1133 | 893k | 9, |
1134 | 893k | v->field_mode ? 9 : 5, |
1135 | 893k | uvsrc_x, |
1136 | 893k | uvsrc_y >> !v->field_mode, |
1137 | 893k | s->h_edge_pos >> 1, |
1138 | 893k | s->v_edge_pos >> 2); |
1139 | 893k | if (!v->field_mode) { |
1140 | 870k | s->vdsp.emulated_edge_mc(ubuf + uvlinesize, |
1141 | 870k | srcU + uvlinesize, |
1142 | 870k | uvlinesize << 1, |
1143 | 870k | uvlinesize << 1, |
1144 | 870k | 9, |
1145 | 870k | 4, |
1146 | 870k | uvsrc_x, |
1147 | 870k | uvsrc_y + 1 >> 1, |
1148 | 870k | s->h_edge_pos >> 1, |
1149 | 870k | s->v_edge_pos >> 2); |
1150 | 870k | s->vdsp.emulated_edge_mc(vbuf + uvlinesize, |
1151 | 870k | srcV + uvlinesize, |
1152 | 870k | uvlinesize << 1, |
1153 | 870k | uvlinesize << 1, |
1154 | 870k | 9, |
1155 | 870k | 4, |
1156 | 870k | uvsrc_x, |
1157 | 870k | uvsrc_y + 1 >> 1, |
1158 | 870k | s->h_edge_pos >> 1, |
1159 | 870k | s->v_edge_pos >> 2); |
1160 | 870k | } |
1161 | 1.51M | } else { |
1162 | 1.51M | s->vdsp.emulated_edge_mc(ubuf, |
1163 | 1.51M | srcU, |
1164 | 1.51M | uvlinesize, |
1165 | 1.51M | uvlinesize, |
1166 | 1.51M | 9, |
1167 | 1.51M | v->field_mode ? 17 : 9, |
1168 | 1.51M | uvsrc_x, |
1169 | 1.51M | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[1] : uvsrc_y, |
1170 | 1.51M | s->h_edge_pos >> 1, |
1171 | 1.51M | s->v_edge_pos >> 1); |
1172 | 1.51M | s->vdsp.emulated_edge_mc(vbuf, |
1173 | 1.51M | srcV, |
1174 | 1.51M | uvlinesize, |
1175 | 1.51M | uvlinesize, |
1176 | 1.51M | 9, |
1177 | 1.51M | v->field_mode ? 17 : 9, |
1178 | 1.51M | uvsrc_x, |
1179 | 1.51M | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[1] : uvsrc_y, |
1180 | 1.51M | s->h_edge_pos >> 1, |
1181 | 1.51M | s->v_edge_pos >> 1); |
1182 | 1.51M | } |
1183 | 2.41M | srcU = ubuf; |
1184 | 2.41M | srcV = vbuf; |
1185 | | /* if we deal with range reduction we need to scale source blocks */ |
1186 | 2.41M | if (v->rangeredfrm) { |
1187 | 246k | vc1_scale_luma(srcY, k, s->linesize); |
1188 | 246k | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
1189 | 246k | } |
1190 | | |
1191 | 2.41M | if (use_ic) { |
1192 | 19.1k | const uint8_t (*luty )[256] = v->next_luty; |
1193 | 19.1k | const uint8_t (*lutuv)[256] = v->next_lutuv; |
1194 | 19.1k | vc1_lut_scale_luma(srcY, |
1195 | 19.1k | luty[v->field_mode ? v->ref_field_type[1] : ((0+src_y - s->mspel) & 1)], |
1196 | 19.1k | luty[v->field_mode ? v->ref_field_type[1] : ((1+src_y - s->mspel) & 1)], |
1197 | 19.1k | k, s->linesize); |
1198 | 19.1k | vc1_lut_scale_chroma(srcU, srcV, |
1199 | 19.1k | lutuv[v->field_mode ? v->ref_field_type[1] : ((0+uvsrc_y) & 1)], |
1200 | 19.1k | lutuv[v->field_mode ? v->ref_field_type[1] : ((1+uvsrc_y) & 1)], |
1201 | 19.1k | 9, s->uvlinesize); |
1202 | 19.1k | } |
1203 | 2.41M | srcY += s->mspel * (1 + s->linesize); |
1204 | 2.41M | } |
1205 | | |
1206 | 8.84M | if (s->mspel) { |
1207 | 6.63M | dxy = ((my & 3) << 2) | (mx & 3); |
1208 | 6.63M | v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd); |
1209 | 6.63M | } else { // hpel mc |
1210 | 2.21M | dxy = (my & 2) | ((mx & 2) >> 1); |
1211 | | |
1212 | 2.21M | if (!v->rnd) |
1213 | 1.27M | s->hdsp.avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
1214 | 930k | else |
1215 | 930k | s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0], srcY, s->linesize, 16); |
1216 | 2.21M | } |
1217 | | |
1218 | 8.84M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
1219 | 0 | return; |
1220 | | /* Chroma MC always uses qpel bilinear */ |
1221 | 8.84M | uvmx = (uvmx & 3) << 1; |
1222 | 8.84M | uvmy = (uvmy & 3) << 1; |
1223 | 8.84M | if (!v->rnd) { |
1224 | 3.25M | h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
1225 | 3.25M | h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
1226 | 5.58M | } else { |
1227 | 5.58M | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
1228 | 5.58M | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
1229 | 5.58M | } |
1230 | 8.84M | } |