Directory: | ../../../ffmpeg/ |
---|---|
File: | src/libavcodec/mpegvideo_motion.c |
Date: | 2022-07-05 19:52:29 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 370 | 497 | 74.4% |
Branches: | 155 | 234 | 66.2% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Copyright (c) 2000,2001 Fabrice Bellard | ||
3 | * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> | ||
4 | * | ||
5 | * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> | ||
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 | #include "config_components.h" | ||
25 | |||
26 | #include "libavutil/avassert.h" | ||
27 | #include "libavutil/internal.h" | ||
28 | #include "libavutil/mem_internal.h" | ||
29 | |||
30 | #include "avcodec.h" | ||
31 | #include "h261.h" | ||
32 | #include "mpegutils.h" | ||
33 | #include "mpegvideo.h" | ||
34 | #include "qpeldsp.h" | ||
35 | #include "wmv2.h" | ||
36 | |||
37 | ✗ | static void gmc1_motion(MpegEncContext *s, | |
38 | uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | ||
39 | uint8_t **ref_picture) | ||
40 | { | ||
41 | uint8_t *ptr; | ||
42 | int src_x, src_y, motion_x, motion_y; | ||
43 | ptrdiff_t offset, linesize, uvlinesize; | ||
44 | ✗ | int emu = 0; | |
45 | |||
46 | ✗ | motion_x = s->sprite_offset[0][0]; | |
47 | ✗ | motion_y = s->sprite_offset[0][1]; | |
48 | ✗ | src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1)); | |
49 | ✗ | src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1)); | |
50 | ✗ | motion_x *= 1 << (3 - s->sprite_warping_accuracy); | |
51 | ✗ | motion_y *= 1 << (3 - s->sprite_warping_accuracy); | |
52 | ✗ | src_x = av_clip(src_x, -16, s->width); | |
53 | ✗ | if (src_x == s->width) | |
54 | ✗ | motion_x = 0; | |
55 | ✗ | src_y = av_clip(src_y, -16, s->height); | |
56 | ✗ | if (src_y == s->height) | |
57 | ✗ | motion_y = 0; | |
58 | |||
59 | ✗ | linesize = s->linesize; | |
60 | ✗ | uvlinesize = s->uvlinesize; | |
61 | |||
62 | ✗ | ptr = ref_picture[0] + src_y * linesize + src_x; | |
63 | |||
64 | ✗ | if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) || | |
65 | ✗ | (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) { | |
66 | ✗ | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr, | |
67 | linesize, linesize, | ||
68 | 17, 17, | ||
69 | src_x, src_y, | ||
70 | s->h_edge_pos, s->v_edge_pos); | ||
71 | ✗ | ptr = s->sc.edge_emu_buffer; | |
72 | } | ||
73 | |||
74 | ✗ | if ((motion_x | motion_y) & 7) { | |
75 | ✗ | s->mdsp.gmc1(dest_y, ptr, linesize, 16, | |
76 | ✗ | motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
77 | ✗ | s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16, | |
78 | ✗ | motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
79 | } else { | ||
80 | int dxy; | ||
81 | |||
82 | ✗ | dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2); | |
83 | ✗ | if (s->no_rounding) { | |
84 | ✗ | s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16); | |
85 | } else { | ||
86 | ✗ | s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16); | |
87 | } | ||
88 | } | ||
89 | |||
90 | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) | ||
91 | return; | ||
92 | |||
93 | ✗ | motion_x = s->sprite_offset[1][0]; | |
94 | ✗ | motion_y = s->sprite_offset[1][1]; | |
95 | ✗ | src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1)); | |
96 | ✗ | src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1)); | |
97 | ✗ | motion_x *= 1 << (3 - s->sprite_warping_accuracy); | |
98 | ✗ | motion_y *= 1 << (3 - s->sprite_warping_accuracy); | |
99 | ✗ | src_x = av_clip(src_x, -8, s->width >> 1); | |
100 | ✗ | if (src_x == s->width >> 1) | |
101 | ✗ | motion_x = 0; | |
102 | ✗ | src_y = av_clip(src_y, -8, s->height >> 1); | |
103 | ✗ | if (src_y == s->height >> 1) | |
104 | ✗ | motion_y = 0; | |
105 | |||
106 | ✗ | offset = (src_y * uvlinesize) + src_x; | |
107 | ✗ | ptr = ref_picture[1] + offset; | |
108 | ✗ | if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) || | |
109 | ✗ | (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) { | |
110 | ✗ | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr, | |
111 | uvlinesize, uvlinesize, | ||
112 | 9, 9, | ||
113 | src_x, src_y, | ||
114 | ✗ | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
115 | ✗ | ptr = s->sc.edge_emu_buffer; | |
116 | ✗ | emu = 1; | |
117 | } | ||
118 | ✗ | s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8, | |
119 | ✗ | motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
120 | |||
121 | ✗ | ptr = ref_picture[2] + offset; | |
122 | ✗ | if (emu) { | |
123 | ✗ | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr, | |
124 | uvlinesize, uvlinesize, | ||
125 | 9, 9, | ||
126 | src_x, src_y, | ||
127 | ✗ | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
128 | ✗ | ptr = s->sc.edge_emu_buffer; | |
129 | } | ||
130 | ✗ | s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8, | |
131 | ✗ | motion_x & 15, motion_y & 15, 128 - s->no_rounding); | |
132 | } | ||
133 | |||
134 | ✗ | static void gmc_motion(MpegEncContext *s, | |
135 | uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | ||
136 | uint8_t **ref_picture) | ||
137 | { | ||
138 | uint8_t *ptr; | ||
139 | int linesize, uvlinesize; | ||
140 | ✗ | const int a = s->sprite_warping_accuracy; | |
141 | int ox, oy; | ||
142 | |||
143 | ✗ | linesize = s->linesize; | |
144 | ✗ | uvlinesize = s->uvlinesize; | |
145 | |||
146 | ✗ | ptr = ref_picture[0]; | |
147 | |||
148 | ✗ | ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 + | |
149 | ✗ | s->sprite_delta[0][1] * s->mb_y * 16; | |
150 | ✗ | oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 + | |
151 | ✗ | s->sprite_delta[1][1] * s->mb_y * 16; | |
152 | |||
153 | ✗ | s->mdsp.gmc(dest_y, ptr, linesize, 16, | |
154 | ox, oy, | ||
155 | s->sprite_delta[0][0], s->sprite_delta[0][1], | ||
156 | s->sprite_delta[1][0], s->sprite_delta[1][1], | ||
157 | ✗ | a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
158 | s->h_edge_pos, s->v_edge_pos); | ||
159 | ✗ | s->mdsp.gmc(dest_y + 8, ptr, linesize, 16, | |
160 | ✗ | ox + s->sprite_delta[0][0] * 8, | |
161 | ✗ | oy + s->sprite_delta[1][0] * 8, | |
162 | s->sprite_delta[0][0], s->sprite_delta[0][1], | ||
163 | s->sprite_delta[1][0], s->sprite_delta[1][1], | ||
164 | ✗ | a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
165 | s->h_edge_pos, s->v_edge_pos); | ||
166 | |||
167 | if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY) | ||
168 | return; | ||
169 | |||
170 | ✗ | ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 + | |
171 | ✗ | s->sprite_delta[0][1] * s->mb_y * 8; | |
172 | ✗ | oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 + | |
173 | ✗ | s->sprite_delta[1][1] * s->mb_y * 8; | |
174 | |||
175 | ✗ | ptr = ref_picture[1]; | |
176 | ✗ | s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8, | |
177 | ox, oy, | ||
178 | s->sprite_delta[0][0], s->sprite_delta[0][1], | ||
179 | s->sprite_delta[1][0], s->sprite_delta[1][1], | ||
180 | ✗ | a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
181 | ✗ | (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1); | |
182 | |||
183 | ✗ | ptr = ref_picture[2]; | |
184 | ✗ | s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8, | |
185 | ox, oy, | ||
186 | s->sprite_delta[0][0], s->sprite_delta[0][1], | ||
187 | s->sprite_delta[1][0], s->sprite_delta[1][1], | ||
188 | ✗ | a + 1, (1 << (2 * a + 1)) - s->no_rounding, | |
189 | ✗ | (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1); | |
190 | } | ||
191 | |||
192 | 2639244 | static inline int hpel_motion(MpegEncContext *s, | |
193 | uint8_t *dest, uint8_t *src, | ||
194 | int src_x, int src_y, | ||
195 | op_pixels_func *pix_op, | ||
196 | int motion_x, int motion_y) | ||
197 | { | ||
198 | 2639244 | int dxy = 0; | |
199 | 2639244 | int emu = 0; | |
200 | |||
201 | 2639244 | src_x += motion_x >> 1; | |
202 | 2639244 | src_y += motion_y >> 1; | |
203 | |||
204 | /* WARNING: do no forget half pels */ | ||
205 | 2639244 | src_x = av_clip(src_x, -16, s->width); // FIXME unneeded for emu? | |
206 |
2/2✓ Branch 0 taken 2637339 times.
✓ Branch 1 taken 1905 times.
|
2639244 | if (src_x != s->width) |
207 | 2637339 | dxy |= motion_x & 1; | |
208 | 2639244 | src_y = av_clip(src_y, -16, s->height); | |
209 |
2/2✓ Branch 0 taken 2636911 times.
✓ Branch 1 taken 2333 times.
|
2639244 | if (src_y != s->height) |
210 | 2636911 | dxy |= (motion_y & 1) << 1; | |
211 | 2639244 | src += src_y * s->linesize + src_x; | |
212 | |||
213 |
3/4✓ Branch 0 taken 2639244 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2596367 times.
✓ Branch 3 taken 42877 times.
|
2639244 | if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 7, 0) || |
214 |
3/4✓ Branch 0 taken 2596367 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46181 times.
✓ Branch 3 taken 2550186 times.
|
2596367 | (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 1) - 7, 0)) { |
215 | 89058 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, src, | |
216 | s->linesize, s->linesize, | ||
217 | 9, 9, | ||
218 | src_x, src_y, | ||
219 | s->h_edge_pos, s->v_edge_pos); | ||
220 | 89058 | src = s->sc.edge_emu_buffer; | |
221 | 89058 | emu = 1; | |
222 | } | ||
223 | 2639244 | pix_op[dxy](dest, src, s->linesize, 8); | |
224 | 2639244 | return emu; | |
225 | } | ||
226 | |||
227 | static av_always_inline | ||
228 | 8157600 | void mpeg_motion_internal(MpegEncContext *s, | |
229 | uint8_t *dest_y, | ||
230 | uint8_t *dest_cb, | ||
231 | uint8_t *dest_cr, | ||
232 | int field_based, | ||
233 | int bottom_field, | ||
234 | int field_select, | ||
235 | uint8_t **ref_picture, | ||
236 | op_pixels_func (*pix_op)[4], | ||
237 | int motion_x, | ||
238 | int motion_y, | ||
239 | int h, | ||
240 | int is_mpeg12, | ||
241 | int is_16x8, | ||
242 | int mb_y) | ||
243 | { | ||
244 | uint8_t *ptr_y, *ptr_cb, *ptr_cr; | ||
245 | int dxy, uvdxy, mx, my, src_x, src_y, | ||
246 | uvsrc_x, uvsrc_y, v_edge_pos, block_y_half; | ||
247 | ptrdiff_t uvlinesize, linesize; | ||
248 | |||
249 | 8157600 | v_edge_pos = s->v_edge_pos >> field_based; | |
250 | 8157600 | linesize = s->current_picture.f->linesize[0] << field_based; | |
251 | 8157600 | uvlinesize = s->current_picture.f->linesize[1] << field_based; | |
252 | 8157600 | block_y_half = (field_based | is_16x8); | |
253 | |||
254 | 8157600 | dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
255 | 8157600 | src_x = s->mb_x * 16 + (motion_x >> 1); | |
256 | 8157600 | src_y = (mb_y << (4 - block_y_half)) + (motion_y >> 1); | |
257 | |||
258 |
4/4✓ Branch 0 taken 3969683 times.
✓ Branch 1 taken 4187917 times.
✓ Branch 2 taken 3763726 times.
✓ Branch 3 taken 205957 times.
|
8157600 | if (!is_mpeg12 && s->out_format == FMT_H263) { |
259 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 3763726 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
3763726 | if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) { |
260 | ✗ | mx = (motion_x >> 1) | (motion_x & 1); | |
261 | ✗ | my = motion_y >> 1; | |
262 | ✗ | uvdxy = ((my & 1) << 1) | (mx & 1); | |
263 | ✗ | uvsrc_x = s->mb_x * 8 + (mx >> 1); | |
264 | ✗ | uvsrc_y = (mb_y << (3 - block_y_half)) + (my >> 1); | |
265 | } else { | ||
266 | 3763726 | uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); | |
267 | 3763726 | uvsrc_x = src_x >> 1; | |
268 | 3763726 | uvsrc_y = src_y >> 1; | |
269 | } | ||
270 | // Even chroma mv's are full pel in H261 | ||
271 |
3/4✓ Branch 0 taken 205957 times.
✓ Branch 1 taken 4187917 times.
✓ Branch 2 taken 205957 times.
✗ Branch 3 not taken.
|
4393874 | } else if (!is_mpeg12 && s->out_format == FMT_H261) { |
272 | 205957 | mx = motion_x / 4; | |
273 | 205957 | my = motion_y / 4; | |
274 | 205957 | uvdxy = 0; | |
275 | 205957 | uvsrc_x = s->mb_x * 8 + mx; | |
276 | 205957 | uvsrc_y = mb_y * 8 + my; | |
277 | } else { | ||
278 |
2/2✓ Branch 0 taken 3512421 times.
✓ Branch 1 taken 675496 times.
|
4187917 | if (s->chroma_y_shift) { |
279 | 3512421 | mx = motion_x / 2; | |
280 | 3512421 | my = motion_y / 2; | |
281 | 3512421 | uvdxy = ((my & 1) << 1) | (mx & 1); | |
282 | 3512421 | uvsrc_x = s->mb_x * 8 + (mx >> 1); | |
283 | 3512421 | uvsrc_y = (mb_y << (3 - block_y_half)) + (my >> 1); | |
284 | } else { | ||
285 |
1/2✓ Branch 0 taken 675496 times.
✗ Branch 1 not taken.
|
675496 | if (s->chroma_x_shift) { |
286 | // Chroma422 | ||
287 | 675496 | mx = motion_x / 2; | |
288 | 675496 | uvdxy = ((motion_y & 1) << 1) | (mx & 1); | |
289 | 675496 | uvsrc_x = s->mb_x * 8 + (mx >> 1); | |
290 | 675496 | uvsrc_y = src_y; | |
291 | } else { | ||
292 | // Chroma444 | ||
293 | ✗ | uvdxy = dxy; | |
294 | ✗ | uvsrc_x = src_x; | |
295 | ✗ | uvsrc_y = src_y; | |
296 | } | ||
297 | } | ||
298 | } | ||
299 | |||
300 | 8157600 | ptr_y = ref_picture[0] + src_y * linesize + src_x; | |
301 | 8157600 | ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; | |
302 | 8157600 | ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; | |
303 | |||
304 |
3/4✓ Branch 0 taken 8157600 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8020179 times.
✓ Branch 3 taken 137421 times.
|
8157600 | if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 1) - 15 , 0) || |
305 |
3/4✓ Branch 0 taken 8020179 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 150313 times.
✓ Branch 3 taken 7869866 times.
|
8020179 | (unsigned)src_y >= FFMAX( v_edge_pos - (motion_y & 1) - h + 1, 0)) { |
306 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 287734 times.
|
287734 | if (is_mpeg12 || (CONFIG_SMALL && |
307 | (s->codec_id == AV_CODEC_ID_MPEG2VIDEO || | ||
308 | s->codec_id == AV_CODEC_ID_MPEG1VIDEO))) { | ||
309 | ✗ | av_log(s->avctx, AV_LOG_DEBUG, | |
310 | "MPEG motion vector out of boundary (%d %d)\n", src_x, | ||
311 | src_y); | ||
312 | ✗ | return; | |
313 | } | ||
314 | 287734 | src_y = (unsigned)src_y << field_based; | |
315 | 287734 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y, | |
316 | s->linesize, s->linesize, | ||
317 | 17, 17 + field_based, | ||
318 | src_x, src_y, | ||
319 | s->h_edge_pos, s->v_edge_pos); | ||
320 | 287734 | ptr_y = s->sc.edge_emu_buffer; | |
321 | if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { | ||
322 | 287734 | uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize; | |
323 | 287734 | uint8_t *vbuf = ubuf + 10 * s->uvlinesize; | |
324 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 287734 times.
|
287734 | if (s->workaround_bugs & FF_BUG_IEDGE) |
325 | ✗ | vbuf -= s->uvlinesize; | |
326 | 287734 | uvsrc_y = (unsigned)uvsrc_y << field_based; | |
327 | 287734 | s->vdsp.emulated_edge_mc(ubuf, ptr_cb, | |
328 | s->uvlinesize, s->uvlinesize, | ||
329 | 9, 9 + field_based, | ||
330 | uvsrc_x, uvsrc_y, | ||
331 | 287734 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
332 | 287734 | s->vdsp.emulated_edge_mc(vbuf, ptr_cr, | |
333 | s->uvlinesize, s->uvlinesize, | ||
334 | 9, 9 + field_based, | ||
335 | uvsrc_x, uvsrc_y, | ||
336 | 287734 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
337 | 287734 | ptr_cb = ubuf; | |
338 | 287734 | ptr_cr = vbuf; | |
339 | } | ||
340 | } | ||
341 | |||
342 | /* FIXME use this for field pix too instead of the obnoxious hack which | ||
343 | * changes picture.data */ | ||
344 |
2/2✓ Branch 0 taken 230843 times.
✓ Branch 1 taken 7926757 times.
|
8157600 | if (bottom_field) { |
345 | 230843 | dest_y += s->linesize; | |
346 | 230843 | dest_cb += s->uvlinesize; | |
347 | 230843 | dest_cr += s->uvlinesize; | |
348 | } | ||
349 | |||
350 |
2/2✓ Branch 0 taken 526900 times.
✓ Branch 1 taken 7630700 times.
|
8157600 | if (field_select) { |
351 | 526900 | ptr_y += s->linesize; | |
352 | 526900 | ptr_cb += s->uvlinesize; | |
353 | 526900 | ptr_cr += s->uvlinesize; | |
354 | } | ||
355 | |||
356 | 8157600 | pix_op[0][dxy](dest_y, ptr_y, linesize, h); | |
357 | |||
358 | if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { | ||
359 | 8157600 | pix_op[s->chroma_x_shift][uvdxy] | |
360 | 8157600 | (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); | |
361 | 8157600 | pix_op[s->chroma_x_shift][uvdxy] | |
362 | 8157600 | (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); | |
363 | } | ||
364 |
2/2✓ Branch 0 taken 3969683 times.
✓ Branch 1 taken 4187917 times.
|
8157600 | if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) && |
365 |
2/2✓ Branch 0 taken 205957 times.
✓ Branch 1 taken 3763726 times.
|
3969683 | s->out_format == FMT_H261) { |
366 | 205957 | ff_h261_loop_filter(s); | |
367 | } | ||
368 | } | ||
369 | /* apply one mpeg motion vector to the three components */ | ||
370 | 7695914 | static void mpeg_motion(MpegEncContext *s, | |
371 | uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | ||
372 | int field_select, uint8_t **ref_picture, | ||
373 | op_pixels_func (*pix_op)[4], | ||
374 | int motion_x, int motion_y, int h, int is_16x8, int mb_y) | ||
375 | { | ||
376 | #if !CONFIG_SMALL | ||
377 |
2/2✓ Branch 0 taken 3726231 times.
✓ Branch 1 taken 3969683 times.
|
7695914 | if (s->out_format == FMT_MPEG1) |
378 | 3726231 | mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0, | |
379 | field_select, ref_picture, pix_op, | ||
380 | motion_x, motion_y, h, 1, is_16x8, mb_y); | ||
381 | else | ||
382 | #endif | ||
383 | 3969683 | mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0, | |
384 | field_select, ref_picture, pix_op, | ||
385 | motion_x, motion_y, h, 0, is_16x8, mb_y); | ||
386 | 7695914 | } | |
387 | |||
388 | 461686 | static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y, | |
389 | uint8_t *dest_cb, uint8_t *dest_cr, | ||
390 | int bottom_field, int field_select, | ||
391 | uint8_t **ref_picture, | ||
392 | op_pixels_func (*pix_op)[4], | ||
393 | int motion_x, int motion_y, int h, int mb_y) | ||
394 | { | ||
395 | #if !CONFIG_SMALL | ||
396 |
1/2✓ Branch 0 taken 461686 times.
✗ Branch 1 not taken.
|
461686 | if (s->out_format == FMT_MPEG1) |
397 | 461686 | mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1, | |
398 | bottom_field, field_select, ref_picture, pix_op, | ||
399 | motion_x, motion_y, h, 1, 0, mb_y); | ||
400 | else | ||
401 | #endif | ||
402 | ✗ | mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1, | |
403 | bottom_field, field_select, ref_picture, pix_op, | ||
404 | motion_x, motion_y, h, 0, 0, mb_y); | ||
405 | 461686 | } | |
406 | |||
407 | // FIXME: SIMDify, avg variant, 16x16 version | ||
408 | 412968 | static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride) | |
409 | { | ||
410 | int x; | ||
411 | 412968 | uint8_t *const top = src[1]; | |
412 | 412968 | uint8_t *const left = src[2]; | |
413 | 412968 | uint8_t *const mid = src[0]; | |
414 | 412968 | uint8_t *const right = src[3]; | |
415 | 412968 | uint8_t *const bottom = src[4]; | |
416 | #define OBMC_FILTER(x, t, l, m, r, b)\ | ||
417 | dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3 | ||
418 | #define OBMC_FILTER4(x, t, l, m, r, b)\ | ||
419 | OBMC_FILTER(x , t, l, m, r, b);\ | ||
420 | OBMC_FILTER(x+1 , t, l, m, r, b);\ | ||
421 | OBMC_FILTER(x +stride, t, l, m, r, b);\ | ||
422 | OBMC_FILTER(x+1+stride, t, l, m, r, b); | ||
423 | |||
424 | 412968 | x = 0; | |
425 | 412968 | OBMC_FILTER (x , 2, 2, 4, 0, 0); | |
426 | 412968 | OBMC_FILTER (x + 1, 2, 1, 5, 0, 0); | |
427 | 412968 | OBMC_FILTER4(x + 2, 2, 1, 5, 0, 0); | |
428 | 412968 | OBMC_FILTER4(x + 4, 2, 0, 5, 1, 0); | |
429 | 412968 | OBMC_FILTER (x + 6, 2, 0, 5, 1, 0); | |
430 | 412968 | OBMC_FILTER (x + 7, 2, 0, 4, 2, 0); | |
431 | 412968 | x += stride; | |
432 | 412968 | OBMC_FILTER (x , 1, 2, 5, 0, 0); | |
433 | 412968 | OBMC_FILTER (x + 1, 1, 2, 5, 0, 0); | |
434 | 412968 | OBMC_FILTER (x + 6, 1, 0, 5, 2, 0); | |
435 | 412968 | OBMC_FILTER (x + 7, 1, 0, 5, 2, 0); | |
436 | 412968 | x += stride; | |
437 | 412968 | OBMC_FILTER4(x , 1, 2, 5, 0, 0); | |
438 | 412968 | OBMC_FILTER4(x + 2, 1, 1, 6, 0, 0); | |
439 | 412968 | OBMC_FILTER4(x + 4, 1, 0, 6, 1, 0); | |
440 | 412968 | OBMC_FILTER4(x + 6, 1, 0, 5, 2, 0); | |
441 | 412968 | x += 2 * stride; | |
442 | 412968 | OBMC_FILTER4(x , 0, 2, 5, 0, 1); | |
443 | 412968 | OBMC_FILTER4(x + 2, 0, 1, 6, 0, 1); | |
444 | 412968 | OBMC_FILTER4(x + 4, 0, 0, 6, 1, 1); | |
445 | 412968 | OBMC_FILTER4(x + 6, 0, 0, 5, 2, 1); | |
446 | 412968 | x += 2*stride; | |
447 | 412968 | OBMC_FILTER (x , 0, 2, 5, 0, 1); | |
448 | 412968 | OBMC_FILTER (x + 1, 0, 2, 5, 0, 1); | |
449 | 412968 | OBMC_FILTER4(x + 2, 0, 1, 5, 0, 2); | |
450 | 412968 | OBMC_FILTER4(x + 4, 0, 0, 5, 1, 2); | |
451 | 412968 | OBMC_FILTER (x + 6, 0, 0, 5, 2, 1); | |
452 | 412968 | OBMC_FILTER (x + 7, 0, 0, 5, 2, 1); | |
453 | 412968 | x += stride; | |
454 | 412968 | OBMC_FILTER (x , 0, 2, 4, 0, 2); | |
455 | 412968 | OBMC_FILTER (x + 1, 0, 1, 5, 0, 2); | |
456 | 412968 | OBMC_FILTER (x + 6, 0, 0, 5, 1, 2); | |
457 | 412968 | OBMC_FILTER (x + 7, 0, 0, 4, 2, 2); | |
458 | 412968 | } | |
459 | |||
460 | /* obmc for 1 8x8 luma block */ | ||
461 | 412968 | static inline void obmc_motion(MpegEncContext *s, | |
462 | uint8_t *dest, uint8_t *src, | ||
463 | int src_x, int src_y, | ||
464 | op_pixels_func *pix_op, | ||
465 | int16_t mv[5][2] /* mid top left right bottom */) | ||
466 | #define MID 0 | ||
467 | { | ||
468 | int i; | ||
469 | uint8_t *ptr[5]; | ||
470 | |||
471 | av_assert2(s->quarter_sample == 0); | ||
472 | |||
473 |
2/2✓ Branch 0 taken 2064840 times.
✓ Branch 1 taken 412968 times.
|
2477808 | for (i = 0; i < 5; i++) { |
474 |
6/6✓ Branch 0 taken 1651872 times.
✓ Branch 1 taken 412968 times.
✓ Branch 2 taken 1341676 times.
✓ Branch 3 taken 310196 times.
✓ Branch 4 taken 1241572 times.
✓ Branch 5 taken 100104 times.
|
2064840 | if (i && mv[i][0] == mv[MID][0] && mv[i][1] == mv[MID][1]) { |
475 | 1241572 | ptr[i] = ptr[MID]; | |
476 | } else { | ||
477 | 823268 | ptr[i] = s->sc.obmc_scratchpad + 8 * (i & 1) + | |
478 | 823268 | s->linesize * 8 * (i >> 1); | |
479 | 823268 | hpel_motion(s, ptr[i], src, src_x, src_y, pix_op, | |
480 | 823268 | mv[i][0], mv[i][1]); | |
481 | } | ||
482 | } | ||
483 | |||
484 | 412968 | put_obmc(dest, ptr, s->linesize); | |
485 | 412968 | } | |
486 | |||
487 | 212545 | static inline void qpel_motion(MpegEncContext *s, | |
488 | uint8_t *dest_y, | ||
489 | uint8_t *dest_cb, | ||
490 | uint8_t *dest_cr, | ||
491 | int field_based, int bottom_field, | ||
492 | int field_select, uint8_t **ref_picture, | ||
493 | op_pixels_func (*pix_op)[4], | ||
494 | qpel_mc_func (*qpix_op)[16], | ||
495 | int motion_x, int motion_y, int h) | ||
496 | { | ||
497 | uint8_t *ptr_y, *ptr_cb, *ptr_cr; | ||
498 | int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos; | ||
499 | ptrdiff_t linesize, uvlinesize; | ||
500 | |||
501 | 212545 | dxy = ((motion_y & 3) << 2) | (motion_x & 3); | |
502 | |||
503 | 212545 | src_x = s->mb_x * 16 + (motion_x >> 2); | |
504 | 212545 | src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); | |
505 | |||
506 | 212545 | v_edge_pos = s->v_edge_pos >> field_based; | |
507 | 212545 | linesize = s->linesize << field_based; | |
508 | 212545 | uvlinesize = s->uvlinesize << field_based; | |
509 | |||
510 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 212545 times.
|
212545 | if (field_based) { |
511 | ✗ | mx = motion_x / 2; | |
512 | ✗ | my = motion_y >> 1; | |
513 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 212545 times.
|
212545 | } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA2) { |
514 | static const int rtab[8] = { 0, 0, 1, 1, 0, 0, 0, 1 }; | ||
515 | ✗ | mx = (motion_x >> 1) + rtab[motion_x & 7]; | |
516 | ✗ | my = (motion_y >> 1) + rtab[motion_y & 7]; | |
517 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 212545 times.
|
212545 | } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA) { |
518 | ✗ | mx = (motion_x >> 1) | (motion_x & 1); | |
519 | ✗ | my = (motion_y >> 1) | (motion_y & 1); | |
520 | } else { | ||
521 | 212545 | mx = motion_x / 2; | |
522 | 212545 | my = motion_y / 2; | |
523 | } | ||
524 | 212545 | mx = (mx >> 1) | (mx & 1); | |
525 | 212545 | my = (my >> 1) | (my & 1); | |
526 | |||
527 | 212545 | uvdxy = (mx & 1) | ((my & 1) << 1); | |
528 | 212545 | mx >>= 1; | |
529 | 212545 | my >>= 1; | |
530 | |||
531 | 212545 | uvsrc_x = s->mb_x * 8 + mx; | |
532 | 212545 | uvsrc_y = s->mb_y * (8 >> field_based) + my; | |
533 | |||
534 | 212545 | ptr_y = ref_picture[0] + src_y * linesize + src_x; | |
535 | 212545 | ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; | |
536 | 212545 | ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; | |
537 | |||
538 |
3/4✓ Branch 0 taken 212545 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 202996 times.
✓ Branch 3 taken 9549 times.
|
212545 | if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 15 , 0) || |
539 |
3/4✓ Branch 0 taken 202996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11156 times.
✓ Branch 3 taken 191840 times.
|
202996 | (unsigned)src_y >= FFMAX( v_edge_pos - (motion_y & 3) - h + 1, 0)) { |
540 | 20705 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y, | |
541 | s->linesize, s->linesize, | ||
542 | 17, 17 + field_based, | ||
543 | src_x, src_y * (1 << field_based), | ||
544 | s->h_edge_pos, s->v_edge_pos); | ||
545 | 20705 | ptr_y = s->sc.edge_emu_buffer; | |
546 | if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { | ||
547 | 20705 | uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize; | |
548 | 20705 | uint8_t *vbuf = ubuf + 10 * s->uvlinesize; | |
549 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20705 times.
|
20705 | if (s->workaround_bugs & FF_BUG_IEDGE) |
550 | ✗ | vbuf -= s->uvlinesize; | |
551 | 20705 | s->vdsp.emulated_edge_mc(ubuf, ptr_cb, | |
552 | s->uvlinesize, s->uvlinesize, | ||
553 | 9, 9 + field_based, | ||
554 | uvsrc_x, uvsrc_y * (1 << field_based), | ||
555 | 20705 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
556 | 20705 | s->vdsp.emulated_edge_mc(vbuf, ptr_cr, | |
557 | s->uvlinesize, s->uvlinesize, | ||
558 | 9, 9 + field_based, | ||
559 | uvsrc_x, uvsrc_y * (1 << field_based), | ||
560 | 20705 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
561 | 20705 | ptr_cb = ubuf; | |
562 | 20705 | ptr_cr = vbuf; | |
563 | } | ||
564 | } | ||
565 | |||
566 |
1/2✓ Branch 0 taken 212545 times.
✗ Branch 1 not taken.
|
212545 | if (!field_based) |
567 | 212545 | qpix_op[0][dxy](dest_y, ptr_y, linesize); | |
568 | else { | ||
569 | ✗ | if (bottom_field) { | |
570 | ✗ | dest_y += s->linesize; | |
571 | ✗ | dest_cb += s->uvlinesize; | |
572 | ✗ | dest_cr += s->uvlinesize; | |
573 | } | ||
574 | |||
575 | ✗ | if (field_select) { | |
576 | ✗ | ptr_y += s->linesize; | |
577 | ✗ | ptr_cb += s->uvlinesize; | |
578 | ✗ | ptr_cr += s->uvlinesize; | |
579 | } | ||
580 | // damn interlaced mode | ||
581 | // FIXME boundary mirroring is not exactly correct here | ||
582 | ✗ | qpix_op[1][dxy](dest_y, ptr_y, linesize); | |
583 | ✗ | qpix_op[1][dxy](dest_y + 8, ptr_y + 8, linesize); | |
584 | } | ||
585 | if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { | ||
586 | 212545 | pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1); | |
587 | 212545 | pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1); | |
588 | } | ||
589 | 212545 | } | |
590 | |||
591 | /** | ||
592 | * H.263 chroma 4mv motion compensation. | ||
593 | */ | ||
594 | 683767 | static void chroma_4mv_motion(MpegEncContext *s, | |
595 | uint8_t *dest_cb, uint8_t *dest_cr, | ||
596 | uint8_t **ref_picture, | ||
597 | op_pixels_func *pix_op, | ||
598 | int mx, int my) | ||
599 | { | ||
600 | uint8_t *ptr; | ||
601 | 683767 | int src_x, src_y, dxy, emu = 0; | |
602 | ptrdiff_t offset; | ||
603 | |||
604 | /* In case of 8X8, we construct a single chroma motion vector | ||
605 | * with a special rounding */ | ||
606 | 683767 | mx = ff_h263_round_chroma(mx); | |
607 | 683767 | my = ff_h263_round_chroma(my); | |
608 | |||
609 | 683767 | dxy = ((my & 1) << 1) | (mx & 1); | |
610 | 683767 | mx >>= 1; | |
611 | 683767 | my >>= 1; | |
612 | |||
613 | 683767 | src_x = s->mb_x * 8 + mx; | |
614 | 683767 | src_y = s->mb_y * 8 + my; | |
615 | 683767 | src_x = av_clip(src_x, -8, (s->width >> 1)); | |
616 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 683765 times.
|
683767 | if (src_x == (s->width >> 1)) |
617 | 2 | dxy &= ~1; | |
618 | 683767 | src_y = av_clip(src_y, -8, (s->height >> 1)); | |
619 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 683752 times.
|
683767 | if (src_y == (s->height >> 1)) |
620 | 15 | dxy &= ~2; | |
621 | |||
622 | 683767 | offset = src_y * s->uvlinesize + src_x; | |
623 | 683767 | ptr = ref_picture[1] + offset; | |
624 |
3/4✓ Branch 0 taken 683767 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 656829 times.
✓ Branch 3 taken 26938 times.
|
683767 | if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - (dxy & 1) - 7, 0) || |
625 |
3/4✓ Branch 0 taken 656829 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28739 times.
✓ Branch 3 taken 628090 times.
|
656829 | (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 7, 0)) { |
626 | 55677 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr, | |
627 | s->uvlinesize, s->uvlinesize, | ||
628 | 9, 9, src_x, src_y, | ||
629 | 55677 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
630 | 55677 | ptr = s->sc.edge_emu_buffer; | |
631 | 55677 | emu = 1; | |
632 | } | ||
633 | 683767 | pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8); | |
634 | |||
635 | 683767 | ptr = ref_picture[2] + offset; | |
636 |
2/2✓ Branch 0 taken 55677 times.
✓ Branch 1 taken 628090 times.
|
683767 | if (emu) { |
637 | 55677 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr, | |
638 | s->uvlinesize, s->uvlinesize, | ||
639 | 9, 9, src_x, src_y, | ||
640 | 55677 | s->h_edge_pos >> 1, s->v_edge_pos >> 1); | |
641 | 55677 | ptr = s->sc.edge_emu_buffer; | |
642 | } | ||
643 | 683767 | pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8); | |
644 | 683767 | } | |
645 | |||
646 | 8738249 | static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir) | |
647 | { | ||
648 | /* fetch pixels for estimated mv 4 macroblocks ahead | ||
649 | * optimized for 64byte cache lines */ | ||
650 |
2/2✓ Branch 0 taken 339076 times.
✓ Branch 1 taken 8399173 times.
|
8738249 | const int shift = s->quarter_sample ? 2 : 1; |
651 | 8738249 | const int mx = (s->mv[dir][0][0] >> shift) + 16 * s->mb_x + 8; | |
652 | 8738249 | const int my = (s->mv[dir][0][1] >> shift) + 16 * s->mb_y; | |
653 | 8738249 | int off = mx + (my + (s->mb_x & 3) * 4) * s->linesize + 64; | |
654 | |||
655 | 8738249 | s->vdsp.prefetch(pix[0] + off, s->linesize, 4); | |
656 | 8738249 | off = (mx >> 1) + ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize + 64; | |
657 | 8738249 | s->vdsp.prefetch(pix[1] + off, pix[2] - pix[1], 2); | |
658 | 8738249 | } | |
659 | |||
660 | 103242 | static inline void apply_obmc(MpegEncContext *s, | |
661 | uint8_t *dest_y, | ||
662 | uint8_t *dest_cb, | ||
663 | uint8_t *dest_cr, | ||
664 | uint8_t **ref_picture, | ||
665 | op_pixels_func (*pix_op)[4]) | ||
666 | { | ||
667 | 103242 | LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]); | |
668 | 103242 | Picture *cur_frame = &s->current_picture; | |
669 | 103242 | int mb_x = s->mb_x; | |
670 | 103242 | int mb_y = s->mb_y; | |
671 | 103242 | const int xy = mb_x + mb_y * s->mb_stride; | |
672 | 103242 | const int mot_stride = s->b8_stride; | |
673 | 103242 | const int mot_xy = mb_x * 2 + mb_y * 2 * mot_stride; | |
674 | int mx, my, i; | ||
675 | |||
676 | av_assert2(!s->mb_skipped); | ||
677 | |||
678 | 103242 | AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy]); | |
679 | 103242 | AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]); | |
680 | |||
681 | 103242 | AV_COPY32(mv_cache[2][1], | |
682 | cur_frame->motion_val[0][mot_xy + mot_stride]); | ||
683 | 103242 | AV_COPY32(mv_cache[2][2], | |
684 | cur_frame->motion_val[0][mot_xy + mot_stride + 1]); | ||
685 | |||
686 | 103242 | AV_COPY32(mv_cache[3][1], | |
687 | cur_frame->motion_val[0][mot_xy + mot_stride]); | ||
688 | 103242 | AV_COPY32(mv_cache[3][2], | |
689 | cur_frame->motion_val[0][mot_xy + mot_stride + 1]); | ||
690 | |||
691 |
4/4✓ Branch 0 taken 97570 times.
✓ Branch 1 taken 5672 times.
✓ Branch 2 taken 2068 times.
✓ Branch 3 taken 95502 times.
|
103242 | if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) { |
692 | 7740 | AV_COPY32(mv_cache[0][1], mv_cache[1][1]); | |
693 | 7740 | AV_COPY32(mv_cache[0][2], mv_cache[1][2]); | |
694 | } else { | ||
695 | 95502 | AV_COPY32(mv_cache[0][1], | |
696 | cur_frame->motion_val[0][mot_xy - mot_stride]); | ||
697 | 95502 | AV_COPY32(mv_cache[0][2], | |
698 | cur_frame->motion_val[0][mot_xy - mot_stride + 1]); | ||
699 | } | ||
700 | |||
701 |
4/4✓ Branch 0 taken 98604 times.
✓ Branch 1 taken 4638 times.
✓ Branch 2 taken 1848 times.
✓ Branch 3 taken 96756 times.
|
103242 | if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) { |
702 | 6486 | AV_COPY32(mv_cache[1][0], mv_cache[1][1]); | |
703 | 6486 | AV_COPY32(mv_cache[2][0], mv_cache[2][1]); | |
704 | } else { | ||
705 | 96756 | AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]); | |
706 | 96756 | AV_COPY32(mv_cache[2][0], | |
707 | cur_frame->motion_val[0][mot_xy - 1 + mot_stride]); | ||
708 | } | ||
709 | |||
710 |
4/4✓ Branch 0 taken 98684 times.
✓ Branch 1 taken 4558 times.
✓ Branch 2 taken 1971 times.
✓ Branch 3 taken 96713 times.
|
103242 | if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) { |
711 | 6529 | AV_COPY32(mv_cache[1][3], mv_cache[1][2]); | |
712 | 6529 | AV_COPY32(mv_cache[2][3], mv_cache[2][2]); | |
713 | } else { | ||
714 | 96713 | AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]); | |
715 | 96713 | AV_COPY32(mv_cache[2][3], | |
716 | cur_frame->motion_val[0][mot_xy + 2 + mot_stride]); | ||
717 | } | ||
718 | |||
719 | 103242 | mx = 0; | |
720 | 103242 | my = 0; | |
721 |
2/2✓ Branch 0 taken 412968 times.
✓ Branch 1 taken 103242 times.
|
516210 | for (i = 0; i < 4; i++) { |
722 | 412968 | const int x = (i & 1) + 1; | |
723 | 412968 | const int y = (i >> 1) + 1; | |
724 | 412968 | int16_t mv[5][2] = { | |
725 | 412968 | { mv_cache[y][x][0], mv_cache[y][x][1] }, | |
726 | 412968 | { mv_cache[y - 1][x][0], mv_cache[y - 1][x][1] }, | |
727 | 412968 | { mv_cache[y][x - 1][0], mv_cache[y][x - 1][1] }, | |
728 | 412968 | { mv_cache[y][x + 1][0], mv_cache[y][x + 1][1] }, | |
729 | 412968 | { mv_cache[y + 1][x][0], mv_cache[y + 1][x][1] } | |
730 | }; | ||
731 | // FIXME cleanup | ||
732 | 412968 | obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, | |
733 | ref_picture[0], | ||
734 | 412968 | mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8, | |
735 | 412968 | pix_op[1], | |
736 | mv); | ||
737 | |||
738 | 412968 | mx += mv[0][0]; | |
739 | 412968 | my += mv[0][1]; | |
740 | } | ||
741 | if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) | ||
742 | 103242 | chroma_4mv_motion(s, dest_cb, dest_cr, | |
743 | 103242 | ref_picture, pix_op[1], | |
744 | mx, my); | ||
745 | 103242 | } | |
746 | |||
747 | 580525 | static inline void apply_8x8(MpegEncContext *s, | |
748 | uint8_t *dest_y, | ||
749 | uint8_t *dest_cb, | ||
750 | uint8_t *dest_cr, | ||
751 | int dir, | ||
752 | uint8_t **ref_picture, | ||
753 | qpel_mc_func (*qpix_op)[16], | ||
754 | op_pixels_func (*pix_op)[4]) | ||
755 | { | ||
756 | int dxy, mx, my, src_x, src_y; | ||
757 | int i; | ||
758 | 580525 | int mb_x = s->mb_x; | |
759 | 580525 | int mb_y = s->mb_y; | |
760 | uint8_t *ptr, *dest; | ||
761 | |||
762 | 580525 | mx = 0; | |
763 | 580525 | my = 0; | |
764 |
2/2✓ Branch 0 taken 126531 times.
✓ Branch 1 taken 453994 times.
|
580525 | if (s->quarter_sample) { |
765 |
2/2✓ Branch 0 taken 506124 times.
✓ Branch 1 taken 126531 times.
|
632655 | for (i = 0; i < 4; i++) { |
766 | 506124 | int motion_x = s->mv[dir][i][0]; | |
767 | 506124 | int motion_y = s->mv[dir][i][1]; | |
768 | |||
769 | 506124 | dxy = ((motion_y & 3) << 2) | (motion_x & 3); | |
770 | 506124 | src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; | |
771 | 506124 | src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8; | |
772 | |||
773 | /* WARNING: do no forget half pels */ | ||
774 | 506124 | src_x = av_clip(src_x, -16, s->width); | |
775 |
2/2✓ Branch 0 taken 698 times.
✓ Branch 1 taken 505426 times.
|
506124 | if (src_x == s->width) |
776 | 698 | dxy &= ~3; | |
777 | 506124 | src_y = av_clip(src_y, -16, s->height); | |
778 |
2/2✓ Branch 0 taken 838 times.
✓ Branch 1 taken 505286 times.
|
506124 | if (src_y == s->height) |
779 | 838 | dxy &= ~12; | |
780 | |||
781 | 506124 | ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); | |
782 |
3/4✓ Branch 0 taken 506124 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 494465 times.
✓ Branch 3 taken 11659 times.
|
506124 | if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 7, 0) || |
783 |
3/4✓ Branch 0 taken 494465 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12714 times.
✓ Branch 3 taken 481751 times.
|
494465 | (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 3) - 7, 0)) { |
784 | 24373 | s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr, | |
785 | s->linesize, s->linesize, | ||
786 | 9, 9, | ||
787 | src_x, src_y, | ||
788 | s->h_edge_pos, | ||
789 | s->v_edge_pos); | ||
790 | 24373 | ptr = s->sc.edge_emu_buffer; | |
791 | } | ||
792 | 506124 | dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; | |
793 | 506124 | qpix_op[1][dxy](dest, ptr, s->linesize); | |
794 | |||
795 | 506124 | mx += s->mv[dir][i][0] / 2; | |
796 | 506124 | my += s->mv[dir][i][1] / 2; | |
797 | } | ||
798 | } else { | ||
799 |
2/2✓ Branch 0 taken 1815976 times.
✓ Branch 1 taken 453994 times.
|
2269970 | for (i = 0; i < 4; i++) { |
800 | 1815976 | hpel_motion(s, | |
801 | 1815976 | dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, | |
802 | ref_picture[0], | ||
803 | 1815976 | mb_x * 16 + (i & 1) * 8, | |
804 | 1815976 | mb_y * 16 + (i >> 1) * 8, | |
805 | 1815976 | pix_op[1], | |
806 | s->mv[dir][i][0], | ||
807 | s->mv[dir][i][1]); | ||
808 | |||
809 | 1815976 | mx += s->mv[dir][i][0]; | |
810 | 1815976 | my += s->mv[dir][i][1]; | |
811 | } | ||
812 | } | ||
813 | |||
814 | if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) | ||
815 | 580525 | chroma_4mv_motion(s, dest_cb, dest_cr, | |
816 | 580525 | ref_picture, pix_op[1], mx, my); | |
817 | 580525 | } | |
818 | |||
819 | /** | ||
820 | * motion compensation of a single macroblock | ||
821 | * @param s context | ||
822 | * @param dest_y luma destination pointer | ||
823 | * @param dest_cb chroma cb/u destination pointer | ||
824 | * @param dest_cr chroma cr/v destination pointer | ||
825 | * @param dir direction (0->forward, 1->backward) | ||
826 | * @param ref_picture array[3] of pointers to the 3 planes of the reference picture | ||
827 | * @param pix_op halfpel motion compensation function (average or put normally) | ||
828 | * @param qpix_op qpel motion compensation function (average or put normally) | ||
829 | * the motion vectors are taken from s->mv and the MV type from s->mv_type | ||
830 | */ | ||
831 | 8738249 | static av_always_inline void mpv_motion_internal(MpegEncContext *s, | |
832 | uint8_t *dest_y, | ||
833 | uint8_t *dest_cb, | ||
834 | uint8_t *dest_cr, | ||
835 | int dir, | ||
836 | uint8_t **ref_picture, | ||
837 | op_pixels_func (*pix_op)[4], | ||
838 | qpel_mc_func (*qpix_op)[16], | ||
839 | int is_mpeg12) | ||
840 | { | ||
841 | int i; | ||
842 | 8738249 | int mb_y = s->mb_y; | |
843 | |||
844 |
5/6✓ Branch 0 taken 4946488 times.
✓ Branch 1 taken 3791761 times.
✓ Branch 2 taken 103242 times.
✓ Branch 3 taken 4843246 times.
✓ Branch 4 taken 103242 times.
✗ Branch 5 not taken.
|
8738249 | if (!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B) { |
845 | 103242 | apply_obmc(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op); | |
846 | 103242 | return; | |
847 | } | ||
848 | |||
849 |
5/6✓ Branch 0 taken 7409864 times.
✓ Branch 1 taken 580525 times.
✓ Branch 2 taken 479305 times.
✓ Branch 3 taken 153889 times.
✓ Branch 4 taken 11424 times.
✗ Branch 5 not taken.
|
8635007 | switch (s->mv_type) { |
850 | 7409864 | case MV_TYPE_16X16: | |
851 |
3/4✓ Branch 0 taken 4262721 times.
✓ Branch 1 taken 3147143 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4262721 times.
|
7409864 | if (!is_mpeg12 && s->mcsel) { |
852 | ✗ | if (s->real_sprite_warping_points == 1) { | |
853 | ✗ | gmc1_motion(s, dest_y, dest_cb, dest_cr, | |
854 | ref_picture); | ||
855 | } else { | ||
856 | ✗ | gmc_motion(s, dest_y, dest_cb, dest_cr, | |
857 | ref_picture); | ||
858 | } | ||
859 |
4/4✓ Branch 0 taken 4262721 times.
✓ Branch 1 taken 3147143 times.
✓ Branch 2 taken 212545 times.
✓ Branch 3 taken 4050176 times.
|
7409864 | } else if (!is_mpeg12 && s->quarter_sample) { |
860 | 212545 | qpel_motion(s, dest_y, dest_cb, dest_cr, | |
861 | 0, 0, 0, | ||
862 | ref_picture, pix_op, qpix_op, | ||
863 | s->mv[dir][0][0], s->mv[dir][0][1], 16); | ||
864 |
2/2✓ Branch 0 taken 4050176 times.
✓ Branch 1 taken 3147143 times.
|
7197319 | } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && |
865 |
3/4✓ Branch 0 taken 80493 times.
✓ Branch 1 taken 3969683 times.
✓ Branch 2 taken 80493 times.
✗ Branch 3 not taken.
|
4050176 | s->mspel && s->codec_id == AV_CODEC_ID_WMV2) { |
866 | 80493 | ff_mspel_motion(s, dest_y, dest_cb, dest_cr, | |
867 | ref_picture, pix_op, | ||
868 | s->mv[dir][0][0], s->mv[dir][0][1], 16); | ||
869 | } else { | ||
870 | 7116826 | mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, | |
871 | ref_picture, pix_op, | ||
872 | s->mv[dir][0][0], s->mv[dir][0][1], 16, 0, mb_y); | ||
873 | } | ||
874 | 7409864 | break; | |
875 | 580525 | case MV_TYPE_8X8: | |
876 |
1/2✓ Branch 0 taken 580525 times.
✗ Branch 1 not taken.
|
580525 | if (!is_mpeg12) |
877 | 580525 | apply_8x8(s, dest_y, dest_cb, dest_cr, | |
878 | dir, ref_picture, qpix_op, pix_op); | ||
879 | 580525 | break; | |
880 | 479305 | case MV_TYPE_FIELD: | |
881 |
2/2✓ Branch 0 taken 230843 times.
✓ Branch 1 taken 248462 times.
|
479305 | if (s->picture_structure == PICT_FRAME) { |
882 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 230843 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
230843 | if (!is_mpeg12 && s->quarter_sample) { |
883 | ✗ | for (i = 0; i < 2; i++) | |
884 | ✗ | qpel_motion(s, dest_y, dest_cb, dest_cr, | |
885 | 1, i, s->field_select[dir][i], | ||
886 | ref_picture, pix_op, qpix_op, | ||
887 | s->mv[dir][i][0], s->mv[dir][i][1], 8); | ||
888 | } else { | ||
889 | /* top field */ | ||
890 | 230843 | mpeg_motion_field(s, dest_y, dest_cb, dest_cr, | |
891 | 0, s->field_select[dir][0], | ||
892 | ref_picture, pix_op, | ||
893 | s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y); | ||
894 | /* bottom field */ | ||
895 | 230843 | mpeg_motion_field(s, dest_y, dest_cb, dest_cr, | |
896 | 1, s->field_select[dir][1], | ||
897 | ref_picture, pix_op, | ||
898 | s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y); | ||
899 | } | ||
900 | } else { | ||
901 |
6/6✓ Branch 0 taken 40900 times.
✓ Branch 1 taken 207562 times.
✓ Branch 2 taken 29953 times.
✓ Branch 3 taken 10947 times.
✓ Branch 4 taken 7184 times.
✓ Branch 5 taken 22769 times.
|
248462 | if ( s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field |
902 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 225693 times.
|
225693 | || !ref_picture[0]) { |
903 | 22769 | ref_picture = s->current_picture_ptr->f->data; | |
904 | } | ||
905 | |||
906 | 248462 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
907 | s->field_select[dir][0], | ||
908 | ref_picture, pix_op, | ||
909 | s->mv[dir][0][0], s->mv[dir][0][1], 16, 0, mb_y >> 1); | ||
910 | } | ||
911 | 479305 | break; | |
912 | 153889 | case MV_TYPE_16X8: | |
913 |
1/2✓ Branch 0 taken 153889 times.
✗ Branch 1 not taken.
|
153889 | if (CONFIG_SMALL || is_mpeg12) { |
914 |
2/2✓ Branch 0 taken 307778 times.
✓ Branch 1 taken 153889 times.
|
461667 | for (i = 0; i < 2; i++) { |
915 | uint8_t **ref2picture; | ||
916 | |||
917 |
2/2✓ Branch 0 taken 42179 times.
✓ Branch 1 taken 265599 times.
|
307778 | if ((s->picture_structure == s->field_select[dir][i] + 1 || |
918 |
4/4✓ Branch 0 taken 40482 times.
✓ Branch 1 taken 1697 times.
✓ Branch 2 taken 4332 times.
✓ Branch 3 taken 36150 times.
|
42179 | s->pict_type == AV_PICTURE_TYPE_B || s->first_field) && |
919 |
1/2✓ Branch 0 taken 271628 times.
✗ Branch 1 not taken.
|
271628 | ref_picture[0]) { |
920 | 271628 | ref2picture = ref_picture; | |
921 | } else { | ||
922 | 36150 | ref2picture = s->current_picture_ptr->f->data; | |
923 | } | ||
924 | |||
925 | 307778 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
926 | s->field_select[dir][i], | ||
927 | ref2picture, pix_op, | ||
928 | s->mv[dir][i][0], s->mv[dir][i][1], | ||
929 | 307778 | 8, 1, (mb_y & ~1) + i); | |
930 | |||
931 | 307778 | dest_y += 16 * s->linesize; | |
932 | 307778 | dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize; | |
933 | 307778 | dest_cr += (16 >> s->chroma_y_shift) * s->uvlinesize; | |
934 | } | ||
935 | 153889 | break; | |
936 | } | ||
937 | case MV_TYPE_DMV: | ||
938 |
1/2✓ Branch 0 taken 11424 times.
✗ Branch 1 not taken.
|
11424 | if (CONFIG_SMALL || is_mpeg12) { |
939 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11424 times.
|
11424 | if (s->picture_structure == PICT_FRAME) { |
940 | ✗ | for (i = 0; i < 2; i++) { | |
941 | ✗ | for (int j = 0; j < 2; j++) | |
942 | ✗ | mpeg_motion_field(s, dest_y, dest_cb, dest_cr, | |
943 | j, j ^ i, ref_picture, pix_op, | ||
944 | ✗ | s->mv[dir][2 * i + j][0], | |
945 | ✗ | s->mv[dir][2 * i + j][1], 8, mb_y); | |
946 | ✗ | pix_op = s->hdsp.avg_pixels_tab; | |
947 | } | ||
948 | } else { | ||
949 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11424 times.
|
11424 | if (!ref_picture[0]) { |
950 | ✗ | ref_picture = s->current_picture_ptr->f->data; | |
951 | } | ||
952 |
2/2✓ Branch 0 taken 22848 times.
✓ Branch 1 taken 11424 times.
|
34272 | for (i = 0; i < 2; i++) { |
953 | 22848 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
954 | 22848 | s->picture_structure != i + 1, | |
955 | ref_picture, pix_op, | ||
956 | 22848 | s->mv[dir][2 * i][0], s->mv[dir][2 * i][1], | |
957 | 16, 0, mb_y >> 1); | ||
958 | |||
959 | // after put we make avg of the same block | ||
960 | 22848 | pix_op = s->hdsp.avg_pixels_tab; | |
961 | |||
962 | /* opposite parity is always in the same frame if this is | ||
963 | * second field */ | ||
964 |
2/2✓ Branch 0 taken 19632 times.
✓ Branch 1 taken 3216 times.
|
22848 | if (!s->first_field) |
965 | 19632 | ref_picture = s->current_picture_ptr->f->data; | |
966 | } | ||
967 | } | ||
968 | 11424 | break; | |
969 | } | ||
970 | default: av_assert2(0); | ||
971 | } | ||
972 | } | ||
973 | |||
974 | 8738249 | void ff_mpv_motion(MpegEncContext *s, | |
975 | uint8_t *dest_y, uint8_t *dest_cb, | ||
976 | uint8_t *dest_cr, int dir, | ||
977 | uint8_t **ref_picture, | ||
978 | op_pixels_func (*pix_op)[4], | ||
979 | qpel_mc_func (*qpix_op)[16]) | ||
980 | { | ||
981 | 8738249 | prefetch_motion(s, ref_picture, dir); | |
982 | |||
983 | #if !CONFIG_SMALL | ||
984 |
2/2✓ Branch 0 taken 3791761 times.
✓ Branch 1 taken 4946488 times.
|
8738249 | if (s->out_format == FMT_MPEG1) |
985 | 3791761 | mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir, | |
986 | ref_picture, pix_op, qpix_op, 1); | ||
987 | else | ||
988 | #endif | ||
989 | 4946488 | mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir, | |
990 | ref_picture, pix_op, qpix_op, 0); | ||
991 | 8738249 | } | |
992 |