Commit | Line | Data |
---|---|---|
3ada94ba | 1 | /* |
406792e7 | 2 | * Copyright (c) 2000,2001 Fabrice Bellard |
3ada94ba BF |
3 | * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> |
4 | * | |
7b94177e DB |
5 | * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> |
6 | * | |
2912e87a | 7 | * This file is part of Libav. |
3ada94ba | 8 | * |
2912e87a | 9 | * Libav is free software; you can redistribute it and/or |
3ada94ba BF |
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 | * | |
2912e87a | 14 | * Libav is distributed in the hope that it will be useful, |
3ada94ba BF |
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 | |
2912e87a | 20 | * License along with Libav; if not, write to the Free Software |
3ada94ba | 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
3ada94ba BF |
22 | */ |
23 | ||
c60208e7 | 24 | #include <string.h> |
3ada94ba BF |
25 | #include "avcodec.h" |
26 | #include "dsputil.h" | |
27 | #include "mpegvideo.h" | |
28 | #include "mjpegenc.h" | |
29 | #include "msmpeg4.h" | |
3ada94ba BF |
30 | #include <limits.h> |
31 | ||
3ada94ba BF |
32 | static inline void gmc1_motion(MpegEncContext *s, |
33 | uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | |
34 | uint8_t **ref_picture) | |
35 | { | |
36 | uint8_t *ptr; | |
37 | int offset, src_x, src_y, linesize, uvlinesize; | |
38 | int motion_x, motion_y; | |
39 | int emu=0; | |
40 | ||
41 | motion_x= s->sprite_offset[0][0]; | |
42 | motion_y= s->sprite_offset[0][1]; | |
43 | src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1)); | |
44 | src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1)); | |
45 | motion_x<<=(3-s->sprite_warping_accuracy); | |
46 | motion_y<<=(3-s->sprite_warping_accuracy); | |
47 | src_x = av_clip(src_x, -16, s->width); | |
48 | if (src_x == s->width) | |
49 | motion_x =0; | |
50 | src_y = av_clip(src_y, -16, s->height); | |
51 | if (src_y == s->height) | |
52 | motion_y =0; | |
53 | ||
54 | linesize = s->linesize; | |
55 | uvlinesize = s->uvlinesize; | |
56 | ||
57 | ptr = ref_picture[0] + (src_y * linesize) + src_x; | |
58 | ||
59 | if(s->flags&CODEC_FLAG_EMU_EDGE){ | |
9b6aafba JB |
60 | if( (unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) |
61 | || (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)){ | |
2e279598 | 62 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos); |
3ada94ba BF |
63 | ptr= s->edge_emu_buffer; |
64 | } | |
65 | } | |
66 | ||
67 | if((motion_x|motion_y)&7){ | |
68 | s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); | |
69 | s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); | |
70 | }else{ | |
71 | int dxy; | |
72 | ||
73 | dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2); | |
74 | if (s->no_rounding){ | |
75 | s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16); | |
76 | }else{ | |
77 | s->dsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16); | |
78 | } | |
79 | } | |
80 | ||
49fb20cb | 81 | if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return; |
3ada94ba BF |
82 | |
83 | motion_x= s->sprite_offset[1][0]; | |
84 | motion_y= s->sprite_offset[1][1]; | |
85 | src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1)); | |
86 | src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1)); | |
87 | motion_x<<=(3-s->sprite_warping_accuracy); | |
88 | motion_y<<=(3-s->sprite_warping_accuracy); | |
89 | src_x = av_clip(src_x, -8, s->width>>1); | |
90 | if (src_x == s->width>>1) | |
91 | motion_x =0; | |
92 | src_y = av_clip(src_y, -8, s->height>>1); | |
93 | if (src_y == s->height>>1) | |
94 | motion_y =0; | |
95 | ||
96 | offset = (src_y * uvlinesize) + src_x; | |
97 | ptr = ref_picture[1] + offset; | |
98 | if(s->flags&CODEC_FLAG_EMU_EDGE){ | |
9b6aafba JB |
99 | if( (unsigned)src_x >= FFMAX((s->h_edge_pos>>1) - 9, 0) |
100 | || (unsigned)src_y >= FFMAX((s->v_edge_pos>>1) - 9, 0)){ | |
2e279598 | 101 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); |
3ada94ba BF |
102 | ptr= s->edge_emu_buffer; |
103 | emu=1; | |
104 | } | |
105 | } | |
106 | s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); | |
107 | ||
108 | ptr = ref_picture[2] + offset; | |
109 | if(emu){ | |
2e279598 | 110 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); |
3ada94ba BF |
111 | ptr= s->edge_emu_buffer; |
112 | } | |
113 | s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); | |
114 | ||
115 | return; | |
116 | } | |
117 | ||
118 | static inline void gmc_motion(MpegEncContext *s, | |
119 | uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | |
120 | uint8_t **ref_picture) | |
121 | { | |
122 | uint8_t *ptr; | |
123 | int linesize, uvlinesize; | |
124 | const int a= s->sprite_warping_accuracy; | |
125 | int ox, oy; | |
126 | ||
127 | linesize = s->linesize; | |
128 | uvlinesize = s->uvlinesize; | |
129 | ||
130 | ptr = ref_picture[0]; | |
131 | ||
132 | ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16; | |
133 | oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16; | |
134 | ||
135 | s->dsp.gmc(dest_y, ptr, linesize, 16, | |
136 | ox, | |
137 | oy, | |
138 | s->sprite_delta[0][0], s->sprite_delta[0][1], | |
139 | s->sprite_delta[1][0], s->sprite_delta[1][1], | |
140 | a+1, (1<<(2*a+1)) - s->no_rounding, | |
141 | s->h_edge_pos, s->v_edge_pos); | |
142 | s->dsp.gmc(dest_y+8, ptr, linesize, 16, | |
143 | ox + s->sprite_delta[0][0]*8, | |
144 | oy + s->sprite_delta[1][0]*8, | |
145 | s->sprite_delta[0][0], s->sprite_delta[0][1], | |
146 | s->sprite_delta[1][0], s->sprite_delta[1][1], | |
147 | a+1, (1<<(2*a+1)) - s->no_rounding, | |
148 | s->h_edge_pos, s->v_edge_pos); | |
149 | ||
49fb20cb | 150 | if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return; |
3ada94ba BF |
151 | |
152 | ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8; | |
153 | oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8; | |
154 | ||
155 | ptr = ref_picture[1]; | |
156 | s->dsp.gmc(dest_cb, ptr, uvlinesize, 8, | |
157 | ox, | |
158 | oy, | |
159 | s->sprite_delta[0][0], s->sprite_delta[0][1], | |
160 | s->sprite_delta[1][0], s->sprite_delta[1][1], | |
161 | a+1, (1<<(2*a+1)) - s->no_rounding, | |
162 | s->h_edge_pos>>1, s->v_edge_pos>>1); | |
163 | ||
164 | ptr = ref_picture[2]; | |
165 | s->dsp.gmc(dest_cr, ptr, uvlinesize, 8, | |
166 | ox, | |
167 | oy, | |
168 | s->sprite_delta[0][0], s->sprite_delta[0][1], | |
169 | s->sprite_delta[1][0], s->sprite_delta[1][1], | |
170 | a+1, (1<<(2*a+1)) - s->no_rounding, | |
171 | s->h_edge_pos>>1, s->v_edge_pos>>1); | |
172 | } | |
173 | ||
174 | static inline int hpel_motion(MpegEncContext *s, | |
175 | uint8_t *dest, uint8_t *src, | |
176 | int field_based, int field_select, | |
177 | int src_x, int src_y, | |
178 | int width, int height, int stride, | |
179 | int h_edge_pos, int v_edge_pos, | |
180 | int w, int h, op_pixels_func *pix_op, | |
181 | int motion_x, int motion_y) | |
182 | { | |
183 | int dxy; | |
184 | int emu=0; | |
185 | ||
186 | dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
187 | src_x += motion_x >> 1; | |
188 | src_y += motion_y >> 1; | |
189 | ||
190 | /* WARNING: do no forget half pels */ | |
191 | src_x = av_clip(src_x, -16, width); //FIXME unneeded for emu? | |
192 | if (src_x == width) | |
193 | dxy &= ~1; | |
194 | src_y = av_clip(src_y, -16, height); | |
195 | if (src_y == height) | |
196 | dxy &= ~2; | |
197 | src += src_y * stride + src_x; | |
198 | ||
199 | if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){ | |
9b6aafba JB |
200 | if( (unsigned)src_x > FFMAX(h_edge_pos - (motion_x&1) - w, 0) |
201 | || (unsigned)src_y > FFMAX(v_edge_pos - (motion_y&1) - h, 0)){ | |
2e279598 | 202 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based, |
3ada94ba BF |
203 | src_x, src_y<<field_based, h_edge_pos, s->v_edge_pos); |
204 | src= s->edge_emu_buffer; | |
205 | emu=1; | |
206 | } | |
207 | } | |
208 | if(field_select) | |
209 | src += s->linesize; | |
210 | pix_op[dxy](dest, src, stride, h); | |
211 | return emu; | |
212 | } | |
213 | ||
08c9bfba | 214 | static av_always_inline |
bd7c626a | 215 | void mpeg_motion_internal(MpegEncContext *s, |
08c9bfba KC |
216 | uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, |
217 | int field_based, int bottom_field, int field_select, | |
218 | uint8_t **ref_picture, op_pixels_func (*pix_op)[4], | |
078cdecf | 219 | int motion_x, int motion_y, int h, int is_mpeg12, int mb_y) |
3ada94ba BF |
220 | { |
221 | uint8_t *ptr_y, *ptr_cb, *ptr_cr; | |
08c9bfba KC |
222 | int dxy, uvdxy, mx, my, src_x, src_y, |
223 | uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize; | |
3ada94ba BF |
224 | |
225 | #if 0 | |
226 | if(s->quarter_sample) | |
227 | { | |
228 | motion_x>>=1; | |
229 | motion_y>>=1; | |
230 | } | |
231 | #endif | |
232 | ||
233 | v_edge_pos = s->v_edge_pos >> field_based; | |
657ccb5a DB |
234 | linesize = s->current_picture.f.linesize[0] << field_based; |
235 | uvlinesize = s->current_picture.f.linesize[1] << field_based; | |
3ada94ba BF |
236 | |
237 | dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
238 | src_x = s->mb_x* 16 + (motion_x >> 1); | |
078cdecf | 239 | src_y =( mb_y<<(4-field_based)) + (motion_y >> 1); |
3ada94ba | 240 | |
bd7c626a | 241 | if (!is_mpeg12 && s->out_format == FMT_H263) { |
3ada94ba BF |
242 | if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){ |
243 | mx = (motion_x>>1)|(motion_x&1); | |
244 | my = motion_y >>1; | |
245 | uvdxy = ((my & 1) << 1) | (mx & 1); | |
246 | uvsrc_x = s->mb_x* 8 + (mx >> 1); | |
078cdecf | 247 | uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1); |
3ada94ba BF |
248 | }else{ |
249 | uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); | |
250 | uvsrc_x = src_x>>1; | |
251 | uvsrc_y = src_y>>1; | |
252 | } | |
bd7c626a | 253 | }else if(!is_mpeg12 && s->out_format == FMT_H261){//even chroma mv's are full pel in H261 |
3ada94ba BF |
254 | mx = motion_x / 4; |
255 | my = motion_y / 4; | |
256 | uvdxy = 0; | |
257 | uvsrc_x = s->mb_x*8 + mx; | |
078cdecf | 258 | uvsrc_y = mb_y*8 + my; |
3ada94ba BF |
259 | } else { |
260 | if(s->chroma_y_shift){ | |
261 | mx = motion_x / 2; | |
262 | my = motion_y / 2; | |
263 | uvdxy = ((my & 1) << 1) | (mx & 1); | |
264 | uvsrc_x = s->mb_x* 8 + (mx >> 1); | |
078cdecf | 265 | uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1); |
3ada94ba BF |
266 | } else { |
267 | if(s->chroma_x_shift){ | |
268 | //Chroma422 | |
269 | mx = motion_x / 2; | |
270 | uvdxy = ((motion_y & 1) << 1) | (mx & 1); | |
271 | uvsrc_x = s->mb_x* 8 + (mx >> 1); | |
272 | uvsrc_y = src_y; | |
273 | } else { | |
274 | //Chroma444 | |
275 | uvdxy = dxy; | |
276 | uvsrc_x = src_x; | |
277 | uvsrc_y = src_y; | |
278 | } | |
279 | } | |
280 | } | |
281 | ||
282 | ptr_y = ref_picture[0] + src_y * linesize + src_x; | |
283 | ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; | |
284 | ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; | |
285 | ||
9b6aafba JB |
286 | if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 16, 0) |
287 | || (unsigned)src_y > FFMAX( v_edge_pos - (motion_y&1) - h , 0)){ | |
36ef5369 AK |
288 | if(is_mpeg12 || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || |
289 | s->codec_id == AV_CODEC_ID_MPEG1VIDEO){ | |
08c9bfba | 290 | av_log(s->avctx,AV_LOG_DEBUG, |
22d4f213 | 291 | "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y); |
81b44c42 | 292 | return; |
3ada94ba | 293 | } |
2e279598 | 294 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, |
08c9bfba KC |
295 | 17, 17+field_based, |
296 | src_x, src_y<<field_based, | |
297 | s->h_edge_pos, s->v_edge_pos); | |
3ada94ba | 298 | ptr_y = s->edge_emu_buffer; |
49fb20cb | 299 | if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ |
3ada94ba | 300 | uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize; |
2e279598 | 301 | s->dsp.emulated_edge_mc(uvbuf , |
08c9bfba KC |
302 | ptr_cb, s->uvlinesize, |
303 | 9, 9+field_based, | |
304 | uvsrc_x, uvsrc_y<<field_based, | |
305 | s->h_edge_pos>>1, s->v_edge_pos>>1); | |
2e279598 | 306 | s->dsp.emulated_edge_mc(uvbuf+16, |
08c9bfba KC |
307 | ptr_cr, s->uvlinesize, |
308 | 9, 9+field_based, | |
309 | uvsrc_x, uvsrc_y<<field_based, | |
310 | s->h_edge_pos>>1, s->v_edge_pos>>1); | |
3ada94ba BF |
311 | ptr_cb= uvbuf; |
312 | ptr_cr= uvbuf+16; | |
313 | } | |
314 | } | |
315 | ||
316 | if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data | |
317 | dest_y += s->linesize; | |
318 | dest_cb+= s->uvlinesize; | |
319 | dest_cr+= s->uvlinesize; | |
320 | } | |
321 | ||
322 | if(field_select){ | |
323 | ptr_y += s->linesize; | |
324 | ptr_cb+= s->uvlinesize; | |
325 | ptr_cr+= s->uvlinesize; | |
326 | } | |
327 | ||
328 | pix_op[0][dxy](dest_y, ptr_y, linesize, h); | |
329 | ||
49fb20cb | 330 | if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ |
08c9bfba KC |
331 | pix_op[s->chroma_x_shift][uvdxy] |
332 | (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); | |
333 | pix_op[s->chroma_x_shift][uvdxy] | |
334 | (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); | |
3ada94ba | 335 | } |
49fb20cb | 336 | if(!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) && |
08c9bfba | 337 | s->out_format == FMT_H261){ |
3ada94ba BF |
338 | ff_h261_loop_filter(s); |
339 | } | |
340 | } | |
bd7c626a KC |
341 | /* apply one mpeg motion vector to the three components */ |
342 | static av_always_inline | |
343 | void mpeg_motion(MpegEncContext *s, | |
344 | uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | |
345 | int field_based, int bottom_field, int field_select, | |
346 | uint8_t **ref_picture, op_pixels_func (*pix_op)[4], | |
078cdecf | 347 | int motion_x, int motion_y, int h, int mb_y) |
bd7c626a | 348 | { |
b250f9c6 | 349 | #if !CONFIG_SMALL |
bd7c626a KC |
350 | if(s->out_format == FMT_MPEG1) |
351 | mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based, | |
352 | bottom_field, field_select, ref_picture, pix_op, | |
078cdecf | 353 | motion_x, motion_y, h, 1, mb_y); |
bd7c626a KC |
354 | else |
355 | #endif | |
356 | mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based, | |
357 | bottom_field, field_select, ref_picture, pix_op, | |
078cdecf | 358 | motion_x, motion_y, h, 0, mb_y); |
bd7c626a | 359 | } |
3ada94ba BF |
360 | |
361 | //FIXME move to dsputil, avg variant, 16x16 version | |
362 | static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){ | |
363 | int x; | |
364 | uint8_t * const top = src[1]; | |
365 | uint8_t * const left = src[2]; | |
366 | uint8_t * const mid = src[0]; | |
367 | uint8_t * const right = src[3]; | |
368 | uint8_t * const bottom= src[4]; | |
369 | #define OBMC_FILTER(x, t, l, m, r, b)\ | |
370 | dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3 | |
371 | #define OBMC_FILTER4(x, t, l, m, r, b)\ | |
372 | OBMC_FILTER(x , t, l, m, r, b);\ | |
373 | OBMC_FILTER(x+1 , t, l, m, r, b);\ | |
374 | OBMC_FILTER(x +stride, t, l, m, r, b);\ | |
375 | OBMC_FILTER(x+1+stride, t, l, m, r, b); | |
376 | ||
377 | x=0; | |
378 | OBMC_FILTER (x , 2, 2, 4, 0, 0); | |
379 | OBMC_FILTER (x+1, 2, 1, 5, 0, 0); | |
380 | OBMC_FILTER4(x+2, 2, 1, 5, 0, 0); | |
381 | OBMC_FILTER4(x+4, 2, 0, 5, 1, 0); | |
382 | OBMC_FILTER (x+6, 2, 0, 5, 1, 0); | |
383 | OBMC_FILTER (x+7, 2, 0, 4, 2, 0); | |
384 | x+= stride; | |
385 | OBMC_FILTER (x , 1, 2, 5, 0, 0); | |
386 | OBMC_FILTER (x+1, 1, 2, 5, 0, 0); | |
387 | OBMC_FILTER (x+6, 1, 0, 5, 2, 0); | |
388 | OBMC_FILTER (x+7, 1, 0, 5, 2, 0); | |
389 | x+= stride; | |
390 | OBMC_FILTER4(x , 1, 2, 5, 0, 0); | |
391 | OBMC_FILTER4(x+2, 1, 1, 6, 0, 0); | |
392 | OBMC_FILTER4(x+4, 1, 0, 6, 1, 0); | |
393 | OBMC_FILTER4(x+6, 1, 0, 5, 2, 0); | |
394 | x+= 2*stride; | |
395 | OBMC_FILTER4(x , 0, 2, 5, 0, 1); | |
396 | OBMC_FILTER4(x+2, 0, 1, 6, 0, 1); | |
397 | OBMC_FILTER4(x+4, 0, 0, 6, 1, 1); | |
398 | OBMC_FILTER4(x+6, 0, 0, 5, 2, 1); | |
399 | x+= 2*stride; | |
400 | OBMC_FILTER (x , 0, 2, 5, 0, 1); | |
401 | OBMC_FILTER (x+1, 0, 2, 5, 0, 1); | |
402 | OBMC_FILTER4(x+2, 0, 1, 5, 0, 2); | |
403 | OBMC_FILTER4(x+4, 0, 0, 5, 1, 2); | |
404 | OBMC_FILTER (x+6, 0, 0, 5, 2, 1); | |
405 | OBMC_FILTER (x+7, 0, 0, 5, 2, 1); | |
406 | x+= stride; | |
407 | OBMC_FILTER (x , 0, 2, 4, 0, 2); | |
408 | OBMC_FILTER (x+1, 0, 1, 5, 0, 2); | |
409 | OBMC_FILTER (x+6, 0, 0, 5, 1, 2); | |
410 | OBMC_FILTER (x+7, 0, 0, 4, 2, 2); | |
411 | } | |
412 | ||
413 | /* obmc for 1 8x8 luma block */ | |
414 | static inline void obmc_motion(MpegEncContext *s, | |
415 | uint8_t *dest, uint8_t *src, | |
416 | int src_x, int src_y, | |
417 | op_pixels_func *pix_op, | |
418 | int16_t mv[5][2]/* mid top left right bottom*/) | |
419 | #define MID 0 | |
420 | { | |
421 | int i; | |
422 | uint8_t *ptr[5]; | |
423 | ||
424 | assert(s->quarter_sample==0); | |
425 | ||
426 | for(i=0; i<5; i++){ | |
427 | if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){ | |
428 | ptr[i]= ptr[MID]; | |
429 | }else{ | |
430 | ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1); | |
431 | hpel_motion(s, ptr[i], src, 0, 0, | |
432 | src_x, src_y, | |
433 | s->width, s->height, s->linesize, | |
434 | s->h_edge_pos, s->v_edge_pos, | |
435 | 8, 8, pix_op, | |
436 | mv[i][0], mv[i][1]); | |
437 | } | |
438 | } | |
439 | ||
440 | put_obmc(dest, ptr, s->linesize); | |
441 | } | |
442 | ||
443 | static inline void qpel_motion(MpegEncContext *s, | |
444 | uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | |
445 | int field_based, int bottom_field, int field_select, | |
446 | uint8_t **ref_picture, op_pixels_func (*pix_op)[4], | |
447 | qpel_mc_func (*qpix_op)[16], | |
448 | int motion_x, int motion_y, int h) | |
449 | { | |
450 | uint8_t *ptr_y, *ptr_cb, *ptr_cr; | |
451 | int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize; | |
452 | ||
453 | dxy = ((motion_y & 3) << 2) | (motion_x & 3); | |
454 | src_x = s->mb_x * 16 + (motion_x >> 2); | |
455 | src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); | |
456 | ||
457 | v_edge_pos = s->v_edge_pos >> field_based; | |
458 | linesize = s->linesize << field_based; | |
459 | uvlinesize = s->uvlinesize << field_based; | |
460 | ||
461 | if(field_based){ | |
462 | mx= motion_x/2; | |
463 | my= motion_y>>1; | |
464 | }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){ | |
465 | static const int rtab[8]= {0,0,1,1,0,0,0,1}; | |
466 | mx= (motion_x>>1) + rtab[motion_x&7]; | |
467 | my= (motion_y>>1) + rtab[motion_y&7]; | |
468 | }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){ | |
469 | mx= (motion_x>>1)|(motion_x&1); | |
470 | my= (motion_y>>1)|(motion_y&1); | |
471 | }else{ | |
472 | mx= motion_x/2; | |
473 | my= motion_y/2; | |
474 | } | |
475 | mx= (mx>>1)|(mx&1); | |
476 | my= (my>>1)|(my&1); | |
477 | ||
478 | uvdxy= (mx&1) | ((my&1)<<1); | |
479 | mx>>=1; | |
480 | my>>=1; | |
481 | ||
482 | uvsrc_x = s->mb_x * 8 + mx; | |
483 | uvsrc_y = s->mb_y * (8 >> field_based) + my; | |
484 | ||
485 | ptr_y = ref_picture[0] + src_y * linesize + src_x; | |
486 | ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; | |
487 | ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; | |
488 | ||
9b6aafba JB |
489 | if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 16, 0) |
490 | || (unsigned)src_y > FFMAX( v_edge_pos - (motion_y&3) - h , 0)){ | |
2e279598 | 491 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, |
cb9501f4 KC |
492 | 17, 17+field_based, src_x, src_y<<field_based, |
493 | s->h_edge_pos, s->v_edge_pos); | |
3ada94ba | 494 | ptr_y= s->edge_emu_buffer; |
49fb20cb | 495 | if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ |
3ada94ba | 496 | uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize; |
2e279598 | 497 | s->dsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize, |
cb9501f4 KC |
498 | 9, 9 + field_based, |
499 | uvsrc_x, uvsrc_y<<field_based, | |
500 | s->h_edge_pos>>1, s->v_edge_pos>>1); | |
2e279598 | 501 | s->dsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, |
cb9501f4 KC |
502 | 9, 9 + field_based, |
503 | uvsrc_x, uvsrc_y<<field_based, | |
504 | s->h_edge_pos>>1, s->v_edge_pos>>1); | |
3ada94ba BF |
505 | ptr_cb= uvbuf; |
506 | ptr_cr= uvbuf + 16; | |
507 | } | |
508 | } | |
509 | ||
510 | if(!field_based) | |
511 | qpix_op[0][dxy](dest_y, ptr_y, linesize); | |
512 | else{ | |
513 | if(bottom_field){ | |
514 | dest_y += s->linesize; | |
515 | dest_cb+= s->uvlinesize; | |
516 | dest_cr+= s->uvlinesize; | |
517 | } | |
518 | ||
519 | if(field_select){ | |
520 | ptr_y += s->linesize; | |
521 | ptr_cb += s->uvlinesize; | |
522 | ptr_cr += s->uvlinesize; | |
523 | } | |
524 | //damn interlaced mode | |
525 | //FIXME boundary mirroring is not exactly correct here | |
526 | qpix_op[1][dxy](dest_y , ptr_y , linesize); | |
527 | qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize); | |
528 | } | |
49fb20cb | 529 | if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ |
3ada94ba BF |
530 | pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1); |
531 | pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1); | |
532 | } | |
533 | } | |
534 | ||
535 | /** | |
b9ca2042 | 536 | * h263 chroma 4mv motion compensation. |
3ada94ba BF |
537 | */ |
538 | static inline void chroma_4mv_motion(MpegEncContext *s, | |
539 | uint8_t *dest_cb, uint8_t *dest_cr, | |
540 | uint8_t **ref_picture, | |
541 | op_pixels_func *pix_op, | |
542 | int mx, int my){ | |
543 | int dxy, emu=0, src_x, src_y, offset; | |
544 | uint8_t *ptr; | |
545 | ||
546 | /* In case of 8X8, we construct a single chroma motion vector | |
547 | with a special rounding */ | |
548 | mx= ff_h263_round_chroma(mx); | |
549 | my= ff_h263_round_chroma(my); | |
550 | ||
551 | dxy = ((my & 1) << 1) | (mx & 1); | |
552 | mx >>= 1; | |
553 | my >>= 1; | |
554 | ||
555 | src_x = s->mb_x * 8 + mx; | |
556 | src_y = s->mb_y * 8 + my; | |
c31a25e7 JGG |
557 | src_x = av_clip(src_x, -8, (s->width >> 1)); |
558 | if (src_x == (s->width >> 1)) | |
3ada94ba | 559 | dxy &= ~1; |
c31a25e7 JGG |
560 | src_y = av_clip(src_y, -8, (s->height >> 1)); |
561 | if (src_y == (s->height >> 1)) | |
3ada94ba BF |
562 | dxy &= ~2; |
563 | ||
ee41963f | 564 | offset = src_y * s->uvlinesize + src_x; |
3ada94ba BF |
565 | ptr = ref_picture[1] + offset; |
566 | if(s->flags&CODEC_FLAG_EMU_EDGE){ | |
9b6aafba JB |
567 | if( (unsigned)src_x > FFMAX((s->h_edge_pos>>1) - (dxy &1) - 8, 0) |
568 | || (unsigned)src_y > FFMAX((s->v_edge_pos>>1) - (dxy>>1) - 8, 0)){ | |
2e279598 | 569 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, |
cb9501f4 KC |
570 | 9, 9, src_x, src_y, |
571 | s->h_edge_pos>>1, s->v_edge_pos>>1); | |
3ada94ba BF |
572 | ptr= s->edge_emu_buffer; |
573 | emu=1; | |
574 | } | |
575 | } | |
576 | pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8); | |
577 | ||
578 | ptr = ref_picture[2] + offset; | |
579 | if(emu){ | |
2e279598 | 580 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, |
cb9501f4 KC |
581 | 9, 9, src_x, src_y, |
582 | s->h_edge_pos>>1, s->v_edge_pos>>1); | |
3ada94ba BF |
583 | ptr= s->edge_emu_buffer; |
584 | } | |
585 | pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8); | |
586 | } | |
587 | ||
588 | static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){ | |
589 | /* fetch pixels for estimated mv 4 macroblocks ahead | |
590 | * optimized for 64byte cache lines */ | |
591 | const int shift = s->quarter_sample ? 2 : 1; | |
592 | const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8; | |
593 | const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y; | |
594 | int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64; | |
595 | s->dsp.prefetch(pix[0]+off, s->linesize, 4); | |
596 | off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64; | |
597 | s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2); | |
598 | } | |
599 | ||
600 | /** | |
601 | * motion compensation of a single macroblock | |
602 | * @param s context | |
603 | * @param dest_y luma destination pointer | |
604 | * @param dest_cb chroma cb/u destination pointer | |
605 | * @param dest_cr chroma cr/v destination pointer | |
606 | * @param dir direction (0->forward, 1->backward) | |
607 | * @param ref_picture array[3] of pointers to the 3 planes of the reference picture | |
9a58234f DB |
608 | * @param pix_op halfpel motion compensation function (average or put normally) |
609 | * @param qpix_op qpel motion compensation function (average or put normally) | |
3ada94ba BF |
610 | * the motion vectors are taken from s->mv and the MV type from s->mv_type |
611 | */ | |
b1d31e2f | 612 | static av_always_inline void MPV_motion_internal(MpegEncContext *s, |
cb9501f4 KC |
613 | uint8_t *dest_y, uint8_t *dest_cb, |
614 | uint8_t *dest_cr, int dir, | |
615 | uint8_t **ref_picture, | |
616 | op_pixels_func (*pix_op)[4], | |
bd7c626a | 617 | qpel_mc_func (*qpix_op)[16], int is_mpeg12) |
3ada94ba BF |
618 | { |
619 | int dxy, mx, my, src_x, src_y, motion_x, motion_y; | |
620 | int mb_x, mb_y, i; | |
621 | uint8_t *ptr, *dest; | |
622 | ||
623 | mb_x = s->mb_x; | |
624 | mb_y = s->mb_y; | |
625 | ||
626 | prefetch_motion(s, ref_picture, dir); | |
627 | ||
975a1447 | 628 | if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){ |
3ada94ba BF |
629 | int16_t mv_cache[4][4][2]; |
630 | const int xy= s->mb_x + s->mb_y*s->mb_stride; | |
631 | const int mot_stride= s->b8_stride; | |
632 | const int mot_xy= mb_x*2 + mb_y*2*mot_stride; | |
633 | ||
634 | assert(!s->mb_skipped); | |
635 | ||
657ccb5a DB |
636 | memcpy(mv_cache[1][1], s->current_picture.f.motion_val[0][mot_xy ], sizeof(int16_t) * 4); |
637 | memcpy(mv_cache[2][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4); | |
638 | memcpy(mv_cache[3][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4); | |
3ada94ba | 639 | |
657ccb5a | 640 | if (mb_y == 0 || IS_INTRA(s->current_picture.f.mb_type[xy - s->mb_stride])) { |
3ada94ba BF |
641 | memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4); |
642 | }else{ | |
657ccb5a | 643 | memcpy(mv_cache[0][1], s->current_picture.f.motion_val[0][mot_xy - mot_stride], sizeof(int16_t) * 4); |
3ada94ba BF |
644 | } |
645 | ||
657ccb5a | 646 | if (mb_x == 0 || IS_INTRA(s->current_picture.f.mb_type[xy - 1])) { |
99267eb7 EF |
647 | AV_COPY32(mv_cache[1][0], mv_cache[1][1]); |
648 | AV_COPY32(mv_cache[2][0], mv_cache[2][1]); | |
3ada94ba | 649 | }else{ |
657ccb5a DB |
650 | AV_COPY32(mv_cache[1][0], s->current_picture.f.motion_val[0][mot_xy - 1]); |
651 | AV_COPY32(mv_cache[2][0], s->current_picture.f.motion_val[0][mot_xy - 1 + mot_stride]); | |
3ada94ba BF |
652 | } |
653 | ||
657ccb5a | 654 | if (mb_x + 1 >= s->mb_width || IS_INTRA(s->current_picture.f.mb_type[xy + 1])) { |
99267eb7 EF |
655 | AV_COPY32(mv_cache[1][3], mv_cache[1][2]); |
656 | AV_COPY32(mv_cache[2][3], mv_cache[2][2]); | |
3ada94ba | 657 | }else{ |
657ccb5a DB |
658 | AV_COPY32(mv_cache[1][3], s->current_picture.f.motion_val[0][mot_xy + 2]); |
659 | AV_COPY32(mv_cache[2][3], s->current_picture.f.motion_val[0][mot_xy + 2 + mot_stride]); | |
3ada94ba BF |
660 | } |
661 | ||
662 | mx = 0; | |
663 | my = 0; | |
664 | for(i=0;i<4;i++) { | |
665 | const int x= (i&1)+1; | |
666 | const int y= (i>>1)+1; | |
667 | int16_t mv[5][2]= { | |
668 | {mv_cache[y][x ][0], mv_cache[y][x ][1]}, | |
669 | {mv_cache[y-1][x][0], mv_cache[y-1][x][1]}, | |
670 | {mv_cache[y][x-1][0], mv_cache[y][x-1][1]}, | |
671 | {mv_cache[y][x+1][0], mv_cache[y][x+1][1]}, | |
672 | {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}}; | |
673 | //FIXME cleanup | |
674 | obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, | |
675 | ref_picture[0], | |
676 | mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, | |
677 | pix_op[1], | |
678 | mv); | |
679 | ||
680 | mx += mv[0][0]; | |
681 | my += mv[0][1]; | |
682 | } | |
49fb20cb | 683 | if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) |
3ada94ba BF |
684 | chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); |
685 | ||
686 | return; | |
687 | } | |
688 | ||
689 | switch(s->mv_type) { | |
690 | case MV_TYPE_16X16: | |
691 | if(s->mcsel){ | |
692 | if(s->real_sprite_warping_points==1){ | |
693 | gmc1_motion(s, dest_y, dest_cb, dest_cr, | |
694 | ref_picture); | |
695 | }else{ | |
696 | gmc_motion(s, dest_y, dest_cb, dest_cr, | |
697 | ref_picture); | |
698 | } | |
bd7c626a | 699 | }else if(!is_mpeg12 && s->quarter_sample){ |
3ada94ba BF |
700 | qpel_motion(s, dest_y, dest_cb, dest_cr, |
701 | 0, 0, 0, | |
702 | ref_picture, pix_op, qpix_op, | |
703 | s->mv[dir][0][0], s->mv[dir][0][1], 16); | |
18f2d5cb | 704 | } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && |
36ef5369 | 705 | s->mspel && s->codec_id == AV_CODEC_ID_WMV2) { |
3ada94ba BF |
706 | ff_mspel_motion(s, dest_y, dest_cb, dest_cr, |
707 | ref_picture, pix_op, | |
708 | s->mv[dir][0][0], s->mv[dir][0][1], 16); | |
709 | }else | |
710 | { | |
711 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
712 | 0, 0, 0, | |
713 | ref_picture, pix_op, | |
078cdecf | 714 | s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y); |
3ada94ba BF |
715 | } |
716 | break; | |
717 | case MV_TYPE_8X8: | |
bd7c626a | 718 | if (!is_mpeg12) { |
3ada94ba BF |
719 | mx = 0; |
720 | my = 0; | |
721 | if(s->quarter_sample){ | |
722 | for(i=0;i<4;i++) { | |
723 | motion_x = s->mv[dir][i][0]; | |
724 | motion_y = s->mv[dir][i][1]; | |
725 | ||
726 | dxy = ((motion_y & 3) << 2) | (motion_x & 3); | |
727 | src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; | |
728 | src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8; | |
729 | ||
730 | /* WARNING: do no forget half pels */ | |
731 | src_x = av_clip(src_x, -16, s->width); | |
732 | if (src_x == s->width) | |
733 | dxy &= ~3; | |
734 | src_y = av_clip(src_y, -16, s->height); | |
735 | if (src_y == s->height) | |
736 | dxy &= ~12; | |
737 | ||
738 | ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); | |
739 | if(s->flags&CODEC_FLAG_EMU_EDGE){ | |
9b6aafba JB |
740 | if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 8, 0) |
741 | || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&3) - 8, 0)){ | |
2e279598 | 742 | s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, |
cb9501f4 KC |
743 | s->linesize, 9, 9, |
744 | src_x, src_y, | |
745 | s->h_edge_pos, s->v_edge_pos); | |
3ada94ba BF |
746 | ptr= s->edge_emu_buffer; |
747 | } | |
748 | } | |
749 | dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; | |
750 | qpix_op[1][dxy](dest, ptr, s->linesize); | |
751 | ||
752 | mx += s->mv[dir][i][0]/2; | |
753 | my += s->mv[dir][i][1]/2; | |
754 | } | |
755 | }else{ | |
756 | for(i=0;i<4;i++) { | |
757 | hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, | |
758 | ref_picture[0], 0, 0, | |
759 | mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, | |
760 | s->width, s->height, s->linesize, | |
761 | s->h_edge_pos, s->v_edge_pos, | |
762 | 8, 8, pix_op[1], | |
763 | s->mv[dir][i][0], s->mv[dir][i][1]); | |
764 | ||
765 | mx += s->mv[dir][i][0]; | |
766 | my += s->mv[dir][i][1]; | |
767 | } | |
768 | } | |
769 | ||
49fb20cb | 770 | if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) |
3ada94ba | 771 | chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); |
bd7c626a | 772 | } |
3ada94ba BF |
773 | break; |
774 | case MV_TYPE_FIELD: | |
775 | if (s->picture_structure == PICT_FRAME) { | |
bd7c626a | 776 | if(!is_mpeg12 && s->quarter_sample){ |
3ada94ba BF |
777 | for(i=0; i<2; i++){ |
778 | qpel_motion(s, dest_y, dest_cb, dest_cr, | |
779 | 1, i, s->field_select[dir][i], | |
780 | ref_picture, pix_op, qpix_op, | |
781 | s->mv[dir][i][0], s->mv[dir][i][1], 8); | |
782 | } | |
783 | }else{ | |
784 | /* top field */ | |
785 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
786 | 1, 0, s->field_select[dir][0], | |
787 | ref_picture, pix_op, | |
078cdecf | 788 | s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y); |
3ada94ba BF |
789 | /* bottom field */ |
790 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
791 | 1, 1, s->field_select[dir][1], | |
792 | ref_picture, pix_op, | |
078cdecf | 793 | s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y); |
3ada94ba BF |
794 | } |
795 | } else { | |
975a1447 | 796 | if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field){ |
657ccb5a | 797 | ref_picture = s->current_picture_ptr->f.data; |
3ada94ba BF |
798 | } |
799 | ||
800 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
801 | 0, 0, s->field_select[dir][0], | |
802 | ref_picture, pix_op, | |
078cdecf | 803 | s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y>>1); |
3ada94ba BF |
804 | } |
805 | break; | |
806 | case MV_TYPE_16X8: | |
807 | for(i=0; i<2; i++){ | |
808 | uint8_t ** ref2picture; | |
809 | ||
cb9501f4 | 810 | if(s->picture_structure == s->field_select[dir][i] + 1 |
975a1447 | 811 | || s->pict_type == AV_PICTURE_TYPE_B || s->first_field){ |
3ada94ba BF |
812 | ref2picture= ref_picture; |
813 | }else{ | |
657ccb5a | 814 | ref2picture = s->current_picture_ptr->f.data; |
3ada94ba BF |
815 | } |
816 | ||
817 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
818 | 0, 0, s->field_select[dir][i], | |
819 | ref2picture, pix_op, | |
078cdecf | 820 | s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8, mb_y>>1); |
3ada94ba BF |
821 | |
822 | dest_y += 16*s->linesize; | |
823 | dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize; | |
824 | dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize; | |
825 | } | |
826 | break; | |
827 | case MV_TYPE_DMV: | |
828 | if(s->picture_structure == PICT_FRAME){ | |
829 | for(i=0; i<2; i++){ | |
830 | int j; | |
831 | for(j=0; j<2; j++){ | |
832 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
833 | 1, j, j^i, | |
834 | ref_picture, pix_op, | |
078cdecf | 835 | s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8, mb_y); |
3ada94ba BF |
836 | } |
837 | pix_op = s->dsp.avg_pixels_tab; | |
838 | } | |
839 | }else{ | |
840 | for(i=0; i<2; i++){ | |
841 | mpeg_motion(s, dest_y, dest_cb, dest_cr, | |
842 | 0, 0, s->picture_structure != i+1, | |
843 | ref_picture, pix_op, | |
078cdecf | 844 | s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1); |
3ada94ba BF |
845 | |
846 | // after put we make avg of the same block | |
847 | pix_op=s->dsp.avg_pixels_tab; | |
848 | ||
849 | //opposite parity is always in the same frame if this is second field | |
850 | if(!s->first_field){ | |
657ccb5a | 851 | ref_picture = s->current_picture_ptr->f.data; |
3ada94ba BF |
852 | } |
853 | } | |
854 | } | |
855 | break; | |
856 | default: assert(0); | |
857 | } | |
858 | } | |
859 | ||
7a851153 MR |
860 | void ff_MPV_motion(MpegEncContext *s, |
861 | uint8_t *dest_y, uint8_t *dest_cb, | |
862 | uint8_t *dest_cr, int dir, | |
863 | uint8_t **ref_picture, | |
864 | op_pixels_func (*pix_op)[4], | |
865 | qpel_mc_func (*qpix_op)[16]) | |
bd7c626a | 866 | { |
b250f9c6 | 867 | #if !CONFIG_SMALL |
bd7c626a KC |
868 | if(s->out_format == FMT_MPEG1) |
869 | MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir, | |
870 | ref_picture, pix_op, qpix_op, 1); | |
871 | else | |
872 | #endif | |
873 | MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir, | |
874 | ref_picture, pix_op, qpix_op, 0); | |
875 | } |