📄 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
* - Ye-Kui Wang <wyk@ieee.org>
* - Lowell Winger <lwinger@lsil.com>
* - Alexis Michael Tourapis <alexismt@ieee.org>
***********************************************************************
*/
#include "contributors.h"
#include <math.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 "block.h"
#include "transform8x8.h"
#include "transform.h"
#include "mc_prediction.h"
#include "quant.h"
#include "intra4x4_pred.h"
#include "intra8x8_pred.h"
#include "intra16x16_pred.h"
#if TRACE
#define TRACE_STRING(s) strncpy(currSE.tracestring, s, TRACESTRING_SIZE)
#define TRACE_DECBITS(i) dectracebitcnt(1)
#define TRACE_PRINTF(s) sprintf(type, "%s", s);
#define TRACE_STRING_P(s) strncpy(currSE->tracestring, s, TRACESTRING_SIZE)
#else
#define TRACE_STRING(s)
#define TRACE_DECBITS(i)
#define TRACE_PRINTF(s)
#define TRACE_STRING_P(s)
#endif
//! single scan pattern
static const byte SNGL_SCAN[16][2] =
{
{0,0},{1,0},{0,1},{0,2},
{1,1},{2,0},{3,0},{2,1},
{1,2},{0,3},{1,3},{2,2},
{3,1},{3,2},{2,3},{3,3}
};
//! field scan pattern
static const byte FIELD_SCAN[16][2] =
{
{0,0},{0,1},{1,0},{0,2},
{0,3},{1,1},{1,2},{1,3},
{2,0},{2,1},{2,2},{2,3},
{3,0},{3,1},{3,2},{3,3}
};
//! used to control block sizes : Not used/16x16/16x8/8x16/8x8/8x4/4x8/4x4
static const int BLOCK_STEP[8][2]=
{
{0,0},{4,4},{4,2},{2,4},{2,2},{2,1},{1,2},{1,1}
};
const byte QP_SCALE_CR[52]=
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,
12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,
28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37,
37,38,38,38,39,39,39,39
};
//! single scan pattern
const byte SNGL_SCAN8x8[64][2] = {
{0,0}, {1,0}, {0,1}, {0,2}, {1,1}, {2,0}, {3,0}, {2,1}, {1,2}, {0,3}, {0,4}, {1,3}, {2,2}, {3,1}, {4,0}, {5,0},
{4,1}, {3,2}, {2,3}, {1,4}, {0,5}, {0,6}, {1,5}, {2,4}, {3,3}, {4,2}, {5,1}, {6,0}, {7,0}, {6,1}, {5,2}, {4,3},
{3,4}, {2,5}, {1,6}, {0,7}, {1,7}, {2,6}, {3,5}, {4,4}, {5,3}, {6,2}, {7,1}, {7,2}, {6,3}, {5,4}, {4,5}, {3,6},
{2,7}, {3,7}, {4,6}, {5,5}, {6,4}, {7,3}, {7,4}, {6,5}, {5,6}, {4,7}, {5,7}, {6,6}, {7,5}, {7,6}, {6,7}, {7,7}
};
//! field scan pattern
const byte FIELD_SCAN8x8[64][2] = { // 8x8
{0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {0,3}, {0,4}, {1,2}, {2,0}, {1,3}, {0,5}, {0,6}, {0,7}, {1,4}, {2,1}, {3,0},
{2,2}, {1,5}, {1,6}, {1,7}, {2,3}, {3,1}, {4,0}, {3,2}, {2,4}, {2,5}, {2,6}, {2,7}, {3,3}, {4,1}, {5,0}, {4,2},
{3,4}, {3,5}, {3,6}, {3,7}, {4,3}, {5,1}, {6,0}, {5,2}, {4,4}, {4,5}, {4,6}, {4,7}, {5,3}, {6,1}, {6,2}, {5,4},
{5,5}, {5,6}, {5,7}, {6,3}, {7,0}, {7,1}, {6,4}, {6,5}, {6,6}, {6,7}, {7,2}, {7,3}, {7,4}, {7,5}, {7,6}, {7,7}
};
//! single scan pattern
static const byte SCAN_YUV422[8][2] =
{
{0,0},{0,1},
{1,0},{0,2},
{0,3},{1,1},
{1,2},{1,3}
};
static unsigned char cbp_blk_chroma[8][4] =
{ {16, 17, 18, 19},
{20, 21, 22, 23},
{24, 25, 26, 27},
{28, 29, 30, 31},
{32, 33, 34, 35},
{36, 37, 38, 39},
{40, 41, 42, 43},
{44, 45, 46, 47} };
//! look up tables for FRExt_chroma support
const unsigned char subblk_offset_x[3][8][4] =
{
{ {0, 4, 0, 4},
{0, 4, 0, 4},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}, },
{ {0, 4, 0, 4},
{0, 4, 0, 4},
{0, 4, 0, 4},
{0, 4, 0, 4},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}, },
{ {0, 4, 0, 4},
{8,12, 8,12},
{0, 4, 0, 4},
{8,12, 8,12},
{0, 4, 0, 4},
{8,12, 8,12},
{0, 4, 0, 4},
{8,12, 8,12} }
};
const unsigned char subblk_offset_y[3][8][4] =
{ { {0, 0, 4, 4},
{0, 0, 4, 4},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}, },
{ {0, 0, 4, 4},
{8, 8,12,12},
{0, 0, 4, 4},
{8, 8,12,12},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0} },
{ {0, 0, 4, 4},
{0, 0, 4, 4},
{8, 8,12,12},
{8, 8,12,12},
{0, 0, 4, 4},
{0, 0, 4, 4},
{8, 8,12,12},
{8, 8,12,12} }
};
const unsigned char cofuv_blk_x[3][8][4] =
{ { {0, 1, 0, 1},
{0, 1, 0, 1},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0} },
{ {0, 1, 0, 1},
{0, 1, 0, 1},
{0, 1, 0, 1},
{0, 1, 0, 1},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0} },
{ {0, 1, 0, 1},
{2, 3, 2, 3},
{0, 1, 0, 1},
{2, 3, 2, 3},
{0, 1, 0, 1},
{2, 3, 2, 3},
{0, 1, 0, 1},
{2, 3, 2, 3} }
};
static const unsigned char cofuv_blk_y[3][8][4] =
{
{ { 0, 0, 1, 1},
{ 0, 0, 1, 1},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0} },
{ { 0, 0, 1, 1},
{ 2, 2, 3, 3},
{ 0, 0, 1, 1},
{ 2, 2, 3, 3},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0} },
{ { 0, 0, 1, 1},
{ 0, 0, 1, 1},
{ 2, 2, 3, 3},
{ 2, 2, 3, 3},
{ 0, 0, 1, 1},
{ 0, 0, 1, 1},
{ 2, 2, 3, 3},
{ 2, 2, 3, 3}}
};
void dectracebitcnt(int count);
extern int last_dquant;
extern ColocatedParams *Co_located;
extern ColocatedParams *Co_located_JV[MAX_PLANE]; //!< Co_located to be used during 4:4:4 independent mode decoding
static void readMotionInfoFromNAL (ImageParameters *img, Slice *currSlice, Macroblock *currMB);
static void read_ipred_modes (ImageParameters *img, Slice *currSlice, Macroblock *currMB);
static void readCBPandCoeffsFromNAL(ImageParameters *img, Slice *currSlice, Macroblock *currMB);
static void readIPCMcoeffsFromNAL (ImageParameters *img, struct datapartition *dP);
// Interpret MB mode
static void (*interpret_mb_mode)(Macroblock *currMB);
/*!
************************************************************************
* \brief
* Set context for reference frames
************************************************************************
*/
int BType2CtxRef (int btype)
{
return (btype >= 4);
}
/*!
************************************************************************
* \brief
* Function pointer for reading the reference picture indices
************************************************************************
*/
static char (*readRefPictureIdx) (SyntaxElement *currSE, DataPartition *dP, char b8mode, int list);
/*!
************************************************************************
* \brief
* Function for reading the reference picture indices using VLC
************************************************************************
*/
static char readRefPictureIdx_VLC(SyntaxElement *currSE, DataPartition *dP, char b8mode, int list)
{
#if TRACE
static char tstring[20];
sprintf( tstring, "ref_idx_l%d", list);
strncpy(currSE->tracestring, tstring, TRACESTRING_SIZE);
#endif
currSE->context = BType2CtxRef (b8mode);
currSE->value2 = list;
dP->readSyntaxElement (currSE,img,dP);
return (char) currSE->value1;
}
/*!
************************************************************************
* \brief
* Function for reading the reference picture indices using FLC
************************************************************************
*/
static char readRefPictureIdx_FLC(SyntaxElement *currSE, DataPartition *dP, char b8mode, int list)
{
#if TRACE
static char tstring[20];
sprintf( tstring, "ref_idx_l%d", list);
strncpy(currSE->tracestring, tstring, TRACESTRING_SIZE);
#endif
currSE->context = BType2CtxRef (b8mode);
currSE->len = 1;
readSyntaxElement_FLC(currSE, dP->bitstream);
currSE->value1 = 1 - currSE->value1;
return (char) currSE->value1;
}
/*!
************************************************************************
* \brief
* Dummy Function for reading the reference picture indices
************************************************************************
*/
static char readRefPictureIdx_Null(SyntaxElement *currSE, DataPartition *dP, char b8mode, int list)
{
return 0;
}
/*!
************************************************************************
* \brief
* Function to prepare reference picture indice function pointer
************************************************************************
*/
static inline void prepareListforRefIdx ( SyntaxElement *currSE, DataPartition *dP, int num_ref_idx_active, int refidx_present)
{
readRefPictureIdx = readRefPictureIdx_Null; // Initialize readRefPictureIdx
if(num_ref_idx_active > 1)
{
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
{
currSE->mapping = linfo_ue;
if (refidx_present)
{
if (num_ref_idx_active == 2)
readRefPictureIdx = readRefPictureIdx_FLC;
else
readRefPictureIdx = readRefPictureIdx_VLC;
}
}
else
{
currSE->reading = readRefFrame_CABAC;
if (refidx_present)
readRefPictureIdx = readRefPictureIdx_VLC;
}
}
}
void set_chroma_qp(ImageParameters *img, Macroblock* currMB)
{
int i;
for (i=0; i<2; i++)
{
currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, currMB->qp + dec_picture->chroma_qp_offset[i] );
currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]];
currMB->qp_scaled[i + 1] = currMB->qpc[i] + img->bitdepth_chroma_qp_scale;
}
}
/*!
************************************************************************
* \brief
* updates chroma QP according to luma QP and bit depth
************************************************************************
*/
void update_qp(ImageParameters *img, Macroblock *currMB, int qp)
{
currMB->qp = qp;
currMB->qp_scaled[0] = qp + img->bitdepth_luma_qp_scale;
set_chroma_qp(img, currMB);
currMB->is_lossless = (Boolean) ((currMB->qp_scaled[0] == 0) && (img->lossless_qpprime_flag == 1));
}
static void read_delta_quant(SyntaxElement *currSE, DataPartition *dP, Slice *currSlice, ImageParameters *img, Macroblock *currMB, byte *partMap, int type)
{
currSE->type = type;
dP = &(currSlice->partArr[partMap[currSE->type]]);
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
{
currSE->mapping = linfo_se;
}
else
currSE->reading= readDquant_CABAC;
TRACE_STRING_P("mb_qp_delta");
dP->readSyntaxElement(currSE,img,dP);
currMB->delta_quant = currSE->value1;
if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2)))
error ("mb_qp_delta is out of range", 500);
img->qp = ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) -
img->bitdepth_luma_qp_scale;
update_qp(img, currMB, img->qp);
}
/*!
************************************************************************
* \brief
* Function to read reference picture indice values
************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -