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

📄 rdopt.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/************************************************************************* 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 rdopt.c * * \brief *    Rate-Distortion optimized mode decision * * \author *    Heiko Schwarz <hschwarz@hhi.de> * * \date *    12. April 2001 ************************************************************************** */#include <stdlib.h>#include <math.h>#include <memory.h>#include "rdopt.h"#include "refbuf.h"extern const byte PRED_IPRED[7][7][6];extern       int  QP2QUANT  [32];//=== static parameters ===RDOpt  *rdopt     = NULL;int    *forward_me_done[9];int    *tot_for_sad[9];/*! ************************************************************************ * \brief *    delete structure for RD-optimized mode decision ************************************************************************ */void clear_rdopt (){  int i;  // rd-optimization structure  if (rdopt != NULL)  {    free (rdopt);    rdopt = NULL;    for (i=0; i<9; i++)    {      free (forward_me_done[i]);      free (tot_for_sad    [i]);    }  }  // structure for saving the coding state  clear_coding_state ();}/*! ************************************************************************ * \brief *    create structure for RD-optimized mode decision ************************************************************************ */voidinit_rdopt (){  int i;  if (!input->rdopt)    return;  clear_rdopt ();  // rd-optimization structure  if ((rdopt = (RDOpt*) calloc (1, sizeof(RDOpt))) == NULL)  {    no_mem_exit ("init_rdopt: rdopt");  }  for (i=0; i<9; i++)  {    if ((forward_me_done[i] = (int*)malloc (img->buf_cycle*sizeof(int))) == NULL) no_mem_exit ("init_rdopt: forward_me_done");    if ((tot_for_sad    [i] = (int*)malloc (img->buf_cycle*sizeof(int))) == NULL) no_mem_exit ("init_rdopt: tot_for_sad");  }  // structure for saving the coding state  init_coding_state ();}/*! ************************************************************************ * \brief *    set Rate-Distortion cost of 4x4 Intra modes ************************************************************************ */voidRDCost_Intra4x4_Block (int block_x,                       int block_y,                       int ipmode){  int             dummy, left_ipmode, upper_ipmode, curr_ipmode, x, y;  int             i            = block_x >> 2;  int             j            = block_y >> 2;  int             pic_block_x  = (img->pix_x+block_x) / BLOCK_SIZE;  int             pic_block_y  = (img->pix_y+block_y) / BLOCK_SIZE;  int             even_block   = ((i & 1) == 1);  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;  //===== perform DCT, Q, IQ, IDCT =====  dct_luma (block_x, block_y, &dummy);  //===== get distortion (SSD) of 4x4 block =====  for   (y=0; y < BLOCK_SIZE; y++)    for (x=0; x < BLOCK_SIZE; x++)    {      dummy = imgY_org[img->pix_y+block_y+y][img->pix_x+block_x+x] - img->m7[x][y];      rdopt->distortion_4x4[j][i][ipmode] += img->quad[abs(dummy)];    }  rdopt->rdcost_4x4[j][i][ipmode] = (double)rdopt->distortion_4x4[j][i][ipmode];  if (rdopt->rdcost_4x4[j][i][ipmode] >= rdopt->min_rdcost_4x4[j][i])    return;  //===== store the coding state =====  store_coding_state ();  //===== get (estimate) rate for intra prediction mode =====  //--- set or estimate the values of syntax element ---  if (even_block)    // EVEN BLOCK: the values the of syntax element can be set correctly  {    // value of last block    upper_ipmode   =  img->ipredmode [pic_block_x  ][pic_block_y  ];    left_ipmode    =  img->ipredmode [pic_block_x-1][pic_block_y+1];    curr_ipmode    =  img->ipredmode [pic_block_x  ][pic_block_y+1];    currSE->value1 =  PRED_IPRED [upper_ipmode+1][left_ipmode+1][curr_ipmode];    // value of this block    upper_ipmode   =  img->ipredmode [pic_block_x+1][pic_block_y  ];    currSE->value2 =  PRED_IPRED [upper_ipmode+1][curr_ipmode+1][ipmode];  }  else  /* ODD BLOCK:  the second value of the syntax element cannot be set, since   *             it will be known only after the next step. For estimating   *             the rate the corresponding prediction mode is set to zero   *             (minimum rate). */  {    upper_ipmode   =  img->ipredmode [pic_block_x+1][pic_block_y  ];    left_ipmode    =  img->ipredmode [pic_block_x  ][pic_block_y+1];    currSE->value1 =  PRED_IPRED [upper_ipmode+1][left_ipmode+1][ipmode];    currSE->value2 =  0; // value with maximum probability  }  //--- set function pointers for syntax element ---  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)     dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);  else                        dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);  //--- get length of syntax element ---  dataPart->writeSyntaxElement (currSE, dataPart);  rdopt->rate_imode_4x4[j][i][ipmode] = currSE->len;  rdopt->rdcost_4x4[j][i][ipmode] += rdopt->lambda_intra*(double)rdopt->rate_imode_4x4[j][i][ipmode];  if (rdopt->rdcost_4x4[j][i][ipmode] >= rdopt->min_rdcost_4x4[j][i])  {    restore_coding_state ();    return;  }  currSE++;  currMB->currSEnr++;  //===== get rate for luminance coefficients =====  rdopt->rate_luma_4x4[j][i][ipmode] = writeMB_bits_for_4x4_luma (i, j, 0);  rdopt->rdcost_4x4[j][i][ipmode] += rdopt->lambda_intra*(double)rdopt->rate_luma_4x4[j][i][ipmode];  //===== restore the saved coding state =====  restore_coding_state ();  //===== update best mode =====  if (rdopt->rdcost_4x4[j][i][ipmode] < rdopt->min_rdcost_4x4[j][i])  {    rdopt->best_mode_4x4 [j][i] = ipmode;    rdopt->min_rdcost_4x4[j][i] = rdopt->rdcost_4x4[j][i][ipmode];  }}/*! ************************************************************************ * \brief *    Get best 4x4 Intra mode by rate-dist-based decision ************************************************************************ */intRD_Intra4x4_Mode_Decision (int block_x,                           int block_y){  int  ipmode, i, j;  int  index_y     = block_y >> 2;  int  index_x     = block_x >> 2;  int  pic_pix_y   = img->pix_y + block_y;  int  pic_pix_x   = img->pix_x + block_x;  int  pic_block_y = pic_pix_y / BLOCK_SIZE;  int  pic_block_x = pic_pix_x / BLOCK_SIZE;  typedef int (*WRITE_SE)(SyntaxElement*, struct datapartition*);  WRITE_SE     *writeSE=0;  int           symbol_mode;  /*=== set symbol mode to UVLC (CABAC does not work correctly -> wrong coding order) ===*   *=== and store the original symbol mode and function pointers                      ===*/  symbol_mode = input->symbol_mode;  if (input->symbol_mode != UVLC)  {    input->symbol_mode = UVLC;    if ((writeSE = (WRITE_SE*) calloc (img->currentSlice->max_part_nr, sizeof (WRITE_SE))) == NULL)    {      no_mem_exit ("RD_Intra4x4_Mode_Decision: writeSE");    }    for (i=0; i<img->currentSlice->max_part_nr; i++)    {      writeSE[i] = img->currentSlice->partArr[i].writeSyntaxElement;      img->currentSlice->partArr[i].writeSyntaxElement = writeSyntaxElement_UVLC;    }  }  //=== LOOP OVER ALL 4x4 INTRA PREDICTION MODES ===  rdopt->best_mode_4x4 [index_y][index_x] = -1;  rdopt->min_rdcost_4x4[index_y][index_x] =  1e30;  for (ipmode=0; ipmode < NO_INTRA_PMODE; ipmode++)  {    rdopt->rdcost_4x4    [index_y][index_x][ipmode] = -1;    rdopt->distortion_4x4[index_y][index_x][ipmode] =  0;    rdopt->rate_imode_4x4[index_y][index_x][ipmode] =  0;    rdopt->rate_luma_4x4 [index_y][index_x][ipmode] =  0;    // Horizontal pred from Y neighbour pix , vertical use X pix, diagonal needs both    if (ipmode==DC_PRED || ipmode==HOR_PRED || img->ipredmode[pic_block_x+1][pic_block_y] >= 0)      // DC or vert pred or hor edge    {      if (ipmode==DC_PRED || ipmode==VERT_PRED || img->ipredmode[pic_block_x][pic_block_y+1] >= 0)        // DC or hor pred or vert edge      {        // find diff        for   (j=0; j < BLOCK_SIZE; j++)          for (i=0; i < BLOCK_SIZE; i++)            img->m7[i][j] = imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mprr[ipmode][j][i];          // copy intra prediction block          for   (j=0; j < BLOCK_SIZE; j++)            for (i=0; i < BLOCK_SIZE; i++)              img->mpr[i+block_x][j+block_y] = img->mprr[ipmode][j][i];          // get lagrangian cost          RDCost_Intra4x4_Block (block_x, block_y, ipmode);      }    }  }  //=== restore the original symbol mode and function pointers ===  if (symbol_mode != UVLC)  {    input->symbol_mode = symbol_mode;    for (i=0; i<img->currentSlice->max_part_nr; i++)    {      img->currentSlice->partArr[i].writeSyntaxElement = writeSE[i];    }    free (writeSE);  }  return rdopt->best_mode_4x4[index_y][index_x];}/*! ************************************************************************ * \brief *    Rate-Distortion opt. mode decision for 4x4 intra blocks ************************************************************************ */voidIntra4x4_Mode_Decision (){  int i,j;  int block_x, block_y;  int best_ipmode;  int coeff_cost; // not used  int pic_pix_y,pic_pix_x,pic_block_y,pic_block_x;  int last_ipred=0;           // keeps last chosen intra prediction mode for 4x4 intra pred  int nonzero;                          // keep track of nonzero coefficients  int cbp_mask;  Macroblock *currMB = &img->mb_data[img->current_mb_nr];  // start making 4x4 intra prediction  currMB->cbp=0;  img->mb_data[img->current_mb_nr].intraOrInter = INTRA_MB_4x4;  for(block_y = 0 ; block_y < MB_BLOCK_SIZE ; block_y += BLOCK_MULTIPLE)  {    pic_pix_y=img->pix_y+block_y;    pic_block_y=pic_pix_y/BLOCK_SIZE;    for(block_x = 0 ; block_x < MB_BLOCK_SIZE  ; block_x += BLOCK_MULTIPLE)    {      cbp_mask=(1<<(2*(block_y/8)+block_x/8));      pic_pix_x=img->pix_x+block_x;      pic_block_x=pic_pix_x/BLOCK_SIZE;      /*      intrapred_luma() makes and returns 4x4 blocks with all 5 intra prediction modes.      Notice that some modes are not possible at frame edges.      */      intrapred_luma (pic_pix_x,pic_pix_y);      //=== rate-constrained mode decision ===      best_ipmode = RD_Intra4x4_Mode_Decision (block_x, block_y);      img->ipredmode[pic_block_x+1][pic_block_y+1]=best_ipmode;      if ((pic_block_x & 1) == 1) // just even blocks, two and two predmodes are sent together      {        currMB->intra_pred_modes[block_x/4+block_y]=PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][best_ipmode];        currMB->intra_pred_modes[block_x/4-1+block_y]=last_ipred;      }      last_ipred=PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][best_ipmode];

⌨️ 快捷键说明

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