mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 11:24:05 +00:00
Added new function init_tables() and new global tables
This commit is contained in:
parent
6b9f5a7282
commit
43354b412b
|
@ -102,6 +102,7 @@
|
|||
}
|
||||
|
||||
/* Initialization */
|
||||
init_tables();
|
||||
init_exp_golomb(4096*8);
|
||||
cabac_init(&cabac);
|
||||
init_encoder_control(encoder, (bitstream*)malloc(sizeof(bitstream)));
|
||||
|
|
206
src/encoder.c
206
src/encoder.c
|
@ -26,6 +26,164 @@
|
|||
#include "nal.h"
|
||||
#include "context.h"
|
||||
|
||||
void initSigLastScan(uint32_t* pBuffZ, uint32_t* pBuffH, uint32_t* pBuffV, uint32_t* pBuffD, int32_t iWidth, int32_t iHeight, int32_t iDepth)
|
||||
{
|
||||
uint32_t uiNumScanPos = iWidth * iWidth;
|
||||
uint32_t uiNextScanPos = 0;
|
||||
int32_t iX,iY,x,y;
|
||||
uint32_t uiScanLine;
|
||||
uint32_t blkY,blkX;
|
||||
uint32_t uiBlk;
|
||||
uint32_t uiCnt = 0;
|
||||
|
||||
if( iWidth < 16 )
|
||||
{
|
||||
uint32_t* pBuffTemp = pBuffD;
|
||||
if( iWidth == 8 )
|
||||
{
|
||||
pBuffTemp = (uint32_t *)g_sigLastScanCG32x32;
|
||||
}
|
||||
for( uiScanLine = 0; uiNextScanPos < uiNumScanPos; uiScanLine++ )
|
||||
{
|
||||
int iPrimDim = uiScanLine;
|
||||
int iScndDim = 0;
|
||||
while( iPrimDim >= iWidth )
|
||||
{
|
||||
iScndDim++;
|
||||
iPrimDim--;
|
||||
}
|
||||
while( iPrimDim >= 0 && iScndDim < iWidth )
|
||||
{
|
||||
pBuffTemp[ uiNextScanPos ] = iPrimDim * iWidth + iScndDim ;
|
||||
uiNextScanPos++;
|
||||
iScndDim++;
|
||||
iPrimDim--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( iWidth > 4 )
|
||||
{
|
||||
uint32_t uiNumBlkSide = iWidth >> 2;
|
||||
uint32_t uiNumBlks = uiNumBlkSide * uiNumBlkSide;
|
||||
uint32_t log2Blk = g_aucConvertToBit[ uiNumBlkSide ] + 1;
|
||||
|
||||
for(uiBlk = 0; uiBlk < uiNumBlks; uiBlk++ )
|
||||
{
|
||||
uint32_t initBlkPos = g_auiSigLastScan[ SCAN_DIAG ][ log2Blk ][ uiBlk ];
|
||||
uiNextScanPos = 0;
|
||||
if( iWidth == 32 )
|
||||
{
|
||||
initBlkPos = g_sigLastScanCG32x32[ uiBlk ];
|
||||
}
|
||||
{
|
||||
uint32_t offsetY = initBlkPos / uiNumBlkSide;
|
||||
uint32_t offsetX = initBlkPos - offsetY * uiNumBlkSide;
|
||||
uint32_t offsetD = 4 * ( offsetX + offsetY * iWidth );
|
||||
uint32_t offsetScan = 16 * uiBlk;
|
||||
for( uiScanLine = 0; uiNextScanPos < 16; uiScanLine++ )
|
||||
{
|
||||
int iPrimDim = uiScanLine;
|
||||
int iScndDim = 0;
|
||||
while( iPrimDim >= 4 )
|
||||
{
|
||||
iScndDim++;
|
||||
iPrimDim--;
|
||||
}
|
||||
while( iPrimDim >= 0 && iScndDim < 4 )
|
||||
{
|
||||
pBuffD[ uiNextScanPos + offsetScan ] = iPrimDim * iWidth + iScndDim + offsetD;
|
||||
uiNextScanPos++;
|
||||
iScndDim++;
|
||||
iPrimDim--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( iWidth > 2 )
|
||||
{
|
||||
uint32_t numBlkSide = iWidth >> 2;
|
||||
for(blkY=0; blkY < numBlkSide; blkY++)
|
||||
{
|
||||
for(blkX=0; blkX < numBlkSide; blkX++)
|
||||
{
|
||||
uint32_t offset = blkY * 4 * iWidth + blkX * 4;
|
||||
for(y=0; y < 4; y++)
|
||||
{
|
||||
for(x=0; x < 4; x++)
|
||||
{
|
||||
pBuffH[uiCnt] = y*iWidth + x + offset;
|
||||
uiCnt ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uiCnt = 0;
|
||||
for(blkX=0; blkX < numBlkSide; blkX++)
|
||||
{
|
||||
for(blkY=0; blkY < numBlkSide; blkY++)
|
||||
{
|
||||
uint32_t offset = blkY * 4 * iWidth + blkX * 4;
|
||||
for(x=0; x < 4; x++)
|
||||
{
|
||||
for(y=0; y < 4; y++)
|
||||
{
|
||||
pBuffV[uiCnt] = y*iWidth + x + offset;
|
||||
uiCnt ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(iY=0; iY < iHeight; iY++)
|
||||
{
|
||||
for(iX=0; iX < iWidth; iX++)
|
||||
{
|
||||
pBuffH[uiCnt] = iY*iWidth + iX;
|
||||
uiCnt ++;
|
||||
}
|
||||
}
|
||||
|
||||
uiCnt = 0;
|
||||
for(iX=0; iX < iWidth; iX++)
|
||||
{
|
||||
for(iY=0; iY < iHeight; iY++)
|
||||
{
|
||||
pBuffV[uiCnt] = iY*iWidth + iX;
|
||||
uiCnt ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_tables(void)
|
||||
{
|
||||
int i;
|
||||
int c = 0;
|
||||
memset( g_aucConvertToBit,-1, sizeof( g_aucConvertToBit ) );
|
||||
for ( i=4; i<LCU_WIDTH; i*=2 )
|
||||
{
|
||||
g_aucConvertToBit[i] = c;
|
||||
c++;
|
||||
}
|
||||
g_aucConvertToBit[i] = c;
|
||||
|
||||
c = 2;
|
||||
for ( i=0; i<MAX_DEPTH; i++ )
|
||||
{
|
||||
g_auiSigLastScan[0][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t));
|
||||
g_auiSigLastScan[1][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t));
|
||||
g_auiSigLastScan[2][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t));
|
||||
g_auiSigLastScan[3][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t));
|
||||
|
||||
initSigLastScan( g_auiSigLastScan[0][i], g_auiSigLastScan[1][i], g_auiSigLastScan[2][i], g_auiSigLastScan[3][i], c, c, i);
|
||||
c <<= 1;
|
||||
}
|
||||
|
||||
}
|
||||
void init_encoder_control(encoder_control* control,bitstream* output)
|
||||
{
|
||||
control->stream = output;
|
||||
|
@ -298,8 +456,8 @@ void encode_slice_data(encoder_control* encoder)
|
|||
|
||||
init_contexts(encoder);
|
||||
|
||||
encoder->in.cur_pic.CU[1][2].type = CU_INTRA;
|
||||
encoder->in.cur_pic.CU[1][3].type = CU_INTRA;
|
||||
//encoder->in.cur_pic.CU[3][5].type = CU_INTRA;
|
||||
//encoder->in.cur_pic.CU[3][6].type = CU_INTRA;
|
||||
|
||||
/* Loop through every LCU in the slice */
|
||||
for(yCtb = 0; yCtb < encoder->in.height_in_LCU; yCtb++)
|
||||
|
@ -325,19 +483,19 @@ void encode_slice_data(encoder_control* encoder)
|
|||
void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, uint8_t depth)
|
||||
{
|
||||
int i,x,y;
|
||||
uint8_t split_flag = (depth!=1)?1:0;
|
||||
uint8_t split_flag = (depth<1)?1:0; /* ToDo: get from CU data */
|
||||
uint8_t split_model = 0;
|
||||
|
||||
/* Check for slice border */
|
||||
uint8_t border_x = ((encoder->in.width)<( xCtb*(LCU_WIDTH>>(MAX_DEPTH)) + LCU_WIDTH>>depth ))?1:0;
|
||||
uint8_t border_y = ((encoder->in.height)<( yCtb*(LCU_WIDTH>>(MAX_DEPTH)) + LCU_WIDTH>>depth ))?1:0;
|
||||
uint8_t border_x = ((encoder->in.width)<(uint32_t)( xCtb*(LCU_WIDTH>>MAX_DEPTH) + (LCU_WIDTH>>depth) ))?1:0;
|
||||
uint8_t border_y = ((encoder->in.height)<(uint32_t)( yCtb*(LCU_WIDTH>>MAX_DEPTH) + (LCU_WIDTH>>depth) ))?1:0;
|
||||
uint8_t border = border_x | border_y;
|
||||
|
||||
CU_info *cur_CU = &encoder->in.cur_pic.CU[depth][(xCtb>>(MAX_DEPTH-depth))+(yCtb>>(MAX_DEPTH-depth))*(encoder->in.width_in_LCU<<MAX_DEPTH)];
|
||||
|
||||
/* When not in MAX_DEPTH, insert split flag and split the blocks if needed */
|
||||
if(depth != MAX_DEPTH)
|
||||
{
|
||||
SET_SPLITDATA(&(encoder->in.cur_pic.CU[depth][(xCtb>>(MAX_DEPTH-depth))+(yCtb>>(MAX_DEPTH-depth))*(encoder->in.width_in_LCU<<MAX_DEPTH)]),split_flag);
|
||||
SET_SPLITDATA(cur_CU,split_flag);
|
||||
//Implisit split flag when on border
|
||||
if(!border)
|
||||
{
|
||||
|
@ -374,6 +532,12 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(yCtb > 20 && xCtb > 20)
|
||||
{
|
||||
cur_CU->type = CU_INTRA;
|
||||
}
|
||||
|
||||
/* coding_unit( x0, y0, log2CbSize ) */
|
||||
/* prediction_unit 2Nx2N*/
|
||||
//if !intra PREDMODE
|
||||
|
@ -386,9 +550,8 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
}
|
||||
/*end partsize*/
|
||||
//If MODE_INTRA
|
||||
//cabac.ctx = &PCMFlagSCModel;
|
||||
/* Code IPCM block */
|
||||
if(encoder->in.cur_pic.CU[depth][(xCtb>>(MAX_DEPTH-depth))+(yCtb>>(MAX_DEPTH-depth))*(encoder->in.width_in_LCU<<MAX_DEPTH)].type <= CU_PCM)
|
||||
/* Code IPCM block */
|
||||
if(cur_CU->type == CU_PCM || cur_CU->type == CU_NOTSET)
|
||||
{
|
||||
cabac_encodeBinTrm(&cabac, 1); /* IPCMFlag == 1 */
|
||||
//printf("\tIPCMFlag = 1\n");
|
||||
|
@ -433,7 +596,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
cabac_start(&cabac);
|
||||
|
||||
} /* end Code IPCM block */
|
||||
else
|
||||
else if(cur_CU->type == CU_INTRA)
|
||||
{
|
||||
cabac_encodeBinTrm(&cabac, 0); /* IPCMFlag == 0 */
|
||||
|
||||
|
@ -491,7 +654,15 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
/* scanCG == g_sigLastScanCG32x32 */
|
||||
/* Residual Coding */
|
||||
/* LastSignificantXY */
|
||||
encode_lastSignificantXY(encoder,31/*last_coeff_x */, 31/* last_coeff_y */, 32, 32, 0, 0);
|
||||
int16_t coeff[32*32];
|
||||
uint8_t last_coeff_x = 0;
|
||||
uint8_t last_coeff_y = 0;
|
||||
uint32_t sig_coeffgroup_flag[64];
|
||||
memset(coeff,0,sizeof(int16_t)*16*16);
|
||||
memset(sig_coeffgroup_flag,0,sizeof(uint32_t)*64);
|
||||
coeff[8*16+8] = 123;
|
||||
|
||||
encode_lastSignificantXY(encoder,last_coeff_x, last_coeff_y, LCU_WIDTH>>depth, LCU_WIDTH>>depth, 0, 0);
|
||||
|
||||
for(i = 15; i >= 0; i-- )
|
||||
{
|
||||
|
@ -530,6 +701,11 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
/* end Transform tree */
|
||||
/* end Coeff */
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("UNHANDLED TYPE!\r\n");
|
||||
//exit(1);
|
||||
}
|
||||
//endif
|
||||
/* end prediction unit */
|
||||
|
||||
|
@ -541,7 +717,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
|
||||
}
|
||||
|
||||
|
||||
/* ToDo: fix for others than 32x32 */
|
||||
void encode_lastSignificantXY(encoder_control* encoder,uint8_t lastpos_x, uint8_t lastpos_y, uint8_t width, uint8_t height, uint8_t type, uint8_t scan)
|
||||
{
|
||||
uint8_t offset_x = type?0:((TOBITS(width)*3) + ((TOBITS(width)+1)>>2)),offset_y = offset_x;
|
||||
|
@ -562,7 +738,7 @@ void encode_lastSignificantXY(encoder_control* encoder,uint8_t lastpos_x, uint8_
|
|||
cabac.ctx = &g_CuCtxLastX_luma[offset_x+(last_x>>shift_x)];
|
||||
CABAC_BIN(&cabac,1,"LastSignificantX");
|
||||
}
|
||||
if(uiGroupIdxX < g_uiGroupIdx[32-1])
|
||||
if(uiGroupIdxX < g_uiGroupIdx[width-1])
|
||||
{
|
||||
cabac.ctx = &g_CuCtxLastX_luma[offset_x+(last_x>>shift_x)];
|
||||
CABAC_BIN(&cabac,0,"LastSignificantX");
|
||||
|
@ -574,7 +750,7 @@ void encode_lastSignificantXY(encoder_control* encoder,uint8_t lastpos_x, uint8_
|
|||
cabac.ctx = &g_CuCtxLastY_luma[offset_y+(last_y>>shift_y)];
|
||||
CABAC_BIN(&cabac,1,"LastSignificantY");
|
||||
}
|
||||
if(uiGroupIdxY < g_uiGroupIdx[32-1])
|
||||
if(uiGroupIdxY < g_uiGroupIdx[height-1])
|
||||
{
|
||||
cabac.ctx = &g_CuCtxLastY_luma[offset_y+(last_y>>shift_y)];
|
||||
CABAC_BIN(&cabac,0,"LastSignificantY");
|
||||
|
|
|
@ -67,11 +67,14 @@ void encode_slice_header(encoder_control* encoder);
|
|||
void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, uint8_t depth);
|
||||
void encode_lastSignificantXY(encoder_control* encoder,uint8_t lastpos_x, uint8_t lastpos_y, uint8_t width, uint8_t height, uint8_t type, uint8_t scan);
|
||||
|
||||
static uint8_t* g_auiSigLastScan[4][7];
|
||||
void init_tables(void);
|
||||
|
||||
static uint32_t* g_auiSigLastScan[4][7];
|
||||
int8_t g_aucConvertToBit[LCU_WIDTH+1];
|
||||
|
||||
static const uint8_t g_uiGroupIdx[ 32 ] = {0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9};
|
||||
static const uint8_t g_uiMinInGroup[ 10 ] = {0,1,2,3,4,6,8,12,16,24};
|
||||
static const uint8_t g_sigLastScanCG32x32[ 64 ] =
|
||||
static uint32_t g_sigLastScanCG32x32[ 64 ] =
|
||||
{ 0, 8, 1,16, 9, 2,24,17,
|
||||
10, 3,32,25,18,11, 4,40,
|
||||
33,26,19,12, 5,48,41,34,
|
||||
|
@ -80,6 +83,11 @@ static const uint8_t g_sigLastScanCG32x32[ 64 ] =
|
|||
29,22,15,58,51,44,37,30,
|
||||
23,59,52,45,38,31,60,53,
|
||||
46,39,61,54,47,62,55,63 };
|
||||
static const uint32_t g_sigLastScan8x8[ 4 ][ 4 ] =
|
||||
{ {0, 1, 2, 3},
|
||||
{0, 1, 2, 3},
|
||||
{0, 2, 1, 3},
|
||||
{0, 2, 1, 3} };
|
||||
|
||||
//
|
||||
//4 8 16 32 64 128
|
||||
|
@ -100,5 +108,13 @@ static const uint8_t g_toBits[129] =
|
|||
#define C1FLAG_NUMBER 8 // maximum number of largerThan1 flag coded in one chunk
|
||||
#define C2FLAG_NUMBER 1 // maximum number of largerThan2 flag coded in one chunk
|
||||
|
||||
enum COEFF_SCAN_TYPE
|
||||
{
|
||||
SCAN_ZIGZAG = 0,
|
||||
SCAN_HOR,
|
||||
SCAN_VER,
|
||||
SCAN_DIAG
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue