diff --git a/src/encmain.c b/src/encmain.c index b7abb922..c99ba98e 100644 --- a/src/encmain.c +++ b/src/encmain.c @@ -102,6 +102,7 @@ } /* Initialization */ + init_tables(); init_exp_golomb(4096*8); cabac_init(&cabac); init_encoder_control(encoder, (bitstream*)malloc(sizeof(bitstream))); diff --git a/src/encoder.c b/src/encoder.c index 34533591..53ccf13c 100644 --- a/src/encoder.c +++ b/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; istream = 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<in.cur_pic.CU[depth][(xCtb>>(MAX_DEPTH-depth))+(yCtb>>(MAX_DEPTH-depth))*(encoder->in.width_in_LCU< 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<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"); diff --git a/src/encoder.h b/src/encoder.h index 89650763..ba81c882 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -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 \ No newline at end of file