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

📄 macroblock.c

📁 包含了从MPEG4的视频解码到H.264的视频编码部分的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      currStream->bits_to_go = currStream->stored_bits_to_go;
      currStream->byte_pos  = currStream->stored_byte_pos;
      currStream->byte_buf  = currStream->stored_byte_buf;
      if (input->symbol_mode == CABAC)
      {
        eep = &(dataPart->ee_cabac);
        eep->Elow            = eep->ElowS;
        eep->Erange           = eep->ErangeS;
        eep->Ebuffer         = eep->EbufferS;
        eep->Ebits_to_go     = eep->Ebits_to_goS;
        eep->Ebits_to_follow = eep->Ebits_to_followS;
        eep->Ecodestrm       = eep->EcodestrmS;
        eep->Ecodestrm_len   = eep->Ecodestrm_lenS;
        eep->C               = eep->CS;
        eep->B               = eep->BS;
        eep->E               = eep->ES;       
      }
    }
  }

  if(*end_of_slice == TRUE  && skip == TRUE) //! TO 4.11.2001 Skip MBs at the end of this slice
  { 
    //! only for Slice Mode 2 or 3
    // If we still have to write the skip, let's do it!
    if(img->cod_counter && *recode_macroblock == TRUE) //! MB that did not fit in this slice
    { 
      // If recoding is true and we have had skip, 
      // we have to reduce the counter in case of recoding
      img->cod_counter--;
      if(img->cod_counter)
      {
        currSE->value1 = img->cod_counter;
        currSE->mapping = ue_linfo;
        currSE->type = SE_MBTYPE;
        if (img->type != B_IMG && img->type != BS_IMG)   dataPart = &(currSlice->partArr[partMap[currSE->type]]);
        else                                             dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
        dataPart->writeSyntaxElement(  currSE, dataPart);
        rlc_bits=currSE->len;
        currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
        img->cod_counter = 0;
      }
    }
    else //! MB that did not fit in this slice anymore is not a Skip MB
    {
      if (img->type != B_IMG && img->type != BS_IMG)   dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
      else                                             dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
       
      currStream = dataPart->bitstream;
        // update the bitstream
      currStream->bits_to_go = currStream->bits_to_go_skip;
      currStream->byte_pos  = currStream->byte_pos_skip;
      currStream->byte_buf  = currStream->byte_buf_skip;

      // update the statistics
      img->cod_counter = 0;
      skip = FALSE;
    }
  }
  
  //! TO 4.11.2001 Skip MBs at the end of this slice for Slice Mode 0 or 1
  if(*end_of_slice == TRUE && img->cod_counter && !use_bitstream_backing)
  {
    currSE->value1 = img->cod_counter;
    currSE->mapping = ue_linfo;
    currSE->type = SE_MBTYPE;
    if (img->type != B_IMG && img->type != BS_IMG)   dataPart = &(currSlice->partArr[partMap[currSE->type]]);
    else                                             dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
    dataPart->writeSyntaxElement(  currSE, dataPart);
    rlc_bits=currSE->len;
    currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
    img->cod_counter = 0;
  }
}

/*!
 *****************************************************************************
 *
 * \brief 
 *    For Slice Mode 2: Checks if one partition of one slice exceeds the 
 *    allowed size
 * 
 * \return
 *    FALSE if all Partitions of this slice are smaller than the allowed size
 *    TRUE is at least one Partition exceeds the limit
 *
 * \para Parameters
 *    
 *    
 *
 * \para Side effects
 *    none
 *
 * \para Other Notes
 *    
 *    
 *
 * \date
 *    4 November 2001
 *
 * \author
 *    Tobias Oelbaum      drehvial@gmx.net
 *****************************************************************************/
 
 int slice_too_big(int rlc_bits)
 {
   Slice *currSlice = img->currentSlice;
   DataPartition *dataPart;
   Bitstream *currStream;
   EncodingEnvironmentPtr eep;
   int i;
   int size_in_bytes;
  
   //! UVLC
   if (input->symbol_mode == UVLC)
   {
     for (i=0; i<currSlice->max_part_nr; i++)
     {
       dataPart = &(currSlice->partArr[i]);
       currStream = dataPart->bitstream;
       size_in_bytes = currStream->byte_pos /*- currStream->tmp_byte_pos*/;

       if (currStream->bits_to_go < 8)
         size_in_bytes++;
       if (currStream->bits_to_go < rlc_bits)
         size_in_bytes++;
       if(size_in_bytes > input->slice_argument)
         return TRUE;
     }
   }
    
   //! CABAC
   if (input->symbol_mode ==CABAC)
   {
     for (i=0; i<currSlice->max_part_nr; i++)
     {
        dataPart= &(currSlice->partArr[i]);
        eep = &(dataPart->ee_cabac);
      
       if( arienco_bits_written(eep) > (input->slice_argument*8))
          return TRUE;
     }
   }
   return FALSE;
 }
/*!
 ************************************************************************
 * \brief
 *    Checks the availability of neighboring macroblocks of
 *    the current macroblock for prediction and context determination;
 *    marks the unavailable MBs for intra prediction in the
 *    ipredmode-array by -1. Only neighboring MBs in the causal
 *    past of the current MB are checked.
 ************************************************************************
 */
