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

📄 mbprediction.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 2 页
字号:
	int Z1, Z2;

	/* store current coeffs to pred_values[] for future prediction */
	pCurrent[0] = qcoeff[0] * iDcScaler;
	pCurrent[0] = CLIP(pCurrent[0], -2048, 2047);
	for (i = 1; i < 8; i++) {
		pCurrent[i] = qcoeff[i];
		pCurrent[i + 7] = qcoeff[i * 8];
	}


	/* dc prediction */
	qcoeff[0] = qcoeff[0] - predictors[0];

	/* calc cost before ac prediction */
	Z2 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[0]);

	/* apply ac prediction & calc cost*/
	if (direction == 1) {
		for (i = 1; i < 8; i++) {
			tmp[i] = qcoeff[i];
			qcoeff[i] -= predictors[i];
			predictors[i] = qcoeff[i];
		}
	}else{						/* acpred_direction == 2 */
		for (i = 1; i < 8; i++) {
			tmp[i] = qcoeff[i*8];
			qcoeff[i*8] -= predictors[i];
			predictors[i] = qcoeff[i*8];
		}
	}

	Z1 = CodeCoeffIntra_CalcBits(qcoeff, scan_tables[direction]);

	/* undo prediction */
	if (direction == 1) {
		for (i = 1; i < 8; i++)
			qcoeff[i] = tmp[i];
	}else{						/* acpred_direction == 2 */
		for (i = 1; i < 8; i++)
			qcoeff[i*8] = tmp[i];
	}

	return Z2-Z1;
}

/* apply predictors[] to qcoeff */

static void
apply_acdc(MACROBLOCK * pMB,
		   uint32_t block,
		   int16_t qcoeff[64],
		   int16_t predictors[8])
{
	unsigned int i;

	if (pMB->acpred_directions[block] == 1) {
		for (i = 1; i < 8; i++)
			qcoeff[i] = predictors[i];
	} else {
		for (i = 1; i < 8; i++)
			qcoeff[i * 8] = predictors[i];
	}
}


void
MBPrediction(FRAMEINFO * frame,
			 uint32_t x,
			 uint32_t y,
			 uint32_t mb_width,
			 int16_t qcoeff[6 * 64])
{

	int32_t j;
	int32_t iDcScaler, iQuant;
	int S = 0;
	int16_t predictors[6][8];

	MACROBLOCK *pMB = &frame->mbs[x + y * mb_width];
    iQuant = pMB->quant;

	if ((pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q)) {

		for (j = 0; j < 6; j++) {
			iDcScaler = get_dc_scaler(iQuant, j<4);

			predict_acdc(frame->mbs, x, y, mb_width, j, &qcoeff[j * 64],
						 iQuant, iDcScaler, predictors[j], 0);

			if ((frame->vop_flags & XVID_VOP_HQACPRED))
				S += calc_acdc_bits(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);
			else
				S += calc_acdc_coeff(pMB, j, &qcoeff[j * 64], iDcScaler, predictors[j]);

		}

		if (S<=0) {				/* dont predict */
			for (j = 0; j < 6; j++)
				pMB->acpred_directions[j] = 0;
		}else{
			for (j = 0; j < 6; j++)
				apply_acdc(pMB, j, &qcoeff[j * 64], predictors[j]);
		}

		pMB->cbp = calc_cbp(qcoeff);
	}
}

static const VECTOR zeroMV = { 0, 0 };

