mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +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 */
|
/* Initialization */
|
||||||
|
init_tables();
|
||||||
init_exp_golomb(4096*8);
|
init_exp_golomb(4096*8);
|
||||||
cabac_init(&cabac);
|
cabac_init(&cabac);
|
||||||
init_encoder_control(encoder, (bitstream*)malloc(sizeof(bitstream)));
|
init_encoder_control(encoder, (bitstream*)malloc(sizeof(bitstream)));
|
||||||
|
|
204
src/encoder.c
204
src/encoder.c
|
@ -26,6 +26,164 @@
|
||||||
#include "nal.h"
|
#include "nal.h"
|
||||||
#include "context.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)
|
void init_encoder_control(encoder_control* control,bitstream* output)
|
||||||
{
|
{
|
||||||
control->stream = output;
|
control->stream = output;
|
||||||
|
@ -298,8 +456,8 @@ void encode_slice_data(encoder_control* encoder)
|
||||||
|
|
||||||
init_contexts(encoder);
|
init_contexts(encoder);
|
||||||
|
|
||||||
encoder->in.cur_pic.CU[1][2].type = CU_INTRA;
|
//encoder->in.cur_pic.CU[3][5].type = CU_INTRA;
|
||||||
encoder->in.cur_pic.CU[1][3].type = CU_INTRA;
|
//encoder->in.cur_pic.CU[3][6].type = CU_INTRA;
|
||||||
|
|
||||||
/* Loop through every LCU in the slice */
|
/* Loop through every LCU in the slice */
|
||||||
for(yCtb = 0; yCtb < encoder->in.height_in_LCU; yCtb++)
|
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)
|
void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, uint8_t depth)
|
||||||
{
|
{
|
||||||
int i,x,y;
|
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;
|
uint8_t split_model = 0;
|
||||||
|
|
||||||
/* Check for slice border */
|
/* Check for slice border */
|
||||||
uint8_t border_x = ((encoder->in.width)<( xCtb*(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)<( yCtb*(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;
|
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 */
|
/* When not in MAX_DEPTH, insert split flag and split the blocks if needed */
|
||||||
if(depth != MAX_DEPTH)
|
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
|
//Implisit split flag when on border
|
||||||
if(!border)
|
if(!border)
|
||||||
{
|
{
|
||||||
|
@ -374,6 +532,12 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(yCtb > 20 && xCtb > 20)
|
||||||
|
{
|
||||||
|
cur_CU->type = CU_INTRA;
|
||||||
|
}
|
||||||
|
|
||||||
/* coding_unit( x0, y0, log2CbSize ) */
|
/* coding_unit( x0, y0, log2CbSize ) */
|
||||||
/* prediction_unit 2Nx2N*/
|
/* prediction_unit 2Nx2N*/
|
||||||
//if !intra PREDMODE
|
//if !intra PREDMODE
|
||||||
|
@ -386,9 +550,8 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
||||||
}
|
}
|
||||||
/*end partsize*/
|
/*end partsize*/
|
||||||
//If MODE_INTRA
|
//If MODE_INTRA
|
||||||
//cabac.ctx = &PCMFlagSCModel;
|
|
||||||
/* Code IPCM block */
|
/* 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)
|
if(cur_CU->type == CU_PCM || cur_CU->type == CU_NOTSET)
|
||||||
{
|
{
|
||||||
cabac_encodeBinTrm(&cabac, 1); /* IPCMFlag == 1 */
|
cabac_encodeBinTrm(&cabac, 1); /* IPCMFlag == 1 */
|
||||||
//printf("\tIPCMFlag = 1\n");
|
//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);
|
cabac_start(&cabac);
|
||||||
|
|
||||||
} /* end Code IPCM block */
|
} /* end Code IPCM block */
|
||||||
else
|
else if(cur_CU->type == CU_INTRA)
|
||||||
{
|
{
|
||||||
cabac_encodeBinTrm(&cabac, 0); /* IPCMFlag == 0 */
|
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 */
|
/* scanCG == g_sigLastScanCG32x32 */
|
||||||
/* Residual Coding */
|
/* Residual Coding */
|
||||||
/* LastSignificantXY */
|
/* 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-- )
|
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 Transform tree */
|
||||||
/* end Coeff */
|
/* end Coeff */
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//printf("UNHANDLED TYPE!\r\n");
|
||||||
|
//exit(1);
|
||||||
|
}
|
||||||
//endif
|
//endif
|
||||||
/* end prediction unit */
|
/* 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)
|
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;
|
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.ctx = &g_CuCtxLastX_luma[offset_x+(last_x>>shift_x)];
|
||||||
CABAC_BIN(&cabac,1,"LastSignificantX");
|
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.ctx = &g_CuCtxLastX_luma[offset_x+(last_x>>shift_x)];
|
||||||
CABAC_BIN(&cabac,0,"LastSignificantX");
|
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.ctx = &g_CuCtxLastY_luma[offset_y+(last_y>>shift_y)];
|
||||||
CABAC_BIN(&cabac,1,"LastSignificantY");
|
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.ctx = &g_CuCtxLastY_luma[offset_y+(last_y>>shift_y)];
|
||||||
CABAC_BIN(&cabac,0,"LastSignificantY");
|
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_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);
|
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_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_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,
|
{ 0, 8, 1,16, 9, 2,24,17,
|
||||||
10, 3,32,25,18,11, 4,40,
|
10, 3,32,25,18,11, 4,40,
|
||||||
33,26,19,12, 5,48,41,34,
|
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,
|
29,22,15,58,51,44,37,30,
|
||||||
23,59,52,45,38,31,60,53,
|
23,59,52,45,38,31,60,53,
|
||||||
46,39,61,54,47,62,55,63 };
|
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
|
//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 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
|
#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
|
#endif
|
Loading…
Reference in a new issue