📄 macroblock.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 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 + -