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

📄 macroblock.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			encoder->method.DCT (tmpblk, tmpblk);    // 2/11/2003 lcl
			if (encoder->method.Quant_blk_I (tmpblk, qcoeff_i, QI))                // 2/12/2003 lcl
			{
				cbp|=flag;
			}
			encoder->method.DeQuant_blk_I (qcoeff_i, tmpblk, QI);                //  2/12/2003 lcl
			encoder->method.IDCT (tmpblk, tmpblk);          // 2/25/2003 lcl
			encoder->method.block_copy3(recon_block, tmpblk, rec_width);
			flag = flag >> 1;
			qcoeff_i+=64;
		}
	}
    //! Cb block
	curr_block = curr_mb.pCb;
	recon_block = recon_mb.pCb;
	encoder->method.block_copy2(tmpblk, curr_block, pic_width/2);
	encoder->method.DCT (tmpblk, tmpblk);    // 2/12/2003 lcl
	if (encoder->method.Quant_blk_I (tmpblk, qcoeff_i, QI))                // 2/12/2003 lcl
	{
		cbp|=flag;
	}
	encoder->method.DeQuant_blk_I (qcoeff_i, tmpblk, QI);                  // 2/12/2003 lcl
	encoder->method.IDCT (tmpblk, tmpblk);           // 2/26/2003 lcl
	encoder->method.block_copy3(recon_block, tmpblk, rec_width/2);
	flag = flag >> 1;
	qcoeff_i+=64;
    //! Cr block
	curr_block = curr_mb.pCr;
	recon_block = recon_mb.pCr;
	encoder->method.block_copy2(tmpblk, curr_block, pic_width/2);
	encoder->method.DCT (tmpblk, tmpblk);    // 2/12/2003 lcl
	if (encoder->method.Quant_blk_I (tmpblk, qcoeff_i, QI))                // 2/12/2003 lcl
	{
		cbp|=flag;
	}
	encoder->method.DeQuant_blk_I (qcoeff_i, tmpblk, QI);                  // 2/12/2003 lcl
	encoder->method.IDCT (tmpblk, tmpblk);           // 2/25/2003 lcl
	encoder->method.block_copy3(recon_block, tmpblk, rec_width/2);
	
	return cbp;     
}


