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

📄 macroblock.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
          if (nonzero)          {            currMB->cbp_blk |= 1 << cbp_blk_mask ;            // one bit for every 4x4 block            currMB->cbp     |= cbp_mask;       // one bit for the 4x4 blocks of an 8x8 block          }        }      }      /*      The purpose of the action below is to prevent that single or 'expensive' coefficients are coded.      With 4x4 transform there is larger chance that a single coefficient in a 8x8 or 16x16 block may be nonzero.      A single small (level=1) coefficient in a 8x8 block will cost: 3 or more bits for the coefficient,      4 bits for EOBs for the 4x4 blocks,possibly also more bits for CBP.  Hence the total 'cost' of that single      coefficient will typically be 10-12 bits which in a RD consideration is too much to justify the distortion improvement.      The action below is to watch such 'single' coefficients and set the reconstructed block equal to the prediction according      to a given criterium.  The action is taken only for inter luma blocks.        Notice that this is a pure encoder issue and hence does not have any implication on the standard.        coeff_cost is a parameter set in dct_luma() and accumulated for each 8x8 block.  If level=1 for a coefficient,        coeff_cost is increased by a number depending on RUN for that coefficient.The numbers are (see also dct_luma()): 3,2,2,1,1,1,0,0,...        when RUN equals 0,1,2,3,4,5,6, etc.        If level >1 coeff_cost is increased by 9 (or any number above 3). The threshold is set to 3. This means for example:        1: If there is one coefficient with (RUN,level)=(0,1) in a 8x8 block this coefficient is discarded.        2: If there are two coefficients with (RUN,level)=(1,1) and (4,1) the coefficients are also discarded        sum_cnt_nonz is the accumulation of coeff_cost over a whole macro block.  If sum_cnt_nonz is 5 or less for the whole MB,        all nonzero coefficients are discarded for the MB and the reconstructed block is set equal to the prediction.      */      if (coeff_cost > 3)      {        sum_cnt_nonz += coeff_cost;      }      else //discard      {        currMB->cbp     &=  (63  -  cbp_mask ) ;        currMB->cbp_blk &= ~(51 << (mb_y + (mb_x>>2) )) ;        for (i=mb_x; i < mb_x+BLOCK_SIZE*2; i++)        {          for (j=mb_y; j < mb_y+BLOCK_SIZE*2; j++)          {            imgY[img->pix_y+j][img->pix_x+i]=img->mpr[i][j];          }        }        if (img->types==SP_IMG)          for (i=mb_x; i < mb_x+BLOCK_SIZE*2; i+=BLOCK_SIZE)            for (j=mb_y; j < mb_y+BLOCK_SIZE*2; j+=BLOCK_SIZE)              copyblock_sp(i,j);      }    }  }  if (sum_cnt_nonz <= 5 )  {     currMB->cbp     &= 0xfffff0 ;     currMB->cbp_blk &= 0xff0000 ;     for (i=0; i < MB_BLOCK_SIZE; i++)     {       for (j=0; j < MB_BLOCK_SIZE; j++)       {         imgY[img->pix_y+j][img->pix_x+i]=img->mpr[i][j];       }     }     if (img->types==SP_IMG)       for (i=0; i < MB_BLOCK_SIZE; i+=BLOCK_SIZE)         for (j=0; j < MB_BLOCK_SIZE; j+=BLOCK_SIZE)           copyblock_sp(i,j);   }}/*! ************************************************************************ * \brief *    Performs DCT, quantization, run/level pre-coding and IDCT *    for the chrominance of a I- of P-frame macroblock; *    current cbp and cr_cbp are affected ************************************************************************ */void ChromaCoding_P(int *cr_cbp){  int i, j;  int uv, ii,jj,ii0,jj0,ii1,jj1,if1,jf1,if0,jf0,f1,f2,f3,f4;  int pic_block_y, pic_block_x;  Macroblock *currMB = &img->mb_data[img->current_mb_nr];  if(input->mv_res)  {    f1=16;    f2=15;  }  else  {    f1=8;    f2=7;  }  f3=f1*f1;  f4=f3/2;  *cr_cbp=0;  for (uv=0; uv < 2; uv++)  {    if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)    {      intrapred_chroma(img->pix_c_x,img->pix_c_y,uv);    }    else    {      for (j=0; j < MB_BLOCK_SIZE/2; j++)      {        pic_block_y=(img->pix_c_y+j)/2;        for (i=0; i < MB_BLOCK_SIZE/2; i++)        {          pic_block_x=(img->pix_c_x+i)/2;          ii=(img->pix_c_x+i)*f1+tmp_mv[0][pic_block_y][pic_block_x+4];          jj=(img->pix_c_y+j)*f1+tmp_mv[1][pic_block_y][pic_block_x+4];          ii0 = max (0, min (img->width_cr-1,ii/f1));          jj0 = max (0, min (img->height_cr-1,jj/f1));          ii1 = max (0, min (img->width_cr-1,(ii+f2)/f1));          jj1 = max (0, min (img->height_cr-1,(jj+f2)/f1));          if1=(ii & f2);          jf1=(jj & f2);          if0=f1-if1;          jf0=f1-jf1;          img->mpr[i][j]=(if0*jf0*mcef[img->multframe_no][uv][jj0][ii0]+            if1*jf0*mcef[img->multframe_no][uv][jj0][ii1]+            if0*jf1*mcef[img->multframe_no][uv][jj1][ii0]+            if1*jf1*mcef[img->multframe_no][uv][jj1][ii1]+f4)/f3;          img->m7[i][j]=imgUV_org[uv][img->pix_c_y+j][img->pix_c_x+i]-img->mpr[i][j];        }      }    }    if (img->types!=SP_IMG || (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW) )      *cr_cbp=dct_chroma(uv,*cr_cbp);    else *cr_cbp=dct_chroma_sp(uv,*cr_cbp);  }  currMB->cbp += *cr_cbp*16;}/*! ************************************************************************ * \brief *    Set reference frame information in global arrays *    depending on mode decision. Used for motion vector prediction. ************************************************************************ */void SetRefFrameInfo_P(){  int i,j;  if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)  {    // Set the reference frame information for motion vector prediction as unavailable    for (j = 0;j < BLOCK_MULTIPLE;j++)    {      for (i = 0;i < BLOCK_MULTIPLE;i++)      {        refFrArr[img->block_y+j][img->block_x+i] = -1;      }    }  }  else  {    // Set the reference frame information for motion vector prediction    for (j = 0;j < BLOCK_MULTIPLE;j++)    {      for (i = 0;i < BLOCK_MULTIPLE;i++)      {        refFrArr[img->block_y+j][img->block_x+i] =  img->mb_data[img->current_mb_nr].ref_frame;      }    }  }}/*! ************************************************************************ * \brief *    Encode one macroblock depending on chosen picture type ************************************************************************ */void encode_one_macroblock(){  int cr_cbp;             // chroma coded block pattern  int tot_intra_sad;  int intra_pred_mode_2;  // best 16x16 intra mode  if (input->rdopt)  {    RD_Mode_Decision ();  }  else  {    Macroblock *currMB = &img->mb_data[img->current_mb_nr];    tot_intra_sad = MakeIntraPrediction(&intra_pred_mode_2);     // Intra Prediction    if (img->type != B_IMG)         // I- or P-frame    {      if ((img->mb_y == img->mb_y_upd && img->mb_y_upd != img->mb_y_intra) || img->type == INTRA_IMG)      {        img->mb_mode=8*img->type+img->imod;  // Intra mode: set if intra image or if intra GOB for error robustness      }      else      {        currMB->ref_frame = motion_search(tot_intra_sad);      // P-frames MV-search      }    }    else                          // B-frame      currMB->ref_frame = motion_search_Bframe(tot_intra_sad); // B-frames MV-search    if (img->type == B_IMG)         // B-frame    {      LumaResidualCoding_B(img);           // Residual coding of Luma (B-modes only)      ChromaCoding_B(&cr_cbp);                              // Coding of Chrominance      SetRefFrameInfo_B();     // Set ref-frame info for mv-prediction of future MBs    }    else                  // I- or P-frame    {      if (currMB->intraOrInter == INTER_MB)        LumaResidualCoding_P();    // Residual coding of Luma (only for inter modes)      // Coding of Luma in intra mode is done implicitly in MakeIntraPredicition      ChromaCoding_P(&cr_cbp);                              // Coding of Chrominance      // Set reference frame information for motion vector prediction of future MBs      SetRefFrameInfo_P();      //  Check if a MB is skipped (no coeffs. only 0-vectors and prediction from the most recent frame)      if(   (currMB->ref_frame                      == 0) && (currMB->intraOrInter == INTER_MB)        && (tmp_mv[0][img->block_y][img->block_x+4]== 0) && (img->mb_mode         == M16x16_MB)        && (tmp_mv[1][img->block_y][img->block_x+4]== 0) && (currMB->cbp          == 0) )        img->mb_mode=COPY_MB;    }    currMB->qp = img->qp; // this should (or has to be) done somewere else. where?    DeblockMb(img, imgY, imgUV) ; // Deblock this MB ( pixels to the right and above are affected)    if (img->imod==INTRA_MB_NEW)        // Set 16x16 intra mode and make "intra CBP"    {      img->mb_mode += intra_pred_mode_2 + 4*cr_cbp + 12*img->kac;      currMB->cbp += 15*img->kac; //GB    }    if ((((img->type == INTER_IMG)||(img->types==SP_IMG))  && ((img->imod==INTRA_MB_NEW) || (img->imod==INTRA_MB_OLD)))      || (img->type == B_IMG && (img->imod==B_Backward || img->imod==B_Direct || img->imod==INTRA_MB_NEW || img->imod==INTRA_MB_OLD)))// gb b-frames too      currMB->ref_frame = 0;  }}/*! ************************************************************************ * \brief *    Passes the chosen syntax elements to the NAL ************************************************************************ */void write_one_macroblock(){  int i;  int mb_nr = img->current_mb_nr;  SyntaxElement *currSE = img->MB_SyntaxElements;  Macroblock *currMB = &img->mb_data[mb_nr];  int *bitCount = currMB->bitcounter;  Slice *currSlice = img->currentSlice;  DataPartition *dataPart;  int *partMap = assignSE2partition[input->partition_mode];  // Store imod for further use  currMB->mb_imode = img->imod;  // Store mb_mode for further use  currMB->mb_type = (currSE->value1 = img->mb_mode);  // choose the appropriate data partition  if (img->type == B_IMG)    dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);  else    dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);  //  Bits for mode  if(img->type == INTRA_IMG || img->types == SP_IMG || input->symbol_mode == CABAC)  {    if (input->symbol_mode == UVLC)      currSE->mapping = n_linfo2;    else      currSE->writing = writeMB_typeInfo2Buffer_CABAC;    currSE->type = SE_MBTYPE;#if TRACE    if (img->type == B_IMG)      snprintf(currSE->tracestring, TRACESTRING_SIZE, "B_MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y, img->mb_mode);    else      snprintf(currSE->tracestring, TRACESTRING_SIZE, "MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y,img->mb_mode);#endif    dataPart->writeSyntaxElement( currSE, dataPart);    bitCount[BITS_MB_MODE]+=currSE->len;    currSE++;    currMB->currSEnr++;  }  else  {    if (img->mb_mode != COPY_MB || currMB->intraOrInter != INTER_MB || (img->type == B_IMG && currMB->cbp != 0))  {      // Macroblock is coded, put out run and mbmode      currSE->value1 = img->cod_counter;      currSE->mapping = n_linfo2;      currSE->type = SE_MBTYPE;#if TRACE      snprintf(currSE->tracestring, TRACESTRING_SIZE, "MB runlength = %3d",img->cod_counter);#endif      dataPart->writeSyntaxElement( currSE, dataPart);      bitCount[BITS_MB_MODE]+=currSE->len;      currSE++;      currMB->currSEnr++;    // Reset cod counter      img->cod_counter = 0;      // Put out mb mode      currSE->value1 = img->mb_mode;      if(img->type != B_IMG)        currSE->value1--;      currSE->mapping = n_linfo2;      currSE->type = SE_MBTYPE;#if TRACE      if (img->type == B_IMG)        snprintf(currSE->tracestring, TRACESTRING_SIZE, "B_MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y, img->mb_mode);      else        snprintf(currSE->tracestring, TRACESTRING_SIZE, "MB mode(%2d,%2d) = %3d",img->mb_x, img->mb_y,img->mb_mode);#endif      dataPart->writeSyntaxElement( currSE, dataPart);      bitCount[BITS_MB_MODE]+=currSE->len;      currSE++;      currMB->currSEnr++;    }  else  {      // Macroblock is skipped, increase cod_counter      img->cod_counter++;      if(img->current_mb_nr == img->total_number_mb)      {        // Put out run        currSE->value1 = img->cod_counter;        currSE->mapping = n_linfo2;        currSE->type = SE_MBTYPE;#if TRACE        snprintf(currSE->tracestring, TRACESTRING_SIZE, "MB runlength = %3d",img->cod_counter);#endif        dataPart->writeSyntaxElement( currSE, dataPart);        bitCount[BITS_MB_MODE]+=currSE->len;        currSE++;        currMB->currSEnr++;        // Reset cod counter        img->cod_counter = 0;      }    }  }  if(input->UseConstrainedIntraPred)  {    if (img->type==INTER_IMG && img->types != SP_IMG)      if(currMB->intraOrInter == INTER_MB)        img->intra_mb[img->current_mb_nr] = 0;  }  //  Do nothing more if copy and inter mode  if (img->mb_mode != COPY_MB || currMB->intraOrInter != INTER_MB ||     (img->type == B_IMG && input->symbol_mode == CABAC) ||     (img->type == B_IMG && input->symbol_mode == UVLC &&  currMB->cbp != 0))  {    //  Bits for intra prediction modes    if (img->imod == INTRA_MB_OLD)    {      for (i=0; i < MB_BLOCK_SIZE/2; i++)      {        currSE->value1 = currMB->intra_pred_modes[2*i];        currSE->value2 = currMB->intra_pred_modes[2*i+1];        if (input->symbol_mode == UVLC)          currSE->mapping = intrapred_linfo;        else          currSE->writing = writeIntraPredMode2Buffer_CABAC;        currSE->type = SE_INTRAPREDMODE;        // choose the appropriate data partition        if (img->type != B_IMG)        {#if TRACE          snprintf(currSE->tracestring, TRACESTRING_SIZE, "Intra mode     = %3d",IPRED_ORDER[currSE->value1][currSE->value2]);#endif          dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);

⌨️ 快捷键说明

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