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>
6 * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
8 * This file is part of FFmpeg.
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.
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.
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
26 * @file mpegvideo_common.h
27 * The simplest mpeg encoder (well, it was the simplest!).
30 #ifndef FFMPEG_MPEGVIDEO_COMMON_H
31 #define FFMPEG_MPEGVIDEO_COMMON_H
35 #include "mpegvideo.h"
41 int dct_quantize_c(MpegEncContext
*s
, DCTELEM
*block
, int n
, int qscale
, int *overflow
);
42 int dct_quantize_trellis_c(MpegEncContext
*s
, DCTELEM
*block
, int n
, int qscale
, int *overflow
);
43 void denoise_dct_c(MpegEncContext
*s
, DCTELEM
*block
);
44 void copy_picture(Picture
*dst
, Picture
*src
);
48 * The pixels are allocated/set by calling get_buffer() if shared=0
50 int alloc_picture(MpegEncContext
*s
, Picture
*pic
, int shared
);
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.
56 void MPV_common_defaults(MpegEncContext
*s
);
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
)
63 int offset
, src_x
, src_y
, linesize
, uvlinesize
;
64 int motion_x
, motion_y
;
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
)
76 src_y
= av_clip(src_y
, -16, s
->height
);
77 if (src_y
== s
->height
)
80 linesize
= s
->linesize
;
81 uvlinesize
= s
->uvlinesize
;
83 ptr
= ref_picture
[0] + (src_y
* linesize
) + src_x
;
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
;
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
);
99 dxy
= ((motion_x
>>3)&1) | ((motion_y
>>2)&2);
101 s
->dsp
.put_no_rnd_pixels_tab
[0][dxy
](dest_y
, ptr
, linesize
, 16);
103 s
->dsp
.put_pixels_tab
[0][dxy
](dest_y
, ptr
, linesize
, 16);
107 if(ENABLE_GRAY
&& s
->flags
&CODEC_FLAG_GRAY
) return;
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)
118 src_y
= av_clip(src_y
, -8, s
->height
>>1);
119 if (src_y
== s
->height
>>1)
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
;
132 s
->dsp
.gmc1(dest_cb
, ptr
, uvlinesize
, 8, motion_x
&15, motion_y
&15, 128 - s
->no_rounding
);
134 ptr
= ref_picture
[2] + offset
;
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
;
139 s
->dsp
.gmc1(dest_cr
, ptr
, uvlinesize
, 8, motion_x
&15, motion_y
&15, 128 - s
->no_rounding
);
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
)
149 int linesize
, uvlinesize
;
150 const int a
= s
->sprite_warping_accuracy
;
153 linesize
= s
->linesize
;
154 uvlinesize
= s
->uvlinesize
;
156 ptr
= ref_picture
[0];
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;
161 s
->dsp
.gmc(dest_y
, ptr
, linesize
, 16,
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
);
176 if(ENABLE_GRAY
&& s
->flags
&CODEC_FLAG_GRAY
) return;
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;
181 ptr
= ref_picture
[1];
182 s
->dsp
.gmc(dest_cb
, ptr
, uvlinesize
, 8,
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);
190 ptr
= ref_picture
[2];
191 s
->dsp
.gmc(dest_cr
, ptr
, uvlinesize
, 8,
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);
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
)
212 dxy
= ((motion_y
& 1) << 1) | (motion_x
& 1);
213 src_x
+= motion_x
>> 1;
214 src_y
+= motion_y
>> 1;
216 /* WARNING: do no forget half pels */
217 src_x
= av_clip(src_x
, -16, width
); //FIXME unneeded for emu?
220 src_y
= av_clip(src_y
, -16, height
);
223 src
+= src_y
* stride
+ src_x
;
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
;
236 pix_op
[dxy
](dest
, src
, stride
, h
);
240 static av_always_inline
241 void mpeg_motion_internal(MpegEncContext
*s
,
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],
245 int motion_x
, int motion_y
, int h
, int is_mpeg12
)
247 uint8_t *ptr_y
, *ptr_cb
, *ptr_cr
;
248 int dxy
, uvdxy
, mx
, my
, src_x
, src_y
,
249 uvsrc_x
, uvsrc_y
, v_edge_pos
, uvlinesize
, linesize
;
252 if(s
->quarter_sample
)
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
;
263 dxy
= ((motion_y
& 1) << 1) | (motion_x
& 1);
264 src_x
= s
->mb_x
* 16 + (motion_x
>> 1);
265 src_y
=(s
->mb_y
<<(4-field_based
)) + (motion_y
>> 1);
267 if (!is_mpeg12
&& s
->out_format
== FMT_H263
) {
268 if((s
->workaround_bugs
& FF_BUG_HPEL_CHROMA
) && field_based
){
269 mx
= (motion_x
>>1)|(motion_x
&1);
271 uvdxy
= ((my
& 1) << 1) | (mx
& 1);
272 uvsrc_x
= s
->mb_x
* 8 + (mx
>> 1);
273 uvsrc_y
= (s
->mb_y
<<(3-field_based
)) + (my
>> 1);
275 uvdxy
= dxy
| (motion_y
& 2) | ((motion_x
& 2) >> 1);
279 }else if(!is_mpeg12
&& s
->out_format
== FMT_H261
){//even chroma mv's are full pel in H261
283 uvsrc_x
= s
->mb_x
*8 + mx
;
284 uvsrc_y
= s
->mb_y
*8 + my
;
286 if(s
->chroma_y_shift
){
289 uvdxy
= ((my
& 1) << 1) | (mx
& 1);
290 uvsrc_x
= s
->mb_x
* 8 + (mx
>> 1);
291 uvsrc_y
= (s
->mb_y
<<(3-field_based
)) + (my
>> 1);
293 if(s
->chroma_x_shift
){
296 uvdxy
= ((motion_y
& 1) << 1) | (mx
& 1);
297 uvsrc_x
= s
->mb_x
* 8 + (mx
>> 1);
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
;
312 if( (unsigned)src_x
> s
->h_edge_pos
- (motion_x
&1) - 16
313 || (unsigned)src_y
> v_edge_pos
- (motion_y
&1) - h
){
314 if(is_mpeg12
|| s
->codec_id
== CODEC_ID_MPEG2VIDEO
||
315 s
->codec_id
== CODEC_ID_MPEG1VIDEO
){
316 av_log(s
->avctx
,AV_LOG_DEBUG
,
317 "MPEG motion vector out of boundary\n");
320 ff_emulated_edge_mc(s
->edge_emu_buffer
, ptr_y
, s
->linesize
,
322 src_x
, src_y
<<field_based
,
323 s
->h_edge_pos
, s
->v_edge_pos
);
324 ptr_y
= s
->edge_emu_buffer
;
325 if(!ENABLE_GRAY
|| !(s
->flags
&CODEC_FLAG_GRAY
)){
326 uint8_t *uvbuf
= s
->edge_emu_buffer
+18*s
->linesize
;
327 ff_emulated_edge_mc(uvbuf
,
328 ptr_cb
, s
->uvlinesize
,
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
,
335 uvsrc_x
, uvsrc_y
<<field_based
,
336 s
->h_edge_pos
>>1, s
->v_edge_pos
>>1);
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
;
349 ptr_y
+= s
->linesize
;
350 ptr_cb
+= s
->uvlinesize
;
351 ptr_cr
+= s
->uvlinesize
;
354 pix_op
[0][dxy
](dest_y
, ptr_y
, linesize
, h
);
356 if(!ENABLE_GRAY
|| !(s
->flags
&CODEC_FLAG_GRAY
)){
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
);
362 if(!is_mpeg12
&& (ENABLE_H261_ENCODER
|| ENABLE_H261_DECODER
) &&
363 s
->out_format
== FMT_H261
){
364 ff_h261_loop_filter(s
);
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],
373 int motion_x
, int motion_y
, int h
)
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
,
379 motion_x
, motion_y
, h
, 1);
382 mpeg_motion_internal(s
, dest_y
, dest_cb
, dest_cr
, field_based
,
383 bottom_field
, field_select
, ref_picture
, pix_op
,
384 motion_x
, motion_y
, h
, 0);
387 //FIXME move to dsputil, avg variant, 16x16 version
388 static inline void put_obmc(uint8_t *dst
, uint8_t *src
[5], int stride
){
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);
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);
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);
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);
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);
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);
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);
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*/)
450 assert(s
->quarter_sample
==0);
453 if(i
&& mv
[i
][0]==mv
[MID
][0] && mv
[i
][1]==mv
[MID
][1]){
456 ptr
[i
]= s
->obmc_scratchpad
+ 8*(i
&1) + s
->linesize
*8*(i
>>1);
457 hpel_motion(s
, ptr
[i
], src
, 0, 0,
459 s
->width
, s
->height
, s
->linesize
,
460 s
->h_edge_pos
, s
->v_edge_pos
,
466 put_obmc(dest
, ptr
, s
->linesize
);
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
)
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
;
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);
483 v_edge_pos
= s
->v_edge_pos
>> field_based
;
484 linesize
= s
->linesize
<< field_based
;
485 uvlinesize
= s
->uvlinesize
<< field_based
;
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);
504 uvdxy
= (mx
&1) | ((my
&1)<<1);
508 uvsrc_x
= s
->mb_x
* 8 + mx
;
509 uvsrc_y
= s
->mb_y
* (8 >> field_based
) + my
;
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
;
515 if( (unsigned)src_x
> s
->h_edge_pos
- (motion_x
&3) - 16
516 || (unsigned)src_y
> v_edge_pos
- (motion_y
&3) - h
){
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
);
520 ptr_y
= s
->edge_emu_buffer
;
521 if(!ENABLE_GRAY
|| !(s
->flags
&CODEC_FLAG_GRAY
)){
522 uint8_t *uvbuf
= s
->edge_emu_buffer
+ 18*s
->linesize
;
523 ff_emulated_edge_mc(uvbuf
, ptr_cb
, s
->uvlinesize
,
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
,
529 uvsrc_x
, uvsrc_y
<<field_based
,
530 s
->h_edge_pos
>>1, s
->v_edge_pos
>>1);
537 qpix_op
[0][dxy
](dest_y
, ptr_y
, linesize
);
540 dest_y
+= s
->linesize
;
541 dest_cb
+= s
->uvlinesize
;
542 dest_cr
+= s
->uvlinesize
;
546 ptr_y
+= s
->linesize
;
547 ptr_cb
+= s
->uvlinesize
;
548 ptr_cr
+= s
->uvlinesize
;
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
);
555 if(!ENABLE_GRAY
|| !(s
->flags
&CODEC_FLAG_GRAY
)){
556 pix_op
[1][uvdxy
](dest_cr
, ptr_cr
, uvlinesize
, h
>> 1);
557 pix_op
[1][uvdxy
](dest_cb
, ptr_cb
, uvlinesize
, h
>> 1);
562 * h263 chroma 4mv motion compensation.
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
,
569 int dxy
, emu
=0, src_x
, src_y
, offset
;
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
);
577 dxy
= ((my
& 1) << 1) | (mx
& 1);
581 src_x
= s
->mb_x
* 8 + mx
;
582 src_y
= s
->mb_y
* 8 + my
;
583 src_x
= av_clip(src_x
, -8, s
->width
/2);
584 if (src_x
== s
->width
/2)
586 src_y
= av_clip(src_y
, -8, s
->height
/2);
587 if (src_y
== s
->height
/2)
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){
595 ff_emulated_edge_mc(s
->edge_emu_buffer
, ptr
, s
->uvlinesize
,
597 s
->h_edge_pos
>>1, s
->v_edge_pos
>>1);
598 ptr
= s
->edge_emu_buffer
;
602 pix_op
[dxy
](dest_cb
, ptr
, s
->uvlinesize
, 8);
604 ptr
= ref_picture
[2] + offset
;
606 ff_emulated_edge_mc(s
->edge_emu_buffer
, ptr
, s
->uvlinesize
,
608 s
->h_edge_pos
>>1, s
->v_edge_pos
>>1);
609 ptr
= s
->edge_emu_buffer
;
611 pix_op
[dxy
](dest_cr
, ptr
, s
->uvlinesize
, 8);
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);
627 * motion compensation of a single macroblock
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
634 * @param pic_op halfpel motion compensation function (average or put normally)
635 * @param pic_op qpel motion compensation function (average or put normally)
636 * the motion vectors are taken from s->mv and the MV type from s->mv_type
638 static av_always_inline
void MPV_motion_internal(MpegEncContext
*s
,
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],
643 qpel_mc_func (*qpix_op
)[16], int is_mpeg12
)
645 int dxy
, mx
, my
, src_x
, src_y
, motion_x
, motion_y
;
652 prefetch_motion(s
, ref_picture
, dir
);
654 if(!is_mpeg12
&& s
->obmc
&& s
->pict_type
!= FF_B_TYPE
){
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
;
660 assert(!s
->mb_skipped
);
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);
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);
669 memcpy(mv_cache
[0][1], s
->current_picture
.motion_val
[0][mot_xy
-mot_stride
], sizeof(int16_t)*4);
672 if(mb_x
==0 || IS_INTRA(s
->current_picture
.mb_type
[xy
-1])){
673 *(int32_t*)mv_cache
[1][0]= *(int32_t*)mv_cache
[1][1];
674 *(int32_t*)mv_cache
[2][0]= *(int32_t*)mv_cache
[2][1];
676 *(int32_t*)mv_cache
[1][0]= *(int32_t*)s
->current_picture
.motion_val
[0][mot_xy
-1];
677 *(int32_t*)mv_cache
[2][0]= *(int32_t*)s
->current_picture
.motion_val
[0][mot_xy
-1+mot_stride
];
680 if(mb_x
+1>=s
->mb_width
|| IS_INTRA(s
->current_picture
.mb_type
[xy
+1])){
681 *(int32_t*)mv_cache
[1][3]= *(int32_t*)mv_cache
[1][2];
682 *(int32_t*)mv_cache
[2][3]= *(int32_t*)mv_cache
[2][2];
684 *(int32_t*)mv_cache
[1][3]= *(int32_t*)s
->current_picture
.motion_val
[0][mot_xy
+2];
685 *(int32_t*)mv_cache
[2][3]= *(int32_t*)s
->current_picture
.motion_val
[0][mot_xy
+2+mot_stride
];
691 const int x
= (i
&1)+1;
692 const int y
= (i
>>1)+1;
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]}};
700 obmc_motion(s
, dest_y
+ ((i
& 1) * 8) + (i
>> 1) * 8 * s
->linesize
,
702 mb_x
* 16 + (i
& 1) * 8, mb_y
* 16 + (i
>>1) * 8,
709 if(!ENABLE_GRAY
|| !(s
->flags
&CODEC_FLAG_GRAY
))
710 chroma_4mv_motion(s
, dest_cb
, dest_cr
, ref_picture
, pix_op
[1], mx
, my
);
718 if(s
->real_sprite_warping_points
==1){
719 gmc1_motion(s
, dest_y
, dest_cb
, dest_cr
,
722 gmc_motion(s
, dest_y
, dest_cb
, dest_cr
,
725 }else if(!is_mpeg12
&& s
->quarter_sample
){
726 qpel_motion(s
, dest_y
, dest_cb
, dest_cr
,
728 ref_picture
, pix_op
, qpix_op
,
729 s
->mv
[dir
][0][0], s
->mv
[dir
][0][1], 16);
730 }else if(!is_mpeg12
&& ENABLE_WMV2
&& s
->mspel
){
731 ff_mspel_motion(s
, dest_y
, dest_cb
, dest_cr
,
733 s
->mv
[dir
][0][0], s
->mv
[dir
][0][1], 16);
736 mpeg_motion(s
, dest_y
, dest_cb
, dest_cr
,
739 s
->mv
[dir
][0][0], s
->mv
[dir
][0][1], 16);
746 if(s
->quarter_sample
){
748 motion_x
= s
->mv
[dir
][i
][0];
749 motion_y
= s
->mv
[dir
][i
][1];
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;
755 /* WARNING: do no forget half pels */
756 src_x
= av_clip(src_x
, -16, s
->width
);
757 if (src_x
== s
->width
)
759 src_y
= av_clip(src_y
, -16, s
->height
);
760 if (src_y
== s
->height
)
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 ){
767 ff_emulated_edge_mc(s
->edge_emu_buffer
, ptr
,
770 s
->h_edge_pos
, s
->v_edge_pos
);
771 ptr
= s
->edge_emu_buffer
;
774 dest
= dest_y
+ ((i
& 1) * 8) + (i
>> 1) * 8 * s
->linesize
;
775 qpix_op
[1][dxy
](dest
, ptr
, s
->linesize
);
777 mx
+= s
->mv
[dir
][i
][0]/2;
778 my
+= s
->mv
[dir
][i
][1]/2;
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
,
788 s
->mv
[dir
][i
][0], s
->mv
[dir
][i
][1]);
790 mx
+= s
->mv
[dir
][i
][0];
791 my
+= s
->mv
[dir
][i
][1];
795 if(!ENABLE_GRAY
|| !(s
->flags
&CODEC_FLAG_GRAY
))
796 chroma_4mv_motion(s
, dest_cb
, dest_cr
, ref_picture
, pix_op
[1], mx
, my
);
800 if (s
->picture_structure
== PICT_FRAME
) {
801 if(!is_mpeg12
&& s
->quarter_sample
){
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);
810 mpeg_motion(s
, dest_y
, dest_cb
, dest_cr
,
811 1, 0, s
->field_select
[dir
][0],
813 s
->mv
[dir
][0][0], s
->mv
[dir
][0][1], 8);
815 mpeg_motion(s
, dest_y
, dest_cb
, dest_cr
,
816 1, 1, s
->field_select
[dir
][1],
818 s
->mv
[dir
][1][0], s
->mv
[dir
][1][1], 8);
821 if(s
->picture_structure
!= s
->field_select
[dir
][0] + 1 && s
->pict_type
!= FF_B_TYPE
&& !s
->first_field
){
822 ref_picture
= s
->current_picture_ptr
->data
;
825 mpeg_motion(s
, dest_y
, dest_cb
, dest_cr
,
826 0, 0, s
->field_select
[dir
][0],
828 s
->mv
[dir
][0][0], s
->mv
[dir
][0][1], 16);
833 uint8_t ** ref2picture
;
835 if(s
->picture_structure
== s
->field_select
[dir
][i
] + 1
836 || s
->pict_type
== FF_B_TYPE
|| s
->first_field
){
837 ref2picture
= ref_picture
;
839 ref2picture
= s
->current_picture_ptr
->data
;
842 mpeg_motion(s
, dest_y
, dest_cb
, dest_cr
,
843 0, 0, s
->field_select
[dir
][i
],
845 s
->mv
[dir
][i
][0], s
->mv
[dir
][i
][1] + 16*i
, 8);
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
;
853 if(s
->picture_structure
== PICT_FRAME
){
857 mpeg_motion(s
, dest_y
, dest_cb
, dest_cr
,
860 s
->mv
[dir
][2*i
+ j
][0], s
->mv
[dir
][2*i
+ j
][1], 8);
862 pix_op
= s
->dsp
.avg_pixels_tab
;
866 mpeg_motion(s
, dest_y
, dest_cb
, dest_cr
,
867 0, 0, s
->picture_structure
!= i
+1,
869 s
->mv
[dir
][2*i
][0],s
->mv
[dir
][2*i
][1],16);
871 // after put we make avg of the same block
872 pix_op
=s
->dsp
.avg_pixels_tab
;
874 //opposite parity is always in the same frame if this is second field
876 ref_picture
= s
->current_picture_ptr
->data
;
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])
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);
898 MPV_motion_internal(s
, dest_y
, dest_cb
, dest_cr
, dir
,
899 ref_picture
, pix_op
, qpix_op
, 0);
901 #endif /* FFMPEG_MPEGVIDEO_COMMON_H */