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