VECTOR
get_pmv2(const MACROBLOCK * const mbs,
		const int mb_width,
		const int bound,
		const int x,
		const int y,
		const int block)
{
	int lx, ly, lz;		/* left */
	int tx, ty, tz;		/* top */
	int rx, ry, rz;		/* top-right */
	int lpos, tpos, rpos;
	int num_cand = 0, last_cand = 1;

	VECTOR pmv[4];	/* left neighbour, top neighbour, top-right neighbour */

	switch (block) {
	case 0:
		lx = x - 1;	ly = y;		lz = 1;
		tx = x;		ty = y - 1;	tz = 2;
		rx = x + 1;	ry = y - 1;	rz = 2;
		break;
	case 1:
		lx = x;		ly = y;		lz = 0;
		tx = x;		ty = y - 1;	tz = 3;
		rx = x + 1;	ry = y - 1;	rz = 2;
		break;
	case 2:
		lx = x - 1;	ly = y;		lz = 3;
		tx = x;		ty = y;		tz = 0;
		rx = x;		ry = y;		rz = 1;
		break;
	default:
		lx = x;		ly = y;		lz = 2;
		tx = x;		ty = y;		tz = 0;
		rx = x;		ry = y;		rz = 1;
	}

	lpos = lx + ly * mb_width;
	rpos = rx + ry * mb_width;
	tpos = tx + ty * mb_width;

	if (lpos >= bound && lx >= 0) {
		num_cand++;
		pmv[1] = mbs[lpos].mvs[lz];
	} else pmv[1] = zeroMV;

	if (tpos >= bound) {
		num_cand++;
		last_cand = 2;
		pmv[2] = mbs[tpos].mvs[tz];
	} else pmv[2] = zeroMV;

	if (rpos >= bound && rx < mb_width) {
		num_cand++;
		last_cand = 3;
		pmv[3] = mbs[rpos].mvs[rz];
	} else pmv[3] = zeroMV;

	/* If there're more than one candidate, we return the median vector */

	if (num_cand > 1) {
		/* set median */
		pmv[0].x =
			MIN(MAX(pmv[1].x, pmv[2].x),
				MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
		pmv[0].y =
			MIN(MAX(pmv[1].y, pmv[2].y),
				MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
		return pmv[0];
	}

	return pmv[last_cand];	/* no point calculating median mv */
}

VECTOR get_pmv2_interlaced(const MACROBLOCK * const mbs,
   const int mb_width,
   const int bound,
   const int x,
   const int y,
   const int block)
{
  int lx, ly, lz;   /* left */
  int tx, ty, tz;   /* top */
  int rx, ry, rz;   /* top-right */
  int lpos, tpos, rpos;
  int num_cand = 0, last_cand = 1;

  VECTOR pmv[4];  /* left neighbour, top neighbour, top-right neighbour */

  lx=x-1; ly=y;   lz=1;
  tx=x;   ty=y-1; tz=2;
  rx=x+1; ry=y-1; rz=2;

  lpos=lx+ly*mb_width;
  rpos=rx+ry*mb_width;
  tpos=tx+ty*mb_width;

  if(lx>=0 && lpos>=bound) 
  {
    num_cand++;
    if(mbs[lpos].field_pred)
     pmv[1] = mbs[lpos].mvs_avg;
    else 
     pmv[1] = mbs[lpos].mvs[lz];
  }
  else 
  {
    pmv[1] = zeroMV;
  }  

  if(tpos>=bound) 
  {
    num_cand++;
    last_cand=2;
    if(mbs[tpos].field_pred)
     pmv[2] = mbs[tpos].mvs_avg;
    else
     pmv[2] = mbs[tpos].mvs[tz];
  } 
  else
  { 
    pmv[2] = zeroMV;
  }
        
  if(rx<mb_width && rpos>=bound) 
  {
    num_cand++;
    last_cand = 3;
    if(mbs[rpos].field_pred)
     pmv[3] = mbs[rpos].mvs_avg;
    else
     pmv[3] = mbs[rpos].mvs[rz];
  } 
  else
  { 
    pmv[3] = zeroMV;
  }  

  /* If there're more than one candidate, we return the median vector */
  if(num_cand>1) 
  {
    /* set median */
    pmv[0].x = MIN(MAX(pmv[1].x, pmv[2].x),
               MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
    pmv[0].y = MIN(MAX(pmv[1].y, pmv[2].y),
               MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
          
    return pmv[0];
  }

  return pmv[last_cand];  /* no point calculating median mv */
}

VECTOR
get_qpmv2(const MACROBLOCK * const mbs,
		const int mb_width,
		const int bound,
		const int x,
		const int y,
		const int block)
{
	int lx, ly, lz;		/* left */
	int tx, ty, tz;		/* top */
	int rx, ry, rz;		/* top-right */
	int lpos, tpos, rpos;
	int num_cand = 0, last_cand = 1;

	VECTOR pmv[4];	/* left neighbour, top neighbour, top-right neighbour */

	switch (block) {
	case 0:
		lx = x - 1;	ly = y;		lz = 1;
		tx = x;		ty = y - 1;	tz = 2;
		rx = x + 1;	ry = y - 1;	rz = 2;
		break;
	case 1:
		lx = x;		ly = y;		lz = 0;
		tx = x;		ty = y - 1;	tz = 3;
		rx = x + 1;	ry = y - 1;	rz = 2;
		break;
	case 2:
		lx = x - 1;	ly = y;		lz = 3;
		tx = x;		ty = y;		tz = 0;
		rx = x;		ry = y;		rz = 1;
		break;
	default:
		lx = x;		ly = y;		lz = 2;
		tx = x;		ty = y;		tz = 0;
		rx = x;		ry = y;		rz = 1;
	}

	lpos = lx + ly * mb_width;
	rpos = rx + ry * mb_width;
	tpos = tx + ty * mb_width;

	if (lpos >= bound && lx >= 0) {
		num_cand++;
		pmv[1] = mbs[lpos].qmvs[lz];
	} else pmv[1] = zeroMV;

	if (tpos >= bound) {
		num_cand++;
		last_cand = 2;
		pmv[2] = mbs[tpos].qmvs[tz];
	} else pmv[2] = zeroMV;

	if (rpos >= bound && rx < mb_width) {
		num_cand++;
		last_cand = 3;
		pmv[3] = mbs[rpos].qmvs[rz];
	} else pmv[3] = zeroMV;

	/* If there're more than one candidate, we return the median vector */

	if (num_cand > 1) {
		/* set median */
		pmv[0].x =
			MIN(MAX(pmv[1].x, pmv[2].x),
				MIN(MAX(pmv[2].x, pmv[3].x), MAX(pmv[1].x, pmv[3].x)));
		pmv[0].y =
			MIN(MAX(pmv[1].y, pmv[2].y),
				MIN(MAX(pmv[2].y, pmv[3].y), MAX(pmv[1].y, pmv[3].y)));
		return pmv[0];
	}

	return pmv[last_cand];	/* no point calculating median mv */
}

⌨️ 快捷键说明

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