+ (chroma ? FLAG_CHROMA : 0);
}
-static always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
+/*! \brief compares a block (either a full macroblock or a partition thereof)
+ against a proposed motion-compensated prediction of that block
+ */
+static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby,
const int size, const int h, int ref_index, int src_index,
me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){
MotionEstContext * const c= &s->me;
int d;
//FIXME check chroma 4mv, (no crashes ...)
if(flags&FLAG_DIRECT){
+ assert(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1));
if(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1)){
const int time_pp= s->pp_time;
const int time_pb= s->pb_time;
void ff_init_me(MpegEncContext *s){
MotionEstContext * const c= &s->me;
+ int cache_size= FFMIN(ME_MAP_SIZE>>ME_MAP_SHIFT, 1<<ME_MAP_SHIFT);
+ int dia_size= FFMAX(FFABS(s->avctx->dia_size)&255, FFABS(s->avctx->pre_dia_size)&255);
c->avctx= s->avctx;
+ if(cache_size < 2*dia_size && !c->stride){
+ av_log(s->avctx, AV_LOG_INFO, "ME_MAP size may be a little small for the selected diamond size\n");
+ }
+
ff_set_cmp(&s->dsp, s->dsp.me_pre_cmp, c->avctx->me_pre_cmp);
ff_set_cmp(&s->dsp, s->dsp.me_cmp, c->avctx->me_cmp);
ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, c->avctx->me_sub_cmp);
static inline void get_limits(MpegEncContext *s, int x, int y)
{
MotionEstContext * const c= &s->me;
+ int range= c->avctx->me_range >> (1 + !!(c->flags&FLAG_QPEL));
/*
if(c->avctx->me_range) c->range= c->avctx->me_range >> 1;
else c->range= 16;
c->xmax = - x + s->mb_width *16 - 16;
c->ymax = - y + s->mb_height*16 - 16;
}
+ if(range){
+ c->xmin = FFMAX(c->xmin,-range);
+ c->xmax = FFMIN(c->xmax, range);
+ c->ymin = FFMAX(c->ymin,-range);
+ c->ymax = FFMIN(c->ymax, range);
+ }
}
static inline void init_mv4_ref(MotionEstContext *c){
{
MotionEstContext * const c= &s->me;
uint8_t *pix, *ppix;
- int sum, varc, vard, mx, my, dmin;
+ int sum, mx, my, dmin;
+ int varc; ///< the variance of the block (sum of squared (p[y][x]-average))
+ int vard; ///< sum of squared differences with the estimated motion vector
int P[10][2];
const int shift= 1+s->quarter_sample;
int mb_type=0;
c->pred_x=0;
c->pred_y=0;
- P_LEFT[0] = clip(mv_table[mot_xy - 1][0], xmin<<shift, xmax<<shift);
- P_LEFT[1] = clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift);
+ P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin<<shift, xmax<<shift);
+ P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift);
/* special case for first line */
if (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as its clipped
- P_TOP[0] = clip(mv_table[mot_xy - mot_stride ][0], xmin<<shift, xmax<<shift);
- P_TOP[1] = clip(mv_table[mot_xy - mot_stride ][1], ymin<<shift, ymax<<shift);
- P_TOPRIGHT[0] = clip(mv_table[mot_xy - mot_stride + 1 ][0], xmin<<shift, xmax<<shift);
- P_TOPRIGHT[1] = clip(mv_table[mot_xy - mot_stride + 1 ][1], ymin<<shift, ymax<<shift);
+ P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin<<shift, xmax<<shift);
+ P_TOP[1] = av_clip(mv_table[mot_xy - mot_stride ][1], ymin<<shift, ymax<<shift);
+ P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1 ][0], xmin<<shift, xmax<<shift);
+ P_TOPRIGHT[1] = av_clip(mv_table[mot_xy - mot_stride + 1 ][1], ymin<<shift, ymax<<shift);
P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
get_limits(s, 16*mb_x, 16*mb_y); //restore c->?min/max, maybe not needed
- s->b_direct_mv_table[mot_xy][0]= mx;
- s->b_direct_mv_table[mot_xy][1]= my;
+ mv_table[mot_xy][0]= mx;
+ mv_table[mot_xy][1]= my;
c->flags &= ~FLAG_DIRECT;
c->sub_flags &= ~FLAG_DIRECT;
get_limits(s, 16*mb_x, 16*mb_y);
c->skip=0;
+
+ if(s->codec_id == CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]){
+ int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0
+
+ score= ((unsigned)(score*score + 128*256))>>16;
+ c->mc_mb_var_sum_temp += score;
+ s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE
+ s->mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_DIRECT0;
+
+ return;
+ }
+
if(c->avctx->me_threshold){
int vard= check_input_motion(s, mb_x, mb_y, 0);
}
//FIXME something smarter
if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //dont try direct mode if its invalid for this MB
+ if(s->codec_id == CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT && s->flags&CODEC_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy])
+ type |= CANDIDATE_MB_TYPE_DIRECT0;
#if 0
if(s->out_format == FMT_MPEG1)
type |= CANDIDATE_MB_TYPE_INTRA;