📄 macroblock.c
字号:
/*!
*************************************************************************************
* \file macroblock.c
*
* \brief
* Process one macroblock
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Inge Lille-Langoy <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>
* - Alexis Michael Tourapis <alexismt@ieee.org>
*************************************************************************************
*/
#include "contributors.h"
#include <limits.h>
#include <math.h>
#include "global.h"
#include "enc_statistics.h"
#include "elements.h"
#include "macroblock.h"
#include "mc_prediction.h"
#include "refbuf.h"
#include "fmo.h"
#include "vlc.h"
#include "image.h"
#include "mb_access.h"
#include "ratectl.h" // header file for rate control
#include "cabac.h"
#include "transform8x8.h"
#include "transform.h"
#include "me_fullsearch.h"
#include "me_fullfast.h"
#include "symbol.h"
#include "rdoq.h"
#include "mv-search.h"
#if TRACE
#define TRACE_SE(trace,str) snprintf(trace,TRACESTRING_SIZE,str)
#else
#define TRACE_SE(trace,str)
#endif
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
};
static const int block8x8_idx[3][4][4] =
{
{ {0, 1, 0, 0},
{2, 3, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
},
{ {0, 1, 0, 0},
{0, 1, 0, 0},
{2, 3, 0, 0},
{2, 3, 0, 0},
},
{ {0, 0, 1, 1},
{0, 0, 1, 1},
{2, 2, 3, 3},
{2, 2, 3, 3}
}
};
static int slice_too_big(Slice *currSlice, int rlc_bits);
static int writeChromaIntraPredMode (Macroblock* currMB);
static int writeMotionInfo2NAL (Macroblock* currMB);
static int writeChromaCoeff (Macroblock* currMB);
static int writeCBPandDquant (Macroblock* currMB);
static int diff [16];
static int diff64[64];
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},
}
};
extern ColocatedParams *Co_located;
extern ColocatedParams *Co_located_JV[MAX_PLANE]; //!< Co_located to be used during 4:4:4 independent mode encoding
/*!
************************************************************************
* \brief
* updates the coordinates for the next macroblock to be processed
*
* \param mb_addr
* macroblock address in scan order
************************************************************************
*/
void set_MB_parameters (int mb_addr)
{
img->current_mb_nr = mb_addr;
get_mb_block_pos(mb_addr, &img->mb_x, &img->mb_y);
img->block_x = img->mb_x << 2;
img->block_y = img->mb_y << 2;
img->pix_x = img->block_x << 2;
img->pix_y = img->block_y << 2;
img->opix_x = img->pix_x;
if (img->MbaffFrameFlag)
{
if (img->mb_data[mb_addr].mb_field)
{
pCurImg = (mb_addr & 0x01) ? img_org_bot[0] : img_org_top[0];
pImgOrg[0] = pCurImg;
if ((img->yuv_format != YUV400) && !IS_INDEPENDENT(params))
{
if (mb_addr & 0x01)
{
pImgOrg[1] = img_org_bot[1];
pImgOrg[2] = img_org_bot[2];
}
else
{
pImgOrg[1] = img_org_top[1];
pImgOrg[2] = img_org_top[2];
}
}
img->opix_y = (img->mb_y >> 1 ) << 4;
img->mb_data[mb_addr].list_offset = (mb_addr % 2) ? 4 : 2;
}
else
{
pCurImg = img_org_frm[0];
pImgOrg[0] = img_org_frm[0];
if ((img->yuv_format != YUV400) && !IS_INDEPENDENT(params))
{
pImgOrg[1] = img_org_frm[1];
pImgOrg[2] = img_org_frm[2];
}
img->opix_y = img->block_y << 2;
img->mb_data[mb_addr].list_offset = 0;
}
}
else
{
img->opix_y = img->block_y << 2;
img->mb_data[mb_addr].list_offset = 0;
}
if (img->yuv_format != YUV400)
{
img->pix_c_x = (img->mb_cr_size_x * img->pix_x) >> 4;
img->pix_c_y = (img->mb_cr_size_y * img->pix_y) >> 4;
img->opix_c_x = (img->mb_cr_size_x * img->opix_x) >> 4;
img->opix_c_y = (img->mb_cr_size_y * img->opix_y) >> 4;
}
// printf ("set_MB_parameters: mb %d, mb_x %d, mb_y %d\n", mb_addr, img->mb_x, img->mb_y);
}
/*!
************************************************************************
* \brief
* updates the coordinates and statistics parameter for the
* next macroblock
************************************************************************
*/
void proceed2nextMacroblock(Macroblock *currMB)
{
#if TRACE
int use_bitstream_backing = (params->slice_mode == FIXED_RATE || params->slice_mode == CALL_BACK);
#endif
int *bitCount = currMB->bitcounter;
int i;
StatParameters *cur_stats = &enc_picture->stats;
if (bitCount[BITS_TOTAL_MB] > img->max_bitCount)
printf("Warning!!! Number of bits (%d) of macroblock_layer() data seems to exceed defined limit (%d).\n", bitCount[BITS_TOTAL_MB],img->max_bitCount);
// Update the statistics
cur_stats->bit_use_mb_type[img->type] += bitCount[BITS_MB_MODE ];
cur_stats->tmp_bit_use_cbp[img->type] += bitCount[BITS_CBP_MB ];
cur_stats->bit_use_coeffC[img->type] += bitCount[BITS_COEFF_UV_MB ];
cur_stats->bit_use_coeff[0][img->type] += bitCount[BITS_COEFF_Y_MB ];
cur_stats->bit_use_coeff[1][img->type] += bitCount[BITS_COEFF_CB_MB ];
cur_stats->bit_use_coeff[2][img->type] += bitCount[BITS_COEFF_CR_MB ];
cur_stats->bit_use_delta_quant[img->type] += bitCount[BITS_DELTA_QUANT_MB];
cur_stats->bit_use_stuffingBits[img->type] += bitCount[BITS_STUFFING ];
if (IS_INTRA(currMB))
{
++cur_stats->intra_chroma_mode[currMB->c_ipred_mode];
if ((currMB->cbp&15) != 0)
{
++cur_stats->mode_use_transform[img->type][currMB->mb_type][currMB->luma_transform_size_8x8_flag];
}
}
++cur_stats->mode_use[img->type][currMB->mb_type];
cur_stats->bit_use_mode[img->type][currMB->mb_type] += bitCount[BITS_INTER_MB];
if (img->type != I_SLICE)
{
if (currMB->mb_type == P8x8)
{
for(i=0;i<4;i++)
{
if (currMB->b8mode[i] > 0)
++cur_stats->mode_use[img->type][currMB->b8mode[i]];
else
++cur_stats->b8_mode_0_use[img->type][currMB->luma_transform_size_8x8_flag];
if (currMB->b8mode[i]==4)
{
if ((currMB->luma_transform_size_8x8_flag && (currMB->cbp&15) != 0) || params->Transform8x8Mode == 2)
++cur_stats->mode_use_transform[img->type][4][1];
else
++cur_stats->mode_use_transform[img->type][4][0];
}
}
}
else if (currMB->mb_type >= 0 && currMB->mb_type <=3 && ((currMB->cbp&15) != 0))
{
++cur_stats->mode_use_transform[img->type][currMB->mb_type][currMB->luma_transform_size_8x8_flag];
}
}
// Statistics
cur_stats->quant[img->type] += currMB->qp;
cur_stats->num_macroblocks[img->type]++;
}
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 + img->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)
{
currMB->qp_scaled[0] = currMB->qp + img->bitdepth_luma_qp_scale;
set_chroma_qp(img, currMB);
select_dct(img, currMB);
}
/*!
************************************************************************
* \brief
* resets info for the current macroblock
*
* \param currMB
* current macroblock
* \param prev_mb
* previous macroblock address
************************************************************************
*/
void reset_macroblock(Macroblock *currMB, int prev_mb)
{
int i,j,l;
// Reset vectors and reference indices
for (l=0; l<2; l++)
{
for (j=img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
{
memset(&enc_picture->motion.ref_idx[l][j][img->block_x], -1, BLOCK_MULTIPLE * sizeof(char));
memset(enc_picture->motion.mv [l][j][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short));
for (i=img->block_x; i < img->block_x + BLOCK_MULTIPLE; i++)
enc_picture->motion.ref_pic_id[l][j][i]= -1;
}
}
// Reset syntax element entries in MB struct
currMB->mb_type = 0;
currMB->cbp_blk = 0;
currMB->cbp = 0;
currMB->c_ipred_mode = DC_PRED_8;
cmp_cbp[1] = cmp_cbp[2] = curr_cbp[0] = curr_cbp[1] = 0;
memset(currMB->cbp_bits , 0, 3 * sizeof(int64));
memset(currMB->cbp_bits_8x8, 0, 3 * sizeof(int64));
memset (currMB->mvd, 0, BLOCK_CONTEXT * sizeof(short));
memset (currMB->intra_pred_modes, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char)); // changing this to char would allow us to use memset
memset (currMB->intra_pred_modes8x8, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
memset (currMB->bipred_me, 0, 4* sizeof(short));
//initialize the whole MB as INTRA coded
//Blocks are set to notINTRA in write_one_macroblock
if (params->UseConstrainedIntraPred)
{
img->intra_block[img->current_mb_nr] = 1;
}
// Initialize bitcounters for this macroblock
if(prev_mb < 0) // No slice header to account for
{
currMB->bitcounter[BITS_HEADER] = 0;
}
else if (currMB->slice_nr == img->mb_data[prev_mb].slice_nr) // current MB belongs to the
// same slice as the last MB
{
currMB->bitcounter[BITS_HEADER] = 0;
}
currMB->bitcounter[BITS_MB_MODE ] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -