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

📄 decoder.cpp

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 CPP
📖 第 1 页 / 共 4 页
字号:
         if (dc_size > 8) {            bs->Skip(1);   /* marker */         }         block[i * 64 + 0] = dc_dif;         start_coeff = 1;         DPRINTF(XVID_DEBUG_COEFF,"block[0] %i\n", dc_dif);         PROF_E(PROF_1);      }else{         start_coeff = 0;      }      if(cbp & (1 << (5 - i))){                              //coded         int direction = alternate_vertical_scan ? 2 : pMB->acpred_directions[i];         get_intra_block(bs, &block[i * 64], direction, start_coeff);      }      add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors);      if(quant_type == 0){         dequant_h263_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, mpeg_quant_matrices);      }else{         dequant_mpeg_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, mpeg_quant_matrices);      }      InverseDiscreteCosineTransform(&data[i * 64]);   }   dword next_block = stride * 8;   if(interlacing && pMB->field_dct){      next_block = stride;      stride *= 2;   }   if(reduced_resolution){      next_block*=2;      copy_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride);      copy_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride);      copy_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride);      copy_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride);      copy_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2);      copy_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2);   }else{      transfer_16to8copy(pY_Cur, &data[0 * 64], stride);      transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);      transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);      transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride);      transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);      transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);   }}//----------------------------void S_decoder::mb_decode(const dword cbp, Bitstream * bs, byte * pY_Cur, byte * pU_Cur, byte * pV_Cur, bool reduced_resolution, const MACROBLOCK *pMB){   DECLARE_ALIGNED_MATRIX(block, 1, 64, int, CACHE_LINE);   DECLARE_ALIGNED_MATRIX(data, 6, 64, int, CACHE_LINE);   int i;   int stride = edged_width;   const int stride2 = stride/2;   const dword iQuant = pMB->quant;   const int direction = alternate_vertical_scan ? 2 : 0;   const quant_interFuncPtr dequant = quant_type == 0 ? dequant_h263_inter : dequant_mpeg_inter;   for(i = 0; i < 6; i++){      if(cbp & (1 << (5 - i))){                              //coded         XVID_ClearMatrix(block);         get_inter_block(bs, block, direction);         dequant(&data[i * 64], block, iQuant, mpeg_quant_matrices);         InverseDiscreteCosineTransform(&data[i * 64]);      }   }   int next_block = stride * (reduced_resolution ? 16 : 8);   if(interlacing && pMB->field_dct){      next_block = stride;      stride *= 2;   }   if(reduced_resolution){      if(cbp & 32)         add_upsampled_8x8_16to8(pY_Cur, &data[0 * 64], stride);      if(cbp & 16)         add_upsampled_8x8_16to8(pY_Cur + 16, &data[1 * 64], stride);      if(cbp & 8)         add_upsampled_8x8_16to8(pY_Cur + next_block, &data[2 * 64], stride);      if(cbp & 4)         add_upsampled_8x8_16to8(pY_Cur + 16 + next_block, &data[3 * 64], stride);      if(cbp & 2)         add_upsampled_8x8_16to8(pU_Cur, &data[4 * 64], stride2);      if(cbp & 1)         add_upsampled_8x8_16to8(pV_Cur, &data[5 * 64], stride2);   }else{      if(cbp & 32)         transfer_16to8add(pY_Cur, &data[0 * 64], stride);      if(cbp & 16)         transfer_16to8add(pY_Cur + 8, &data[1 * 64], stride);      if(cbp & 8)         transfer_16to8add(pY_Cur + next_block, &data[2 * 64], stride);      if(cbp & 4)         transfer_16to8add(pY_Cur + 8 + next_block, &data[3 * 64], stride);      if(cbp & 2)         transfer_16to8add(pU_Cur, &data[4 * 64], stride2);      if(cbp & 1)         transfer_16to8add(pV_Cur, &data[5 * 64], stride2);   }}//----------------------------void S_decoder::DecodeInterMacroBlock(const MACROBLOCK * pMB, dword x_pos, dword y_pos, dword cbp, Bitstream *bs,   bool rounding, bool reduced_resolution, int ref){   dword stride = edged_width;   dword stride2 = stride / 2;   dword i;   byte *pY_Cur, *pU_Cur, *pV_Cur;   int uv_dx, uv_dy;   VECTOR mv[4];              //local copy of mvs   if(reduced_resolution){      pY_Cur = cur.y + (y_pos << 5) * stride + (x_pos << 5);      pU_Cur = cur.u + (y_pos << 4) * stride2 + (x_pos << 4);      pV_Cur = cur.v + (y_pos << 4) * stride2 + (x_pos << 4);      for (i = 0; i < 4; i++) {         mv[i].x = RRV_MV_SCALEUP(pMB->mvs[i].x);         mv[i].y = RRV_MV_SCALEUP(pMB->mvs[i].y);      }   }else{      pY_Cur = cur.y + (y_pos << 4) * stride + (x_pos << 4);      pU_Cur = cur.u + (y_pos << 3) * stride2 + (x_pos << 3);      pV_Cur = cur.v + (y_pos << 3) * stride2 + (x_pos << 3);      for(i = 0; i < 4; i++)         mv[i] = pMB->mvs[i];   }   if(pMB->mode != MODE_INTER4V){                              //INTER, INTER_Q, NOT_CODED, FORWARD, BACKWARD      uv_dx = mv[0].x;      uv_dy = mv[0].y;      if (quarterpel) {         uv_dx /= 2;         uv_dy /= 2;      }      uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];      uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];      if(reduced_resolution)         interpolate32x32_switch(cur.y, refn[0].y, 32*x_pos, 32*y_pos, mv[0].x, mv[0].y, stride, rounding);      else      if(quarterpel)         interpolate16x16_quarterpel(cur.y, refn[ref].y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, mv[0].x, mv[0].y, stride, rounding);      else         interpolate16x16_switch(cur.y, refn[ref].y, 16*x_pos, 16*y_pos, mv[0].x, mv[0].y, stride, rounding);   }else{                              //MODE_INTER4V      if(quarterpel) {         uv_dx = (mv[0].x / 2) + (mv[1].x / 2) + (mv[2].x / 2) + (mv[3].x / 2);         uv_dy = (mv[0].y / 2) + (mv[1].y / 2) + (mv[2].y / 2) + (mv[3].y / 2);      }else{         uv_dx = mv[0].x + mv[1].x + mv[2].x + mv[3].x;         uv_dy = mv[0].y + mv[1].y + mv[2].y + mv[3].y;      }      uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];      uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];      if(reduced_resolution){         interpolate16x16_switch(cur.y, refn[0].y, 32*x_pos,      32*y_pos,      mv[0].x, mv[0].y, stride, rounding);         interpolate16x16_switch(cur.y, refn[0].y, 32*x_pos + 16, 32*y_pos,      mv[1].x, mv[1].y, stride, rounding);         interpolate16x16_switch(cur.y, refn[0].y, 32*x_pos,      32*y_pos + 16, mv[2].x, mv[2].y, stride, rounding);         interpolate16x16_switch(cur.y, refn[0].y, 32*x_pos + 16, 32*y_pos + 16, mv[3].x, mv[3].y, stride, rounding);         interpolate16x16_switch(cur.u, refn[0].u, 16*x_pos,      16*y_pos,      uv_dx,   uv_dy,   stride2, rounding);         interpolate16x16_switch(cur.v, refn[0].v, 16*x_pos,      16*y_pos,      uv_dx,   uv_dy,   stride2, rounding);      }else      if(quarterpel){         interpolate8x8_quarterpel(cur.y, refn[0].y , qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, mv[0].x, mv[0].y, stride, rounding);         interpolate8x8_quarterpel(cur.y, refn[0].y , qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos, mv[1].x, mv[1].y, stride, rounding);         interpolate8x8_quarterpel(cur.y, refn[0].y , qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos + 8, mv[2].x, mv[2].y, stride, rounding);         interpolate8x8_quarterpel(cur.y, refn[0].y , qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8, mv[3].x, mv[3].y, stride, rounding);      } else {         interpolate8x8_switch(cur.y, refn[0].y , 16*x_pos, 16*y_pos, mv[0].x, mv[0].y, stride, rounding);         interpolate8x8_switch(cur.y, refn[0].y , 16*x_pos + 8, 16*y_pos, mv[1].x, mv[1].y, stride, rounding);         interpolate8x8_switch(cur.y, refn[0].y , 16*x_pos, 16*y_pos + 8, mv[2].x, mv[2].y, stride, rounding);         interpolate8x8_switch(cur.y, refn[0].y , 16*x_pos + 8, 16*y_pos + 8, mv[3].x, mv[3].y, stride, rounding);      }   }                              //chroma   if(reduced_resolution){      interpolate16x16_switch(cur.u, refn[0].u, 16*x_pos, 16*y_pos, uv_dx, uv_dy, stride2, rounding);      interpolate16x16_switch(cur.v, refn[0].v, 16*x_pos, 16*y_pos, uv_dx, uv_dy, stride2, rounding);   }else{      interpolate8x8_switch(cur.u, refn[ref].u,  8*x_pos,  8*y_pos, uv_dx, uv_dy, stride2, rounding);      interpolate8x8_switch(cur.v, refn[ref].v,  8*x_pos,  8*y_pos, uv_dx, uv_dy, stride2, rounding);   }   if(cbp)      mb_decode(cbp, bs, pY_Cur, pU_Cur, pV_Cur, reduced_resolution, pMB);}//----------------------------inline int gmc_sanitize(int value, int quarterpel, int fcode){   int length = 1 << (fcode+4);#if 0   if (quarterpel) value *= 2;#endif   if (value < -length)      return -length;   else if (value >= length)      return length-1;   else return value;}//----------------------------void S_decoder::mbgmc(MACROBLOCK *pMB, dword x_pos, dword y_pos, dword fcode, dword cbp, Bitstream * bs, bool rounding){   const dword stride = edged_width;   const dword stride2 = stride / 2;   byte *const pY_Cur=cur.y + (y_pos << 4) * stride + (x_pos << 4);   byte *const pU_Cur=cur.u + (y_pos << 3) * stride2 + (x_pos << 3);   byte *const pV_Cur=cur.v + (y_pos << 3) * stride2 + (x_pos << 3);   NEW_GMC_DATA *gmc_data = &new_gmc_data;   pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;                              //this is where the calculations are done   gmc_data->predict_16x16(gmc_data, cur.y + y_pos*16*stride + x_pos*16, refn[0].y, stride, stride, x_pos, y_pos, rounding);   gmc_data->predict_8x8(gmc_data, cur.u + y_pos*8*stride2 + x_pos*8, refn[0].u, cur.v + y_pos*8*stride2 + x_pos*8, refn[0].v, stride2, stride2, x_pos, y_pos, rounding);   gmc_data->get_average_mv(gmc_data, &pMB->amv, x_pos, y_pos, quarterpel);   pMB->amv.x = gmc_sanitize(pMB->amv.x, quarterpel, fcode);   pMB->amv.y = gmc_sanitize(pMB->amv.y, quarterpel, fcode);   pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;   if(cbp)      mb_decode(cbp, bs, pY_Cur, pU_Cur, pV_Cur, 0, pMB);}//----------------------------void S_decoder::I_Frame(Bitstream * bs, bool reduced_resolution, int quant, int intra_dc_threshold){   dword bound;   dword x, y;   //dword mb_width = mb_width;   //dword mb_height = mb_height;   if (reduced_resolution) {      mb_width = (width + 31) / 32;      mb_height = (height + 31) / 32;   }   bound = 0;   for (y = 0; y < mb_height; y++) {      for (x = 0; x < mb_width; x++) {         dword mcbpc;         dword cbpc;         dword acpred_flag;         dword cbpy;         dword cbp;         while(bs->ShowBits(9) == 1)            bs->Skip(9);         if(bs->check_resync_marker(0)){            bound = read_video_packet_header(bs, 0, &quant, NULL, NULL, &intra_dc_threshold);            x = bound % mb_width;            y = bound / mb_width;         }         MACROBLOCK *mb = &mbs[y * mb_width + x];         //DPRINTF(XVID_DEBUG_MB, "macroblock (%i,%i) %08x\n", x, y, bs->ShowBits(32));         mcbpc = bs->get_mcbpc_intra();         mb->mode = mcbpc & 7;         cbpc = (mcbpc >> 4);         acpred_flag = bs->GetBit();         cbpy = bs->GetCbpy(1);         cbp = (cbpy << 2) | cbpc;         if (mb->mode == MODE_INTRA_Q) {            quant += dquant_table[bs->GetBits(2)];            if (quant > 31) {               quant = 31;            } else if (quant < 1) {               quant = 1;            }         }         mb->quant = quant;         mb->mvs[0].x = mb->mvs[0].y =         mb->mvs[1].x = mb->mvs[1].y =         mb->mvs[2].x = mb->mvs[2].y =         mb->mvs[3].x = mb->mvs[3].y =0;         if(interlacing){            mb->field_dct = bs->GetBit();            DPRINTF(XVID_DEBUG_MB,"deci: field_dct: %i\n", mb->field_dct);         }         MBIntra(mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold, bound, reduced_resolution);      }      /*#ifdef XVID_CSP_SLICE      if(out_frm)         output_slice(&cur, edged_width,width,out_frm,0,y,mb_width);#endif         */   }}//----------------------------void S_decoder::GetMotionVector(Bitstream * bs, int x, int y, int k, VECTOR *ret_mv, int fcode, int bound){   const int scale_fac = 1 << (fcode - 1);   const int high = (32 * scale_fac) - 1;   const int low = ((-32) * scale_fac);   const int range = (64 * scale_fac);   const VECTOR pmv = get_pmv2(mbs, mb_width, bound, x, y, k);   VECTOR mv;   mv.x = bs->GetMoveVector(fcode);   mv.y = bs->GetMoveVector(fcode);   //DPRINTF(XVID_DEBUG_MV,"mv_diff (%i,%i) pred (%i,%i) result (%i,%i)\n", mv.x, mv.y, pmv.x, pmv.y, mv.x+pmv.x, mv.y+pmv.y);   mv.x += pmv.x;   mv.y += pmv.y;   if(mv.x < low){      mv.x += range;   }else   if(mv.x > high){      mv.x -= range;   }   if(mv.y < low){      mv.y += range;   }else   if(mv.y > high){      mv.y -= range;   }   ret_mv->x = mv.x;   ret_mv->y = mv.y;}//----------------------------

⌨️ 快捷键说明

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