📄 macroblock.cpp
字号:
/*!
********************************************************
*\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 + -