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

📄 macroblock.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*!
********************************************************
*\file
*    macroblock.cpp
*\brief
*    implementation for the macroblock level functions.
*\date
*    12/6/2002
*
********************************************************/
#include <stdio.h>
#include "HEnc.h"
#include "block.h"
#include "AIC.h"
#include "mot_est.h"
#include "cpu.h"


#define CLEAR(array, n) array[n][0] = 1024;	array[n][1] = 0; array[n][2] = 0; array[n][3] = 0; array[n][4] = 0; array[n][5] = 0; array[n][6] = 0; array[n][7] = 0;
 

/*!
*******************************************************************************
*
*   Name:          MB_Encode_P
*   Description:   Encode one Macroblock in P mode(make diff,dct,Q,IQ,IDct,data-recon)
*   Input:         position of curr-MB, encoder structure, MV 
*   Output:        qcoeff_p
*   Side effect:   write reconstructive data to recon_pic in corresponding position
*   Return:        cbp
*   Last modified: 2002/12/17
*
*******************************************************************************/
int MB_Encode_P(H263VencStatus *encoder, int pix_x, int pix_y, MCParam *MC,  
				 INT16 *qcoeff_p)
{
	int i, j;
	int flag = 32;
	unsigned char *curr_block;
	unsigned char *recon_block;
	unsigned char pred_block[64];
	INT16         diff_block[64];

	MB_structure curr_mb;
	MB_structure recon_mb;
	MotionVector *MV;
	int dx, dy;

	int           cbp = 0;
	int           pic_width = encoder->pels;
	int           rec_width = encoder->mv_outside_frame ? encoder->pels + 32 : encoder->pels;
	int           lx_ipol = encoder->mv_outside_frame ? pic_width*2+64 : pic_width*2;
	int           lx_ref_c = encoder->mv_outside_frame ? pic_width/2+16 : pic_width/2;
	int           QP = encoder->total_Q;  
	int           sad_gate = QP*8;
	unsigned char *prev_ipol = encoder->prev_ipol;
	Image         *ref_img   = &(encoder->frame_buf[encoder->ref_index]);
	Image         *curr_img  = &(encoder->frameToEncode);
	Image         *recon_img = &(encoder->frame_buf[encoder->zero_index]);


//! 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; 

	//! Encode each block in the MB
	//!4 lum blocks
	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;

			if (!encoder->obmc)
			{
				if (encoder->use4mv && (MC->mv_frame[0][pix_y/16+1][pix_x/16+1]->Mode == MODE_INTER4V))
				{
					MV = MC->mv_frame[(j>>3)+(i>>2)+1][pix_y/16+1][pix_x/16+1];
				}
				else
				{
					MV = MC->mv_frame[0][pix_y/16+1][pix_x/16+1]; 
				}
				encoder->method.pred_lum(pix_x+j, pix_y+i, MV, prev_ipol, lx_ipol, pred_block);
			}
			else
			{
				encoder->method.pred_obmc(pix_x, pix_y, MC->mv_frame, pic_width, 
					      prev_ipol, lx_ipol, (j>>3)+(i>>2)+1, pred_block);
			}
 			encoder->method.make_diff(curr_block, pic_width, pred_block, diff_block);
			
			if (block_SAD(diff_block)>sad_gate)
			{
				
				encoder->method.DCT(diff_block, diff_block);
				
				if (encoder->method.Quant_blk_P(diff_block, qcoeff_p, QP)) 
					
				{
					cbp|=flag;
					encoder->method.DeQuant_blk_P(qcoeff_p, diff_block, QP);  
					encoder->method.IDCT(diff_block, diff_block);
					encoder->method.recon_pic(recon_block, rec_width, pred_block, diff_block);
				}
				else
				{
					encoder->method.block_copy1(recon_block, pred_block, rec_width);
				}
			}
			else
			{
				encoder->method.block_copy1(recon_block, pred_block, rec_width);
			}
			flag = flag >> 1;
			qcoeff_p+=64;
		}
	}

    findchromMV(encoder, MC, pix_x, pix_y, &dx, &dy, 0);  //!< find MV for 2 chrom blocks

    //! Cb block
	curr_block = curr_mb.pCb;
	recon_block = recon_mb.pCb;
	encoder->method.pred_chrom(pix_x/2, pix_y/2, ref_img->pCb, lx_ref_c, dx, dy, pred_block);
	encoder->method.make_diff(curr_block, pic_width/2, pred_block, diff_block);

	if (block_SAD(diff_block) > sad_gate)
	{
		encoder->method.DCT(diff_block, diff_block);
		if (encoder->method.Quant_blk_P(diff_block, qcoeff_p, QP))               
		{
			cbp|=flag;
			encoder->method.DeQuant_blk_P (qcoeff_p, diff_block, QP);  
			encoder->method.IDCT(diff_block, diff_block);
			encoder->method.recon_pic(recon_block, rec_width/2, pred_block, diff_block);
		}
		else
		{
			encoder->method.block_copy1(recon_block, pred_block, rec_width/2);
		}
	}
	else
	{
		encoder->method.block_copy1(recon_block, pred_block, rec_width/2);
	}
	flag = flag >> 1;
	qcoeff_p+=64;
    //! Cr block
	curr_block = curr_mb.pCr;
	recon_block = recon_mb.pCr;
	encoder->method.pred_chrom(pix_x/2, pix_y/2, ref_img->pCr, lx_ref_c, dx, dy, pred_block);
	encoder->method.make_diff(curr_block, pic_width/2, pred_block, diff_block);
	
	if (block_SAD(diff_block))
	{
		encoder->method.DCT(diff_block, diff_block);
		
		if (encoder->method.Quant_blk_P(diff_block, qcoeff_p, QP))               
		{
			cbp|=flag;
			encoder->method.DeQuant_blk_P (qcoeff_p, diff_block, QP);      
			encoder->method.IDCT(diff_block, diff_block);
			encoder->method.recon_pic(recon_block, rec_width/2, pred_block, diff_block);
		}
		else
		{
			encoder->method.block_copy1(recon_block, pred_block, rec_width/2);
		}
	}
	else
	{
		encoder->method.block_copy1(recon_block, pred_block, rec_width/2);
	}
	return cbp;

}

/*!
*******************************************************************************
*
*   Name:          MB_Encode_I
*   Description:   Encode one Macroblock in I 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
*   Last modified: 2002/12/5 by zj 
*
*******************************************************************************/
int MB_Encode_I(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   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[64];


	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; 

//! Encode each block in the MB
	//! 4 lum blocks
	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, curr_block, pic_width);   // 2/11/2003 lcl

⌨️ 快捷键说明

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