📄 macroblock.c
字号:
imgUV[i][y][x] = imgUV_tmp[i][y][x]; } 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) { 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; 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 { for (i=0; i<currSlice->max_part_nr; i++) { dataPart = &(currSlice->partArr[i]); 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) { 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; 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; 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]; // 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; if(input->UseConstrainedIntraPred) remove_prediction = (remove_prediction || img->intra_mb[mb_nr-1] ==0); if(remove_prediction) { img->ipredmode[img->block_x][img->block_y+1] = -1; img->ipredmode[img->block_x][img->block_y+2] = -1; img->ipredmode[img->block_x][img->block_y+3] = -1; img->ipredmode[img->block_x][img->block_y+4] = -1; } else currMB->mb_available[1][0]=&(img->mb_data[mb_nr-1]); } // Check MB above if(img->pix_y >= MB_BLOCK_SIZE) { int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width].slice_nr; if(input->UseConstrainedIntraPred) remove_prediction = (remove_prediction || img->intra_mb[mb_nr-mb_width] ==0); if(remove_prediction) { img->ipredmode[img->block_x+1][img->block_y] = -1; img->ipredmode[img->block_x+2][img->block_y] = -1; img->ipredmode[img->block_x+3][img->block_y] = -1; img->ipredmode[img->block_x+4][img->block_y] = -1; } else 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 ) { if(currMB->slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr) img->mb_data[mb_nr].mb_available[0][0]=&(img->mb_data[mb_nr-mb_width-1]); } // Check MB right above if(img->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][1]=&(img->mb_data[mb_nr-mb_width+1]); currMB->mb_available[0][2]=&(img->mb_data[mb_nr-mb_width+1]); }}/*! ************************************************************************ * \brief * Performs 4x4 and 16x16 intra prediction and transform coding * of the prediction residue. The routine returns the best cost; * current cbp (for LUMA only) and intra pred modes are affected ************************************************************************ */int MakeIntraPrediction(int *intra_pred_mode_2){ int i,j; int block_x, block_y; int best_ipmode=0; int tot_intra_sad, tot_intra_sad2, best_intra_sad, current_intra_sad; 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 ipmode; // intra pred mode int cbp_mask; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; // start making 4x4 intra prediction currMB->cbp = 0; currMB->intraOrInter = INTRA_MB_4x4; tot_intra_sad=QP2QUANT[img->qp]*24;// sum of intra sad values, start with a 'handicap' 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); best_intra_sad=MAX_VALUE; // initial value, will be modified below img->imod = INTRA_MB_OLD; // for now mode set to intra, may be changed in motion_search() // DM: has to be removed for (ipmode=0; ipmode < NO_INTRA_PMODE; ipmode++) // all intra prediction modes { // 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 { 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]; // find diff } current_intra_sad=QP2QUANT[img->qp]*PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][ipmode]*2; current_intra_sad += find_sad(input->hadamard, img->m7); // add the start 'handicap' and the computed SAD if (current_intra_sad < best_intra_sad) { best_intra_sad=current_intra_sad; best_ipmode=ipmode; 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]; // store the currently best intra prediction block } } } } tot_intra_sad += best_intra_sad; 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]; // Make difference from prediction to be transformed for (j=0; j < BLOCK_SIZE; j++) for (i=0; i < BLOCK_SIZE; i++) img->m7[i][j] =imgY_org[img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr[i+block_x][j+block_y]; if( dct_luma(block_x,block_y,&coeff_cost) ) // if non zero coefficients currMB->cbp |= cbp_mask; // set coded block pattern if nonzero coeffs } } // 16x16 intra prediction intrapred_luma_2(img); // make intra pred for the new 4 modes tot_intra_sad2 = find_sad2(intra_pred_mode_2); // find best SAD for new modes if (tot_intra_sad2<tot_intra_sad) { currMB->cbp = 0; // cbp for 16x16 LUMA is signaled by the MB-mode tot_intra_sad = tot_intra_sad2; // update best intra sad if necessary img->imod = INTRA_MB_NEW; // one of the new modes is used currMB->intraOrInter = INTRA_MB_16x16; dct_luma2(*intra_pred_mode_2); for (i=0;i<4;i++) for (j=0;j<4;j++) img->ipredmode[img->block_x+i+1][img->block_y+j+1]=0; } return tot_intra_sad;}/*! ************************************************************************ * \brief * Performs DCT, R-D constrained quantization, run/level * pre-coding and IDCT for the MC-compensated MB residue * of P-frame; current cbp (for LUMA only) is affected ************************************************************************ */void LumaResidualCoding_P(){ int i,j; int block_x, block_y; int pic_pix_y,pic_pix_x,pic_block_y,pic_block_x; int ii4,i2,jj4,j2; int sum_cnt_nonz; int mb_x, mb_y; int cbp_mask, cbp_blk_mask ; int coeff_cost; int nonzero; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; currMB->cbp = 0 ; currMB->cbp_blk = 0 ; sum_cnt_nonz = 0 ; for (mb_y=0; mb_y < MB_BLOCK_SIZE; mb_y += BLOCK_SIZE*2) { for (mb_x=0; mb_x < MB_BLOCK_SIZE; mb_x += BLOCK_SIZE*2) { cbp_mask = (1<<(mb_x/8+mb_y/4)); coeff_cost = 0; for (block_y=mb_y; block_y < mb_y+BLOCK_SIZE*2; block_y += BLOCK_SIZE) { pic_pix_y=img->pix_y+block_y; pic_block_y=pic_pix_y/BLOCK_SIZE; for (block_x=mb_x; block_x < mb_x+BLOCK_SIZE*2; block_x += BLOCK_SIZE) { pic_pix_x = img->pix_x+block_x; pic_block_x = pic_pix_x/BLOCK_SIZE; cbp_blk_mask = (block_x>>2)+ block_y ; img->ipredmode[pic_block_x+1][pic_block_y+1]=0; if(input->mv_res) { ii4=(img->pix_x+block_x)*8+tmp_mv[0][pic_block_y][pic_block_x+4]; jj4=(img->pix_y+block_y)*8+tmp_mv[1][pic_block_y][pic_block_x+4]; for (j=0;j<4;j++) { j2=j*8; for (i=0;i<4;i++) { i2=i*8; img->mpr[i+block_x][j+block_y]=UMVPelY_18 (mref[img->multframe_no], jj4+j2, ii4+i2); } } } else { ii4=(img->pix_x+block_x)*4+tmp_mv[0][pic_block_y][pic_block_x+4]; jj4=(img->pix_y+block_y)*4+tmp_mv[1][pic_block_y][pic_block_x+4]; for (j=0;j<4;j++) { j2 = jj4+j*4; for (i=0;i<4;i++) { i2 = ii4+i*4; img->mpr[i+block_x][j+block_y]=UMVPelY_14 (mref[img->multframe_no], j2, i2); } } } for (j=0; j < BLOCK_SIZE; j++) { for (i=0; i < BLOCK_SIZE; i++) { img->m7[i][j] =imgY_org[img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr[i+block_x][j+block_y]; } } if (img->types!=SP_IMG) nonzero=dct_luma(block_x,block_y,&coeff_cost); else nonzero=dct_luma_sp(block_x,block_y,&coeff_cost);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -