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