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

📄 h.264

📁 H.264编码解码器源码(c语言版本)
💻 264
📖 第 1 页 / 共 5 页
字号:
       else if(!img->cod_counter)
         skip = FALSE;
     }
     // maximum number of MBs
     if ((*recode_macroblock == FALSE) && ((img->current_mb_nr+1) == img->total_number_mb)) 
     {
       *end_of_slice = TRUE;
       if(!img->cod_counter)
         skip = FALSE;
     }
   
     //! (first MB OR first MB in a slice) AND bigger that maximum size of slice
     if (new_slice && slice_too_big(rlc_bits))
     {
       *end_of_slice = TRUE;
       if(!img->cod_counter)
         skip = FALSE;
     }
     if (!*recode_macroblock)
       currSlice->num_mb++;
     break;

  case  CALLBACK:
    if (img->current_mb_nr > 0 && !new_slice)
    {
      if (currSlice->slice_too_big(rlc_bits))
      {
        *recode_macroblock = TRUE;
        *end_of_slice = TRUE;
      }
    }
    if ( (*recode_macroblock == FALSE) && ((img->current_mb_nr+1) == img->total_number_mb) ) // maximum number of MBs
      *end_of_slice = TRUE;
    break;

  case FMO:
    // The FMO slice mode acts like slice mode 1 (fixed maximum #of mbs per slice, in slice_argument)

    currSlice->num_mb++;
    *recode_macroblock = FALSE;
    // Check end-of-slice group condition first
    *end_of_slice = (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)));
    // Now check maximum # of MBs in slice
    *end_of_slice |= (currSlice->num_mb >= input->slice_argument);
    break;

  default:
    snprintf(errortext, ET_SIZE, "Slice Mode %d not supported", input->slice_mode);
    error(errortext, 600);
  }

  if(*recode_macroblock == TRUE)
  {
    // Restore everything
    for (i=0; i<currSlice->max_part_nr; i++)
    {
      dataPart = &(currSlice->partArr[i]);
      currStream = dataPart->bitstream;
      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_SLICE)   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_SLICE)   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_SLICE)   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]);

⌨️ 快捷键说明

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