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

📄 block.cpp

📁 h264编解码.用C++实现了图像的编解码功能。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include <math.h> 
#include <stdlib.h> 
#include <stdio.h>
#include <memory.h>

#include "global.h"
#include "block.h" 

#define Q_BITS          15
#define DQ_BITS         6
#define DQ_ROUND        (1<<(DQ_BITS-1))

//#define FAST_INTEGER
#define max(a, b)  (((a) > (b)) ? (a) : (b)) 
#define min(a, b)  (((a) < (b)) ? (a) : (b)) 
static const int quant_coef[6][4][4] = {
  {{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243},{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243}},
  {{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660},{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660}},
  {{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194},{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194}},
  {{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647},{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647}},
  {{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355},{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355}},
  {{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893},{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893}}
};

static const int dequant_coef[6][4][4] = {
  {{10, 13, 10, 13},{ 13, 16, 13, 16},{10, 13, 10, 13},{ 13, 16, 13, 16}},
  {{11, 14, 11, 14},{ 14, 18, 14, 18},{11, 14, 11, 14},{ 14, 18, 14, 18}},
  {{13, 16, 13, 16},{ 16, 20, 16, 20},{13, 16, 13, 16},{ 16, 20, 16, 20}},
  {{14, 18, 14, 18},{ 18, 23, 18, 23},{14, 18, 14, 18},{ 18, 23, 18, 23}},
  {{16, 20, 16, 20},{ 20, 25, 20, 25},{16, 20, 16, 20},{ 20, 25, 20, 25}},
  {{18, 23, 18, 23},{ 23, 29, 23, 29},{18, 23, 18, 23},{ 23, 29, 23, 29}}
};
static const int A[4][4] = {
  { 16, 20, 16, 20},
  { 20, 25, 20, 25},
  { 16, 20, 16, 20},
  { 20, 25, 20, 25}
};
static int quant_coef1[6][16];
static int dequant_coef1[6][16];
extern char intra_mb_pos[72][92];
extern char intra_mb_pos1[72][92];

void InitQuantTable()
{
	int i,j,coeff_ctr,qp_rem;

	for(qp_rem=0;qp_rem<6;qp_rem++)
	  for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++)
	  { 
		i=SNGL_SCAN[coeff_ctr][0];
		j=SNGL_SCAN[coeff_ctr][1]; 
		quant_coef1[qp_rem][coeff_ctr]=quant_coef[qp_rem][i][j];
		dequant_coef1[qp_rem][coeff_ctr]=dequant_coef[qp_rem][i][j];
	  }
}

/************************************************************************
*
*  Routine:     intrapred_chroma()
*
*  Description: Chroma intra prediction.  There are 3 pred modes:
*				1. DC, Used if:
*					a) 16x16 based 'plane' luma prediction
*					b) 16x16 based vert/hor pred. impossible due to edges
*					b) if sum of 4x4 luma pred. is 'DC based' 
*			    2) Vertical, used if:
*					a) 16x16 based vertical luma pred. is used
*					b) if sum of 4x4 luma pred is 'vertical based'
*			    3) Horizontal, used if:
*					a) 16x16 based horizontal luma pred. is used
*					b) if sum of 4x4 luma pred is 'horizontal based'
*
*  Input:       Starting point of current chroma macro block image posision, chroma component and predmode
*
*  Output:      8x8 array with given intra chroma prediction and diff array   
*                    
************************************************************************/

void intrapred_chroma(struct img_par *img,int img_c_x,int img_c_y,int uv)
{
  int     s, s0, s1, s2, s3, i, j;
  int     block_x, block_y;
  int     img_cx            = img_c_x;//img->pix_c_x;
  int     img_cy            = img_c_y;//img->pix_c_y;
  int     img_cx_1          = img_c_x-1;//img->pix_c_x-1;
  int     img_cx_4          = img_c_x+4;//img->pix_c_x+4;
  int     img_cy_1          = img_c_y-1;//img->pix_c_y-1;
  int     img_cy_4          = img_c_y+4;//img->pix_c_y+4;
  int     *pp;
  int     width_cr=img->width_cr+IMG_PAD_SIZE;

  if(uv==0) pp=MbCb;
  else pp=MbCr;

  for (block_y=0; block_y<8; block_y+=4)
    for (block_x=0; block_x<8; block_x+=4)
    {
      s=128;
      s0=s1=s2=s3=0;
      //===== get prediction value =====
      switch ((block_y>>1) + (block_x>>2))
      {
      case 0:  //===== TOP LEFT =====
        if      (img_cy > 0)    for (i=0;i<4;i++)  s0 += imgUV[uv][img_cy_1*width_cr+img_cx  +i];
        if      (img_cx > 0)  for (i=0;i<4;i++)  s2 += imgUV[uv][(img_cy  +i)*width_cr+img_cx_1  ];
        if      ((img_cy > 0) && (img_cx > 0))  s  = (s0+s2+4) >> 3;
        else if (img_cy > 0)                       s  = (s0   +2) >> 2;
        else if (img_cx > 0)                     s  = (s2   +2) >> 2;
        img->s[0]=s;
		break;
      case 1: //===== TOP RIGHT =====
        if      (img_cy > 0)    for (i=0;i<4;i++)  s1 += imgUV[uv][img_cy_1*width_cr+img_cx_4+i];
        else if (img_cx > 0)  for (i=0;i<4;i++)  s2 += imgUV[uv][(img_cy  +i)*width_cr+img_cx_1  ];
        if      (img_cy > 0)                       s  = (s1   +2) >> 2;
        else if (img_cx > 0)                     s  = (s2   +2) >> 2;
        img->s[1]=s;
		break;
      case 2: //===== BOTTOM LEFT =====
        if      (img_cx > 0)  for (i=0;i<4;i++)  s3 += imgUV[uv][(img_cy_4+i)*width_cr+img_cx_1  ];
        else if (img_cy > 0)    for (i=0;i<4;i++)  s0 += imgUV[uv][img_cy_1*width_cr+img_cx  +i];
        if      (img_cx > 0)                     s  = (s3   +2) >> 2;
        else if (img_cy > 0)                       s  = (s0   +2) >> 2;
        img->s[2]=s;
		break;
      case 3: //===== BOTTOM RIGHT =====
        if      (img_cy > 0)    for (i=0;i<4;i++)  s1 += imgUV[uv][img_cy_1*width_cr+img_cx_4+i];
        if      (img_cx > 0)  for (i=0;i<4;i++)  s3 += imgUV[uv][(img_cy_4+i)*width_cr+img_cx_1  ];
        if      ((img_cy > 0) && (img_cx > 0))  s  = (s1+s3+4) >> 3;
        else if (img_cy > 0)                       s  = (s1   +2) >> 2;
        else if (img_cx > 0)                     s  = (s3   +2) >> 2;
        img->s[3]=s;
		break;
      }

      //===== prediction =====
      for (j=block_y; j<block_y+4; j++)
      for (i=block_x; i<block_x+4; i++)
      {
		pp[j*8+i]=s;
      }
    }   
}

/************************************************************************
*
*  Routine:     motion_search()
*
*  Description: In this routine motion search (integer pel+1/3 pel) and mode selection 
*               is performed. Since we treat all 4x4 blocks before coding/decoding the 
*               prediction may not be based on decoded pixels (except for some of the blocks). 
*               This will result in too good prediction.  To compensate for this the SAD for 
*               intra(tot_intra_sad) is given a 'handicap' depending on QP.
*
*  Input:       Best intra SAD value.
*
*  Output:      Reference image.  
*
************************************************************************/
#define IABS(x) absm((x))

int SAD_Macroblock(struct img_par *img,byte* ii, byte* kk,int Min_FRAME,int curr_sad)
{
	int sad = curr_sad;
#ifdef FAST_SAD
	int i;
	int x0,x1,x2,x3,x4,x5;
	int y0,y1,y2,y3,y4,y5;
	int lx=img->width+(img->width<<1);
	for(i=0;i<16;i+=3)
	{
		x0=ii[ 0];	y0=kk[ 0];
		x1=ii[ 3];	y1=kk[ 3];
		x2=ii[ 6];	y2=kk[ 6];
		x3=ii[ 9];	y3=kk[ 9];
		x4=ii[12];	y4=kk[12];
		x5=ii[15];	y5=kk[15];
		sad+=IABS(x0-y0)+IABS(x1-y1)+IABS(x2-y2)+IABS(x3-y3)+IABS(x4-y4)+IABS(x5-y5);
		ii += lx;	kk += lx;
		if (sad > Min_FRAME)	return 32767;
	}
	return sad;
#else
	int i;
	int lx=img->width+IMG_PAD_SIZE;
	for(i=0;i<16;i+=1)
	{
		sad += (\
				 IABS(ii[ 0]-kk[ 0])
				+IABS(ii[ 1]-kk[ 1])
				+IABS(ii[ 2]-kk[ 2])
				+IABS(ii[ 3]-kk[ 3])
				+IABS(ii[ 4]-kk[ 4])
				+IABS(ii[ 5]-kk[ 5])
				+IABS(ii[ 6]-kk[ 6])
				+IABS(ii[ 7]-kk[ 7])
				+IABS(ii[ 8]-kk[ 8])
				+IABS(ii[ 9]-kk[ 9])
				+IABS(ii[10]-kk[10])
				+IABS(ii[11]-kk[11])
				+IABS(ii[12]-kk[12])
				+IABS(ii[13]-kk[13])
				+IABS(ii[14]-kk[14])
				+IABS(ii[15]-kk[15]));
		ii += lx;
		kk += lx;
		if (sad > Min_FRAME)
			return 0x7fff;
	} 
	return sad;
#endif
}

int SAD_Macroblock_sub(struct img_par *img,byte* ii, byte* kk,int Min_FRAME,int curr_sad)
{
	int sad = curr_sad;
	int i;
	int lx=img->width+IMG_PAD_SIZE;
	for(i=0;i<8;i+=1)
	{
		sad += (\
				 IABS(ii[ 0]-kk[ 0])
				+IABS(ii[ 1]-kk[ 1])
				+IABS(ii[ 2]-kk[ 2])
				+IABS(ii[ 3]-kk[ 3])
				+IABS(ii[ 4]-kk[ 4])
				+IABS(ii[ 5]-kk[ 5])
				+IABS(ii[ 6]-kk[ 6])
				+IABS(ii[ 7]-kk[ 7])
				+IABS(ii[ 8]-kk[ 8])
				+IABS(ii[ 9]-kk[ 9])
				+IABS(ii[10]-kk[10])
				+IABS(ii[11]-kk[11])
				+IABS(ii[12]-kk[12])
				+IABS(ii[13]-kk[13])
				+IABS(ii[14]-kk[14])
				+IABS(ii[15]-kk[15]));
		ii += lx;
		kk += lx;
		if (sad > Min_FRAME)
			return 0x7fff;
	} 
	return sad;
}

int SAD_Macroblock_sub2(struct img_par *img,byte* ii, byte* kk,int Min_FRAME,int curr_sad)
{
	int sad = curr_sad;
	int i;
	int lx=img->width+IMG_PAD_SIZE;
	for(i=0;i<16;i+=1)
	{
		sad += (\
				 IABS(ii[ 0]-kk[ 0])
				+IABS(ii[ 1]-kk[ 1])
				+IABS(ii[ 2]-kk[ 2])
				+IABS(ii[ 3]-kk[ 3])
				+IABS(ii[ 4]-kk[ 4])
				+IABS(ii[ 5]-kk[ 5])
				+IABS(ii[ 6]-kk[ 6])
				+IABS(ii[ 7]-kk[ 7]));
		ii += lx;
		kk += lx;
		if (sad > Min_FRAME)
			return 0x7fff;
	} 
	return sad;
}

int motion_search_16x8(struct img_par *img,int MinCost)
{
  int i,index;
  int vec0_x,vec0_y,vec1_x,vec1_y,vec2_x,vec2_y;
  int pic_block_x,pic_block_y,pic_pix_y,pic_pix_x;
  int ip0,ip1,ip2,ip3,ip4,ip5;
  int best_inter_sad[2],current_inter_sad;
  int tmp0,tmp1; 
  int lambda = QP2QUANT[img->qp-SHIFT_QP]; 
  int x,y,offset,type,pos;  
        byte* curr;
	byte* prev;
	Point* point=search;
	SAD_TABLE * sadTbl=sadTable;
	int maxX=img->width-12;
	int maxY=img->height-4;
	int sadTimes=25;
	int mvx0,mvy0,mvx1,mvy1; 
	int x_curr,y_curr;
	int width=img->width+IMG_PAD_SIZE;

#ifdef FAST_INTEGER	
	int prev_AE1[17];
	int prev_m1,prev_m2=0;
	static int prevm[4] = {2, 3, 0, 1};
	static int htp[4] = {-1, 0, 1, 0};
	static int vtp[4] = {0, 1, 0, -1};
	int j_min_now, i_min_now, i_min_next=0, j_min_next=0, sad_layr,Coffset,ioffset=0,l,m,j;
	int distortion_0, distortion_1, distortion_2;
#endif  

  for(index=0;index<2;index++)
  {
	  point=search;
	  sadTbl=sadTable;
	  pic_block_y=img->block_y+2*index;
	  pic_pix_y=img->pix_y+8*index;
	        
	  pic_block_x=img->block_x;
	  pic_pix_x=img->pix_x;
	
	  x_curr=pic_pix_x;
	  y_curr=pic_pix_y;
	                    
	  if(index==0)
	  {
		  vec0_x=pic_block_x-1;
		  vec0_y=pic_block_y;
		  vec1_x=pic_block_x;
		  vec1_y=pic_block_y-1;
		  vec2_x=pic_block_x+4;
		  vec2_y=pic_block_y-1;
		  if (pic_block_y == 0) 
          {
            vec1_x=vec0_x;
            vec2_x=vec0_x;
            vec1_y=vec0_y;
            vec2_y=vec0_y;
          }                
          if (vec2_x > (img->width>>2)-1) 
          {
            vec2_x=pic_block_x-1;
          }
		  
            ip1=tmp_mv[vec1_y][vec1_x+4][0];
			ip0=tmp_mv[vec0_y][vec0_x+4][0];
			ip2=tmp_mv[vec2_y][vec2_x+4][0];
			ip3=tmp_mv[vec0_y][vec0_x+4][1];
            ip4=tmp_mv[vec1_y][vec1_x+4][1];
            ip5=tmp_mv[vec2_y][vec2_x+4][1];
		  if(!intra_mb_pos[vec1_y][vec1_x+4])
			{
				img->mv1[index][0] = ip1;
				img->mv1[index][1] = ip4;
			}
		  else
		  {			  				
				if((!intra_mb_pos[vec0_y][vec0_x+4])&&(intra_mb_pos[vec2_y][vec2_x+4]))
				{
					img->mv1[index][0] = ip0;
					img->mv1[index][1] = ip3;
				}
				else if((intra_mb_pos[vec0_y][vec0_x+4])&&(!intra_mb_pos[vec2_y][vec2_x+4]))
				{
					img->mv1[index][0] = ip2;
					img->mv1[index][1] = ip5;
				}
				else
				{
					img->mv1[index][0]=ip0+ip1+ip2-min(min(ip0,ip1),ip2)-max(max(ip0,ip1),ip2);
					img->mv1[index][1]=ip3+ip4+ip5-min(min(ip3,ip4),ip5)-max(max(ip3,ip4),ip5);
				}
		  }
	  }
	  else
	  {
		  vec0_x=pic_block_x-1;
		  vec0_y=pic_block_y;
		  vec1_x=pic_block_x;
		  vec1_y=pic_block_y-1;
		  vec2_x=pic_block_x-1;
		  vec2_y=pic_block_y-1;
		  
            ip1=curr_mvx1[0];
            ip4=curr_mvy1[0];
            ip0=tmp_mv[vec0_y][vec0_x+4][0];
			ip2=tmp_mv[vec2_y][vec2_x+4][0];
			ip3=tmp_mv[vec0_y][vec0_x+4][1];            
			ip5=tmp_mv[vec2_y][vec2_x+4][1];
		  if(!intra_mb_pos[vec0_y][vec0_x+4])
			{
				img->mv1[index][0] = ip0;
				img->mv1[index][1] = ip3;
			}
		  else
		  {
				if(intra_mb_pos[vec2_y][vec2_x+4])
				{
					img->mv1[index][0] = ip1;
					img->mv1[index][1] = ip4;
				}
				else
				{
					img->mv1[index][0]=ip0+ip1+ip2-min(min(ip0,ip1),ip2)-max(max(ip0,ip1),ip2);
					img->mv1[index][1]=ip3+ip4+ip5-min(min(ip3,ip4),ip5)-max(max(ip3,ip4),ip5);
				}
		  }
	  }

	  
          ip0=img->mv1[index][0];
          ip1=img->mv1[index][1];
          
        
	
	offset=width*pic_pix_y+pic_pix_x; 
	curr=imgY_org + offset;
	prev=ipol[0] + offset;
#ifndef FAST_INTEGER
	    tmp0=-ip0;
	    tmp1=-ip1;
	    current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
	    best_inter_sad[index] = SAD_Macroblock_sub(img,curr, prev, MAX_VALUE,current_inter_sad);
	    //best_inter_sad[index] -= lambda * 16;//is 16x16block,here should not
        mvx0=0;
	    mvy0=0;        
    
 
	pos=0;
	for (i = 1; i < sadTimes; i++)
	{
		sadTbl++;
		x=x_curr+sadTbl->dx;
		y=y_curr+sadTbl->dy;
		//if((x<0)||(y<0)||(x>maxX)||(y>maxY))
		//	continue;

		tmp0=(sadTbl->dx<<2)-ip0;
		tmp1=(sadTbl->dy<<2)-ip1;
		current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
		//current_inter_sad+ = SAD_Macroblock_sub(img,prev+sadTbl->offset, curr, best_inter_sad[index],current_inter_sad);
		current_inter_sad = SAD_Macroblock_sub(img,prev+sadTbl->offset, curr, best_inter_sad[index],current_inter_sad);
		if (current_inter_sad < best_inter_sad[index])
		{
			pos=i;
			best_inter_sad[index] = current_inter_sad;
		}
	}
	mvx0 = sadTable[pos].dx;
	mvy0 = sadTable[pos].dy;
	offset+=sadTable[pos].offset;
	x_curr+=mvx0;
	y_curr+=mvy0;

#else
	
	i_min_now = min(maxX,max(-4, x_curr+(ip0>>2)));
	j_min_now = min(maxY,max(-4, y_curr+(ip1>>2)));
	//i_min_now = x_curr;
	//j_min_now = y_curr;
	mvx0=i_min_now-x_curr;
	mvy0=j_min_now-y_curr;
	ioffset=width*mvy0+mvx0;
	tmp0=(mvx0<<2)-ip0;
	tmp1=(mvy0<<2)-ip1;
	current_inter_sad=(lambda*(img->mv_bituse[absm(tmp0)]+img->mv_bituse[absm(tmp1)]));
	best_inter_sad[index] = SAD_Macroblock_sub(img,curr, prev+j_min_now*width+i_min_now-offset, MAX_VALUE,current_inter_sad);
  	
	distortion_0 = distortion_1 = distortion_2 = 65536;
  	prev_AE1[0] = best_inter_sad[index];

⌨️ 快捷键说明

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