📄 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
stat->bit_use_mb_type[img->type] += currMB->bitcounter[BITS_MB_MODE];
stat->bit_use_coeffY[img->type] += currMB->bitcounter[BITS_COEFF_Y_MB] ;
stat->bit_use_mode_inter[img->mb_mode]+= currMB->bitcounter[BITS_INTER_MB];
stat->tmp_bit_use_cbp[img->type] += currMB->bitcounter[BITS_CBP_MB];
stat->bit_use_coeffC[img->type] += currMB->bitcounter[BITS_COEFF_UV_MB];
stat->bit_use_delta_quant[img->type] += currMB->bitcounter[BITS_DELTA_QUANT_MB];
/* if (input->symbol_mode == UVLC)
stat->bit_ctr += currMB->bitcounter[BITS_TOTAL_MB]; */
if (img->type==INTRA_IMG)
++stat->mode_use_intra[img->mb_mode];
else
if (img->type != B_IMG)
++stat->mode_use_inter[img->mb_mode];
else
++stat->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) )
{
++stat->quant0;
stat->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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -