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

📄 decoder.cpp

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// for P_VOP set gmc_warp to NULLvoid S_decoder::P_Frame(Bitstream *bs, int rounding, bool reduced_resolution, int quant, int fcode,   int intra_dc_threshold, const WARPPOINTS *gmc_warp){   //dword mb_width = mb_width;   //dword mb_height = mb_height;   if(reduced_resolution){      mb_width = (width + 31) / 32;      mb_height = (height + 31) / 32;   }   SetEdges(refn[0]);   if(gmc_warp){                              //accuracy: 0==1/2, 1=1/4, 2=1/8, 3=1/16      generate_GMCparameters(sprite_warping_points, sprite_warping_accuracy, gmc_warp, width, height, &new_gmc_data);                              //image warping is done block-based in decoder_mbgmc(), now   }   PROF_S(PROF_FRM_P);   dword bound = 0;   for(dword y = 0; y < mb_height; y++){      //int cp_mb = 0, st_mb = 0;      for(dword x = 0; x < mb_width; x++){                              //skip stuffing         while(bs->ShowBits(10) == 1)            bs->Skip(10);         if(bs->check_resync_marker(fcode - 1)){            bound = read_video_packet_header(bs, fcode - 1, &quant, &fcode, 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));         if(!(bs->GetBit())){                              //block _is_ coded            int mcsel = 0;    //mcsel: '0'=local motion, '1'=GMC            //cp_mb++;            dword mcbpc = bs->GetMcbpcInter();            mb->mode = mcbpc & 7;            dword cbpc = (mcbpc >> 4);            DPRINTF(XVID_DEBUG_MB, "mode %i\n", mb->mode);            DPRINTF(XVID_DEBUG_MB, "cbpc %i\n", cbpc);            dword intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);            dword acpred_flag = 0;            if(gmc_warp && (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q))               mcsel = bs->GetBit();            else            if(intra)               acpred_flag = bs->GetBit();            dword cbpy = bs->GetCbpy(intra);            //DPRINTF(XVID_DEBUG_MB, "cbpy %i mcsel %i \n", cbpy,mcsel);            dword cbp = (cbpy << 2) | cbpc;            if(mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q){               int dquant = dquant_table[bs->GetBits(2)];               DPRINTF(XVID_DEBUG_MB, "dquant %i\n", dquant);               quant += dquant;               if (quant > 31) {                  quant = 31;               } else if (quant < 1) {                  quant = 1;               }               DPRINTF(XVID_DEBUG_MB, "quant %i\n", quant);            }            mb->quant = quant;            if(interlacing){               if((cbp || intra) && !mcsel){                  mb->field_dct = bs->GetBit();                  DPRINTF(XVID_DEBUG_MB,"decp: field_dct: %i\n", mb->field_dct);               }               if(mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q){                  mb->field_pred = bs->GetBit();                  DPRINTF(XVID_DEBUG_MB, "decp: field_pred: %i\n", mb->field_pred);                  if(mb->field_pred){                     mb->field_for_top = bs->GetBit();                     DPRINTF(XVID_DEBUG_MB,"decp: field_for_top: %i\n", mb->field_for_top);                     mb->field_for_bot = bs->GetBit();                     DPRINTF(XVID_DEBUG_MB,"decp: field_for_bot: %i\n", mb->field_for_bot);                  }               }            }            if(mcsel){               mbgmc(mb, x, y, fcode, cbp, bs, rounding);               PROF_E(PROF_0);               continue;            }else            if(mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q){               if(interlacing && mb->field_pred){                  GetMotionVector(bs, x, y, 0, &mb->mvs[0], fcode, bound);                  GetMotionVector(bs, x, y, 0, &mb->mvs[1], fcode, bound);               }else{                  GetMotionVector(bs, x, y, 0, &mb->mvs[0], fcode, bound);                  mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = mb->mvs[0];               }            }else            if(mb->mode == MODE_INTER4V){               GetMotionVector(bs, x, y, 0, &mb->mvs[0], fcode, bound);               GetMotionVector(bs, x, y, 1, &mb->mvs[1], fcode, bound);               GetMotionVector(bs, x, y, 2, &mb->mvs[2], fcode, bound);               GetMotionVector(bs, x, y, 3, &mb->mvs[3], fcode, bound);            }else{    /* MODE_INTRA, MODE_INTRA_Q */               mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;               mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;               MBIntra(mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold, bound, reduced_resolution);               continue;            }            PROF_S(PROF_5);            DecodeInterMacroBlock(mb, x, y, cbp, bs, rounding, reduced_resolution, 0);            PROF_E(PROF_5);         }else         if(gmc_warp){                              //a not coded S(GMC)-VOP macroblock            mb->mode = MODE_NOT_CODED_GMC;            mbgmc(mb, x, y, fcode, 0x00, bs, rounding);            /*#ifdef XVID_CSP_SLICE            if(out_frm && cp_mb > 0) {               output_slice(&cur, edged_width,width,out_frm,st_mb,y,cp_mb);               cp_mb = 0;            }            st_mb = x+1;#endif            */         }else{                              //not coded P_VOP macroblock            mb->mode = MODE_NOT_CODED;            mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;            mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;            DecodeInterMacroBlock(mb, x, y, 0, bs, rounding, reduced_resolution, 0);            /*#ifdef XVID_CSP_SLICE            if(out_frm && cp_mb > 0) {               output_slice(&cur, edged_width,width,out_frm,st_mb,y,cp_mb);               cp_mb = 0;            }            st_mb = x+1;#endif            */         }      }      /*#ifdef XVID_CSP_SLICE      if(out_frm && cp_mb > 0)         output_slice(&cur, edged_width,width,out_frm,st_mb,y,cp_mb);#endif         */   }   PROF_E(PROF_FRM_P);}//----------------------------/* decode B-frame motion vector */static void get_b_motion_vector(Bitstream * bs, VECTOR * mv, int fcode, const VECTOR pmv){   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);   int mv_x = bs->GetMoveVector(fcode);   int mv_y = bs->GetMoveVector(fcode);   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;   mv->x = mv_x;   mv->y = mv_y;}//----------------------------/* decode an B-frame direct & interpolate macroblock */void S_decoder::BFrameInterpolateMBInter(const IMAGE &forward, const IMAGE &backward, const MACROBLOCK *pMB, dword x_pos, dword y_pos, Bitstream *bs, int direct){   PROF_S(PROF_BINT_MBI);   dword stride = edged_width;   dword stride2 = stride / 2;   int uv_dx, uv_dy;   int b_uv_dx, b_uv_dy;   byte *pY_Cur, *pU_Cur, *pV_Cur;   const dword cbp = pMB->cbp;   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);   if(!direct){      uv_dx = pMB->mvs[0].x;      uv_dy = pMB->mvs[0].y;      b_uv_dx = pMB->b_mvs[0].x;      b_uv_dy = pMB->b_mvs[0].y;      if(quarterpel){         uv_dx /= 2;         uv_dy /= 2;         b_uv_dx /= 2;         b_uv_dy /= 2;      }      uv_dx = (uv_dx >> 1) + roundtab_79[uv_dx & 0x3];      uv_dy = (uv_dy >> 1) + roundtab_79[uv_dy & 0x3];      b_uv_dx = (b_uv_dx >> 1) + roundtab_79[b_uv_dx & 0x3];      b_uv_dy = (b_uv_dy >> 1) + roundtab_79[b_uv_dy & 0x3];   }else{      if(quarterpel) {         uv_dx = (pMB->mvs[0].x / 2) + (pMB->mvs[1].x / 2) + (pMB->mvs[2].x / 2) + (pMB->mvs[3].x / 2);         uv_dy = (pMB->mvs[0].y / 2) + (pMB->mvs[1].y / 2) + (pMB->mvs[2].y / 2) + (pMB->mvs[3].y / 2);         b_uv_dx = (pMB->b_mvs[0].x / 2) + (pMB->b_mvs[1].x / 2) + (pMB->b_mvs[2].x / 2) + (pMB->b_mvs[3].x / 2);         b_uv_dy = (pMB->b_mvs[0].y / 2) + (pMB->b_mvs[1].y / 2) + (pMB->b_mvs[2].y / 2) + (pMB->b_mvs[3].y / 2);      } else {         uv_dx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;         uv_dy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;         b_uv_dx = pMB->b_mvs[0].x + pMB->b_mvs[1].x + pMB->b_mvs[2].x + pMB->b_mvs[3].x;         b_uv_dy = pMB->b_mvs[0].y + pMB->b_mvs[1].y + pMB->b_mvs[2].y + pMB->b_mvs[3].y;      }      uv_dx = (uv_dx >> 3) + roundtab_76[uv_dx & 0xf];      uv_dy = (uv_dy >> 3) + roundtab_76[uv_dy & 0xf];      b_uv_dx = (b_uv_dx >> 3) + roundtab_76[b_uv_dx & 0xf];      b_uv_dy = (b_uv_dy >> 3) + roundtab_76[b_uv_dy & 0xf];   }   if(quarterpel){      if(!direct){         interpolate16x16_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);      }else{         interpolate8x8_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);         interpolate8x8_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos, pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);         interpolate8x8_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);         interpolate8x8_quarterpel(cur.y, forward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);      }   }else{      interpolate8x8_switch(cur.y, forward.y, 16 * x_pos, 16 * y_pos, pMB->mvs[0].x, pMB->mvs[0].y, stride, 0);      interpolate8x8_switch(cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos, pMB->mvs[1].x, pMB->mvs[1].y, stride, 0);      interpolate8x8_switch(cur.y, forward.y, 16 * x_pos, 16 * y_pos + 8, pMB->mvs[2].x, pMB->mvs[2].y, stride, 0);      interpolate8x8_switch(cur.y, forward.y, 16 * x_pos + 8, 16 * y_pos + 8, pMB->mvs[3].x, pMB->mvs[3].y, stride, 0);   }   interpolate8x8_switch(cur.u, forward.u, 8 * x_pos, 8 * y_pos, uv_dx, uv_dy, stride2, 0);   interpolate8x8_switch(cur.v, forward.v, 8 * x_pos, 8 * y_pos, uv_dx, uv_dy, stride2, 0);   if(quarterpel){      if(!direct){         interpolate16x16_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);      }else{         interpolate8x8_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos, pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);         interpolate8x8_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);         interpolate8x8_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos, 16*y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);         interpolate8x8_quarterpel(tmp.y, backward.y, qtmp.y, qtmp.y + 64, qtmp.y + 128, 16*x_pos + 8, 16*y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);      }   }else{      interpolate8x8_switch(tmp.y, backward.y, 16 * x_pos, 16 * y_pos, pMB->b_mvs[0].x, pMB->b_mvs[0].y, stride, 0);      interpolate8x8_switch(tmp.y, backward.y, 16 * x_pos + 8, 16 * y_pos, pMB->b_mvs[1].x, pMB->b_mvs[1].y, stride, 0);      interpolate8x8_switch(tmp.y, backward.y, 16 * x_pos, 16 * y_pos + 8, pMB->b_mvs[2].x, pMB->b_mvs[2].y, stride, 0);      interpolate8x8_switch(tmp.y, backward.y, 16 * x_pos + 8, 16 * y_pos + 8, pMB->b_mvs[3].x, pMB->b_mvs[3].y, stride, 0);   }   interpolate8x8_switch(tmp.u, backward.u, 8 * x_pos, 8 * y_pos, b_uv_dx, b_uv_dy, stride2, 0);   interpolate8x8_switch(tmp.v, backward.v, 8 * x_pos, 8 * y_pos, b_uv_dx, b_uv_dy, stride2, 0);   interpolate8x8_avg2(cur.y + (16 * y_pos * stride) + 16 * x_pos, cur.y + (16 * y_pos * stride) + 16 * x_pos,      tmp.y + (16 * y_pos * stride) + 16 * x_pos, stride, 1, 8);   interpolate8x8_avg2(cur.y + (16 * y_pos * stride) + 16 * x_pos + 8, cur.y + (16 * y_pos * stride) + 16 * x_pos + 8,      tmp.y + (16 * y_pos * stride) + 16 * x_pos + 8, stride, 1, 8);   interpolate8x8_avg2(cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos, cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos,      tmp.y + ((16 * y_pos + 8) * stride) + 16 * x_pos, stride, 1, 8);   interpolate8x8_avg2(cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8, cur.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8,      tmp.y + ((16 * y_pos + 8) * stride) + 16 * x_pos + 8, stride, 1, 8);   interpolate8x8_avg2(cur.u + (8 * y_pos * stride2) + 8 * x_pos, cur.u + (8 * y_pos * stride2) + 8 * x_pos,      tmp.u + (8 * y_pos * stride2) + 8 * x_pos, stride2, 1, 8);   interpolate8x8_avg2(cur.v + (8 * y_pos * stride2) + 8 * x_pos, cur.v + (8 * y_pos * stride2) + 8 * x_pos,      tmp.v + (8 * y_pos * stride2) + 8 * x_pos, stride2, 1, 8);   if(cbp)      mb_decode(cbp, bs, pY_Cur, pU_Cur, pV_Cur, 0, pMB);   PROF_E(PROF_BINT_MBI);}//----------------------------/* for decode B-frame dbquant */static int get_dbquant(Bitstream * bs){   if (!bs->GetBit())     /*  '0' */      return (0);   else if (!bs->GetBit())   /* '10' */      return (-2);   else                    /* '11' */      return (2);}//----------------------------/* * decode B-frame mb_type * bit      ret_value * 1     0 * 01    1 * 001      2 * 0001     3 */static int get_mbtype(Bitstream * bs){   int mb_type;   for (mb_type = 0; mb_type <= 3; mb_type++)      if (bs->GetBit())         return (mb_type);   return -1;}//----------------------------void S_decoder::B_Frame(Bitstream *bs, int quant, int fcode_forward, int fcode_backward){   dword x, y;   VECTOR mv;   const VECTOR zeromv = {0,0};   const int64_t TRB = time_pp - time_bp, TRD = time_pp;   int i;   PROF_S(PROF_FRM_B);   SetEdges(refn[0]);   SetEdges(refn[1]);   for(y = 0; y < mb_height; y++){                              //initialize Pred Motion Vector      p_fmv = p_bmv = zeromv;      for(x = 0; x < mb_width; x++){         MACROBLOCK *mb = &mbs[y * mb_width + x];         MACROBLOCK *last_mb = &last_mbs[y * mb_width + x];         const int fcode_max = (fcode_forward>fcode_backward) ? fcode_forward : fcode_backward;

⌨️ 快捷键说明

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