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

📄 macroblock.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************************* COPYRIGHT AND WARRANTY INFORMATION** Copyright 2001, International Telecommunications Union, Geneva** DISCLAIMER OF WARRANTY** These software programs are available to the user without any* license fee or royalty on an "as is" basis. The ITU disclaims* any and all warranties, whether express, implied, or* statutory, including any implied warranties of merchantability* or of fitness for a particular purpose.  In no event shall the* contributor or the ITU be liable for any incidental, punitive, or* consequential damages of any kind whatsoever arising from the* use of these programs.** This disclaimer of warranty extends to the user of these programs* and user's customers, employees, agents, transferees, successors,* and assigns.** The ITU does not represent or warrant that the programs furnished* hereunder are free of infringement of any third-party patents.* Commercial implementations of ITU-T Recommendations, including* shareware, may be subject to royalty fees to patent holders.* Information regarding the ITU-T patent policy is available from* the ITU Web site at http://www.itu.int.** THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.*************************************************************************//*! ************************************************************************************* * \file macroblock.c * * \brief *    Process one macroblock * * \author *    Main contributors (see contributors.h for copyright, address and affiliation details) *    - Inge Lille-Lang鴜               <inge.lille-langoy@telenor.com> *    - Rickard Sjoberg                 <rickard.sjoberg@era.ericsson.se> *    - Jani Lainema                    <jani.lainema@nokia.com> *    - Sebastian Purreiter             <sebastian.purreiter@mch.siemens.de> *    - Detlev Marpe                    <marpe@hhi.de> *    - Thomas Wedi                     <wedi@tnt.uni-hannover.de> *    - Ragip Kurceren                  <ragip.kurceren@nokia.com> ************************************************************************************* */#include "contributors.h"#include <math.h>#include <stdlib.h>#include "elements.h"#include "macroblock.h"#include "refbuf.h"/*! ************************************************************************ * \brief *    updates the coordinates and statistics parameter for the *    next macroblock ************************************************************************ */void proceed2nextMacroblock(){#if TRACE  int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);#endif  const int number_mb_per_row = img->width / MB_BLOCK_SIZE ;  Macroblock *currMB = &img->mb_data[img->current_mb_nr];#if TRACE  int i;  if (p_trace)  {    if(use_bitstream_backing)      fprintf(p_trace, "\n*********** Pic: %i (I/P) MB: %i Slice: %i **********\n\n", frame_no, img->current_mb_nr, img->current_slice_nr);   // Write out the tracestring for each symbol     for (i=0; i<currMB->currSEnr; i++)       trace2out(&(img->MB_SyntaxElements[i]));  }#endif  // Update the statistics  h26lstat->bit_use_mb_type[img->type]      += currMB->bitcounter[BITS_MB_MODE];  h26lstat->bit_use_coeffY[img->type]       += currMB->bitcounter[BITS_COEFF_Y_MB] ;  h26lstat->bit_use_mode_inter[img->mb_mode]+= currMB->bitcounter[BITS_INTER_MB];  h26lstat->tmp_bit_use_cbp[img->type]      += currMB->bitcounter[BITS_CBP_MB];  h26lstat->bit_use_coeffC[img->type]       += currMB->bitcounter[BITS_COEFF_UV_MB];  h26lstat->bit_use_delta_quant[img->type]  += currMB->bitcounter[BITS_DELTA_QUANT_MB];/*  if (input->symbol_mode == UVLC)    h26lstat->bit_ctr += currMB->bitcounter[BITS_TOTAL_MB]; */  if (img->type==INTRA_IMG)    ++h26lstat->mode_use_intra[img->mb_mode];  else    if (img->type != B_IMG)      ++h26lstat->mode_use_inter[img->mb_mode];    else      ++h26lstat->mode_use_Bframe[img->mb_mode];  // Update coordinates of macroblock  img->mb_x++;  if (img->mb_x == number_mb_per_row) // next row of MBs  {    img->mb_x = 0; // start processing of next row    img->mb_y++;  }  img->current_mb_nr++;  // Define vertical positions  img->block_y = img->mb_y * BLOCK_SIZE;      // vertical luma block position  img->pix_y   = img->mb_y * MB_BLOCK_SIZE;   // vertical luma macroblock position  img->pix_c_y = img->mb_y * MB_BLOCK_SIZE/2; // vertical chroma macroblock position  if (img->type != B_IMG)  {    if (input->intra_upd > 0 && img->mb_y <= img->mb_y_intra)      img->height_err=(img->mb_y_intra*16)+15;     // for extra intra MB    else      img->height_err=img->height-1;  }  // Define horizontal positions  img->block_x = img->mb_x * BLOCK_SIZE;        // luma block  img->pix_x   = img->mb_x * MB_BLOCK_SIZE;     // luma pixel  img->block_c_x = img->mb_x * BLOCK_SIZE/2;    // chroma block  img->pix_c_x   = img->mb_x * MB_BLOCK_SIZE/2; // chroma pixel  // Statistics  if ((img->type == INTER_IMG)||(img->types==SP_IMG) )  {    ++h26lstat->quant0;    h26lstat->quant1 += img->qp;      // to find average quant for inter frames  }}/*! ************************************************************************ * \brief *    initializes the current macroblock ************************************************************************ */void start_macroblock(){  int i,j,k,l;  int x=0, y=0 ;  int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);  Macroblock *currMB = &img->mb_data[img->current_mb_nr];  Slice *curr_slice = img->currentSlice;  DataPartition *dataPart;  Bitstream *currStream;  EncodingEnvironmentPtr eep;  if(use_bitstream_backing)  {     // Save image to allow recoding if necessary     for(y=0; y<img->height; y++)       for(x=0; x<img->width; x++)         imgY_tmp[y][x] = imgY[y][x];     for(i=0; i<2; i++)       for(y=0; y<img->height_cr; y++)         for(x=0; x<img->width_cr; x++)           imgUV_tmp[i][y][x] = imgUV[i][y][x];    // Keep the current state of the bitstreams    if(!img->cod_counter)      for (i=0; i<curr_slice->max_part_nr; i++)      {        dataPart = &(curr_slice->partArr[i]);        currStream = dataPart->bitstream;        currStream->stored_bits_to_go   = currStream->bits_to_go;        currStream->stored_byte_pos   = currStream->byte_pos;        currStream->stored_byte_buf   = currStream->byte_buf;        if (input->symbol_mode ==CABAC)        {          eep = &(dataPart->ee_cabac);          eep->ElowS            = eep->Elow;          eep->EhighS           = eep->Ehigh;          eep->EbufferS         = eep->Ebuffer;          eep->Ebits_to_goS     = eep->Ebits_to_go;          eep->Ebits_to_followS = eep->Ebits_to_follow;          eep->EcodestrmS       = eep->Ecodestrm;          eep->Ecodestrm_lenS   = eep->Ecodestrm_len;        }      }  }  // Save the slice number of this macroblock. When the macroblock below  // is coded it will use this to decide if prediction for above is possible  img->slice_numbers[img->current_mb_nr] = img->current_slice_nr;  // Save the slice and macroblock number of the current MB  currMB->slice_nr = img->current_slice_nr;    // Initialize delta qp change from last macroblock. Feature may be used for future rate control  currMB->delta_qp=0;  // Initialize counter for MB symbols  currMB->currSEnr=0;  // If MB is next to a slice boundary, mark neighboring blocks unavailable for prediction  CheckAvailabilityOfNeighbors(img);  // Reset vectors before doing motion search in motion_search().  if (img->type != B_IMG)  {    for (k=0; k < 2; k++)    {      for (j=0; j < BLOCK_MULTIPLE; j++)        for (i=0; i < BLOCK_MULTIPLE; i++)          tmp_mv[k][img->block_y+j][img->block_x+i+4]=0;    }  }  // Reset syntax element entries in MB struct  currMB->ref_frame = 0;  currMB->mb_type   = 0;  currMB->cbp_blk   = 0;  currMB->cbp       = 0;  for (l=0; l < 2; l++)    for (j=0; j < BLOCK_MULTIPLE; j++)      for (i=0; i < BLOCK_MULTIPLE; i++)        for (k=0; k < 2; k++)          currMB->mvd[l][j][i][k] = 0;  for (i=0; i < (BLOCK_MULTIPLE*BLOCK_MULTIPLE); i++)    currMB->intra_pred_modes[i] = 0;  // Initialize bitcounters for this macroblock  if(img->current_mb_nr == 0) // No slice header to account for  {    currMB->bitcounter[BITS_HEADER] = 0;  }  else if (img->slice_numbers[img->current_mb_nr] == img->slice_numbers[img->current_mb_nr-1]) // current MB belongs to the  // same slice as the last MB  {    currMB->bitcounter[BITS_HEADER] = 0;  }  currMB->bitcounter[BITS_MB_MODE] = 0;  currMB->bitcounter[BITS_COEFF_Y_MB] = 0;  currMB->bitcounter[BITS_INTER_MB] = 0;  currMB->bitcounter[BITS_CBP_MB] = 0;  currMB->bitcounter[BITS_DELTA_QUANT_MB] = 0;  currMB->bitcounter[BITS_COEFF_UV_MB] = 0;#ifdef _FAST_FULL_ME_  ResetFastFullIntegerSearch ();#endif}/*! ************************************************************************ * \brief *    terminates processing of the current macroblock depending *    on the chosen slice mode ************************************************************************ */void terminate_macroblock(Boolean *end_of_slice, Boolean *recode_macroblock){  int i,x=0, y=0 ;  Slice *currSlice = img->currentSlice;  Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];  SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];  int *partMap = assignSE2partition[input->partition_mode];  DataPartition *dataPart;  Bitstream *currStream;  int rlc_bits=0;  EncodingEnvironmentPtr eep;  int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);  int new_slice = ( (img->current_mb_nr == 0) || img->mb_data[img->current_mb_nr-1].slice_nr != img->current_slice_nr);  static int skip = FALSE;  switch(input->slice_mode)  {  case NO_SLICES:    *recode_macroblock = FALSE;    if ((img->current_mb_nr+1) == img->total_number_mb) // maximum number of MBs      *end_of_slice = TRUE;    break;  case FIXED_MB:    // For slice mode one, check if a new slice boundary follows    *recode_macroblock = FALSE;    if ( ((img->current_mb_nr+1) % input->slice_argument == 0) || ((img->current_mb_nr+1) == img->total_number_mb) )    {      *end_of_slice = TRUE;    }    break;    // For slice modes two and three, check if coding of this macroblock    // resulted in too many bits for this slice. If so, indicate slice    // boundary before this macroblock and code the macroblock again  case FIXED_RATE:     // in case of skip MBs check if there is a slice boundary     // only for UVLC (img->cod_counter is always 0 in case of CABAC)     if(img->cod_counter)     {       // write out the skip MBs to know how many bits we need for the RLC       dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);       currSE->value1 = img->cod_counter;       currSE->mapping = n_linfo2;       currSE->type = SE_MBTYPE;       dataPart->writeSyntaxElement(  currSE, dataPart);       rlc_bits=currSE->len;       currStream = dataPart->bitstream;       // save the bitstream as it would be if we write the skip MBs       currStream->bits_to_go_skip  = currStream->bits_to_go;       currStream->byte_pos_skip    = currStream->byte_pos;       currStream->byte_buf_skip    = currStream->byte_buf;       // restore the bitstream       currStream->bits_to_go = currStream->stored_bits_to_go;       currStream->byte_pos = currStream->stored_byte_pos;       currStream->byte_buf = currStream->stored_byte_buf;       skip = TRUE;     }     //! Check if the last coded macroblock fits into the size of the slice     //! But only if this is not the first macroblock of this slice     if (!new_slice)     {       if(slice_too_big(rlc_bits))       {         *recode_macroblock = TRUE;         *end_of_slice = TRUE;       }       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;     }     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;  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->Ehigh           = eep->EhighS;        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;      }    }    // Restore image to avoid DeblockMB to operate twice    // Note that this can be simplified! The copy range!    for(y=0; y<img->height; y++)      for(x=0; x<img->width; x++)        imgY[y][x] = imgY_tmp[y][x];    for(i=0; i<2; i++)      for(y=0; y<img->height_cr; y++)        for(x=0; x<img->width_cr; x++)

⌨️ 快捷键说明

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