📄 rdopt.c
字号:
/************************************************************************* 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 + -