📄 macroblock.c
字号:
/*!
***********************************************************************
* \file macroblock.c
*
* \brief
* Decode a 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>
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
* - Detlev Marpe <marpe@hhi.de>
* - Gabi Blaettermann <blaetter@hhi.de>
* - Ye-Kui Wang <wyk@ieee.org>
* - Lowell Winger <lwinger@lsil.com>
***********************************************************************
*/
#include "contributors.h"
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "global.h"
#include "mbuffer.h"
#include "elements.h"
#include "errorconcealment.h"
#include "macroblock.h"
#include "fmo.h"
#include "cabac.h"
#include "vlc.h"
#include "image.h"
#include "mb_access.h"
#include "biaridecod.h"
#include "transform8x8.h"
#ifdef MV_COMPETITION
#include "mv_competition.h"
extern MV_Competition mv_comp; // to each possible predictor
#endif
#ifdef ADAPTIVE_FILTER
#include "adaptive_filter.h"
#endif
#ifdef ADAPTIVE_QUANTIZATION
#include "adaptive_quantization.h"
#endif
#ifdef ADAPTIVE_FD_SD_CODING
#include "spatial_domain_coding.h"
#endif
#ifdef SWITCHED_FILTERS
#include "switched_filters.h"
#endif
#if TRACE
#define TRACE_STRING(s) strncpy(currSE.tracestring, s, TRACESTRING_SIZE)
#else
#define TRACE_STRING(s) // do nothing
#endif
extern int last_dquant;
extern ColocatedParams *Co_located;
/*!
************************************************************************
* \brief
* initializes the current macroblock
************************************************************************
*/
void start_macroblock(struct img_par *img,struct inp_par *inp, int CurrentMBInScanOrder)
{
int i,j,k,l;
Macroblock *currMB; // intialization code deleted, see below, StW
assert (img->current_mb_nr < img->PicSizeInMbs);
currMB = &img->mb_data[img->current_mb_nr];
/* Update coordinates of the current macroblock */
if (img->MbaffFrameFlag)
{
img->mb_x = (img->current_mb_nr)%((2*img->width)/MB_BLOCK_SIZE);
img->mb_y = 2*((img->current_mb_nr)/((2*img->width)/MB_BLOCK_SIZE));
if (img->mb_x % 2)
{
img->mb_y++;
}
img->mb_x /= 2;
}
else
{
img->mb_x = (img->current_mb_nr)%(img->width/MB_BLOCK_SIZE);
img->mb_y = (img->current_mb_nr)/(img->width/MB_BLOCK_SIZE);
}
/* Define vertical positions */
img->block_y = img->mb_y * BLOCK_SIZE; /* luma block position */
img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */
img->pix_c_y = img->mb_y * img->mb_cr_size_y; /* chroma macroblock position */
/* Define horizontal positions */
img->block_x = img->mb_x * BLOCK_SIZE; /* luma block position */
img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */
img->pix_c_x = img->mb_x * img->mb_cr_size_x; /* chroma pixel position */
// 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
currMB->slice_nr = img->current_slice_nr;
if (img->current_slice_nr >= MAX_NUM_SLICES)
{
error ("maximum number of supported slices exceeded, please recompile with increased value for MAX_NUM_SLICES", 200);
}
dec_picture->slice_id[img->mb_y][img->mb_x] = img->current_slice_nr;
if (img->current_slice_nr > dec_picture->max_slice_id)
{
dec_picture->max_slice_id=img->current_slice_nr;
}
CheckAvailabilityOfNeighbors(img);
// Reset syntax element entries in MB struct
currMB->qp = img->qp ;
currMB->mb_type = 0;
currMB->delta_quant = 0;
currMB->cbp = 0;
currMB->cbp_blk = 0;
currMB->c_ipred_mode= DC_PRED_8; //GB
#ifdef ADAPTIVE_QUANTIZATION
currMB->mb_iaqms_idx = 0;
#endif
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;
currMB->cbp_bits = 0;
#ifdef ADAPTIVE_FD_SD_CODING
currMB->FD_or_SD_bits= 0;
#endif
// initialize img->m7 for ABT
for (j=0; j<MB_BLOCK_SIZE; j++)
for (i=0; i<MB_BLOCK_SIZE; i++)
img->m7[i][j] = 0;
// store filtering parameters for this MB
currMB->LFDisableIdc = img->currentSlice->LFDisableIdc;
currMB->LFAlphaC0Offset = img->currentSlice->LFAlphaC0Offset;
currMB->LFBetaOffset = img->currentSlice->LFBetaOffset;
}
/*!
************************************************************************
* \brief
* set coordinates of the next macroblock
* check end_of_slice condition
************************************************************************
*/
int exit_macroblock(struct img_par *img,struct inp_par *inp,int eos_bit)
{
//! The if() statement below resembles the original code, which tested
//! img->current_mb_nr == img->PicSizeInMbs. Both is, of course, nonsense
//! In an error prone environment, one can only be sure to have a new
//! picture by checking the tr of the next slice header!
// printf ("exit_macroblock: FmoGetLastMBOfPicture %d, img->current_mb_nr %d\n", FmoGetLastMBOfPicture(), img->current_mb_nr);
img->num_dec_mb++;
if (img->num_dec_mb == img->PicSizeInMbs)
// if (img->current_mb_nr == FmoGetLastMBOfPicture(currSlice->structure))
{
//thb
/*
if (currSlice->next_header != EOS)
currSlice->next_header = SOP;
*/
//the
// assert (nal_startcode_follows (img, inp, eos_bit) == TRUE);
return TRUE;
}
// ask for last mb in the slice UVLC
else
{
// printf ("exit_macroblock: Slice %d old MB %d, now using MB %d\n", img->current_slice_nr, img->current_mb_nr, FmoGetNextMBNr (img->current_mb_nr));
img->current_mb_nr = FmoGetNextMBNr (img->current_mb_nr);
if (img->current_mb_nr == -1) // End of Slice group, MUST be end of slice
{
assert (nal_startcode_follows (img, inp, eos_bit) == TRUE);
return TRUE;
}
if(nal_startcode_follows(img, inp, eos_bit) == FALSE)
return FALSE;
if(img->type == I_SLICE || img->type == SI_SLICE || active_pps->entropy_coding_mode_flag == CABAC)
return TRUE;
if(img->cod_counter<=0)
return TRUE;
return FALSE;
}
}
/*!
************************************************************************
* \brief
* Interpret the mb mode for P-Frames
************************************************************************
*/
void interpret_mb_mode_P(struct img_par *img)
{
int i;
const int ICBPTAB[6] = {0,16,32,15,31,47};
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int mbmode = currMB->mb_type;
#define ZERO_P8x8 (mbmode==5)
#define MODE_IS_P8x8 (mbmode==4 || mbmode==5)
#define MODE_IS_I4x4 (mbmode==6)
#define I16OFFSET (mbmode-7)
#define MODE_IS_IPCM (mbmode==31)
if(mbmode <4)
{
currMB->mb_type = mbmode;
for (i=0;i<4;i++)
{
currMB->b8mode[i] = mbmode;
currMB->b8pdir[i] = 0;
}
}
else if(MODE_IS_P8x8)
{
currMB->mb_type = P8x8;
img->allrefzero = ZERO_P8x8;
}
else if(MODE_IS_I4x4)
{
currMB->mb_type = I4MB;
for (i=0;i<4;i++)
{
currMB->b8mode[i] = IBLOCK;
currMB->b8pdir[i] = -1;
}
}
else if(MODE_IS_IPCM)
{
currMB->mb_type=IPCM;
for (i=0;i<4;i++)
{
currMB->b8mode[i]=0; currMB->b8pdir[i]=-1;
}
currMB->cbp= -1;
currMB->i16mode = 0;
}
else
{
currMB->mb_type = I16MB;
for (i=0;i<4;i++)
{
currMB->b8mode[i]=0; currMB->b8pdir[i]=-1;
}
currMB->cbp= ICBPTAB[(I16OFFSET)>>2];
currMB->i16mode = (I16OFFSET) & 0x03;
}
}
/*!
************************************************************************
* \brief
* Interpret the mb mode for I-Frames
************************************************************************
*/
void interpret_mb_mode_I(struct img_par *img)
{
int i;
const int ICBPTAB[6] = {0,16,32,15,31,47};
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int mbmode = currMB->mb_type;
if (mbmode==0)
{
currMB->mb_type = I4MB;
for (i=0;i<4;i++)
{
currMB->b8mode[i]=IBLOCK; currMB->b8pdir[i]=-1;
}
}
else if(mbmode==25)
{
currMB->mb_type=IPCM;
for (i=0;i<4;i++)
{
currMB->b8mode[i]=0; currMB->b8pdir[i]=-1;
}
currMB->cbp= -1;
currMB->i16mode = 0;
}
else
{
currMB->mb_type = I16MB;
for (i=0;i<4;i++)
{
currMB->b8mode[i]=0; currMB->b8pdir[i]=-1;
}
currMB->cbp= ICBPTAB[(mbmode-1)>>2];
currMB->i16mode = (mbmode-1) & 0x03;
}
}
/*!
************************************************************************
* \brief
* Interpret the mb mode for B-Frames
************************************************************************
*/
void interpret_mb_mode_B(struct img_par *img)
{
static const int offset2pdir16x16[12] = {0, 0, 1, 2, 0,0,0,0,0,0,0,0};
static const int offset2pdir16x8[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},{1,0},
{0,0},{0,2},{0,0},{1,2},{0,0},{2,0},{0,0},{2,1},{0,0},{2,2},{0,0}};
static const int offset2pdir8x16[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},
{1,0},{0,0},{0,2},{0,0},{1,2},{0,0},{2,0},{0,0},{2,1},{0,0},{2,2}};
const int ICBPTAB[6] = {0,16,32,15,31,47};
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int i, mbmode;
int mbtype = currMB->mb_type;
int *b8mode = currMB->b8mode;
int *b8pdir = currMB->b8pdir;
//--- set mbtype, b8type, and b8pdir ---
if (mbtype==0) // direct
{
mbmode=0;
for(i=0;i<4;i++)
{
b8mode[i]=0;
b8pdir[i]=2;
}
}
else if (mbtype==23) // intra4x4
{
mbmode=I4MB;
for(i=0;i<4;i++)
{
b8mode[i]=IBLOCK;
b8pdir[i]=-1;
}
}
else if ((mbtype>23) && (mbtype<48) ) // intra16x16
{
mbmode=I16MB;
for(i=0;i<4;i++)
{
b8mode[i]=0;
b8pdir[i]=-1;
}
currMB->cbp = ICBPTAB[(mbtype-24)>>2];
currMB->i16mode = (mbtype-24) & 0x03;
}
else if (mbtype==22) // 8x8(+split)
{
mbmode=P8x8; // b8mode and pdir is transmitted in additional codewords
}
else if (mbtype<4) // 16x16
{
mbmode=1;
for(i=0;i<4;i++)
{
b8mode[i]=1;
b8pdir[i]=offset2pdir16x16[mbtype];
}
}
else if(mbtype==48)
{
mbmode=IPCM;
for (i=0;i<4;i++)
{
currMB->b8mode[i]=0;
currMB->b8pdir[i]=-1;
}
currMB->cbp= -1;
currMB->i16mode = 0;
}
else if (mbtype%2==0) // 16x8
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -