⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fame_motion_fourstep.c

📁 一个很好用的MPEG1/4的开源编码器
💻 C
📖 第 1 页 / 共 2 页
字号:
    for(i = 0; i < current_td->number; i++)    {      test[0].dx =	current_td->directions[i].dx *	ptr_stepx[current_td->directions[i].dx];      test[0].dy =	current_td->directions[i].dy *	ptr_stepy[current_td->directions[i].dy];            test[0].error =	eval_error(ref[residual]->y+edged_offset[0]+motion+		   (test[0].dx+test[0].dy*(pitch+32)),		   current+offset[0],		   shape+offset[0],		   pitch);      test[1].error =	eval_error(ref[residual]->y+edged_offset[1]+motion+		   (test[0].dx+test[0].dy*(pitch+32)),		   current+offset[1],		   shape+offset[1],		   pitch);      test[2].error =	eval_error(ref[residual]->y+edged_offset[2]+motion+		   (test[0].dx+test[0].dy*(pitch+32)),		   current+offset[2],		   shape+offset[2],		   pitch);      test[3].error =	eval_error(ref[residual]->y+edged_offset[3]+motion+		   (test[0].dx+test[0].dy*(pitch+32)),		   current+offset[3],		   shape+offset[3],		   pitch);      if(test[0].error+test[1].error+test[2].error+test[3].error <	 rel[0].error+rel[1].error+rel[2].error+rel[3].error)      {	last_motion = current_td->directions[i].index_direction;	rel[0].error = test[0].error;	rel[1].error = test[1].error;	rel[2].error = test[2].error;	rel[3].error = test[3].error;	rel[0].dx = test[0].dx;	rel[0].dy = test[0].dy;      }    }        /* Update the motion vector_t and the location in the window */    if(rel[0].error+rel[1].error+rel[2].error+rel[3].error <        mv[0].error+mv[1].error+mv[2].error+mv[3].error)    {      mv[0].error = rel[0].error;      mv[1].error = rel[1].error;      mv[2].error = rel[2].error;      mv[3].error = rel[3].error;      mv[0].dx += rel[0].dx << 1;      mv[0].dy += rel[0].dy << 1;	      current_td = &(td[last_motion]);      motion = (mv[0].dx >> 1) + (mv[0].dy >> 1) * (pitch+32);    }    else    {      last_motion = NULL_MOTION;      current_td = &(td[last_motion]);    }  }  mv[3].dx = mv[2].dx = mv[1].dx = mv[0].dx;  mv[3].dy = mv[2].dy = mv[1].dy = mv[0].dy;}static void find_subvector(fame_yuv_t **ref,			   unsigned char *current,			   unsigned char *shape,			   int offset,			   int edged_offset,			   int x,			   int y,			   int width,			   int height,			   int pitch,			   int search_range,			   int step_count,			   compute_error_t eval_error,			   fame_motion_vector_t *mv,			   int unrestricted){  int i;  int counter_fourstep;  int step;  int tab_stepx[3];  int tab_stepy[3];  int *ptr_stepx;  int *ptr_stepy;  int last_motion;  int motion;  int residual;  tab_direction_t *current_td;  fame_motion_vector_t rel;  fame_motion_vector_t test;  ptr_stepx = &tab_stepx[1];  ptr_stepy = &tab_stepy[1];  last_motion = NULL_MOTION;  current_td = &(td[last_motion]);  counter_fourstep = step_count;  rel.error = INFINITE_ERROR / 4;  step = 1 << (step_count - 1);  motion = (mv->dx >> 1) + (mv->dy >> 1) * (pitch+32);  residual = (mv->dx & 1) + ((mv->dy & 1) << 1);  /* initial step */  mv->error = eval_error(ref[residual]->y+offset+motion,			 current+offset,			 shape+offset,			 pitch);  if(mv->error <= 0) return;  while(step)  {    if(unrestricted) {      ptr_stepx[-1] = fame_min(((search_range-1)<<1)+mv->dx,fame_min(((x+16)<<1)+mv->dx, step<<1))>>1;      ptr_stepx[1]  = fame_min(((search_range-1)<<1)-mv->dx,fame_min(((width-x)<<1)-mv->dx, step<<1))>>1;      ptr_stepy[-1] = fame_min(((search_range-1)<<1)+mv->dy,fame_min(((y+16)<<1)+mv->dy, step<<1))>>1;      ptr_stepy[1]  = fame_min(((search_range-1)<<1)-mv->dy,fame_min(((height-y)<<1)-mv->dy, step<<1))>>1;    } else {      ptr_stepx[-1] = fame_min(((search_range-1)<<1)+mv->dx,fame_min((x<<1)+mv->dx, step<<1))>>1;      ptr_stepx[1]  = fame_min(((search_range-1)<<1)-mv->dx,fame_min(((width-x-16)<<1)-mv->dx, step<<1))>>1;      ptr_stepy[-1] = fame_min(((search_range-1)<<1)+mv->dy,fame_min((y<<1)+mv->dy, step<<1))>>1;      ptr_stepy[1]  = fame_min(((search_range-1)<<1)-mv->dy,fame_min(((height-y-16)<<1)-mv->dy, step<<1))>>1;    }    /* update the step */    if(last_motion==NULL_MOTION || counter_fourstep==0)     {      step >>= 1;      current_td = &(td[1]);    }    else      counter_fourstep--;        /* search the best motion vector from the current point */    for(i = 0; i < current_td->number; i++)    {      test.dx =	current_td->directions[i].dx *	ptr_stepx[current_td->directions[i].dx];      test.dy =	current_td->directions[i].dy *	ptr_stepy[current_td->directions[i].dy];            test.error =	eval_error(ref[residual]->y+edged_offset+motion+		   (test.dx+test.dy*(pitch+32)),		   current+offset,		   shape+offset,		   pitch);            if(test.error < rel.error)      {	last_motion = current_td->directions[i].index_direction;	rel.error = test.error;	rel.dx = test.dx;	rel.dy = test.dy;      }    }        /* Update the motion vector_t and the location in the window */    if(rel.error < mv->error)    {      mv->error = rel.error;      mv->dx += rel.dx << 1;      mv->dy += rel.dy << 1;	      current_td = &(td[last_motion]);      motion = (mv->dx >> 1) + (mv->dy >> 1) * (pitch+32);    }    else    {      last_motion = NULL_MOTION;      current_td = &(td[last_motion]);    }  }}/*  find_half_vector                                                         *//*                                                                           *//*  Description:                                                             *//*    Refine integer vector(s) to half-pel vector(s).                        *//*                                                                           *//*  Arguments:                                                               *//*    fame_yuv_t **ref: reference frames (half-pel)                          *//*    unsigned char *current: current frame                                  *//*    unsigned char *shape: current shape                                    *//*    int offset[4]: offsets to the blocks                                   *//*    int x: x coordinate of the block in pixel unit                         *//*    int y: y coordinate of the block in pixel unit                         *//*    int width: width of the block in pixels                                *//*    int height: height of the block in pixels                              *//*    int pitch: number of pixels to the next line                           *//*    compute_error_t eval_error: error evaluation function                  *//*    fame_motion_vector_t *mv: motion vectors                               *//*                                                                           *//*  Notes:                                                                   *//*    The search is centered on the integer vector(s).                       *//*    The search is made on the Y blocks only.                               *//*    When allowing 4 vectors, the search is performed separetely for each.  *//*                                                                           *//*  Return value:                                                            *//*    None.                                                                  */static void find_half_vector(fame_yuv_t **ref,			     unsigned char *current,			     unsigned char *shape,			     int offset[4],			     int edged_offset[4],			     int x,			     int y,			     int width,			     int height,			     int pitch,			     compute_error_t eval,			     fame_motion_vector_t *mv,			     int unrestricted){  int xh, yh;  int e[4], best[4];  int m, r;  int i;  int edge;  xh = yh = 0;  best[0] = mv[0].error;  best[1] = mv[1].error;  best[2] = mv[2].error;  best[3] = mv[3].error;  edge = unrestricted << 4;  if(((y+edge) << 1) + mv[0].dy > 0) {    if(((x+edge) << 1) + mv[0].dx > 0) {      /* -0.5 -0.5 */      for(i = 0; i < 4; i++) {	m = ((mv[i].dx-1)>>1) + ((mv[i].dy-1)>>1) * (pitch+32);	r = ((mv[i].dx-1) & 1) + (((mv[i].dy-1) & 1) << 1);	e[i] = eval(ref[r]->y+edged_offset[i]+m, current + offset[i],		    shape + offset[i], pitch);      }      if(e[0] + e[1] + e[2] + e[3] < best[0] + best[1] + best[2] + best[3]) {	best[0] = e[0]; best[1] = e[1]; best[2] = e[2]; best[3] = e[3];	xh = -1;	yh = -1;      }    }    /* 0 -0.5 */    for(i = 0; i < 4; i++) {      m = ((mv[i].dx)>>1) + ((mv[i].dy-1)>>1) * (pitch+32);      r = ((mv[i].dx) & 1) + (((mv[i].dy-1) & 1) << 1);      e[i] = eval(ref[r]->y+edged_offset[i]+m, current + offset[i],		  shape + offset[i], pitch);    }    if(e[0] + e[1] + e[2] + e[3] < best[0] + best[1] + best[2] + best[3]) {      best[0] = e[0]; best[1] = e[1]; best[2] = e[2]; best[3] = e[3];      xh =  0;      yh = -1;    }    if(((x-edge) << 1) + mv->dx < ((width-16) << 1)) {      /* +0.5 -0.5 */      for(i = 0; i < 4; i++) {	m = ((mv[i].dx+1)>>1) + ((mv[i].dy-1)>>1) * (pitch+32);	r = ((mv[i].dx+1) & 1) + (((mv[i].dy-1) & 1) << 1);	e[i] = eval(ref[r]->y+edged_offset[i]+m, current + offset[i],		    shape + offset[i], pitch);      }      if(e[0] + e[1] + e[2] + e[3] < best[0] + best[1] + best[2] + best[3]) {	best[0] = e[0]; best[1] = e[1]; best[2] = e[2]; best[3] = e[3];	xh = +1;	yh = -1;      }    }  }    if(((x+edge) << 1) + mv->dx > 0) {    /* -0.5 0 */    for(i = 0; i < 4; i++) {      m = ((mv[i].dx-1)>>1) + ((mv[i].dy)>>1) * (pitch+32);      r = ((mv[i].dx-1) & 1) + (((mv[i].dy) & 1) << 1);      e[i] = eval(ref[r]->y+edged_offset[i]+m, current + offset[i],		  shape + offset[i], pitch);    }    if(e[0] + e[1] + e[2] + e[3] < best[0] + best[1] + best[2] + best[3]) {      best[0] = e[0]; best[1] = e[1]; best[2] = e[2]; best[3] = e[3];      xh = -1;      yh =  0;    }  }  if(((x-edge) << 1) + mv->dx < ((width-16) << 1)) {    /* +0.5 0 */    for(i = 0; i < 4; i++) {      m = ((mv[i].dx+1)>>1) + ((mv[i].dy)>>1) * (pitch+32);      r = ((mv[i].dx+1) & 1) + (((mv[i].dy) & 1) << 1);      e[i] = eval(ref[r]->y+edged_offset[i]+m, current + offset[i],		  shape + offset[i], pitch);    }    if(e[0] + e[1] + e[2] + e[3] < best[0] + best[1] + best[2] + best[3]) {      best[0] = e[0]; best[1] = e[1]; best[2] = e[2]; best[3] = e[3];      xh = +1;      yh =  0;    }  }    if(((y-edge) << 1) + mv->dy < ((height-16) << 1)) {    if(((x+edge) << 1) + mv->dx > 0) {      /* -0.5 +0.5 */      for(i = 0; i < 4; i++) {	m = ((mv[i].dx-1)>>1) + ((mv[i].dy+1)>>1) * (pitch+32);	r = ((mv[i].dx-1) & 1) + (((mv[i].dy+1) & 1) << 1);	e[i] = eval(ref[r]->y+edged_offset[i]+m, current + offset[i],		    shape + offset[i], pitch);	}      if(e[0] + e[1] + e[2] + e[3] < best[0] + best[1] + best[2] + best[3]) {	best[0] = e[0]; best[1] = e[1]; best[2] = e[2]; best[3] = e[3];	xh = -1;	yh = +1;      }    }    /* 0 +0.5 */    for(i = 0; i < 4; i++) {      m = ((mv[i].dx)>>1) + ((mv[i].dy+1)>>1) * (pitch+32);      r = ((mv[i].dx) & 1) + (((mv[i].dy+1) & 1) << 1);      e[i] = eval(ref[r]->y+edged_offset[i]+m, current + offset[i],		  shape + offset[i], pitch);    }    if(e[0] + e[1] + e[2] + e[3] < best[0] + best[1] + best[2] + best[3]) {      best[0] = e[0]; best[1] = e[1]; best[2] = e[2]; best[3] = e[3];      xh =  0;      yh = +1;    }    if(((x-edge) << 1) + mv->dx < ((width-16) << 1)) {      /* +0.5 +0.5 */      for(i = 0; i < 4; i++) {	m = ((mv[i].dx+1)>>1) + ((mv[i].dy+1)>>1) * (pitch+32);	r = ((mv[i].dx+1) & 1) + (((mv[i].dy+1) & 1) << 1);	e[i] = eval(ref[r]->y+edged_offset[i]+m, current + offset[i],		    shape + offset[i], pitch);      }      if(e[0] + e[1] + e[2] + e[3] < best[0] + best[1] + best[2] + best[3]) {	best[0] = e[0]; best[1] = e[1]; best[2] = e[2]; best[3] = e[3];	xh = +1;	yh = +1;      }    }  }  mv[0].dx += xh;  mv[0].dy += yh;  mv[0].error = best[0];  mv[1].dx += xh;  mv[1].dy += yh;  mv[1].error = best[1];  mv[2].dx += xh;  mv[2].dy += yh;  mv[2].error = best[2];  mv[3].dx += xh;  mv[3].dy += yh;  mv[3].error = best[3];}static void find_half_subvector(fame_yuv_t **ref,				unsigned char *current,				unsigned char *shape,				int offset,				int edged_offset,				int x,				int y,				int width,				int height,				int pitch,				compute_error_t eval,				fame_motion_vector_t *mv,				int unrestricted){  int xh, yh;  int e, best;  int m, r;  int edge;  xh = yh = 0;  best = mv->error;  edge = unrestricted << 4;  if(((y+edge) << 1) + mv->dy > 0) {    if(((x+edge) << 1) + mv->dx > 0) {      /* -0.5 -0.5 */      m = ((mv->dx-1)>>1) + ((mv->dy-1)>>1) * (pitch+32);      r = ((mv->dx-1) & 1) + (((mv->dy-1) & 1) << 1);      e = eval(ref[r]->y+edged_offset+m, current + offset,	       shape + offset, pitch);      if(e < best) {	best = e;	xh = -1;	yh = -1;      }    }    /* 0 -0.5 */    m = ((mv->dx)>>1) + ((mv->dy-1)>>1) * (pitch+32);    r = ((mv->dx) & 1) + (((mv->dy-1) & 1) << 1);    e = eval(ref[r]->y+edged_offset+m, current + offset,	     shape + offset, pitch);    if(e < best) {      best = e;      xh =  0;      yh = -1;    }    if(((x-edge) << 1) + mv->dx < ((width-16) << 1)) {      /* +0.5 -0.5 */      m = ((mv->dx+1)>>1) + ((mv->dy-1)>>1) * (pitch+32);      r = ((mv->dx+1) & 1) + (((mv->dy-1) & 1) << 1);      e = eval(ref[r]->y+edged_offset+m, current + offset,	       shape + offset, pitch);      if(e < best) {	best = e;	xh = +1;	yh = -1;      }    }  }      if(((x+edge) << 1) + mv->dx > 0) {    /* -0.5 0 */    m = ((mv->dx-1)>>1) + ((mv->dy)>>1) * (pitch+32);    r = ((mv->dx-1) & 1) + (((mv->dy) & 1) << 1);    e = eval(ref[r]->y+edged_offset+m, current + offset,	     shape + offset, pitch);    if(e < best) {      best = e;      xh = -1;      yh =  0;    }  }  if(((x-edge) << 1) + mv->dx < ((width-16) << 1)) {    /* +0.5 0 */    m = ((mv->dx+1)>>1) + ((mv->dy)>>1) * (pitch+32);    r = ((mv->dx+1) & 1) + (((mv->dy) & 1) << 1);    e = eval(ref[r]->y+edged_offset+m, current + offset,	     shape + offset, pitch);    if(e < best) {      best = e;      xh = +1;      yh =  0;    }  }      if(((y-edge) << 1) + mv->dy < ((height-16) << 1)) {    if(((x+edge) << 1) + mv->dx > 0) {      /* -0.5 +0.5 */      m = ((mv->dx-1)>>1) + ((mv->dy+1)>>1) * (pitch+32);      r = ((mv->dx-1) & 1) + (((mv->dy+1) & 1) << 1);      e = eval(ref[r]->y+edged_offset+m, current + offset,	       shape + offset, pitch);      if(e < best) {	best = e;	xh = -1;	yh = +1;      }    }    /* 0 +0.5 */    m = ((mv->dx)>>1) + ((mv->dy+1)>>1) * (pitch+32);    r = ((mv->dx) & 1) + (((mv->dy+1) & 1) << 1);    e = eval(ref[r]->y+edged_offset+m, current + offset,	     shape + offset, pitch);    if(e < best) {      best = e;      xh =  0;      yh = +1;    }    if(((x-edge) << 1) + mv->dx < ((width-16) << 1)) {      /* +0.5 +0.5 */      m = ((mv->dx+1)>>1) + ((mv->dy+1)>>1) * (pitch+32);      r = ((mv->dx+1) & 1) + (((mv->dy+1) & 1) << 1);      e = eval(ref[r]->y+edged_offset+m, current + offset,	       shape + offset, pitch);      if(e < best) {	best = e;	xh = +1;	yh = +1;      }    }  }  mv->dx += xh;  mv->dy += yh;  mv->error = best;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -