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

📄 endecode.cpp

📁 设计并实现了两种分层多描述视频编码器.通过对小波域的运动估计算法进行了分析和研究
💻 CPP
📖 第 1 页 / 共 4 页
字号:
      ptr1  = LSP_ptr1[LSP_idx] = image.address1(nc);
     *ptr = (b & m ? -act_value : act_value);
	 if(mdc==1||last_mark) *ptr1 = *ptr; //保存描述1的内容到coeff1
      m <<= 1; }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void Desc_Test(Tree_Node * act_node)
{//输出Sn(D),有非零子孙,则把该项从LIS摘除,其子节点挂到LISP并输出Sn,非零子节点LIP->LSP
  Image_Coord pc = act_node->coord;
//输出Sn(D),并返回是否有非零子孙标志
  int st_trans = Desc_Transition(int(act_node->state & 0xFFL), pc);

  if (!st_trans) return;
//有非零子孙,进一步处理
  act_node->state |= st_trans;  st_trans >>= 1;

  Tree_Node * new_node;
  long ns = (act_node->state & 0xFF00L) - 0x200L;//子树的状态
  if (ns < 0x300L) ns |= 0xAAL; //最后一层处理结束
  int root = ((act_node->state & 0xFF00L) >= root_code);//LL子带标志

  for (int i = 0; i < 4; i++, st_trans >>= 2)
    if (st_trans & 0x1) {//该节点有非零子孙,把儿子节点挂到LISP队列
      NEW_OBJECT(new_node, Tree_Node, "LISP entry");
      if (root) {//LL子带
        if (i == 3) ns -= 0x100L;
        new_node->coord.x = pc.x + SHF_x[i] * root_dim.x;
        new_node->coord.y = pc.y + SHF_y[i] * root_dim.y; }
      else {
        new_node->coord.x = (pc.x + SHF_x[i]) << 1;
        new_node->coord.y = (pc.y + SHF_y[i]) << 1; }
      new_node->next = NULL;  new_node->state = ns;
      LISP_end->next = new_node;  LISP_end = new_node;
      Node_Test(new_node); }//输出node中各Sn。若有系数>门限,输出该系数的符号,并移出LIP表放入LSP
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void DeDesc_Test(Tree_Node * act_node)
{//输出Sn(D),有非零子孙,则把该项从LIS摘除,其子节点挂到LISP并输出Sn,非零子节点LIP->LSP
  Image_Coord pc = act_node->coord;
//输出Sn(D),并返回是否有非零子孙标志
  int st_trans = DeDesc_Transition(int(act_node->state & 0xFFL), pc);

  if (!st_trans) return;
//有非零子孙,进一步处理
  act_node->state |= st_trans;  st_trans >>= 1;

  Tree_Node * new_node;
  long ns = (act_node->state & 0xFF00L) - 0x200L;//子树的状态
  if (ns < 0x300L) ns |= 0xAAL; //最后一层处理结束
  int root = ((act_node->state & 0xFF00L) >= root_code);//LL子带标志

  for (int i = 0; i < 4; i++, st_trans >>= 2)
    if (st_trans & 0x1) {//该节点有非零子孙,把儿子节点挂到LISP队列
      NEW_OBJECT(new_node, Tree_Node, "LISP entry");
      if (root) {//LL子带
        if (i == 3) ns -= 0x100L;
        new_node->coord.x = pc.x + SHF_x[i] * root_dim.x;
        new_node->coord.y = pc.y + SHF_y[i] * root_dim.y; }
      else {
        new_node->coord.x = (pc.x + SHF_x[i]) << 1;
        new_node->coord.y = (pc.y + SHF_y[i]) << 1; }
      new_node->next = NULL;  new_node->state = ns;
      LISP_end->next = new_node;  LISP_end = new_node;
      DeNode_Test(new_node); }//输出node中各Sn。若有系数>门限,输出该系数的符号,并移出LIP表放入LSP
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

int Node_Transition(int old_st, const Image_Coord & pc, int * signs)
{
  int st_trans = 0, os = old_st, ps = old_st, mask = 1/*处理LIP表*/, i;
  int msk[3], count[4];

  for (i = 0; i < 4; i++) count[i] = 0;//LIS+LIP;LIS+LSP;LIP;LSP
  for (i = 0; i < 4; i++, ps >>= 2) ++count[ps&0x3];//计算不同状态树的个数
  msk[0] = msk[1] = 1;  msk[2] = 1 << count[0];//低位存LIS+LIP项,每项占1位,高位存LIP项
  int mod = count[2] - count[0] * count[1] - 1 + //选择算术编码模式
    (count[0] * (count[0] * (count[0] - 18) + 107)) / 6 +
    (count[1] * (11 - count[1])) / 2;

  int b = 0;//初始化非零标志Sn
  for (*signs = i = 0; i < 4; i++, mask <<= 2, os >>= 2) {//LIP队列处理
    if (old_st & mask) continue; //LSP项,不处理
    ps = os & 0x3;
    if (ABS(image(pc.x + SHF_x[i], pc.y + SHF_y[i])) >= threshold) {
      b |= msk[ps];//LIS存低位,非LIS存高位
      st_trans |= mask;  ++(*signs); }//置LIP->LSP的标志和个数
    msk[ps] <<= 1; }

  data_file.code_symbol(b, node_model[mod]);
  return st_trans;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

int DeNode_Transition(int old_st, const Image_Coord & pc, int * signs)
{
  int st_trans = 0, os = old_st, ps = old_st, mask = 1/*处理LIP表*/, i;
  int msk[3], count[4];

  for (i = 0; i < 4; i++) count[i] = 0;//LIS+LIP;LIS+LSP;LIP;LSP
  for (i = 0; i < 4; i++, ps >>= 2) ++count[ps&0x3];//计算不同状态树的个数
  msk[0] = msk[1] = 1;  msk[2] = 1 << count[0];//低位存LIS+LIP项,每项占1位,高位存LIP项
  int mod = count[2] - count[0] * count[1] - 1 + //选择算术编码模式
    (count[0] * (count[0] * (count[0] - 18) + 107)) / 6 +
    (count[1] * (11 - count[1])) / 2;

  int b = dedata_file.decode_symbol(node_model[mod]);
  for (*signs = i = 0; i < 4; i++, mask <<= 2, os >>= 2) {//LIP队列处理
    if (old_st & mask) continue; //LSP项,不处理
    ps = os & 0x3;
    if (b & msk[ps]) {
      st_trans |= mask;  ++(*signs); }//置LIP->LSP的标志和个数
    msk[ps] <<= 1; }

  return st_trans;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

int Desc_Transition(int old_st, const Image_Coord & pc)
{//输出Sn(D),若有非零子孙,返回标志
  int os = old_st, ps = os, st_trans = 0, mask = 2/*处理LIS*/, i;
  int msk[3], count[4];

  for (i = 0; i < 4; i++) count[i] = 0;
  for (i = 0; i < 4; i++, ps >>= 2) ++count[ps & 0x3];
  msk[0] = 1;  msk[1] = msk[2] = 1 << count[0];//低位存LIS+LIP项,每项占1位,高位存LIS项
  int mod = count[2] - count[0] * count[1] - 1 +
    (count[0] * (count[0] * (count[0] - 18) + 107)) / 6 +
    (count[1] * (11 - count[1])) / 2;

  int b = 0;
  for (i = 0; i < 4; i++, mask <<= 2, os >>= 2) {
    if (old_st & mask) continue;
    ps = os & 0x3;
    if (max_image(pc.x + SHF_x[i], pc.y + SHF_y[i]) >= threshold) {//有非零子孙Sn(D)=1
      b |= msk[ps];
      st_trans |= mask; }
    msk[ps] <<= 1; }//指向下一个位置

  if ((old_st & 0xAA) == 0) {//四个均为LIS
    data_file.code_symbol(st_trans == 0, group_model[count[0]]);//可视为输出Sn(L)
    if (st_trans == 0) return 0; }
  data_file.code_symbol(b, desc_model[mod]);

  return st_trans;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

int DeDesc_Transition(int old_st, const Image_Coord & pc)
{//输出Sn(D),若有非零子孙,返回标志
  int os = old_st, ps = os, st_trans = 0, mask = 2/*处理LIS*/, i;
  int msk[3], count[4];

  for (i = 0; i < 4; i++) count[i] = 0;
  for (i = 0; i < 4; i++, ps >>= 2) ++count[ps & 0x3];
  msk[0] = 1;  msk[1] = msk[2] = 1 << count[0];//低位存LIS+LIP项,每项占1位,高位存LIS项
  int mod = count[2] - count[0] * count[1] - 1 +
    (count[0] * (count[0] * (count[0] - 18) + 107)) / 6 +
    (count[1] * (11 - count[1])) / 2;

  if ((old_st & 0xAA) == 0)
    if (dedata_file.decode_symbol(group_model[count[0]])) return 0;
  int b = dedata_file.decode_symbol(desc_model[mod]);

  for (i = 0; i < 4; i++, mask <<= 2, os >>= 2) {
    if (old_st & mask) continue;
    ps = os & 0x3;
    if (b & msk[ps]) {
      st_trans |= mask; }
    msk[ps] <<= 1; }//指向下一个位置

  return st_trans;
}
// - - Lossy version functions - - - - - - - - - - - - - - - - - - - - -

void Node_Test(Tree_Node * act_node)
{//若node中有IP项,输出Sn。若有系数>门限,输出该系数的符号,并移出LIP表放入LSP
  int st_trans, signs;
  st_trans = Node_Transition(int(act_node->state & 0xFFL),
    act_node->coord, &signs);//若node中有IP项,输出Sn。若有系数>门限,移出LIP表

  if (st_trans) {//若有系数>门限,输出该系数的符号,并放入LSP
    act_node->state |= long(st_trans);
    Output_Signs(signs, st_trans, act_node->coord); }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void DeNode_Test(Tree_Node * act_node)
{
  int st_trans, signs;
  st_trans = DeNode_Transition(int(act_node->state & 0xFFL),
    act_node->coord, &signs);

  if (st_trans) {
    act_node->state |= long(st_trans);
    DeOutput_Signs(signs, st_trans, act_node->coord); }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

boolean Refinement_Pass(void)
{
  int b, p, m, n = LSP_plane, k = LSP_dim.y;
  double * ptr, * smk, ** mtx = LSP_mtx[0];

  LSP_mark[LSP_plane++] = (LSP_ptr ? LSP_ptr[LSP_idx] : 0);

  for (m = p = 0; p < n; p++) {
    for (smk = LSP_mark[p], ptr = 0; ptr != smk;) {
      if (!k) {
        mtx = LSP_mtx[++m];  k = LSP_dim.y; }
      ptr = mtx[--k];
      if (b = (*ptr >= threshold)) *ptr -= threshold;
      data_file.code_bit(b);
      if (data_file.bytes_used() >= byte_budget) return true; } }

  return false;
}
//----------------------------------------------------------------------
boolean DeRefinement_Pass(void)
{
  double t, ht1, ht2;
  int b, p, m, n = LSP_plane, k = LSP_dim.y;
  double * ptr, * smk, ** mtx = LSP_mtx[0];
  double *ptr1, ** mtx1 = LSP_mtx1[0];

  LSP_mark[LSP_plane++] = (LSP_ptr ? LSP_ptr[LSP_idx] : 0);

  for (m = p = 0; p < n; p++) {
    t = bias[p];
    bias[p] = threshold * (0.5 - 0.25 / Sqr(LSP_plane - p));
    ht1 = bias[p] - t;  ht2 = ht1 + threshold;
    for (smk = LSP_mark[p], ptr = 0; ptr != smk;) {
      if (!k) {
        mtx = LSP_mtx[++m];  mtx1 = LSP_mtx1[m];  k = LSP_dim.y; }
      ptr = mtx[--k]; ptr1 = mtx1[k];
      t = (dedata_file.decode_bit() ? ht2 : ht1);
      if (*ptr > 0) {
		  *ptr += t; 
		  if (mdc==1) *ptr1 += t; } //只有描述1写入coeff1
	  else {
		  *ptr -= t; 
		  if (mdc==1) *ptr1 -= t; }
      if (dedata_file.bytes_used() >= byte_budget) return true; } }

  return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void final_bit()
{
  int b, p, m, n = LSP_plane, k = LSP_dim.y, ss=mdc-1;
  double * ptr, * smk, ** mtx = LSP_mtx[0];

  LSP_mark[LSP_plane++] = (LSP_ptr ? LSP_ptr[LSP_idx] : 0);

  for (m = p = 0; p < n; p++) {
    for (smk = LSP_mark[p], ptr = 0; ptr != smk;) {
      if (!k) {
        mtx = LSP_mtx[++m];  k = LSP_dim.y; }
      ptr = mtx[--k];
      b = (*ptr >= threshold);
      if (!ss) data_file.code_bit(b); }
	ss^=1; }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Definal_bit(void)
{
  double t, ht1, ht2;
  int p, m, n = LSP_plane, k = LSP_dim.y;
  int ss=mdc-1;
  double * ptr, * smk, ** mtx = LSP_mtx[0];
  double * ptr1, **mtx1 = LSP_mtx1[0];

  LSP_mark[LSP_plane++] = (LSP_ptr ? LSP_ptr[LSP_idx] : 0);

  for (m = p = 0; p < n; p++) {
    t = bias[p];
    bias[p] = threshold * (0.5 - 0.25 / Sqr(LSP_plane - p));
    ht1 = bias[p] - t;  ht2 = ht1 + threshold;
    for (smk = LSP_mark[p], ptr = 0; ptr != smk;) {
      if (!k) {
        mtx = LSP_mtx[++m];  k = LSP_dim.y; 
		mtx1 = LSP_mtx1[m];}
      ptr = mtx[--k]; ptr1 = mtx1[k];
      if (!ss) { 
		t = (dedata_file.decode_bit() ? ht2 : ht1);
		if (*ptr > 0) {*ptr += t; *ptr1 += t; }
		else {*ptr -= t; *ptr1 -= t; }}}
	ss^=1;}
		
}
// - - Encoder functions - - - - - - - - - - - - - - - - - - - - - - - -

Pel_Type Max_Desc_Val(int l, int s, int x, int y)
{
  Pel_Type t, m = 0;
  Image_Coord ds;
  --l;  --s;
  for (int d = 0; d < 4; d++) {
    ds.x = x + SHF_x[d];  ds.y = y + SHF_y[d];
    t = Magn_Val(image[ds], s);
    if (m < t) m = t;
    if (l > 0) {
      max_image[ds] = t = Max_Desc_Val(l, s, ds.x << 1, ds.y << 1);
      if (m < t) m = t; } }
  return m;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

int Calc_Max_Image(void)
{
  Image_Coord tc, pc = image.dimension(), lm = pc;
  int i, sd, lv = image.pyramid_levels(), sp = lv + 1;
  Pel_Type t, max = 0;
  

  lm.x >>= lv;  lm.y >>= lv;  pc.x >>= 1;  pc.y >>= 1;
  max_image.reset(pc, 0);

  for (pc.x = 0; pc.x < lm.x; pc.x += 2)
    for (pc.y = 0; pc.y < lm.y; pc.y += 2) {
      t = max_image[pc] = Magn_Val(image[pc], sp);
      if (max < t) max = t;
      for (sd = sp, i = 1; i < 4; i++) {
        tc.x = pc.x + SHF_x[i];  tc.y = pc.y + SHF_y[i];
        t = Magn_Val(image[tc], sp);
        if (max < t) max = t;
        if (i == 3) --sd;
        t = max_image[tc] = Max_Desc_Val(lv, sd,
          pc.x + SHF_x[i] * lm.x, pc.y + SHF_y[i] * lm.y);
        if (max < t) max = t; } }

  return int(log(max) / log(2.0));
}


//---------------------------------------------------------------------


void all_phase_motion_Estimation(Image_Coord dimension, Pel_Type ** Pcoeff, Pel_Type ** Pcoeff2) //double
{
	int i, j, i0, j0, dx, dy, i2, j2, i1, j1;
	int x, y, dx1, dy1, W = 8;//搜索窗口大小
    int Width=dimension.y,Height=dimension.x;
	double sad, smin;
//	char c1;
/*	FILE *mvfile;

	mvfile = fopen(mp, "wb");
	if(!mvfile) {
		cout<<"cannot open mvfile1"<<endl;
		exit(-1);
	}*/
  //------------- Do motion estimation and store result in array 
	for ( y=0, j=0; y<Height; j++, y+=16) {//最大子带每块8x8,全相分解变成16x16
	    for ( x=0, i=0; x<Width; i++, x+=16) {
			smin = 665536; dx1=0; dy1=0;
			for (dy=-W;dy<W;dy++) {
				if (y+dy<0||y+dy+14>=Height) continue; //为什么要加14??????
				for(dx=-W;dx<W;dx++) {
					if(x+dx<0||x+dx+14>=Width) continue;
					sad=0;
			//求第1次分解(HL1, LH1, HH1)残差
					i0 = x>>1; j0 = y>>1;
					i1 = i0 + (Width>>1); j1 = j0 + (Height>>1);
					for (j2=0; j2<8;j2++) {//计算最大子带中的残差  
						for (i2=0; i2<8; i2++) {
							sad += fabs(Pcoeff[j0+j2][i1+i2]-w[0][0][y+dy+(j2<<1)][x+dx+(i2<<1)]);
							sad += fabs(Pcoeff[j1+j2][i0+i2]-w[0][1][y+dy+(j2<<1)][x+dx+(i2<<1)]);
							sad += fabs(Pcoeff[j1+j2][i1+i2]-w[0][2][y+dy+(j2<<1)][x+dx+(i2<<1)]);
						}
					}
					i0>>=1; j0>>=1; i1>>=1; j1>>=1;
					for (j2=0; j2<4; j2++) {//计算中间子带中的残差  
						for (i2=0; i2<4; i2++) {
							sad += fabs(Pcoeff[j0+j2][i1+i2]-w[1][0][y+dy+(j2<<2)][x+dx+(i2<<2)]);
							sad += fabs(Pcoeff[j1+j2][i0+i2]-w[1][1][y+dy+(j2<<2)][x+dx+(i2<<2)]);
							sad += fabs(Pcoeff[j1+j2][i1+i2]-w[1][2][y+dy+(j2<<2)][x+dx+(i2<<2)]);
						}
					}
					i0>>=1; j0>>=1; i1>>=1; j1>>=1;
					for (j2=0; j2<2; j2++) {//计算最小子带中的残差  
						for (i2=0; i2<2; i2++) {
							sad += fabs(Pcoeff[j0+j2][i0+i2]-w1[0][0][y+dy+(j2<<3)][x+dx+(i2<<3)]);
							sad += fabs(Pcoeff[j0+j2][i1+i2]-w1[0][1][y+dy+(j2<<3)][x+dx+(i2<<3)]);
							sad += fabs(Pcoeff[j1+j2][i0+i2]-w1[1][0][y+dy+(j2<<3)][x+dx+(i2<<3)]);
							sad += fabs(Pcoeff[j1+j2][i1+i2]-w1[1][1][y+dy+(j2<<3)][x+dx+(i2<<3)]);
						}
					}
					if (sad < smin) {
						dx1=dx; dy1=dy; 
						smin=sad;
					}
				}
			}
			dx = dx1; dy = dy1;
			for (j2=0; j2<2; j2++) {//计算最小子带中的参考图像块
				for (i2=0; i2<2; i2++) {
					Pcoeff2[j0+j2][i0+i2] = w1[0][0][y+dy+(j2<<3)][x+dx+(i2<<3)];
					Pcoeff2[j0+j2][i1+i2] = w1[0][1][y+dy+(j2<<3)][x+dx+(i2<<3)];
					Pcoeff2[j1+j2][i0+i2] = w1[1][0][y+dy+(j2<<3)][x+dx+(i2<<3)];
					Pcoeff2[j1+j2][i1+i2] = w1[1][1][y+dy+(j2<<3)][x+dx+(i2<<3)];

⌨️ 快捷键说明

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