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 Libav.
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.
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.
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
27
* The simplest mpeg encoder (well, it was the simplest!).
30
#ifndef AVCODEC_MPEGVIDEO_COMMON_H
31
#define AVCODEC_MPEGVIDEO_COMMON_H
36
#include "mpegvideo.h"
42
int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
46
* The pixels are allocated/set by calling get_buffer() if shared = 0.
48
int alloc_picture(MpegEncContext *s, Picture *pic, int shared);
51
* Set the given MpegEncContext to common defaults (same for encoding and decoding).
52
* The changed fields will not depend upon the prior state of the MpegEncContext.
54
void MPV_common_defaults(MpegEncContext *s);
56
static inline void gmc1_motion(MpegEncContext *s,
57
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
58
uint8_t **ref_picture)
61
int offset, src_x, src_y, linesize, uvlinesize;
62
int motion_x, motion_y;
65
motion_x= s->sprite_offset[0][0];
66
motion_y= s->sprite_offset[0][1];
67
src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1));
68
src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1));
69
motion_x<<=(3-s->sprite_warping_accuracy);
70
motion_y<<=(3-s->sprite_warping_accuracy);
71
src_x = av_clip(src_x, -16, s->width);
72
if (src_x == s->width)
74
src_y = av_clip(src_y, -16, s->height);
75
if (src_y == s->height)
78
linesize = s->linesize;
79
uvlinesize = s->uvlinesize;
81
ptr = ref_picture[0] + (src_y * linesize) + src_x;
83
if(s->flags&CODEC_FLAG_EMU_EDGE){
84
if( (unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0)
85
|| (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)){
86
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);
87
ptr= s->edge_emu_buffer;
91
if((motion_x|motion_y)&7){
92
s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
93
s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
97
dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2);
99
s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
101
s->dsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16);
105
if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return;
107
motion_x= s->sprite_offset[1][0];
108
motion_y= s->sprite_offset[1][1];
109
src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1));
110
src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1));
111
motion_x<<=(3-s->sprite_warping_accuracy);
112
motion_y<<=(3-s->sprite_warping_accuracy);
113
src_x = av_clip(src_x, -8, s->width>>1);
114
if (src_x == s->width>>1)
116
src_y = av_clip(src_y, -8, s->height>>1);
117
if (src_y == s->height>>1)
120
offset = (src_y * uvlinesize) + src_x;
121
ptr = ref_picture[1] + offset;
122
if(s->flags&CODEC_FLAG_EMU_EDGE){
123
if( (unsigned)src_x >= FFMAX((s->h_edge_pos>>1) - 9, 0)
124
|| (unsigned)src_y >= FFMAX((s->v_edge_pos>>1) - 9, 0)){
125
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);
126
ptr= s->edge_emu_buffer;
130
s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
132
ptr = ref_picture[2] + offset;
134
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);
135
ptr= s->edge_emu_buffer;
137
s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
142
static inline void gmc_motion(MpegEncContext *s,
143
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
144
uint8_t **ref_picture)
147
int linesize, uvlinesize;
148
const int a= s->sprite_warping_accuracy;
151
linesize = s->linesize;
152
uvlinesize = s->uvlinesize;
154
ptr = ref_picture[0];
156
ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16;
157
oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16;
159
s->dsp.gmc(dest_y, ptr, linesize, 16,
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
s->dsp.gmc(dest_y+8, ptr, linesize, 16,
167
ox + s->sprite_delta[0][0]*8,
168
oy + s->sprite_delta[1][0]*8,
169
s->sprite_delta[0][0], s->sprite_delta[0][1],
170
s->sprite_delta[1][0], s->sprite_delta[1][1],
171
a+1, (1<<(2*a+1)) - s->no_rounding,
172
s->h_edge_pos, s->v_edge_pos);
174
if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return;
176
ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8;
177
oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8;
179
ptr = ref_picture[1];
180
s->dsp.gmc(dest_cb, ptr, uvlinesize, 8,
183
s->sprite_delta[0][0], s->sprite_delta[0][1],
184
s->sprite_delta[1][0], s->sprite_delta[1][1],
185
a+1, (1<<(2*a+1)) - s->no_rounding,
186
s->h_edge_pos>>1, s->v_edge_pos>>1);
188
ptr = ref_picture[2];
189
s->dsp.gmc(dest_cr, ptr, uvlinesize, 8,
192
s->sprite_delta[0][0], s->sprite_delta[0][1],
193
s->sprite_delta[1][0], s->sprite_delta[1][1],
194
a+1, (1<<(2*a+1)) - s->no_rounding,
195
s->h_edge_pos>>1, s->v_edge_pos>>1);
198
static inline int hpel_motion(MpegEncContext *s,
199
uint8_t *dest, uint8_t *src,
200
int field_based, int field_select,
201
int src_x, int src_y,
202
int width, int height, int stride,
203
int h_edge_pos, int v_edge_pos,
204
int w, int h, op_pixels_func *pix_op,
205
int motion_x, int motion_y)
210
dxy = ((motion_y & 1) << 1) | (motion_x & 1);
211
src_x += motion_x >> 1;
212
src_y += motion_y >> 1;
214
/* WARNING: do no forget half pels */
215
src_x = av_clip(src_x, -16, width); //FIXME unneeded for emu?
218
src_y = av_clip(src_y, -16, height);
221
src += src_y * stride + src_x;
223
if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
224
if( (unsigned)src_x > FFMAX(h_edge_pos - (motion_x&1) - w, 0)
225
|| (unsigned)src_y > FFMAX(v_edge_pos - (motion_y&1) - h, 0)){
226
s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based,
227
src_x, src_y<<field_based, h_edge_pos, s->v_edge_pos);
228
src= s->edge_emu_buffer;
234
pix_op[dxy](dest, src, stride, h);
238
static av_always_inline
239
void mpeg_motion_internal(MpegEncContext *s,
240
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
241
int field_based, int bottom_field, int field_select,
242
uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
243
int motion_x, int motion_y, int h, int is_mpeg12, int mb_y)
245
uint8_t *ptr_y, *ptr_cb, *ptr_cr;
246
int dxy, uvdxy, mx, my, src_x, src_y,
247
uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize;
250
if(s->quarter_sample)
257
v_edge_pos = s->v_edge_pos >> field_based;
258
linesize = s->current_picture.f.linesize[0] << field_based;
259
uvlinesize = s->current_picture.f.linesize[1] << field_based;
261
dxy = ((motion_y & 1) << 1) | (motion_x & 1);
262
src_x = s->mb_x* 16 + (motion_x >> 1);
263
src_y =( mb_y<<(4-field_based)) + (motion_y >> 1);
265
if (!is_mpeg12 && s->out_format == FMT_H263) {
266
if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){
267
mx = (motion_x>>1)|(motion_x&1);
269
uvdxy = ((my & 1) << 1) | (mx & 1);
270
uvsrc_x = s->mb_x* 8 + (mx >> 1);
271
uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1);
273
uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
277
}else if(!is_mpeg12 && s->out_format == FMT_H261){//even chroma mv's are full pel in H261
281
uvsrc_x = s->mb_x*8 + mx;
282
uvsrc_y = mb_y*8 + my;
284
if(s->chroma_y_shift){
287
uvdxy = ((my & 1) << 1) | (mx & 1);
288
uvsrc_x = s->mb_x* 8 + (mx >> 1);
289
uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1);
291
if(s->chroma_x_shift){
294
uvdxy = ((motion_y & 1) << 1) | (mx & 1);
295
uvsrc_x = s->mb_x* 8 + (mx >> 1);
306
ptr_y = ref_picture[0] + src_y * linesize + src_x;
307
ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
308
ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
310
if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 16, 0)
311
|| (unsigned)src_y > FFMAX( v_edge_pos - (motion_y&1) - h , 0)){
312
if(is_mpeg12 || s->codec_id == CODEC_ID_MPEG2VIDEO ||
313
s->codec_id == CODEC_ID_MPEG1VIDEO){
314
av_log(s->avctx,AV_LOG_DEBUG,
315
"MPEG motion vector out of boundary (%d %d)\n", src_x, src_y);
318
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
320
src_x, src_y<<field_based,
321
s->h_edge_pos, s->v_edge_pos);
322
ptr_y = s->edge_emu_buffer;
323
if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
324
uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
325
s->dsp.emulated_edge_mc(uvbuf ,
326
ptr_cb, s->uvlinesize,
328
uvsrc_x, uvsrc_y<<field_based,
329
s->h_edge_pos>>1, s->v_edge_pos>>1);
330
s->dsp.emulated_edge_mc(uvbuf+16,
331
ptr_cr, s->uvlinesize,
333
uvsrc_x, uvsrc_y<<field_based,
334
s->h_edge_pos>>1, s->v_edge_pos>>1);
340
if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data
341
dest_y += s->linesize;
342
dest_cb+= s->uvlinesize;
343
dest_cr+= s->uvlinesize;
347
ptr_y += s->linesize;
348
ptr_cb+= s->uvlinesize;
349
ptr_cr+= s->uvlinesize;
352
pix_op[0][dxy](dest_y, ptr_y, linesize, h);
354
if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
355
pix_op[s->chroma_x_shift][uvdxy]
356
(dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
357
pix_op[s->chroma_x_shift][uvdxy]
358
(dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
360
if(!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&
361
s->out_format == FMT_H261){
362
ff_h261_loop_filter(s);
365
/* apply one mpeg motion vector to the three components */
366
static av_always_inline
367
void mpeg_motion(MpegEncContext *s,
368
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
369
int field_based, int bottom_field, int field_select,
370
uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
371
int motion_x, int motion_y, int h, int mb_y)
374
if(s->out_format == FMT_MPEG1)
375
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based,
376
bottom_field, field_select, ref_picture, pix_op,
377
motion_x, motion_y, h, 1, mb_y);
380
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based,
381
bottom_field, field_select, ref_picture, pix_op,
382
motion_x, motion_y, h, 0, mb_y);
385
//FIXME move to dsputil, avg variant, 16x16 version
386
static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){
388
uint8_t * const top = src[1];
389
uint8_t * const left = src[2];
390
uint8_t * const mid = src[0];
391
uint8_t * const right = src[3];
392
uint8_t * const bottom= src[4];
393
#define OBMC_FILTER(x, t, l, m, r, b)\
394
dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3
395
#define OBMC_FILTER4(x, t, l, m, r, b)\
396
OBMC_FILTER(x , t, l, m, r, b);\
397
OBMC_FILTER(x+1 , t, l, m, r, b);\
398
OBMC_FILTER(x +stride, t, l, m, r, b);\
399
OBMC_FILTER(x+1+stride, t, l, m, r, b);
402
OBMC_FILTER (x , 2, 2, 4, 0, 0);
403
OBMC_FILTER (x+1, 2, 1, 5, 0, 0);
404
OBMC_FILTER4(x+2, 2, 1, 5, 0, 0);
405
OBMC_FILTER4(x+4, 2, 0, 5, 1, 0);
406
OBMC_FILTER (x+6, 2, 0, 5, 1, 0);
407
OBMC_FILTER (x+7, 2, 0, 4, 2, 0);
409
OBMC_FILTER (x , 1, 2, 5, 0, 0);
410
OBMC_FILTER (x+1, 1, 2, 5, 0, 0);
411
OBMC_FILTER (x+6, 1, 0, 5, 2, 0);
412
OBMC_FILTER (x+7, 1, 0, 5, 2, 0);
414
OBMC_FILTER4(x , 1, 2, 5, 0, 0);
415
OBMC_FILTER4(x+2, 1, 1, 6, 0, 0);
416
OBMC_FILTER4(x+4, 1, 0, 6, 1, 0);
417
OBMC_FILTER4(x+6, 1, 0, 5, 2, 0);
419
OBMC_FILTER4(x , 0, 2, 5, 0, 1);
420
OBMC_FILTER4(x+2, 0, 1, 6, 0, 1);
421
OBMC_FILTER4(x+4, 0, 0, 6, 1, 1);
422
OBMC_FILTER4(x+6, 0, 0, 5, 2, 1);
424
OBMC_FILTER (x , 0, 2, 5, 0, 1);
425
OBMC_FILTER (x+1, 0, 2, 5, 0, 1);
426
OBMC_FILTER4(x+2, 0, 1, 5, 0, 2);
427
OBMC_FILTER4(x+4, 0, 0, 5, 1, 2);
428
OBMC_FILTER (x+6, 0, 0, 5, 2, 1);
429
OBMC_FILTER (x+7, 0, 0, 5, 2, 1);
431
OBMC_FILTER (x , 0, 2, 4, 0, 2);
432
OBMC_FILTER (x+1, 0, 1, 5, 0, 2);
433
OBMC_FILTER (x+6, 0, 0, 5, 1, 2);
434
OBMC_FILTER (x+7, 0, 0, 4, 2, 2);
437
/* obmc for 1 8x8 luma block */
438
static inline void obmc_motion(MpegEncContext *s,
439
uint8_t *dest, uint8_t *src,
440
int src_x, int src_y,
441
op_pixels_func *pix_op,
442
int16_t mv[5][2]/* mid top left right bottom*/)
448
assert(s->quarter_sample==0);
451
if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){
454
ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1);
455
hpel_motion(s, ptr[i], src, 0, 0,
457
s->width, s->height, s->linesize,
458
s->h_edge_pos, s->v_edge_pos,
464
put_obmc(dest, ptr, s->linesize);
467
static inline void qpel_motion(MpegEncContext *s,
468
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
469
int field_based, int bottom_field, int field_select,
470
uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
471
qpel_mc_func (*qpix_op)[16],
472
int motion_x, int motion_y, int h)
474
uint8_t *ptr_y, *ptr_cb, *ptr_cr;
475
int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize;
477
dxy = ((motion_y & 3) << 2) | (motion_x & 3);
478
src_x = s->mb_x * 16 + (motion_x >> 2);
479
src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
481
v_edge_pos = s->v_edge_pos >> field_based;
482
linesize = s->linesize << field_based;
483
uvlinesize = s->uvlinesize << field_based;
488
}else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){
489
static const int rtab[8]= {0,0,1,1,0,0,0,1};
490
mx= (motion_x>>1) + rtab[motion_x&7];
491
my= (motion_y>>1) + rtab[motion_y&7];
492
}else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){
493
mx= (motion_x>>1)|(motion_x&1);
494
my= (motion_y>>1)|(motion_y&1);
502
uvdxy= (mx&1) | ((my&1)<<1);
506
uvsrc_x = s->mb_x * 8 + mx;
507
uvsrc_y = s->mb_y * (8 >> field_based) + my;
509
ptr_y = ref_picture[0] + src_y * linesize + src_x;
510
ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
511
ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
513
if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 16, 0)
514
|| (unsigned)src_y > FFMAX( v_edge_pos - (motion_y&3) - h , 0)){
515
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
516
17, 17+field_based, src_x, src_y<<field_based,
517
s->h_edge_pos, s->v_edge_pos);
518
ptr_y= s->edge_emu_buffer;
519
if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
520
uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
521
s->dsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
523
uvsrc_x, uvsrc_y<<field_based,
524
s->h_edge_pos>>1, s->v_edge_pos>>1);
525
s->dsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
527
uvsrc_x, uvsrc_y<<field_based,
528
s->h_edge_pos>>1, s->v_edge_pos>>1);
535
qpix_op[0][dxy](dest_y, ptr_y, linesize);
538
dest_y += s->linesize;
539
dest_cb+= s->uvlinesize;
540
dest_cr+= s->uvlinesize;
544
ptr_y += s->linesize;
545
ptr_cb += s->uvlinesize;
546
ptr_cr += s->uvlinesize;
548
//damn interlaced mode
549
//FIXME boundary mirroring is not exactly correct here
550
qpix_op[1][dxy](dest_y , ptr_y , linesize);
551
qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize);
553
if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
554
pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1);
555
pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1);
560
* h263 chroma 4mv motion compensation.
562
static inline void chroma_4mv_motion(MpegEncContext *s,
563
uint8_t *dest_cb, uint8_t *dest_cr,
564
uint8_t **ref_picture,
565
op_pixels_func *pix_op,
567
int dxy, emu=0, src_x, src_y, offset;
570
/* In case of 8X8, we construct a single chroma motion vector
571
with a special rounding */
572
mx= ff_h263_round_chroma(mx);
573
my= ff_h263_round_chroma(my);
575
dxy = ((my & 1) << 1) | (mx & 1);
579
src_x = s->mb_x * 8 + mx;
580
src_y = s->mb_y * 8 + my;
581
src_x = av_clip(src_x, -8, (s->width >> 1));
582
if (src_x == (s->width >> 1))
584
src_y = av_clip(src_y, -8, (s->height >> 1));
585
if (src_y == (s->height >> 1))
588
offset = src_y * s->uvlinesize + src_x;
589
ptr = ref_picture[1] + offset;
590
if(s->flags&CODEC_FLAG_EMU_EDGE){
591
if( (unsigned)src_x > FFMAX((s->h_edge_pos>>1) - (dxy &1) - 8, 0)
592
|| (unsigned)src_y > FFMAX((s->v_edge_pos>>1) - (dxy>>1) - 8, 0)){
593
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
595
s->h_edge_pos>>1, s->v_edge_pos>>1);
596
ptr= s->edge_emu_buffer;
600
pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
602
ptr = ref_picture[2] + offset;
604
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
606
s->h_edge_pos>>1, s->v_edge_pos>>1);
607
ptr= s->edge_emu_buffer;
609
pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
612
static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){
613
/* fetch pixels for estimated mv 4 macroblocks ahead
614
* optimized for 64byte cache lines */
615
const int shift = s->quarter_sample ? 2 : 1;
616
const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8;
617
const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y;
618
int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64;
619
s->dsp.prefetch(pix[0]+off, s->linesize, 4);
620
off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64;
621
s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
625
* motion compensation of a single macroblock
627
* @param dest_y luma destination pointer
628
* @param dest_cb chroma cb/u destination pointer
629
* @param dest_cr chroma cr/v destination pointer
630
* @param dir direction (0->forward, 1->backward)
631
* @param ref_picture array[3] of pointers to the 3 planes of the reference picture
632
* @param pix_op halfpel motion compensation function (average or put normally)
633
* @param qpix_op qpel motion compensation function (average or put normally)
634
* the motion vectors are taken from s->mv and the MV type from s->mv_type
636
static av_always_inline void MPV_motion_internal(MpegEncContext *s,
637
uint8_t *dest_y, uint8_t *dest_cb,
638
uint8_t *dest_cr, int dir,
639
uint8_t **ref_picture,
640
op_pixels_func (*pix_op)[4],
641
qpel_mc_func (*qpix_op)[16], int is_mpeg12)
643
int dxy, mx, my, src_x, src_y, motion_x, motion_y;
650
prefetch_motion(s, ref_picture, dir);
652
if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){
653
int16_t mv_cache[4][4][2];
654
const int xy= s->mb_x + s->mb_y*s->mb_stride;
655
const int mot_stride= s->b8_stride;
656
const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
658
assert(!s->mb_skipped);
660
memcpy(mv_cache[1][1], s->current_picture.f.motion_val[0][mot_xy ], sizeof(int16_t) * 4);
661
memcpy(mv_cache[2][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4);
662
memcpy(mv_cache[3][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4);
664
if (mb_y == 0 || IS_INTRA(s->current_picture.f.mb_type[xy - s->mb_stride])) {
665
memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4);
667
memcpy(mv_cache[0][1], s->current_picture.f.motion_val[0][mot_xy - mot_stride], sizeof(int16_t) * 4);
670
if (mb_x == 0 || IS_INTRA(s->current_picture.f.mb_type[xy - 1])) {
671
AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
672
AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
674
AV_COPY32(mv_cache[1][0], s->current_picture.f.motion_val[0][mot_xy - 1]);
675
AV_COPY32(mv_cache[2][0], s->current_picture.f.motion_val[0][mot_xy - 1 + mot_stride]);
678
if (mb_x + 1 >= s->mb_width || IS_INTRA(s->current_picture.f.mb_type[xy + 1])) {
679
AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
680
AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
682
AV_COPY32(mv_cache[1][3], s->current_picture.f.motion_val[0][mot_xy + 2]);
683
AV_COPY32(mv_cache[2][3], s->current_picture.f.motion_val[0][mot_xy + 2 + mot_stride]);
689
const int x= (i&1)+1;
690
const int y= (i>>1)+1;
692
{mv_cache[y][x ][0], mv_cache[y][x ][1]},
693
{mv_cache[y-1][x][0], mv_cache[y-1][x][1]},
694
{mv_cache[y][x-1][0], mv_cache[y][x-1][1]},
695
{mv_cache[y][x+1][0], mv_cache[y][x+1][1]},
696
{mv_cache[y+1][x][0], mv_cache[y+1][x][1]}};
698
obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
700
mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
707
if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY))
708
chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
716
if(s->real_sprite_warping_points==1){
717
gmc1_motion(s, dest_y, dest_cb, dest_cr,
720
gmc_motion(s, dest_y, dest_cb, dest_cr,
723
}else if(!is_mpeg12 && s->quarter_sample){
724
qpel_motion(s, dest_y, dest_cb, dest_cr,
726
ref_picture, pix_op, qpix_op,
727
s->mv[dir][0][0], s->mv[dir][0][1], 16);
728
} else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&
729
s->mspel && s->codec_id == CODEC_ID_WMV2) {
730
ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
732
s->mv[dir][0][0], s->mv[dir][0][1], 16);
735
mpeg_motion(s, dest_y, dest_cb, dest_cr,
738
s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y);
745
if(s->quarter_sample){
747
motion_x = s->mv[dir][i][0];
748
motion_y = s->mv[dir][i][1];
750
dxy = ((motion_y & 3) << 2) | (motion_x & 3);
751
src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
752
src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8;
754
/* WARNING: do no forget half pels */
755
src_x = av_clip(src_x, -16, s->width);
756
if (src_x == s->width)
758
src_y = av_clip(src_y, -16, s->height);
759
if (src_y == s->height)
762
ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
763
if(s->flags&CODEC_FLAG_EMU_EDGE){
764
if( (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 8, 0)
765
|| (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&3) - 8, 0)){
766
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
769
s->h_edge_pos, s->v_edge_pos);
770
ptr= s->edge_emu_buffer;
773
dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
774
qpix_op[1][dxy](dest, ptr, s->linesize);
776
mx += s->mv[dir][i][0]/2;
777
my += s->mv[dir][i][1]/2;
781
hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
782
ref_picture[0], 0, 0,
783
mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
784
s->width, s->height, s->linesize,
785
s->h_edge_pos, s->v_edge_pos,
787
s->mv[dir][i][0], s->mv[dir][i][1]);
789
mx += s->mv[dir][i][0];
790
my += s->mv[dir][i][1];
794
if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY))
795
chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
799
if (s->picture_structure == PICT_FRAME) {
800
if(!is_mpeg12 && s->quarter_sample){
802
qpel_motion(s, dest_y, dest_cb, dest_cr,
803
1, i, s->field_select[dir][i],
804
ref_picture, pix_op, qpix_op,
805
s->mv[dir][i][0], s->mv[dir][i][1], 8);
809
mpeg_motion(s, dest_y, dest_cb, dest_cr,
810
1, 0, s->field_select[dir][0],
812
s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y);
814
mpeg_motion(s, dest_y, dest_cb, dest_cr,
815
1, 1, s->field_select[dir][1],
817
s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y);
820
if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field){
821
ref_picture = s->current_picture_ptr->f.data;
824
mpeg_motion(s, dest_y, dest_cb, dest_cr,
825
0, 0, s->field_select[dir][0],
827
s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y>>1);
832
uint8_t ** ref2picture;
834
if(s->picture_structure == s->field_select[dir][i] + 1
835
|| s->pict_type == AV_PICTURE_TYPE_B || s->first_field){
836
ref2picture= ref_picture;
838
ref2picture = s->current_picture_ptr->f.data;
841
mpeg_motion(s, dest_y, dest_cb, dest_cr,
842
0, 0, s->field_select[dir][i],
844
s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8, mb_y>>1);
846
dest_y += 16*s->linesize;
847
dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize;
848
dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize;
852
if(s->picture_structure == PICT_FRAME){
856
mpeg_motion(s, dest_y, dest_cb, dest_cr,
859
s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8, mb_y);
861
pix_op = s->dsp.avg_pixels_tab;
865
mpeg_motion(s, dest_y, dest_cb, dest_cr,
866
0, 0, s->picture_structure != i+1,
868
s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1);
870
// after put we make avg of the same block
871
pix_op=s->dsp.avg_pixels_tab;
873
//opposite parity is always in the same frame if this is second field
875
ref_picture = s->current_picture_ptr->f.data;
884
static inline void MPV_motion(MpegEncContext *s,
885
uint8_t *dest_y, uint8_t *dest_cb,
886
uint8_t *dest_cr, int dir,
887
uint8_t **ref_picture,
888
op_pixels_func (*pix_op)[4],
889
qpel_mc_func (*qpix_op)[16])
892
if(s->out_format == FMT_MPEG1)
893
MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
894
ref_picture, pix_op, qpix_op, 1);
897
MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
898
ref_picture, pix_op, qpix_op, 0);
900
#endif /* AVCODEC_MPEGVIDEO_COMMON_H */