void CheckAvailabilityOfNeighbors()
{
  int i,j;
  const int mb_width = img->width/MB_BLOCK_SIZE;
  const int mb_nr = img->current_mb_nr;
  Macroblock *currMB = &img->mb_data[mb_nr];
  int   pix_y   = img->pix_y;   // For MB level Frame/field coding
  int   block_y = img->block_y;   // For MB level Frame/field coding
  
  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
  {
    pix_y = img->field_pix_y;
    block_y = img->field_block_y;
  }

  // mark all neighbors as unavailable
  for (i=0; i<3; i++)
    for (j=0; j<3; j++)
    {
      img->mb_data[mb_nr].mb_available[i][j]=NULL;
    }

  img->mb_data[mb_nr].mb_available[1][1]=currMB; // current MB
  

  // Check MB to the left
  if(img->pix_x >= MB_BLOCK_SIZE)
  {
    int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-1].slice_nr;
    // upper blocks
    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-1][1]==0))
    {
      img->ipredmode[img->block_x][img->block_y+1] = -1;
      img->ipredmode[img->block_x][img->block_y+2] = -1;
      if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)  // GB
      {
        if(img->top_field)
        {
          img->ipredmode_top[img->block_x][block_y+1] = -1;
          img->ipredmode_top[img->block_x][block_y+2] = -1;
        }
        else
        {
          img->ipredmode_bot[img->block_x][block_y+1] = -1;
          img->ipredmode_bot[img->block_x][block_y+2] = -1;
        }
      }
    }
    // lower blocks
    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-1][3]==0))
    {
      img->ipredmode[img->block_x][img->block_y+3] = -1;
      img->ipredmode[img->block_x][img->block_y+4] = -1;
      if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) //GB
      {
        if(img->top_field)
        {
          img->ipredmode_top[img->block_x][block_y+3] = -1;
          img->ipredmode_top[img->block_x][block_y+4] = -1;
        }
        else
        {
          img->ipredmode_bot[img->block_x][block_y+3] = -1;
          img->ipredmode_bot[img->block_x][block_y+4] = -1;
        }
      }
    }
    if (!remove_prediction)
    {
      currMB->mb_available[1][0]=&(img->mb_data[mb_nr-1]);
    }
  }

  // Check MB above
  if(pix_y >= MB_BLOCK_SIZE) // wrong for MBAFF
  //if(img->pix_y >= MB_BLOCK_SIZE)
  {
    int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width].slice_nr;
    // upper blocks
    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-mb_width][2]==0))
    {
      img->ipredmode[img->block_x+1][img->block_y] = -1;
      img->ipredmode[img->block_x+2][img->block_y] = -1;
      if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) //GB 
      {
        if(img->top_field)
        {
          img->ipredmode_top[img->block_x+1][block_y] = -1;
          img->ipredmode_top[img->block_x+2][block_y] = -1;
        }
        else
        {
          img->ipredmode_bot[img->block_x+1][block_y] = -1;
          img->ipredmode_bot[img->block_x+2][block_y] = -1;
        }
      }
    }
    // lower blocks
    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-mb_width][3]==0))
    {
      img->ipredmode[img->block_x+3][img->block_y] = -1;
      img->ipredmode[img->block_x+4][img->block_y] = -1;
      if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) //GB
      {
        if(img->top_field)
        {
          img->ipredmode_top[img->block_x+3][block_y] = -1;
          img->ipredmode_top[img->block_x+4][block_y] = -1;
        }
        else
        {
          img->ipredmode_bot[img->block_x+3][block_y] = -1;
          img->ipredmode_bot[img->block_x+4][block_y] = -1;
        } 
      }
    }
    if (!remove_prediction)
    {
      currMB->mb_available[0][1]=&(img->mb_data[mb_nr-mb_width]);
    }
  }

  // Check MB left above
  if(img->pix_x >= MB_BLOCK_SIZE && img->pix_y >= MB_BLOCK_SIZE )
  {
    int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width-1].slice_nr;

    if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-mb_width-1][3]==0))
    {
      img->ipredmode[img->block_x][img->block_y] = -1;
      if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) //GB 
      {
        if(img->top_field)
        {
          img->ipredmode_top[img->block_x][block_y] = -1;
        }
        else
        {
          img->ipredmode_bot[img->block_x][block_y] = -1;
        }
      }
    }
    if (!remove_prediction)
    {
      currMB->mb_available[0][0]=&(img->mb_data[mb_nr-mb_width-1]);
    }
  }

  // Check MB right above
  if(pix_y >= MB_BLOCK_SIZE && img->pix_x < (img->width-MB_BLOCK_SIZE ))
  {
    if(currMB->slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr)
      currMB->mb_available[0][2]=&(img->mb_data[mb_nr-mb_width+1]);
  }

  if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive)
    currMB->mb_available[0][2] = NULL;  // set the prediction from top right MB to zero 

}


