/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 | 9.52M | { |
38 | 9.52M | int i, j; |
39 | 129M | for (j = 0; j < k; j++) { |
40 | 1.71G | for (i = 0; i < k; i++) |
41 | 1.59G | srcY[i] = ((srcY[i] - 128) >> 1) + 128; |
42 | 119M | srcY += linesize; |
43 | 119M | } |
44 | 9.52M | } |
45 | | |
46 | | static av_always_inline void vc1_scale_chroma(uint8_t *srcU, uint8_t *srcV, |
47 | | int k, int uvlinesize) |
48 | 3.97M | { |
49 | 3.97M | int i, j; |
50 | 39.7M | for (j = 0; j < k; j++) { |
51 | 357M | for (i = 0; i < k; i++) { |
52 | 321M | srcU[i] = ((srcU[i] - 128) >> 1) + 128; |
53 | 321M | srcV[i] = ((srcV[i] - 128) >> 1) + 128; |
54 | 321M | } |
55 | 35.7M | srcU += uvlinesize; |
56 | 35.7M | srcV += uvlinesize; |
57 | 35.7M | } |
58 | 3.97M | } |
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 | 13.7M | { |
64 | 13.7M | int i, j; |
65 | | |
66 | 101M | for (j = 0; j < k; j += 2) { |
67 | 1.59G | for (i = 0; i < k; i++) |
68 | 1.49G | srcY[i] = lut1[srcY[i]]; |
69 | 101M | srcY += linesize; |
70 | | |
71 | 101M | if (j + 1 == k) |
72 | 13.7M | break; |
73 | | |
74 | 1.38G | for (i = 0; i < k; i++) |
75 | 1.30G | srcY[i] = lut2[srcY[i]]; |
76 | 87.6M | srcY += linesize; |
77 | 87.6M | } |
78 | 13.7M | } |
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 | 9.63M | { |
84 | 9.63M | int i, j; |
85 | | |
86 | 41.4M | for (j = 0; j < k; j += 2) { |
87 | 373M | for (i = 0; i < k; i++) { |
88 | 332M | srcU[i] = lut1[srcU[i]]; |
89 | 332M | srcV[i] = lut1[srcV[i]]; |
90 | 332M | } |
91 | 41.4M | srcU += uvlinesize; |
92 | 41.4M | srcV += uvlinesize; |
93 | | |
94 | 41.4M | if (j + 1 == k) |
95 | 9.63M | break; |
96 | | |
97 | 290M | for (i = 0; i < k; i++) { |
98 | 259M | srcU[i] = lut2[srcU[i]]; |
99 | 259M | srcV[i] = lut2[srcV[i]]; |
100 | 259M | } |
101 | 31.7M | srcU += uvlinesize; |
102 | 31.7M | srcV += uvlinesize; |
103 | 31.7M | } |
104 | 9.63M | } |
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 | 406k | { |
110 | 406k | MpegEncContext *s = &v->s; |
111 | 406k | int idx = v->mv_f[dir][s->block_index[0] + v->blocks_off] | |
112 | 406k | (v->mv_f[dir][s->block_index[1] + v->blocks_off] << 1) | |
113 | 406k | (v->mv_f[dir][s->block_index[2] + v->blocks_off] << 2) | |
114 | 406k | (v->mv_f[dir][s->block_index[3] + v->blocks_off] << 3); |
115 | 406k | static const uint8_t index2[16] = { 0, 0, 0, 0x23, 0, 0x13, 0x03, 0, 0, 0x12, 0x02, 0, 0x01, 0, 0, 0 }; |
116 | 406k | int opp_count = popcount4[idx]; |
117 | | |
118 | 406k | switch (opp_count) { |
119 | 91.0k | case 0: |
120 | 165k | case 4: |
121 | 165k | *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]); |
122 | 165k | *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]); |
123 | 165k | break; |
124 | 84.2k | case 1: |
125 | 84.2k | *tx = mid_pred(s->mv[dir][idx < 2][0], s->mv[dir][1 + (idx < 4)][0], s->mv[dir][2 + (idx < 8)][0]); |
126 | 84.2k | *ty = mid_pred(s->mv[dir][idx < 2][1], s->mv[dir][1 + (idx < 4)][1], s->mv[dir][2 + (idx < 8)][1]); |
127 | 84.2k | break; |
128 | 86.4k | case 3: |
129 | 86.4k | *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]); |
130 | 86.4k | *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]); |
131 | 86.4k | break; |
132 | 69.6k | case 2: |
133 | 69.6k | *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2; |
134 | 69.6k | *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2; |
135 | 69.6k | break; |
136 | 406k | } |
137 | 406k | return opp_count; |
138 | 406k | } |
139 | | |
140 | | static av_always_inline int get_chroma_mv(VC1Context *v, int dir, int16_t *tx, int16_t *ty) |
141 | 3.78M | { |
142 | 3.78M | MpegEncContext *s = &v->s; |
143 | 3.78M | int idx = !v->mb_type[s->block_index[0]] | |
144 | 3.78M | (!v->mb_type[s->block_index[1]] << 1) | |
145 | 3.78M | (!v->mb_type[s->block_index[2]] << 2) | |
146 | 3.78M | (!v->mb_type[s->block_index[3]] << 3); |
147 | 3.78M | static const uint8_t index2[16] = { 0, 0, 0, 0x01, 0, 0x02, 0x12, 0, 0, 0x03, 0x13, 0, 0x23, 0, 0, 0 }; |
148 | 3.78M | int valid_count = popcount4[idx]; |
149 | | |
150 | 3.78M | switch (valid_count) { |
151 | 3.32M | case 4: |
152 | 3.32M | *tx = median4(s->mv[dir][0][0], s->mv[dir][1][0], s->mv[dir][2][0], s->mv[dir][3][0]); |
153 | 3.32M | *ty = median4(s->mv[dir][0][1], s->mv[dir][1][1], s->mv[dir][2][1], s->mv[dir][3][1]); |
154 | 3.32M | break; |
155 | 400k | case 3: |
156 | 400k | *tx = mid_pred(s->mv[dir][idx > 0xd][0], s->mv[dir][1 + (idx > 0xb)][0], s->mv[dir][2 + (idx > 0x7)][0]); |
157 | 400k | *ty = mid_pred(s->mv[dir][idx > 0xd][1], s->mv[dir][1 + (idx > 0xb)][1], s->mv[dir][2 + (idx > 0x7)][1]); |
158 | 400k | break; |
159 | 44.4k | case 2: |
160 | 44.4k | *tx = (s->mv[dir][index2[idx] >> 4][0] + s->mv[dir][index2[idx] & 0xf][0]) / 2; |
161 | 44.4k | *ty = (s->mv[dir][index2[idx] >> 4][1] + s->mv[dir][index2[idx] & 0xf][1]) / 2; |
162 | 44.4k | break; |
163 | 16.4k | default: |
164 | 16.4k | return 0; |
165 | 3.78M | } |
166 | 3.76M | return valid_count; |
167 | 3.78M | } |
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 | 33.5M | { |
174 | 33.5M | MpegEncContext *s = &v->s; |
175 | 33.5M | H264ChromaContext *h264chroma = &v->h264chroma; |
176 | 33.5M | uint8_t *srcY, *srcU, *srcV; |
177 | 33.5M | int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; |
178 | 33.5M | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
179 | 33.5M | int i; |
180 | 33.5M | const uint8_t (*luty)[256], (*lutuv)[256]; |
181 | 33.5M | int use_ic; |
182 | 33.5M | int interlace; |
183 | 33.5M | int linesize, uvlinesize; |
184 | | |
185 | 33.5M | if ((!v->field_mode || |
186 | 1.92M | (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && |
187 | 32.3M | !v->s.last_pic.data[0]) |
188 | 10.8M | return; |
189 | | |
190 | 22.7M | linesize = s->cur_pic.ptr->f->linesize[0]; |
191 | 22.7M | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
192 | | |
193 | 22.7M | mx = s->mv[dir][0][0]; |
194 | 22.7M | my = s->mv[dir][0][1]; |
195 | | |
196 | | // store motion vectors for further use in B-frames |
197 | 22.7M | if (s->pict_type == AV_PICTURE_TYPE_P) { |
198 | 59.5M | for (i = 0; i < 4; i++) { |
199 | 47.6M | s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx; |
200 | 47.6M | s->cur_pic.motion_val[1][s->block_index[i] + v->blocks_off][1] = my; |
201 | 47.6M | } |
202 | 11.9M | } |
203 | | |
204 | 22.7M | uvmx = (mx + ((mx & 3) == 3)) >> 1; |
205 | 22.7M | uvmy = (my + ((my & 3) == 3)) >> 1; |
206 | 22.7M | v->luma_mv[s->mb_x][0] = uvmx; |
207 | 22.7M | v->luma_mv[s->mb_x][1] = uvmy; |
208 | | |
209 | 22.7M | if (v->field_mode && |
210 | 1.91M | v->cur_field_type != v->ref_field_type[dir]) { |
211 | 1.10M | my = my - 2 + 4 * v->cur_field_type; |
212 | 1.10M | uvmy = uvmy - 2 + 4 * v->cur_field_type; |
213 | 1.10M | } |
214 | | |
215 | | // fastuvmc shall be ignored for interlaced frame picture |
216 | 22.7M | if (v->fastuvmc && (v->fcm != ILACE_FRAME)) { |
217 | 5.83M | uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); |
218 | 5.83M | uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); |
219 | 5.83M | } |
220 | 22.7M | if (!dir) { |
221 | 19.4M | if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { |
222 | 907k | srcY = s->cur_pic.data[0]; |
223 | 907k | srcU = s->cur_pic.data[1]; |
224 | 907k | srcV = s->cur_pic.data[2]; |
225 | 907k | luty = v->curr_luty; |
226 | 907k | lutuv = v->curr_lutuv; |
227 | 907k | use_ic = *v->curr_use_ic; |
228 | 907k | interlace = 1; |
229 | 18.5M | } else { |
230 | 18.5M | srcY = s->last_pic.data[0]; |
231 | 18.5M | srcU = s->last_pic.data[1]; |
232 | 18.5M | srcV = s->last_pic.data[2]; |
233 | 18.5M | luty = v->last_luty; |
234 | 18.5M | lutuv = v->last_lutuv; |
235 | 18.5M | use_ic = v->last_use_ic; |
236 | 18.5M | interlace = v->last_interlaced; |
237 | 18.5M | } |
238 | 19.4M | } else { |
239 | 3.23M | srcY = s->next_pic.data[0]; |
240 | 3.23M | srcU = s->next_pic.data[1]; |
241 | 3.23M | srcV = s->next_pic.data[2]; |
242 | 3.23M | luty = v->next_luty; |
243 | 3.23M | lutuv = v->next_lutuv; |
244 | 3.23M | use_ic = v->next_use_ic; |
245 | 3.23M | interlace = v->next_interlaced; |
246 | 3.23M | } |
247 | | |
248 | 22.7M | if (!srcY || !srcU) { |
249 | 13.9k | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
250 | 13.9k | return; |
251 | 13.9k | } |
252 | | |
253 | 22.7M | src_x = s->mb_x * 16 + (mx >> 2); |
254 | 22.7M | src_y = s->mb_y * 16 + (my >> 2); |
255 | 22.7M | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
256 | 22.7M | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
257 | | |
258 | 22.7M | if (v->profile != PROFILE_ADVANCED) { |
259 | 9.14M | src_x = av_clip( src_x, -16, s->mb_width * 16); |
260 | 9.14M | src_y = av_clip( src_y, -16, s->mb_height * 16); |
261 | 9.14M | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
262 | 9.14M | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
263 | 13.5M | } else { |
264 | 13.5M | src_x = av_clip( src_x, -17, s->avctx->coded_width); |
265 | 13.5M | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
266 | 13.5M | if (v->fcm == ILACE_FRAME) { |
267 | 8.18M | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
268 | 8.18M | uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); |
269 | 8.18M | } else { |
270 | 5.36M | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
271 | 5.36M | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
272 | 5.36M | } |
273 | 13.5M | } |
274 | | |
275 | 22.7M | srcY += src_y * s->linesize + src_x; |
276 | 22.7M | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
277 | 22.7M | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
278 | | |
279 | 22.7M | if (v->field_mode && v->ref_field_type[dir]) { |
280 | 863k | srcY += linesize; |
281 | 863k | srcU += uvlinesize; |
282 | 863k | srcV += uvlinesize; |
283 | 863k | } |
284 | | |
285 | | /* for grayscale we should not try to read from unknown area */ |
286 | 22.7M | 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 | 22.7M | if (v->rangeredfrm || use_ic |
292 | 16.5M | || s->h_edge_pos < 22 || v_edge_pos < 22 |
293 | 14.9M | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3 |
294 | 12.9M | || (unsigned)(src_y - 1) > v_edge_pos - (my&3) - 16 - 3) { |
295 | 11.4M | uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize; |
296 | 11.4M | uint8_t *vbuf = ubuf + 9 * s->uvlinesize; |
297 | 11.4M | const int k = 17 + s->mspel * 2; |
298 | | |
299 | 11.4M | srcY -= s->mspel * (1 + s->linesize); |
300 | 11.4M | if (interlace) { |
301 | 1.03M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
302 | 1.03M | srcY, |
303 | 1.03M | linesize << 1, |
304 | 1.03M | linesize << 1, |
305 | 1.03M | k, |
306 | 1.03M | v->field_mode ? k : k + 1 >> 1, |
307 | 1.03M | src_x - s->mspel, |
308 | 1.03M | src_y - s->mspel >> !v->field_mode, |
309 | 1.03M | s->h_edge_pos, |
310 | 1.03M | s->v_edge_pos >> 1); |
311 | 1.03M | if (!v->field_mode) |
312 | 703k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
313 | 703k | srcY + linesize, |
314 | 703k | linesize << 1, |
315 | 703k | linesize << 1, |
316 | 703k | k, |
317 | 703k | k >> 1, |
318 | 703k | src_x - s->mspel, |
319 | 703k | src_y - s->mspel + 1 >> 1, |
320 | 703k | s->h_edge_pos, |
321 | 703k | s->v_edge_pos >> 1); |
322 | 1.03M | } else |
323 | 10.4M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
324 | 10.4M | srcY, |
325 | 10.4M | linesize, |
326 | 10.4M | linesize, |
327 | 10.4M | k, |
328 | 10.4M | v->field_mode ? (k << 1) - 1 : k, |
329 | 10.4M | src_x - s->mspel, |
330 | 10.4M | v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : |
331 | 10.4M | src_y - s->mspel, |
332 | 10.4M | s->h_edge_pos, |
333 | 10.4M | s->v_edge_pos); |
334 | 11.4M | srcY = s->sc.edge_emu_buffer; |
335 | 11.4M | if (interlace) { |
336 | 1.03M | s->vdsp.emulated_edge_mc(ubuf, |
337 | 1.03M | srcU, |
338 | 1.03M | uvlinesize << 1, |
339 | 1.03M | uvlinesize << 1, |
340 | 1.03M | 9, |
341 | 1.03M | v->field_mode ? 9 : 5, |
342 | 1.03M | uvsrc_x, |
343 | 1.03M | uvsrc_y >> !v->field_mode, |
344 | 1.03M | s->h_edge_pos >> 1, |
345 | 1.03M | s->v_edge_pos >> 2); |
346 | 1.03M | s->vdsp.emulated_edge_mc(vbuf, |
347 | 1.03M | srcV, |
348 | 1.03M | uvlinesize << 1, |
349 | 1.03M | uvlinesize << 1, |
350 | 1.03M | 9, |
351 | 1.03M | v->field_mode ? 9 : 5, |
352 | 1.03M | uvsrc_x, |
353 | 1.03M | uvsrc_y >> !v->field_mode, |
354 | 1.03M | s->h_edge_pos >> 1, |
355 | 1.03M | s->v_edge_pos >> 2); |
356 | 1.03M | if (!v->field_mode) { |
357 | 703k | s->vdsp.emulated_edge_mc(ubuf + uvlinesize, |
358 | 703k | srcU + uvlinesize, |
359 | 703k | uvlinesize << 1, |
360 | 703k | uvlinesize << 1, |
361 | 703k | 9, |
362 | 703k | 4, |
363 | 703k | uvsrc_x, |
364 | 703k | uvsrc_y + 1 >> 1, |
365 | 703k | s->h_edge_pos >> 1, |
366 | 703k | s->v_edge_pos >> 2); |
367 | 703k | s->vdsp.emulated_edge_mc(vbuf + uvlinesize, |
368 | 703k | srcV + uvlinesize, |
369 | 703k | uvlinesize << 1, |
370 | 703k | uvlinesize << 1, |
371 | 703k | 9, |
372 | 703k | 4, |
373 | 703k | uvsrc_x, |
374 | 703k | uvsrc_y + 1 >> 1, |
375 | 703k | s->h_edge_pos >> 1, |
376 | 703k | s->v_edge_pos >> 2); |
377 | 703k | } |
378 | 10.4M | } else { |
379 | 10.4M | s->vdsp.emulated_edge_mc(ubuf, |
380 | 10.4M | srcU, |
381 | 10.4M | uvlinesize, |
382 | 10.4M | uvlinesize, |
383 | 10.4M | 9, |
384 | 10.4M | v->field_mode ? 17 : 9, |
385 | 10.4M | uvsrc_x, |
386 | 10.4M | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, |
387 | 10.4M | s->h_edge_pos >> 1, |
388 | 10.4M | s->v_edge_pos >> 1); |
389 | 10.4M | s->vdsp.emulated_edge_mc(vbuf, |
390 | 10.4M | srcV, |
391 | 10.4M | uvlinesize, |
392 | 10.4M | uvlinesize, |
393 | 10.4M | 9, |
394 | 10.4M | v->field_mode ? 17 : 9, |
395 | 10.4M | uvsrc_x, |
396 | 10.4M | v->field_mode ? 2 * uvsrc_y + v->ref_field_type[dir] : uvsrc_y, |
397 | 10.4M | s->h_edge_pos >> 1, |
398 | 10.4M | s->v_edge_pos >> 1); |
399 | 10.4M | } |
400 | 11.4M | srcU = ubuf; |
401 | 11.4M | srcV = vbuf; |
402 | | /* if we deal with range reduction we need to scale source blocks */ |
403 | 11.4M | if (v->rangeredfrm) { |
404 | 1.72M | vc1_scale_luma(srcY, k, s->linesize); |
405 | 1.72M | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
406 | 1.72M | } |
407 | | /* if we deal with intensity compensation we need to scale source blocks */ |
408 | 11.4M | if (use_ic) { |
409 | 4.83M | vc1_lut_scale_luma(srcY, |
410 | 4.83M | luty[v->field_mode ? v->ref_field_type[dir] : ((0 + src_y - s->mspel) & 1)], |
411 | 4.83M | luty[v->field_mode ? v->ref_field_type[dir] : ((1 + src_y - s->mspel) & 1)], |
412 | 4.83M | k, s->linesize); |
413 | 4.83M | vc1_lut_scale_chroma(srcU, srcV, |
414 | 4.83M | lutuv[v->field_mode ? v->ref_field_type[dir] : ((0 + uvsrc_y) & 1)], |
415 | 4.83M | lutuv[v->field_mode ? v->ref_field_type[dir] : ((1 + uvsrc_y) & 1)], |
416 | 4.83M | 9, s->uvlinesize); |
417 | 4.83M | } |
418 | 11.4M | srcY += s->mspel * (1 + s->linesize); |
419 | 11.4M | } |
420 | | |
421 | 22.7M | if (s->mspel) { |
422 | 18.3M | dxy = ((my & 3) << 2) | (mx & 3); |
423 | 18.3M | v->vc1dsp.put_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd); |
424 | 18.3M | } else { // hpel mc - always used for luma |
425 | 4.30M | dxy = (my & 2) | ((mx & 2) >> 1); |
426 | 4.30M | if (!v->rnd) |
427 | 1.64M | s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
428 | 2.65M | else |
429 | 2.65M | s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
430 | 4.30M | } |
431 | | |
432 | 22.7M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
433 | 0 | return; |
434 | | /* Chroma MC always uses qpel bilinear */ |
435 | 22.7M | uvmx = (uvmx & 3) << 1; |
436 | 22.7M | uvmy = (uvmy & 3) << 1; |
437 | 22.7M | if (!v->rnd) { |
438 | 7.61M | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
439 | 7.61M | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
440 | 15.0M | } else { |
441 | 15.0M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
442 | 15.0M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
443 | 15.0M | } |
444 | 22.7M | if (v->field_mode) { |
445 | 1.90M | v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir]; |
446 | 1.90M | v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != v->ref_field_type[dir]; |
447 | 1.90M | } |
448 | 22.7M | } |
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 | 46.9M | { |
454 | 46.9M | MpegEncContext *s = &v->s; |
455 | 46.9M | uint8_t *srcY; |
456 | 46.9M | int dxy, mx, my, src_x, src_y; |
457 | 46.9M | int off; |
458 | 46.9M | int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0; |
459 | 46.9M | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
460 | 46.9M | const uint8_t (*luty)[256]; |
461 | 46.9M | int use_ic; |
462 | 46.9M | int interlace; |
463 | 46.9M | int linesize; |
464 | | |
465 | 46.9M | if ((!v->field_mode || |
466 | 1.32M | (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && |
467 | 46.1M | !v->s.last_pic.data[0]) |
468 | 13.0M | return; |
469 | | |
470 | 33.9M | linesize = s->cur_pic.ptr->f->linesize[0]; |
471 | | |
472 | 33.9M | mx = s->mv[dir][n][0]; |
473 | 33.9M | my = s->mv[dir][n][1]; |
474 | | |
475 | 33.9M | if (!dir) { |
476 | 27.0M | if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { |
477 | 361k | srcY = s->cur_pic.data[0]; |
478 | 361k | luty = v->curr_luty; |
479 | 361k | use_ic = *v->curr_use_ic; |
480 | 361k | interlace = 1; |
481 | 26.6M | } else { |
482 | 26.6M | srcY = s->last_pic.data[0]; |
483 | 26.6M | luty = v->last_luty; |
484 | 26.6M | use_ic = v->last_use_ic; |
485 | 26.6M | interlace = v->last_interlaced; |
486 | 26.6M | } |
487 | 27.0M | } else { |
488 | 6.92M | srcY = s->next_pic.data[0]; |
489 | 6.92M | luty = v->next_luty; |
490 | 6.92M | use_ic = v->next_use_ic; |
491 | 6.92M | interlace = v->next_interlaced; |
492 | 6.92M | } |
493 | | |
494 | 33.9M | if (!srcY) { |
495 | 19.3k | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
496 | 19.3k | return; |
497 | 19.3k | } |
498 | | |
499 | 33.9M | if (v->field_mode) { |
500 | 1.29M | if (v->cur_field_type != v->ref_field_type[dir]) |
501 | 617k | my = my - 2 + 4 * v->cur_field_type; |
502 | 1.29M | } |
503 | | |
504 | 33.9M | if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) { |
505 | 131k | int opp_count = get_luma_mv(v, 0, |
506 | 131k | &s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0], |
507 | 131k | &s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1]); |
508 | 131k | int k, f = opp_count > 2; |
509 | 656k | for (k = 0; k < 4; k++) |
510 | 524k | v->mv_f[1][s->block_index[k] + v->blocks_off] = f; |
511 | 131k | } |
512 | | |
513 | 33.9M | if (v->fcm == ILACE_FRAME) { // not sure if needed for other types of picture |
514 | 18.2M | int qx, qy; |
515 | 18.2M | int width = s->avctx->coded_width; |
516 | 18.2M | int height = s->avctx->coded_height >> 1; |
517 | 18.2M | if (s->pict_type == AV_PICTURE_TYPE_P) { |
518 | 5.37M | s->cur_pic.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx; |
519 | 5.37M | s->cur_pic.motion_val[1][s->block_index[n] + v->blocks_off][1] = my; |
520 | 5.37M | } |
521 | 18.2M | qx = (s->mb_x * 16) + (mx >> 2); |
522 | 18.2M | qy = (s->mb_y * 8) + (my >> 3); |
523 | | |
524 | 18.2M | if (qx < -17) |
525 | 99.7k | mx -= 4 * (qx + 17); |
526 | 18.1M | else if (qx > width) |
527 | 300k | mx -= 4 * (qx - width); |
528 | 18.2M | if (qy < -18) |
529 | 4.37k | my -= 8 * (qy + 18); |
530 | 18.2M | else if (qy > height + 1) |
531 | 90.6k | my -= 8 * (qy - height - 1); |
532 | 18.2M | } |
533 | | |
534 | 33.9M | if ((v->fcm == ILACE_FRAME) && fieldmv) |
535 | 18.1M | 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 | 33.9M | src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2); |
540 | 33.9M | if (!fieldmv) |
541 | 15.8M | src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2); |
542 | 18.1M | else |
543 | 18.1M | src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2); |
544 | | |
545 | 33.9M | if (v->profile != PROFILE_ADVANCED) { |
546 | 14.4M | src_x = av_clip(src_x, -16, s->mb_width * 16); |
547 | 14.4M | src_y = av_clip(src_y, -16, s->mb_height * 16); |
548 | 19.4M | } else { |
549 | 19.4M | src_x = av_clip(src_x, -17, s->avctx->coded_width); |
550 | 19.4M | if (v->fcm == ILACE_FRAME) |
551 | 14.4M | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
552 | 5.01M | else |
553 | 5.01M | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
554 | 19.4M | } |
555 | | |
556 | 33.9M | srcY += src_y * s->linesize + src_x; |
557 | 33.9M | if (v->field_mode && v->ref_field_type[dir]) |
558 | 670k | srcY += linesize; |
559 | | |
560 | 33.9M | if (v->rangeredfrm || use_ic |
561 | 21.4M | || s->h_edge_pos < 13 || v_edge_pos < 23 |
562 | 20.5M | || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2 |
563 | 18.3M | || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) { |
564 | 17.9M | const int k = 9 + s->mspel * 2; |
565 | | |
566 | 17.9M | srcY -= s->mspel * (1 + (s->linesize << fieldmv)); |
567 | | /* check emulate edge stride and offset */ |
568 | 17.9M | if (interlace) { |
569 | 1.82M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
570 | 1.82M | srcY, |
571 | 1.82M | linesize << 1, |
572 | 1.82M | linesize << 1, |
573 | 1.82M | k, |
574 | 1.82M | v->field_mode ? k : (k << fieldmv) + 1 >> 1, |
575 | 1.82M | src_x - s->mspel, |
576 | 1.82M | src_y - (s->mspel << fieldmv) >> !v->field_mode, |
577 | 1.82M | s->h_edge_pos, |
578 | 1.82M | s->v_edge_pos >> 1); |
579 | 1.82M | if (!v->field_mode && !fieldmv) |
580 | 66.5k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
581 | 66.5k | srcY + linesize, |
582 | 66.5k | linesize << 1, |
583 | 66.5k | linesize << 1, |
584 | 66.5k | k, |
585 | 66.5k | k >> 1, |
586 | 66.5k | src_x - s->mspel, |
587 | 66.5k | src_y - s->mspel + 1 >> 1, |
588 | 66.5k | s->h_edge_pos, |
589 | 66.5k | s->v_edge_pos >> 1); |
590 | 1.82M | } else |
591 | 16.1M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
592 | 16.1M | srcY, |
593 | 16.1M | linesize, |
594 | 16.1M | linesize, |
595 | 16.1M | k, |
596 | 16.1M | v->field_mode ? (k << 1) - 1 : k << fieldmv, |
597 | 16.1M | src_x - s->mspel, |
598 | 16.1M | v->field_mode ? 2 * (src_y - s->mspel) + v->ref_field_type[dir] : |
599 | 16.1M | src_y - (s->mspel << fieldmv), |
600 | 16.1M | s->h_edge_pos, |
601 | 16.1M | s->v_edge_pos); |
602 | 17.9M | srcY = s->sc.edge_emu_buffer; |
603 | | /* if we deal with range reduction we need to scale source blocks */ |
604 | 17.9M | if (v->rangeredfrm) { |
605 | 7.50M | vc1_scale_luma(srcY, k, s->linesize << fieldmv); |
606 | 7.50M | } |
607 | | /* if we deal with intensity compensation we need to scale source blocks */ |
608 | 17.9M | if (use_ic) { |
609 | 8.90M | vc1_lut_scale_luma(srcY, |
610 | 8.90M | luty[v->field_mode ? v->ref_field_type[dir] : (((0<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)], |
611 | 8.90M | luty[v->field_mode ? v->ref_field_type[dir] : (((1<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1)], |
612 | 8.90M | k, s->linesize << fieldmv); |
613 | 8.90M | } |
614 | 17.9M | srcY += s->mspel * (1 + (s->linesize << fieldmv)); |
615 | 17.9M | } |
616 | | |
617 | 33.9M | if (s->mspel) { |
618 | 33.9M | dxy = ((my & 3) << 2) | (mx & 3); |
619 | 33.9M | if (avg) |
620 | 4.25M | v->vc1dsp.avg_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd); |
621 | 29.6M | else |
622 | 29.6M | v->vc1dsp.put_vc1_mspel_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd); |
623 | 33.9M | } 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 | 33.9M | } |
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.36M | { |
636 | 5.36M | MpegEncContext *s = &v->s; |
637 | 5.36M | H264ChromaContext *h264chroma = &v->h264chroma; |
638 | 5.36M | uint8_t *srcU, *srcV; |
639 | 5.36M | int uvmx, uvmy, uvsrc_x, uvsrc_y; |
640 | 5.36M | int16_t tx, ty; |
641 | 5.36M | int chroma_ref_type; |
642 | 5.36M | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
643 | 5.36M | const uint8_t (*lutuv)[256]; |
644 | 5.36M | int use_ic; |
645 | 5.36M | int interlace; |
646 | 5.36M | int uvlinesize; |
647 | | |
648 | 5.36M | if (!v->field_mode && !v->s.last_pic.data[0]) |
649 | 1.30M | return; |
650 | 4.05M | 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.05M | if (!v->field_mode || !v->numref) { |
655 | 3.78M | int valid_count = get_chroma_mv(v, dir, &tx, &ty); |
656 | 3.78M | if (!valid_count) { |
657 | 16.4k | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0; |
658 | 16.4k | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0; |
659 | 16.4k | v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0; |
660 | 16.4k | return; //no need to do MC for intra blocks |
661 | 16.4k | } |
662 | 3.76M | chroma_ref_type = v->ref_field_type[dir]; |
663 | 3.76M | } else { |
664 | 275k | int opp_count = get_luma_mv(v, dir, &tx, &ty); |
665 | 275k | chroma_ref_type = v->cur_field_type ^ (opp_count > 2); |
666 | 275k | } |
667 | 4.04M | if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_pic.data[0]) |
668 | 4.72k | return; |
669 | 4.03M | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; |
670 | 4.03M | s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; |
671 | | |
672 | 4.03M | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
673 | | |
674 | 4.03M | uvmx = (tx + ((tx & 3) == 3)) >> 1; |
675 | 4.03M | uvmy = (ty + ((ty & 3) == 3)) >> 1; |
676 | | |
677 | 4.03M | v->luma_mv[s->mb_x][0] = uvmx; |
678 | 4.03M | v->luma_mv[s->mb_x][1] = uvmy; |
679 | | |
680 | 4.03M | if (v->fastuvmc) { |
681 | 2.92M | uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1)); |
682 | 2.92M | uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1)); |
683 | 2.92M | } |
684 | | // Field conversion bias |
685 | 4.03M | if (v->cur_field_type != chroma_ref_type) |
686 | 127k | uvmy += 2 - 4 * chroma_ref_type; |
687 | | |
688 | 4.03M | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
689 | 4.03M | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
690 | | |
691 | 4.03M | if (v->profile != PROFILE_ADVANCED) { |
692 | 2.75M | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
693 | 2.75M | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
694 | 2.75M | } else { |
695 | 1.27M | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
696 | 1.27M | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
697 | 1.27M | } |
698 | | |
699 | 4.03M | if (!dir) { |
700 | 3.91M | if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) { |
701 | 76.1k | srcU = s->cur_pic.data[1]; |
702 | 76.1k | srcV = s->cur_pic.data[2]; |
703 | 76.1k | lutuv = v->curr_lutuv; |
704 | 76.1k | use_ic = *v->curr_use_ic; |
705 | 76.1k | interlace = 1; |
706 | 3.84M | } else { |
707 | 3.84M | srcU = s->last_pic.data[1]; |
708 | 3.84M | srcV = s->last_pic.data[2]; |
709 | 3.84M | lutuv = v->last_lutuv; |
710 | 3.84M | use_ic = v->last_use_ic; |
711 | 3.84M | interlace = v->last_interlaced; |
712 | 3.84M | } |
713 | 3.91M | } else { |
714 | 119k | srcU = s->next_pic.data[1]; |
715 | 119k | srcV = s->next_pic.data[2]; |
716 | 119k | lutuv = v->next_lutuv; |
717 | 119k | use_ic = v->next_use_ic; |
718 | 119k | interlace = v->next_interlaced; |
719 | 119k | } |
720 | | |
721 | 4.03M | if (!srcU) { |
722 | 5.72k | av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); |
723 | 5.72k | return; |
724 | 5.72k | } |
725 | | |
726 | 4.03M | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
727 | 4.03M | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
728 | | |
729 | 4.03M | if (v->field_mode) { |
730 | 321k | if (chroma_ref_type) { |
731 | 183k | srcU += uvlinesize; |
732 | 183k | srcV += uvlinesize; |
733 | 183k | } |
734 | 321k | } |
735 | | |
736 | 4.03M | if (v->rangeredfrm || use_ic |
737 | 1.67M | || s->h_edge_pos < 18 || v_edge_pos < 18 |
738 | 1.46M | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 |
739 | 2.76M | || (unsigned)uvsrc_y > (v_edge_pos >> 1) - 9) { |
740 | 2.76M | if (interlace) { |
741 | 45.8k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
742 | 45.8k | srcU, |
743 | 45.8k | uvlinesize << 1, |
744 | 45.8k | uvlinesize << 1, |
745 | 45.8k | 9, |
746 | 45.8k | v->field_mode ? 9 : 5, |
747 | 45.8k | uvsrc_x, |
748 | 45.8k | uvsrc_y >> !v->field_mode, |
749 | 45.8k | s->h_edge_pos >> 1, |
750 | 45.8k | s->v_edge_pos >> 2); |
751 | 45.8k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
752 | 45.8k | srcV, |
753 | 45.8k | uvlinesize << 1, |
754 | 45.8k | uvlinesize << 1, |
755 | 45.8k | 9, |
756 | 45.8k | v->field_mode ? 9 : 5, |
757 | 45.8k | uvsrc_x, |
758 | 45.8k | uvsrc_y >> !v->field_mode, |
759 | 45.8k | s->h_edge_pos >> 1, |
760 | 45.8k | s->v_edge_pos >> 2); |
761 | 45.8k | if (!v->field_mode) { |
762 | 14.6k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize, |
763 | 14.6k | srcU + uvlinesize, |
764 | 14.6k | uvlinesize << 1, |
765 | 14.6k | uvlinesize << 1, |
766 | 14.6k | 9, |
767 | 14.6k | 4, |
768 | 14.6k | uvsrc_x, |
769 | 14.6k | uvsrc_y + 1 >> 1, |
770 | 14.6k | s->h_edge_pos >> 1, |
771 | 14.6k | s->v_edge_pos >> 2); |
772 | 14.6k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize, |
773 | 14.6k | srcV + uvlinesize, |
774 | 14.6k | uvlinesize << 1, |
775 | 14.6k | uvlinesize << 1, |
776 | 14.6k | 9, |
777 | 14.6k | 4, |
778 | 14.6k | uvsrc_x, |
779 | 14.6k | uvsrc_y + 1 >> 1, |
780 | 14.6k | s->h_edge_pos >> 1, |
781 | 14.6k | s->v_edge_pos >> 2); |
782 | 14.6k | } |
783 | 2.72M | } else { |
784 | 2.72M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
785 | 2.72M | srcU, |
786 | 2.72M | uvlinesize, |
787 | 2.72M | uvlinesize, |
788 | 2.72M | 9, |
789 | 2.72M | v->field_mode ? 17 : 9, |
790 | 2.72M | uvsrc_x, |
791 | 2.72M | v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y, |
792 | 2.72M | s->h_edge_pos >> 1, |
793 | 2.72M | s->v_edge_pos >> 1); |
794 | 2.72M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
795 | 2.72M | srcV, |
796 | 2.72M | uvlinesize, |
797 | 2.72M | uvlinesize, |
798 | 2.72M | 9, |
799 | 2.72M | v->field_mode ? 17 : 9, |
800 | 2.72M | uvsrc_x, |
801 | 2.72M | v->field_mode ? 2 * uvsrc_y + chroma_ref_type : uvsrc_y, |
802 | 2.72M | s->h_edge_pos >> 1, |
803 | 2.72M | s->v_edge_pos >> 1); |
804 | 2.72M | } |
805 | 2.76M | srcU = s->sc.edge_emu_buffer; |
806 | 2.76M | srcV = s->sc.edge_emu_buffer + 16; |
807 | | |
808 | | /* if we deal with range reduction we need to scale source blocks */ |
809 | 2.76M | if (v->rangeredfrm) { |
810 | 1.94M | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
811 | 1.94M | } |
812 | | /* if we deal with intensity compensation we need to scale source blocks */ |
813 | 2.76M | if (use_ic) { |
814 | 1.40M | vc1_lut_scale_chroma(srcU, srcV, |
815 | 1.40M | lutuv[v->field_mode ? chroma_ref_type : ((0 + uvsrc_y) & 1)], |
816 | 1.40M | lutuv[v->field_mode ? chroma_ref_type : ((1 + uvsrc_y) & 1)], |
817 | 1.40M | 9, s->uvlinesize); |
818 | 1.40M | } |
819 | 2.76M | } |
820 | | |
821 | | /* Chroma MC always uses qpel bilinear */ |
822 | 4.03M | uvmx = (uvmx & 3) << 1; |
823 | 4.03M | uvmy = (uvmy & 3) << 1; |
824 | 4.03M | if (!v->rnd) { |
825 | 1.23M | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
826 | 1.23M | h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
827 | 2.79M | } else { |
828 | 2.79M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
829 | 2.79M | v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
830 | 2.79M | } |
831 | 4.03M | if (v->field_mode) { |
832 | 321k | v->mv_f[dir][s->block_index[4] + v->mb_off] = v->cur_field_type != chroma_ref_type; |
833 | 321k | v->mv_f[dir][s->block_index[5] + v->mb_off] = v->cur_field_type != chroma_ref_type; |
834 | 321k | } |
835 | 4.03M | } |
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 | 6.55M | { |
841 | 6.55M | MpegEncContext *s = &v->s; |
842 | 6.55M | H264ChromaContext *h264chroma = &v->h264chroma; |
843 | 6.55M | uint8_t *srcU, *srcV; |
844 | 6.55M | int uvsrc_x, uvsrc_y; |
845 | 6.55M | int uvmx_field[4], uvmy_field[4]; |
846 | 6.55M | int i, off, tx, ty; |
847 | 6.55M | int fieldmv = v->blk_mv_type[s->block_index[0]]; |
848 | 6.55M | static const uint8_t s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 }; |
849 | 6.55M | int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks |
850 | 6.55M | int v_edge_pos = s->v_edge_pos >> 1; |
851 | 6.55M | int use_ic; |
852 | 6.55M | int interlace; |
853 | 6.55M | int uvlinesize; |
854 | 6.55M | const uint8_t (*lutuv)[256]; |
855 | | |
856 | 6.55M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
857 | 0 | return; |
858 | | |
859 | 6.55M | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
860 | | |
861 | 32.7M | for (i = 0; i < 4; i++) { |
862 | 26.2M | int d = i < 2 ? dir: dir2; |
863 | 26.2M | tx = s->mv[d][i][0]; |
864 | 26.2M | uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1; |
865 | 26.2M | ty = s->mv[d][i][1]; |
866 | 26.2M | if (fieldmv) |
867 | 25.9M | uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF]; |
868 | 254k | else |
869 | 254k | uvmy_field[i] = (ty + ((ty & 3) == 3)) >> 1; |
870 | 26.2M | } |
871 | | |
872 | 26.0M | for (i = 0; i < 4; i++) { |
873 | 21.1M | off = (i & 1) * 4 + ((i & 2) ? v_dist * s->uvlinesize : 0); |
874 | 21.1M | uvsrc_x = s->mb_x * 8 + (i & 1) * 4 + (uvmx_field[i] >> 2); |
875 | 21.1M | 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 | 21.1M | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
878 | 21.1M | if (v->fcm == ILACE_FRAME) |
879 | 21.1M | 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 | 21.1M | if (i < 2 ? dir : dir2) { |
883 | 7.64M | srcU = s->next_pic.data[1]; |
884 | 7.64M | srcV = s->next_pic.data[2]; |
885 | 7.64M | lutuv = v->next_lutuv; |
886 | 7.64M | use_ic = v->next_use_ic; |
887 | 7.64M | interlace = v->next_interlaced; |
888 | 13.5M | } else { |
889 | 13.5M | srcU = s->last_pic.data[1]; |
890 | 13.5M | srcV = s->last_pic.data[2]; |
891 | 13.5M | lutuv = v->last_lutuv; |
892 | 13.5M | use_ic = v->last_use_ic; |
893 | 13.5M | interlace = v->last_interlaced; |
894 | 13.5M | } |
895 | 21.1M | if (!srcU) |
896 | 1.71M | return; |
897 | 19.4M | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
898 | 19.4M | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
899 | 19.4M | uvmx_field[i] = (uvmx_field[i] & 3) << 1; |
900 | 19.4M | uvmy_field[i] = (uvmy_field[i] & 3) << 1; |
901 | | |
902 | 19.4M | if (use_ic |
903 | 16.0M | || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv) |
904 | 15.7M | || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5 |
905 | 14.5M | || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) { |
906 | 5.95M | if (interlace) { |
907 | 1.14M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
908 | 1.14M | srcU, |
909 | 1.14M | uvlinesize << 1, |
910 | 1.14M | uvlinesize << 1, |
911 | 1.14M | 5, |
912 | 1.14M | (5 << fieldmv) + 1 >> 1, |
913 | 1.14M | uvsrc_x, |
914 | 1.14M | uvsrc_y >> 1, |
915 | 1.14M | s->h_edge_pos >> 1, |
916 | 1.14M | s->v_edge_pos >> 2); |
917 | 1.14M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
918 | 1.14M | srcV, |
919 | 1.14M | uvlinesize << 1, |
920 | 1.14M | uvlinesize << 1, |
921 | 1.14M | 5, |
922 | 1.14M | (5 << fieldmv) + 1 >> 1, |
923 | 1.14M | uvsrc_x, |
924 | 1.14M | uvsrc_y >> 1, |
925 | 1.14M | s->h_edge_pos >> 1, |
926 | 1.14M | s->v_edge_pos >> 2); |
927 | 1.14M | if (!fieldmv) { |
928 | 6.30k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + uvlinesize, |
929 | 6.30k | srcU + uvlinesize, |
930 | 6.30k | uvlinesize << 1, |
931 | 6.30k | uvlinesize << 1, |
932 | 6.30k | 5, |
933 | 6.30k | 2, |
934 | 6.30k | uvsrc_x, |
935 | 6.30k | uvsrc_y + 1 >> 1, |
936 | 6.30k | s->h_edge_pos >> 1, |
937 | 6.30k | s->v_edge_pos >> 2); |
938 | 6.30k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16 + uvlinesize, |
939 | 6.30k | srcV + uvlinesize, |
940 | 6.30k | uvlinesize << 1, |
941 | 6.30k | uvlinesize << 1, |
942 | 6.30k | 5, |
943 | 6.30k | 2, |
944 | 6.30k | uvsrc_x, |
945 | 6.30k | uvsrc_y + 1 >> 1, |
946 | 6.30k | s->h_edge_pos >> 1, |
947 | 6.30k | s->v_edge_pos >> 2); |
948 | 6.30k | } |
949 | 4.81M | } else { |
950 | 4.81M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
951 | 4.81M | srcU, |
952 | 4.81M | uvlinesize, |
953 | 4.81M | uvlinesize, |
954 | 4.81M | 5, |
955 | 4.81M | 5 << fieldmv, |
956 | 4.81M | uvsrc_x, |
957 | 4.81M | uvsrc_y, |
958 | 4.81M | s->h_edge_pos >> 1, |
959 | 4.81M | s->v_edge_pos >> 1); |
960 | 4.81M | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + 16, |
961 | 4.81M | srcV, |
962 | 4.81M | uvlinesize, |
963 | 4.81M | uvlinesize, |
964 | 4.81M | 5, |
965 | 4.81M | 5 << fieldmv, |
966 | 4.81M | uvsrc_x, |
967 | 4.81M | uvsrc_y, |
968 | 4.81M | s->h_edge_pos >> 1, |
969 | 4.81M | s->v_edge_pos >> 1); |
970 | 4.81M | } |
971 | 5.95M | srcU = s->sc.edge_emu_buffer; |
972 | 5.95M | srcV = s->sc.edge_emu_buffer + 16; |
973 | | |
974 | | /* if we deal with intensity compensation we need to scale source blocks */ |
975 | 5.95M | if (use_ic) { |
976 | 3.37M | vc1_lut_scale_chroma(srcU, srcV, |
977 | 3.37M | lutuv[(uvsrc_y + (0 << fieldmv)) & 1], |
978 | 3.37M | lutuv[(uvsrc_y + (1 << fieldmv)) & 1], |
979 | 3.37M | 5, s->uvlinesize << fieldmv); |
980 | 3.37M | } |
981 | 5.95M | } |
982 | 19.4M | if (avg) { |
983 | 5.08M | if (!v->rnd) { |
984 | 997k | h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
985 | 997k | h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
986 | 4.08M | } else { |
987 | 4.08M | 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.08M | 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.08M | } |
990 | 14.3M | } else { |
991 | 14.3M | if (!v->rnd) { |
992 | 2.96M | h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
993 | 2.96M | h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]); |
994 | 11.4M | } else { |
995 | 11.4M | 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 | 11.4M | 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 | 11.4M | } |
998 | 14.3M | } |
999 | 19.4M | } |
1000 | 6.55M | } |
1001 | | |
1002 | | /** Motion compensation for direct or interpolated blocks in B-frames |
1003 | | */ |
1004 | | void ff_vc1_interp_mc(VC1Context *v) |
1005 | 6.65M | { |
1006 | 6.65M | MpegEncContext *s = &v->s; |
1007 | 6.65M | H264ChromaContext *h264chroma = &v->h264chroma; |
1008 | 6.65M | uint8_t *srcY, *srcU, *srcV; |
1009 | 6.65M | int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; |
1010 | 6.65M | int v_edge_pos = s->v_edge_pos >> v->field_mode; |
1011 | 6.65M | int use_ic = v->next_use_ic; |
1012 | 6.65M | int interlace = v->next_interlaced; |
1013 | 6.65M | int linesize, uvlinesize; |
1014 | | |
1015 | 6.65M | if (!v->field_mode && !v->s.next_pic.data[0]) |
1016 | 0 | return; |
1017 | | |
1018 | 6.65M | linesize = s->cur_pic.ptr->f->linesize[0]; |
1019 | 6.65M | uvlinesize = s->cur_pic.ptr->f->linesize[1]; |
1020 | | |
1021 | 6.65M | mx = s->mv[1][0][0]; |
1022 | 6.65M | my = s->mv[1][0][1]; |
1023 | 6.65M | uvmx = (mx + ((mx & 3) == 3)) >> 1; |
1024 | 6.65M | uvmy = (my + ((my & 3) == 3)) >> 1; |
1025 | 6.65M | if (v->field_mode && v->cur_field_type != v->ref_field_type[1]) { |
1026 | 57.4k | my = my - 2 + 4 * v->cur_field_type; |
1027 | 57.4k | uvmy = uvmy - 2 + 4 * v->cur_field_type; |
1028 | 57.4k | } |
1029 | 6.65M | if (v->fastuvmc) { |
1030 | 2.05M | uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1)); |
1031 | 2.05M | uvmy = uvmy + ((uvmy < 0) ? -(uvmy & 1) : (uvmy & 1)); |
1032 | 2.05M | } |
1033 | 6.65M | srcY = s->next_pic.data[0]; |
1034 | 6.65M | srcU = s->next_pic.data[1]; |
1035 | 6.65M | srcV = s->next_pic.data[2]; |
1036 | | |
1037 | 6.65M | src_x = s->mb_x * 16 + (mx >> 2); |
1038 | 6.65M | src_y = s->mb_y * 16 + (my >> 2); |
1039 | 6.65M | uvsrc_x = s->mb_x * 8 + (uvmx >> 2); |
1040 | 6.65M | uvsrc_y = s->mb_y * 8 + (uvmy >> 2); |
1041 | | |
1042 | 6.65M | if (v->profile != PROFILE_ADVANCED) { |
1043 | 3.94M | src_x = av_clip( src_x, -16, s->mb_width * 16); |
1044 | 3.94M | src_y = av_clip( src_y, -16, s->mb_height * 16); |
1045 | 3.94M | uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); |
1046 | 3.94M | uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); |
1047 | 3.94M | } else { |
1048 | 2.71M | src_x = av_clip( src_x, -17, s->avctx->coded_width); |
1049 | 2.71M | uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); |
1050 | 2.71M | if (v->fcm == ILACE_FRAME) { |
1051 | 1.92M | src_y = av_clip(src_y, -18 + (src_y & 1), s->avctx->coded_height + (src_y & 1)); |
1052 | 1.92M | uvsrc_y = av_clip(uvsrc_y, -8 + (uvsrc_y & 1), (s->avctx->coded_height >> 1) + (uvsrc_y & 1)); |
1053 | 1.92M | } else { |
1054 | 793k | src_y = av_clip(src_y, -18, s->avctx->coded_height + 1); |
1055 | 793k | uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); |
1056 | 793k | } |
1057 | 2.71M | } |
1058 | | |
1059 | 6.65M | srcY += src_y * s->linesize + src_x; |
1060 | 6.65M | srcU += uvsrc_y * s->uvlinesize + uvsrc_x; |
1061 | 6.65M | srcV += uvsrc_y * s->uvlinesize + uvsrc_x; |
1062 | | |
1063 | 6.65M | if (v->field_mode && v->ref_field_type[1]) { |
1064 | 60.7k | srcY += linesize; |
1065 | 60.7k | srcU += uvlinesize; |
1066 | 60.7k | srcV += uvlinesize; |
1067 | 60.7k | } |
1068 | | |
1069 | | /* for grayscale we should not try to read from unknown area */ |
1070 | 6.65M | 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 | 6.65M | if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic |
1076 | 5.61M | || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3 |
1077 | 4.96M | || (unsigned)(src_y - 1) > v_edge_pos - (my & 3) - 16 - 3) { |
1078 | 2.31M | uint8_t *ubuf = s->sc.edge_emu_buffer + 19 * s->linesize; |
1079 | 2.31M | uint8_t *vbuf = ubuf + 9 * s->uvlinesize; |
1080 | 2.31M | const int k = 17 + s->mspel * 2; |
1081 | | |
1082 | 2.31M | srcY -= s->mspel * (1 + s->linesize); |
1083 | 2.31M | if (interlace) { |
1084 | 795k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, |
1085 | 795k | srcY, |
1086 | 795k | linesize << 1, |
1087 | 795k | linesize << 1, |
1088 | 795k | k, |
1089 | 795k | v->field_mode ? k : (k + 1 >> 1), |
1090 | 795k | src_x - s->mspel, |
1091 | 795k | src_y - s->mspel >> !v->field_mode, |
1092 | 795k | s->h_edge_pos, |
1093 | 795k | s->v_edge_pos >> 1); |
1094 | 795k | if (!v->field_mode) |
1095 | 773k | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer + linesize, |
1096 | 773k | srcY + linesize, |
1097 | 773k | linesize << 1, |
1098 | 773k | linesize << 1, |
1099 | 773k | k, |
1100 | 773k | k >> 1, |
1101 | 773k | src_x - s->mspel, |
1102 | 773k | src_y - s->mspel + 1 >> 1, |
1103 | 773k | s->h_edge_pos, |
1104 | 773k | s->v_edge_pos >> 1); |
1105 | 795k | } 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.31M | srcY = s->sc.edge_emu_buffer; |
1118 | 2.31M | if (interlace) { |
1119 | 795k | s->vdsp.emulated_edge_mc(ubuf, |
1120 | 795k | srcU, |
1121 | 795k | uvlinesize << 1, |
1122 | 795k | uvlinesize << 1, |
1123 | 795k | 9, |
1124 | 795k | v->field_mode ? 9 : 5, |
1125 | 795k | uvsrc_x, |
1126 | 795k | uvsrc_y >> !v->field_mode, |
1127 | 795k | s->h_edge_pos >> 1, |
1128 | 795k | s->v_edge_pos >> 2); |
1129 | 795k | s->vdsp.emulated_edge_mc(vbuf, |
1130 | 795k | srcV, |
1131 | 795k | uvlinesize << 1, |
1132 | 795k | uvlinesize << 1, |
1133 | 795k | 9, |
1134 | 795k | v->field_mode ? 9 : 5, |
1135 | 795k | uvsrc_x, |
1136 | 795k | uvsrc_y >> !v->field_mode, |
1137 | 795k | s->h_edge_pos >> 1, |
1138 | 795k | s->v_edge_pos >> 2); |
1139 | 795k | if (!v->field_mode) { |
1140 | 773k | s->vdsp.emulated_edge_mc(ubuf + uvlinesize, |
1141 | 773k | srcU + uvlinesize, |
1142 | 773k | uvlinesize << 1, |
1143 | 773k | uvlinesize << 1, |
1144 | 773k | 9, |
1145 | 773k | 4, |
1146 | 773k | uvsrc_x, |
1147 | 773k | uvsrc_y + 1 >> 1, |
1148 | 773k | s->h_edge_pos >> 1, |
1149 | 773k | s->v_edge_pos >> 2); |
1150 | 773k | s->vdsp.emulated_edge_mc(vbuf + uvlinesize, |
1151 | 773k | srcV + uvlinesize, |
1152 | 773k | uvlinesize << 1, |
1153 | 773k | uvlinesize << 1, |
1154 | 773k | 9, |
1155 | 773k | 4, |
1156 | 773k | uvsrc_x, |
1157 | 773k | uvsrc_y + 1 >> 1, |
1158 | 773k | s->h_edge_pos >> 1, |
1159 | 773k | s->v_edge_pos >> 2); |
1160 | 773k | } |
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.31M | srcU = ubuf; |
1184 | 2.31M | srcV = vbuf; |
1185 | | /* if we deal with range reduction we need to scale source blocks */ |
1186 | 2.31M | if (v->rangeredfrm) { |
1187 | 292k | vc1_scale_luma(srcY, k, s->linesize); |
1188 | 292k | vc1_scale_chroma(srcU, srcV, 9, s->uvlinesize); |
1189 | 292k | } |
1190 | | |
1191 | 2.31M | if (use_ic) { |
1192 | 18.0k | const uint8_t (*luty )[256] = v->next_luty; |
1193 | 18.0k | const uint8_t (*lutuv)[256] = v->next_lutuv; |
1194 | 18.0k | vc1_lut_scale_luma(srcY, |
1195 | 18.0k | luty[v->field_mode ? v->ref_field_type[1] : ((0+src_y - s->mspel) & 1)], |
1196 | 18.0k | luty[v->field_mode ? v->ref_field_type[1] : ((1+src_y - s->mspel) & 1)], |
1197 | 18.0k | k, s->linesize); |
1198 | 18.0k | vc1_lut_scale_chroma(srcU, srcV, |
1199 | 18.0k | lutuv[v->field_mode ? v->ref_field_type[1] : ((0+uvsrc_y) & 1)], |
1200 | 18.0k | lutuv[v->field_mode ? v->ref_field_type[1] : ((1+uvsrc_y) & 1)], |
1201 | 18.0k | 9, s->uvlinesize); |
1202 | 18.0k | } |
1203 | 2.31M | srcY += s->mspel * (1 + s->linesize); |
1204 | 2.31M | } |
1205 | | |
1206 | 6.65M | if (s->mspel) { |
1207 | 4.77M | dxy = ((my & 3) << 2) | (mx & 3); |
1208 | 4.77M | v->vc1dsp.avg_vc1_mspel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, v->rnd); |
1209 | 4.77M | } else { // hpel mc |
1210 | 1.88M | dxy = (my & 2) | ((mx & 2) >> 1); |
1211 | | |
1212 | 1.88M | if (!v->rnd) |
1213 | 901k | s->hdsp.avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); |
1214 | 979k | else |
1215 | 979k | s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0], srcY, s->linesize, 16); |
1216 | 1.88M | } |
1217 | | |
1218 | 6.65M | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) |
1219 | 0 | return; |
1220 | | /* Chroma MC always uses qpel bilinear */ |
1221 | 6.65M | uvmx = (uvmx & 3) << 1; |
1222 | 6.65M | uvmy = (uvmy & 3) << 1; |
1223 | 6.65M | if (!v->rnd) { |
1224 | 2.11M | h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
1225 | 2.11M | h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
1226 | 4.54M | } else { |
1227 | 4.54M | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); |
1228 | 4.54M | v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); |
1229 | 4.54M | } |
1230 | 6.65M | } |