/*!
*******************************************************************************
*
*   Name:          MB_Encode_AI
*   Description:   Encode one Macroblock in Advanced Intra Coding mode
*                  (dct, Q, IQ, Idct, data-recon)
*   Input:         position of curr-MB, encoder structure  
*   Output:        qcoeff_p
*   Side effect:   write reconstructive data to recon_pic in corresponding position
*   Time:          2003/4/26 by lcl 
*
*******************************************************************************/
int MB_Encode_AI(H263VencStatus *encoder, int pix_x, int pix_y, INT16 *qcoeff_i)
{
	int i, j;
	int flag = 32;
	unsigned char *curr_block;
	unsigned char *recon_block;
	MB_structure curr_mb;
	MB_structure recon_mb;

	int   intra_mode;
	int   block = 0;
	int   mb_x = pix_x/16;
	int   mb_y = pix_y/16;
	int   cbp = 0;
	int   pic_width = encoder->pels;
	int   rec_width = encoder->mv_outside_frame? encoder->pels+32 : encoder->pels;
	int   QI = encoder->total_Q;
	Image *curr_img  = &(encoder->frameToEncode);
	Image *recon_img = &(encoder->frame_buf[encoder->zero_index]);

	INT16 tmpblk[384];
	INT16 A[8];                       //< top coeff-predictor
	INT16 B[8];                       //< left coeff-predictor 
	int SAD0 = 0;
	int SAD1 = 0;
	int SAD2 = 0;

	if (encoder->PTYPE == B_IMG)
	{
		curr_img  = &(encoder->BPicture[encoder->B_count]);
		recon_img = &(encoder->BPicture[0]);
		rec_width = encoder->pels;
	}

//! Find MB in the image
	curr_mb.pLum = curr_img->pLum + pix_y * pic_width + pix_x;
	curr_mb.pCb  = curr_img->pCb + pix_y * pic_width/4 + pix_x/2;
	curr_mb.pCr  = curr_img->pCr + pix_y * pic_width/4 + pix_x/2;

	recon_mb.pLum = recon_img->pLum + pix_y * rec_width + pix_x;
	recon_mb.pCb  = recon_img->pCb + pix_y * rec_width/4 + pix_x/2;
	recon_mb.pCr  = recon_img->pCr + pix_y * rec_width/4 + pix_x/2; 


	//!Choose mode for the MB
	for (i = 0; i < 16; i+=8)
	{
		for (j = 0; j < 16; j+=8)
		{
			curr_block = curr_mb.pLum + i*pic_width + j;
			recon_block = recon_mb.pLum + i*rec_width + j;
			encoder->method.block_copy2(tmpblk+block*64, curr_block, pic_width);   
			encoder->method.DCT (tmpblk+block*64, tmpblk+block*64);
			fill_pred(block, mb_x, mb_y, encoder->coeff.top_lum, encoder->coeff.left_lum, A, B);
			acc_SAD(A, B, tmpblk+block*64, &SAD0, &SAD1, &SAD2);
			save_coeff(block, mb_x, mb_y, encoder->coeff.top_lum, encoder->coeff.left_lum, tmpblk+block*64);
			block++;
		}
	}
	//! Cb block
	encoder->method.block_copy2(tmpblk+block*64, curr_mb.pCb, pic_width/2);
	encoder->method.DCT (tmpblk+block*64, tmpblk+block*64); 
	fill_pred(block, mb_x, mb_y, encoder->coeff.top_cb, encoder->coeff.left_cb, A, B);
	acc_SAD(A, B, tmpblk+block*64, &SAD0, &SAD1, &SAD2);
	save_coeff(block, mb_x, mb_y, encoder->coeff.top_cb, encoder->coeff.left_cb, tmpblk+block*64);
	block++;
	//! Cr block
	encoder->method.block_copy2(tmpblk+block*64, curr_mb.pCr, pic_width/2);
	encoder->method.DCT (tmpblk+block*64, tmpblk+block*64); 
	fill_pred(block, mb_x, mb_y, encoder->coeff.top_cr, encoder->coeff.left_cr, A, B);
	acc_SAD(A, B, tmpblk+block*64, &SAD0, &SAD1, &SAD2);
	save_coeff(block, mb_x, mb_y, encoder->coeff.top_cr, encoder->coeff.left_cr, tmpblk+block*64);
     
	intra_mode = choose_intra_mode(SAD0, SAD1, SAD2);

	block = 0;	
	//! Encode each block in the MB
	//! 4 lum blocks
	for (i = 0; i < 16; i+=8)
	{
		for (j = 0; j < 16; j+=8)
		{
			recon_block = recon_mb.pLum + i*rec_width + j;
			coeff_pred(block, intra_mode, mb_x, mb_y, encoder->rcoeff.top_lum, encoder->rcoeff.left_lum, A, B);
			coeff_diff(intra_mode, A, B, tmpblk+block*64);
			if (Quant_AIC(tmpblk+block*64, qcoeff_i, QI, intra_mode))
			{
				cbp |= flag;
			}
			DeQuant_AIC(qcoeff_i, tmpblk+block*64, QI, intra_mode);
            coeff_recon(block, intra_mode, mb_x, mb_y, encoder->rcoeff.top_lum, encoder->rcoeff.left_lum, 
				        tmpblk+block*64, A, B);
			encoder->method.IDCT(tmpblk+block*64, tmpblk+block*64);
			encoder->method.block_copy3(recon_block, tmpblk+block*64, rec_width);
			flag = flag >> 1;
			qcoeff_i+=64;
			block++;
		}
	}
    //! Cb block
	coeff_pred(block, intra_mode, mb_x, mb_y, encoder->rcoeff.top_cb, encoder->rcoeff.left_cb, A, B);
	coeff_diff(intra_mode, A, B, tmpblk+block*64);
	if (Quant_AIC(tmpblk+block*64, qcoeff_i, QI, intra_mode))
	{
		cbp |= flag;
	}
	DeQuant_AIC(qcoeff_i, tmpblk+block*64, QI, intra_mode);
	coeff_recon(block, intra_mode, mb_x, mb_y, encoder->rcoeff.top_cb, encoder->rcoeff.left_cb, 
	        	tmpblk+block*64, A, B);
	encoder->method.IDCT(tmpblk+block*64, tmpblk+block*64);
	encoder->method.block_copy3(recon_mb.pCb, tmpblk+block*64, rec_width/2);
	flag = flag >> 1;
	qcoeff_i+=64;
	block++;
	
	//! Cr block
	coeff_pred(block, intra_mode, mb_x, mb_y, encoder->rcoeff.top_cr, encoder->rcoeff.left_cr, A, B);
	coeff_diff(intra_mode, A, B, tmpblk+block*64);
	if (Quant_AIC(tmpblk+block*64, qcoeff_i, QI, intra_mode))
	{
		cbp |= flag;
	}
	DeQuant_AIC(qcoeff_i, tmpblk+block*64, QI, intra_mode);
	coeff_recon(block, intra_mode, mb_x, mb_y, encoder->rcoeff.top_cr, encoder->rcoeff.left_cr, 
	        	tmpblk+block*64, A, B);
	encoder->method.IDCT(tmpblk+block*64, tmpblk+block*64);
	encoder->method.block_copy3(recon_mb.pCr, tmpblk+block*64, rec_width/2);

	/* intra mode will be returned in cbp */
    cbp |= intra_mode << 16;

	return cbp;     
}
/*!
*  Name: clear_coeff_top
*  Clear coefficients for AIC when meeting new gob or picture edge
*/
int clear_coeff_top(INT16 a1[MBC*2][8], INT16 a2[MBC][8], INT16 a3[MBC][8])
{
	int i;

	for (i = 0; i < MBC*2; i++)
	{
		CLEAR(a1, i); 
	}
	for (i = 0; i < MBC; i++)
	{
		CLEAR(a2, i);
		CLEAR(a3, i);
	}
	return 0;
}

/*!
*  Name: clear_coeff_left
*  Clear coefficients for AIC when meeting picture edge
*/
int clear_coeff_left(INT16 a1[2][8], INT16 a2[1][8], INT16 a3[1][8])
{
	CLEAR(a1, 0);
	CLEAR(a1, 1);
	CLEAR(a2, 0);
	CLEAR(a3, 0);

	return 0;
}

int set_coeff_inter(int i, INT16 a1[MBC*2][8], INT16 a2[MBC][8], INT16 a3[MBC][8],
					 INT16 a4[2][8], INT16 a5[1][8], INT16 a6[1][8])
{
	CLEAR(a1, 2*i);
	CLEAR(a1, 2*i+1);
	CLEAR(a2, i);
	CLEAR(a3, i);
	CLEAR(a4, 0);
	CLEAR(a4, 1);
	CLEAR(a5, 0);
	CLEAR(a6, 0);

	return 0;
}

⌨️ 快捷键说明

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