void CheckAvailabilityOfNeighborsForAff()
{
  const int mb_width = img->width/MB_BLOCK_SIZE;
  const int mb_nr = img->current_mb_nr;
  Macroblock *currMB = &img->mb_data[mb_nr];
  
  // Check Field to the left
  if ((img->pix_x >= MB_BLOCK_SIZE) && (currMB->slice_nr == img->mb_data[mb_nr-1].slice_nr))
    currMB->field_available[1]=&(img->mb_data[mb_nr-1]);
  else
    currMB->field_available[1]=NULL;
  
  // Check Field above
  if ((img->pix_y >= 2*MB_BLOCK_SIZE) && (currMB->slice_nr == img->mb_data[mb_nr-mb_width*2].slice_nr))
    currMB->field_available[0]=&(img->mb_data[mb_nr-mb_width*2]);
  else
    currMB->field_available[0]=NULL;

}



/*!
 ************************************************************************
 * \brief
 *    Predict one component of a 4x4 Luma block
 ************************************************************************
 */
void
OneComponentLumaPrediction4x4 (byte*   mpred,      //  --> array of prediction values (row by row)
                               int    pic_pix_x,  // <--  absolute horizontal coordinate of 4x4 block
                               int    pic_pix_y,  // <--  absolute vertical   coordinate of 4x4 block
                               int*   mv,         // <--  motion vector
                               int    ref)        // <--  reference frame (0.. / -1:backward)
{
  int incr;
  pel_t** ref_pic;

  int     pix_add = 4;
  int     j0      = (pic_pix_y << 2) + mv[1], j1=j0+pix_add, j2=j1+pix_add, j3=j2+pix_add;
  int     i0      = (pic_pix_x << 2) + mv[0], i1=i0+pix_add, i2=i1+pix_add, i3=i2+pix_add;
  int     left=-(IMG_PAD_SIZE<<2),right=(img->width)<<2,top=-(IMG_PAD_SIZE<<2),bottom=(img->height)<<2;
  pel_t (*get_pel) (pel_t**, int, int) = UMVPelY_14;

  // Tian Dong: PLUS1, June 06, 2002
  incr      = 0 ;
  
 
  ref_pic   = img->type==B_IMG? mref [ref+1+incr] : mref [ref];
  if(j0<bottom&&j0>top&&i0>left&&i0<right)
  {
	  pel_t *pt=&(ref_pic[j0+(IMG_PAD_SIZE<<2)][i0+(IMG_PAD_SIZE<<2)]);
	  int w=(img->width+2*IMG_PAD_SIZE)<<2;
	  _asm
	  {
		  mov edi,mpred
		  mov esi,pt
		  mov eax,w
		  shl eax,2
		  movdqu xmm0,[esi]
		  add esi,eax
		  movdqu xmm1,[esi]
		  add esi,eax
		  movdqu xmm2,[esi]
		  add esi,eax
		  movdqu xmm3,[esi]
		  pslld xmm0,24		  
		  pslld xmm1,24
		  pslld xmm2,24
		  pslld xmm3,24
		  psrld xmm0,24		  
		  psrld xmm1,24
		  psrld xmm2,24
		  psrld xmm3,24
		  pxor xmm7,xmm7
		  PACKSSDW xmm0,xmm7		  
		  PACKSSDW xmm1,xmm7
		  PACKSSDW xmm2,xmm7
		  PACKSSDW xmm3,xmm7		  
		  PACKUSWB xmm0,xmm7		 
		  PACKUSWB xmm1,xmm7		  
		  PACKUSWB xmm2,xmm7		  
		  PACKUSWB xmm3,xmm7
		  movdq2q mm0,xmm0
		  movdq2q mm1,xmm1
		  movdq2q mm2,xmm2
		  movdq2q mm3,xmm3
		  movd [edi],mm0
		  movd [edi+4],mm1
		  movd [edi+8],mm2
		  movd [edi+12],mm3
		  emms
	  }
  }
  else
  {
	  *mpred++ = get_pel (ref_pic, j0, i0);
	  *mpred++ = get_pel (ref_pic, j0, i1);
	  *mpred++ = get_pel (ref_pic, j0, i2);
	  *mpred++ = get_pel (ref_pic, j0, i3);
	  *mpred++ = get_pel (ref_pic, j1, i0);
	  *mpred++ = get_pel (ref_pic, j1, i1);
	  *mpred++ = get_pel (ref_pic, j1, i2);
	  *mpred++ = get_pel (ref_pic, j1, i3);
	  *mpred++ = get_pel (ref_pic, j2, i0);
	  *mpred++ = get_pel (ref_pic, j2, i1);
	  *mpred++ = get_pel (ref_pic, j2, i2);
	  *mpred++ = get_pel (ref_pic, j2, i3);
	  *mpred++ = get_pel (ref_pic, j3, i0);
	  *mpred++ = get_pel (ref_pic, j3, i1);
	  *mpred++ = get_pel (ref_pic, j3, i2);
	  *mpred++ = get_pel (ref_pic, j3, i3);
	  

  }
}

/*!
 ************************************************************************
 * \brief

⌨️ 快捷键说明

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