Added support for 16x16 luma coeff coding and disabled PCM

This commit is contained in:
Marko Viitanen 2013-03-20 17:27:47 +02:00
parent ff5652609e
commit 05bbd4daee
8 changed files with 127 additions and 65 deletions

View file

@ -104,8 +104,7 @@ void init_contexts(encoder_control *encoder, int8_t SLICE)
uint32_t context_get_sigCoeffGroup( uint32_t* uiSigCoeffGroupFlag, uint32_t context_get_sigCoeffGroup( uint32_t* uiSigCoeffGroupFlag,
uint32_t uiCGPosX, uint32_t uiCGPosX,
uint32_t uiCGPosY, uint32_t uiCGPosY,
uint32_t scanIdx,
int32_t width) int32_t width)
{ {
uint32_t uiRight = 0; uint32_t uiRight = 0;

View file

@ -22,7 +22,7 @@ void init_contexts(encoder_control *encoder, int8_t SLICE);
int32_t context_calcPatternSigCtx( const uint32_t* sigCoeffGroupFlag, uint32_t posXCG, uint32_t posYCG, int32_t width); int32_t context_calcPatternSigCtx( const uint32_t* sigCoeffGroupFlag, uint32_t posXCG, uint32_t posYCG, int32_t width);
uint32_t context_get_sigCoeffGroup( uint32_t* uiSigCoeffGroupFlag,uint32_t uiCGPosX, uint32_t context_get_sigCoeffGroup( uint32_t* uiSigCoeffGroupFlag,uint32_t uiCGPosX,
uint32_t uiCGPosY,uint32_t scanIdx,int32_t width); uint32_t uiCGPosY,int32_t width);
int32_t context_getSigCtxInc(int32_t patternSigCtx,uint32_t scanIdx,int32_t posX, int32_t context_getSigCtxInc(int32_t patternSigCtx,uint32_t scanIdx,int32_t posX,
int32_t posY,int32_t blockType,int32_t width, int32_t posY,int32_t blockType,int32_t width,

View file

@ -28,7 +28,7 @@
#include "transform.h" #include "transform.h"
#include "intra.h" #include "intra.h"
void initSigLastScan(uint32_t* pBuffZ, uint32_t* pBuffH, uint32_t* pBuffV, uint32_t* pBuffD, int32_t iWidth, int32_t iHeight, int32_t iDepth) void initSigLastScan(uint32_t* pBuffD, uint32_t* pBuffH, uint32_t* pBuffV, int32_t iWidth, int32_t iHeight)
{ {
uint32_t uiNumScanPos = iWidth * iWidth; uint32_t uiNumScanPos = iWidth * iWidth;
uint32_t uiNextScanPos = 0; uint32_t uiNextScanPos = 0;
@ -180,9 +180,8 @@ void init_tables(void)
g_auiSigLastScan[0][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t)); 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[1][i] = (uint32_t*)malloc(c*c*sizeof(uint32_t));
g_auiSigLastScan[2][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); initSigLastScan( g_auiSigLastScan[0][i], g_auiSigLastScan[1][i], g_auiSigLastScan[2][i], c, c);
c <<= 1; c <<= 1;
} }
@ -329,7 +328,7 @@ void encode_pic_parameter_set(encoder_control* encoder)
WRITE_U(encoder->stream, 0, 1, "dependent_slice_segments_enabled_flag"); WRITE_U(encoder->stream, 0, 1, "dependent_slice_segments_enabled_flag");
WRITE_U(encoder->stream, 0, 1, "output_flag_present_flag"); WRITE_U(encoder->stream, 0, 1, "output_flag_present_flag");
WRITE_U(encoder->stream, 0, 3, "num_extra_slice_header_bits"); WRITE_U(encoder->stream, 0, 3, "num_extra_slice_header_bits");
WRITE_U(encoder->stream, 0, 1, "sign_data_hiding_flag"); WRITE_U(encoder->stream, ENABLE_SIGN_HIDING, 1, "sign_data_hiding_flag");
WRITE_U(encoder->stream, 0, 1, "cabac_init_present_flag"); WRITE_U(encoder->stream, 0, 1, "cabac_init_present_flag");
WRITE_UE(encoder->stream, 0, "num_ref_idx_l0_default_active_minus1"); WRITE_UE(encoder->stream, 0, "num_ref_idx_l0_default_active_minus1");
@ -392,7 +391,7 @@ void encode_PTL(encoder_control *encoder)
WRITE_U(encoder->stream, 0, 8, "general_level_idc"); WRITE_U(encoder->stream, 0, 8, "general_level_idc");
WRITE_U(encoder->stream, 0, 1, "sub_layer_profile_present_flag"); WRITE_U(encoder->stream, 0, 1, "sub_layer_profile_present_flag");
WRITE_U(encoder->stream, 0, 1, "sub_layer_level_present_flag"); WRITE_U(encoder->stream, 0, 1, "sub_layer_level_present_flag");
for(i = 1; i < 8; i++) for(i = 1; i < 8; i++)
{ {
@ -430,7 +429,7 @@ void encode_seq_parameter_set(encoder_control* encoder)
WRITE_UE(encoder->stream, encoder->bitdepth-8, "bit_depth_luma_minus8"); WRITE_UE(encoder->stream, encoder->bitdepth-8, "bit_depth_luma_minus8");
WRITE_UE(encoder->stream, encoder->bitdepth-8, "bit_depth_chroma_minus8"); WRITE_UE(encoder->stream, encoder->bitdepth-8, "bit_depth_chroma_minus8");
WRITE_UE(encoder->stream, 4, "log2_max_pic_order_cnt_lsb_minus4"); WRITE_UE(encoder->stream, 0, "log2_max_pic_order_cnt_lsb_minus4");
WRITE_U(encoder->stream, 0, 1, "sps_sub_layer_ordering_info_present_flag"); WRITE_U(encoder->stream, 0, 1, "sps_sub_layer_ordering_info_present_flag");
//for each layer //for each layer
@ -445,6 +444,8 @@ void encode_seq_parameter_set(encoder_control* encoder)
WRITE_UE(encoder->stream, 3, "log2_diff_max_min_transform_block_size"); WRITE_UE(encoder->stream, 3, "log2_diff_max_min_transform_block_size");
WRITE_UE(encoder->stream, 2, "max_transform_hierarchy_depth_inter"); WRITE_UE(encoder->stream, 2, "max_transform_hierarchy_depth_inter");
WRITE_UE(encoder->stream, 2, "max_transform_hierarchy_depth_intra"); WRITE_UE(encoder->stream, 2, "max_transform_hierarchy_depth_intra");
/* Use default scaling list */
WRITE_U(encoder->stream, 1, 1, "scaling_list_enable_flag"); WRITE_U(encoder->stream, 1, 1, "scaling_list_enable_flag");
//IF scaling list //IF scaling list
WRITE_U(encoder->stream, 0, 1, "sps_scaling_list_data_present_flag"); WRITE_U(encoder->stream, 0, 1, "sps_scaling_list_data_present_flag");
@ -499,7 +500,7 @@ void encode_vid_parameter_set(encoder_control* encoder)
//for each layer //for each layer
for(i = 0; i < 1; i++) for(i = 0; i < 1; i++)
{ {
WRITE_UE(encoder->stream, 0, "vps_max_dec_pic_buffering"); WRITE_UE(encoder->stream, 1, "vps_max_dec_pic_buffering");
WRITE_UE(encoder->stream, 0, "vps_num_reorder_pics"); WRITE_UE(encoder->stream, 0, "vps_num_reorder_pics");
WRITE_UE(encoder->stream, 0, "vps_max_latency_increase"); WRITE_UE(encoder->stream, 0, "vps_max_latency_increase");
} }
@ -580,7 +581,7 @@ void encode_slice_header(encoder_control* encoder)
} }
else else
{ {
WRITE_U(encoder->stream, encoder->frame, 8, "pic_order_cnt_lsb"); WRITE_U(encoder->stream, encoder->frame, 4, "pic_order_cnt_lsb");
WRITE_U(encoder->stream, 1, 1, "short_term_ref_pic_set_sps_flag"); WRITE_U(encoder->stream, 1, 1, "short_term_ref_pic_set_sps_flag");
//WRITE_UE(encoder->stream, 0, "short_term_ref_pic_set_idx"); //WRITE_UE(encoder->stream, 0, "short_term_ref_pic_set_idx");
} }
@ -629,7 +630,7 @@ 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 x,y; int x,y;
uint8_t split_flag = (depth<1)?1:0; /* ToDo: get from CU data */ uint8_t split_flag = (depth<2)?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 */
@ -719,14 +720,18 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
uint8_t *recbaseU = &encoder->in.cur_pic.uRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)]; uint8_t *recbaseU = &encoder->in.cur_pic.uRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
uint8_t *recbaseV = &encoder->in.cur_pic.vRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)]; uint8_t *recbaseV = &encoder->in.cur_pic.vRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
#if ENABLE_PCM == 1
/* Code must start after variable initialization */ /* Code must start after variable initialization */
cabac_encodeBinTrm(&cabac, 0); /* IPCMFlag == 0 */ cabac_encodeBinTrm(&cabac, 0); /* IPCMFlag == 0 */
#endif
/* Build reconstructed block to use in prediction with extrapolated borders */ /* Build reconstructed block to use in prediction with extrapolated borders */
intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth))*2+8, rec, (LCU_WIDTH>>(depth))*2+8, 0); intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth))*2+8, rec, (LCU_WIDTH>>(depth))*2+8, 0);
intraPredMode = (uint8_t)intra_prediction(encoder->in.cur_pic.yData,encoder->in.width,recShift,(LCU_WIDTH>>(depth))*2+8,xCtb*(LCU_WIDTH>>(MAX_DEPTH)),yCtb*(LCU_WIDTH>>(MAX_DEPTH)),width,pred,width,&bestSAD); intraPredMode = (uint8_t)intra_prediction(encoder->in.cur_pic.yData,encoder->in.width,recShift,(LCU_WIDTH>>(depth))*2+8,xCtb*(LCU_WIDTH>>(MAX_DEPTH)),yCtb*(LCU_WIDTH>>(MAX_DEPTH)),width,pred,width,&bestSAD);
intra_setBlockMode(&encoder->in.cur_pic, xCtb, yCtb, depth, intraPredMode);
/* ToDo: separate chroma prediction */ /* ToDo: separate chroma prediction */
//printf("(%d, %d) SAD: %d\n", xCtb,yCtb,bestSAD); //printf("(%d, %d) SAD: %d\n", xCtb,yCtb,bestSAD);
intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth+1))*2+8, rec, (LCU_WIDTH>>(depth+1))*2+8, 1); intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth+1))*2+8, rec, (LCU_WIDTH>>(depth+1))*2+8, 1);
@ -742,8 +747,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
ToDo: split to a function ToDo: split to a function
*/ */
intra_getDirLumaPredictor(&encoder->in.cur_pic, xCtb, yCtb, depth, intraPreds); intra_getDirLumaPredictor(&encoder->in.cur_pic, xCtb, yCtb, depth, intraPreds);
intra_setBlockMode(&encoder->in.cur_pic, xCtb, yCtb, depth, intraPredMode);
for(i = 0; i < 3; i++) for(i = 0; i < 3; i++)
{ {
if(intraPreds[i] == intraPredMode) if(intraPreds[i] == intraPredMode)
@ -834,7 +838,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
/* Coeff */ /* Coeff */
/* Transform tree */ /* Transform tree */
cabac.ctx = &g_TransSubdivSCModel[0]; /* uiLog2TransformBlockSize */ cabac.ctx = &g_TransSubdivSCModel[5-g_aucConvertToBit[LCU_WIDTH]+2-depth];
CABAC_BIN(&cabac,0,"TransformSubdivFlag"); CABAC_BIN(&cabac,0,"TransformSubdivFlag");
/* We don't subdiv and we have 64>>depth transform size */ /* We don't subdiv and we have 64>>depth transform size */
@ -857,7 +861,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
for(x = 0; x < LCU_WIDTH>>depth; x++) for(x = 0; x < LCU_WIDTH>>depth; x++)
{ {
block[i++]=((int16_t)base[x+y*encoder->in.width])-pred[x+y*32]; block[i++]=((int16_t)base[x+y*encoder->in.width])-pred[x+y*(LCU_WIDTH>>depth)];
} }
} }
@ -889,7 +893,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
for(x = 0; x < LCU_WIDTH>>depth; x++) for(x = 0; x < LCU_WIDTH>>depth; x++)
{ {
int16_t val = block[i++]+pred[x+y*32]; int16_t val = block[i++]+pred[x+y*(LCU_WIDTH>>depth)];
//ToDo: support 10+bits //ToDo: support 10+bits
recbase[x+y*encoder->in.width] = (uint8_t)CLIP(0,255,val); recbase[x+y*encoder->in.width] = (uint8_t)CLIP(0,255,val);
} }
@ -903,7 +907,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
for(x = 0; x < LCU_WIDTH>>depth; x++) for(x = 0; x < LCU_WIDTH>>depth; x++)
{ {
recbase[x+y*encoder->in.width] = (uint8_t)CLIP(0,255,pred[x+y*32]); recbase[x+y*encoder->in.width] = (uint8_t)CLIP(0,255,pred[x+y*(LCU_WIDTH>>depth)]);
} }
} }
} }
@ -917,7 +921,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
for(x = 0; x < LCU_WIDTH>>(depth+1); x++) for(x = 0; x < LCU_WIDTH>>(depth+1); x++)
{ {
block[i++]=((int16_t)baseU[x+y*(encoder->in.width>>1)])-predU[x+y*16]; block[i++]=((int16_t)baseU[x+y*(encoder->in.width>>1)])-predU[x+y*(LCU_WIDTH>>(depth+1))];
} }
} }
transform2d(block,pre_quant_coeff,LCU_WIDTH>>(depth+1),0); transform2d(block,pre_quant_coeff,LCU_WIDTH>>(depth+1),0);
@ -938,7 +942,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
for(x = 0; x < LCU_WIDTH>>(depth+1); x++) for(x = 0; x < LCU_WIDTH>>(depth+1); x++)
{ {
block[i++]=((int16_t)baseV[x+y*(encoder->in.width>>1)])-predV[x+y*16]; block[i++]=((int16_t)baseV[x+y*(encoder->in.width>>1)])-predV[x+y*(LCU_WIDTH>>(depth+1))];
} }
} }
transform2d(block,pre_quant_coeff,LCU_WIDTH>>(depth+1),0); transform2d(block,pre_quant_coeff,LCU_WIDTH>>(depth+1),0);
@ -964,7 +968,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
for(x = 0; x < LCU_WIDTH>>(depth+1); x++) for(x = 0; x < LCU_WIDTH>>(depth+1); x++)
{ {
int16_t val = block[i++]+predU[x+y*16]; int16_t val = block[i++]+predU[x+y*(LCU_WIDTH>>(depth+1))];
//ToDo: support 10+bits //ToDo: support 10+bits
recbaseU[x+y*(encoder->in.width>>1)] = (uint8_t)CLIP(0,255,val); recbaseU[x+y*(encoder->in.width>>1)] = (uint8_t)CLIP(0,255,val);
} }
@ -994,7 +998,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
for(x = 0; x < LCU_WIDTH>>(depth+1); x++) for(x = 0; x < LCU_WIDTH>>(depth+1); x++)
{ {
int16_t val = block[i++]+predV[x+y*16]; int16_t val = block[i++]+predV[x+y*(LCU_WIDTH>>(depth+1))];
//ToDo: support 10+bits //ToDo: support 10+bits
recbaseV[x+y*(encoder->in.width>>1)] = (uint8_t)CLIP(0,255,val); recbaseV[x+y*(encoder->in.width>>1)] = (uint8_t)CLIP(0,255,val);
} }
@ -1008,7 +1012,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
for(x = 0; x < LCU_WIDTH>>(depth+1); x++) for(x = 0; x < LCU_WIDTH>>(depth+1); x++)
{ {
recbaseV[x+y*(encoder->in.width>>1)] = (uint8_t)CLIP(0,255,predV[x+y*16]); recbaseV[x+y*(encoder->in.width>>1)] = (uint8_t)CLIP(0,255,predV[x+y*(LCU_WIDTH>>(depth+1))]);
} }
} }
} }
@ -1042,27 +1046,64 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
cabac.ctx = &g_QtCbfSCModelY[1]; cabac.ctx = &g_QtCbfSCModelY[1];
CABAC_BIN(&cabac,CbY,"cbf_luma"); CABAC_BIN(&cabac,CbY,"cbf_luma");
{
uint32_t uiCTXIdx;
uint32_t uiScanIdx = SCAN_DIAG;
uint32_t uiDirMode;
switch(width)
{
case 2: uiCTXIdx = 6; break;
case 4: uiCTXIdx = 5; break;
case 8: uiCTXIdx = 4; break;
case 16: uiCTXIdx = 3; break;
case 32: uiCTXIdx = 2; break;
case 64: uiCTXIdx = 1; break;
default: uiCTXIdx = 0; break;
}
/* CoeffNxN */ /* CoeffNxN */
/* Residual Coding */ /* Residual Coding */
if(CbY) if(CbY)
{ {
encode_CoeffNxN(encoder,coeff, width, 0); uiDirMode = intraPredMode;
if (uiCTXIdx >3 && uiCTXIdx < 6) //if multiple scans supported for transform size
{
uiScanIdx = abs((int32_t) uiDirMode - 26) < 5 ? 1 : (abs((int32_t)uiDirMode - 10) < 5 ? 2 : 0);
}
encode_CoeffNxN(encoder,coeff, width, 0, uiScanIdx);
} }
if(CbU) if(CbU||CbV)
{ {
encode_CoeffNxN(encoder,coeffU, width>>1, 2); uiCTXIdx++;
uiDirMode = intraPredModeChroma;
if(uiDirMode==36)
{
/* ToDo: support NxN */
uiDirMode = intraPredMode;
}
uiScanIdx = SCAN_DIAG;
if (uiCTXIdx >4 && uiCTXIdx < 7) //if multiple scans supported for transform size
{
uiScanIdx = abs((int32_t) uiDirMode - 26) < 5 ? 1 : (abs((int32_t)uiDirMode - 10) < 5 ? 2 : 0);
}
if(CbU)
{
encode_CoeffNxN(encoder,coeffU, width>>1, 2, uiScanIdx);
}
if(CbV)
{
encode_CoeffNxN(encoder,coeffV, width>>1, 2, uiScanIdx);
}
} }
if(CbV)
{
encode_CoeffNxN(encoder,coeffV, width>>1, 2);
} }
/* end Residual Coding */ /* end Residual Coding */
} }
/* end Transform tree */ /* end Transform tree */
/* end Coeff */ /* end Coeff */
} }
#if ENABLE_PCM == 1
/* Code IPCM block */ /* Code IPCM block */
else if(cur_CU->type == CU_PCM || cur_CU->type == CU_NOTSET) /* also handling NOTSET conditions */ else if(cur_CU->type == CU_PCM || cur_CU->type == CU_NOTSET) /* also handling NOTSET conditions */
{ {
@ -1105,7 +1146,8 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
/* end PCM sample */ /* end PCM sample */
cabac_start(&cabac); cabac_start(&cabac);
} /* end Code IPCM block */ } /* end Code IPCM block */
#endif /* END ENABLE_PCM */
else /* Should not happend */ else /* Should not happend */
{ {
printf("UNHANDLED TYPE!\r\n"); printf("UNHANDLED TYPE!\r\n");
@ -1116,7 +1158,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
} }
void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uint8_t type) void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uint8_t type, int8_t scanMode)
{ {
int c1 = 1;//,c1_num; int c1 = 1;//,c1_num;
uint8_t last_coeff_x = 0; uint8_t last_coeff_x = 0;
@ -1133,20 +1175,22 @@ void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uin
uint32_t uiGoRiceParam = 0; uint32_t uiGoRiceParam = 0;
uint32_t uiBlkPos, uiPosY, uiPosX, uiSig, uiCtxSig; uint32_t uiBlkPos, uiPosY, uiPosX, uiSig, uiCtxSig;
int8_t beValid = ENABLE_SIGN_HIDING;
/* if !intra, scanMode = SCAN_DIAG */
/* CONSTANTS */ /* CONSTANTS */
const uint32_t uiNumBlkSide = width >> shift; const uint32_t uiNumBlkSide = width >> shift;
const uint32_t uiLog2BlockSize = g_aucConvertToBit[ width ] + 2; const uint32_t uiLog2BlockSize = g_aucConvertToBit[ width ] + 2;
const uint32_t* scan = g_auiSigLastScan[ SCAN_DIAG ][ uiLog2BlockSize - 1 ]; const uint32_t* scan = g_auiSigLastScan[ scanMode ][ uiLog2BlockSize - 1 ];
const uint32_t* scanCG = NULL; const uint32_t* scanCG = NULL;
/* Init base contexts according to block type */ /* Init base contexts according to block type */
cabac_ctx* baseCoeffGroupCtx = &g_CUSigCoeffGroupSCModel[type]; cabac_ctx* baseCoeffGroupCtx = &g_CUSigCoeffGroupSCModel[type];
cabac_ctx* baseCtx = (type==0) ? &g_CUSigSCModel_luma[0] :&g_CUSigSCModel_chroma[0]; cabac_ctx* baseCtx = (type==0) ? &g_CUSigSCModel_luma[0] :&g_CUSigSCModel_chroma[0];
memset(sig_coeffgroup_flag,0,sizeof(uint32_t)*64); memset(sig_coeffgroup_flag,0,sizeof(uint32_t)*64);
/* Count non-zero coeffs */ /* Count non-zero coeffs */
for(i = 0; i < width*width; i++) for(i = 0; i < width*width; i++)
{ {
@ -1156,10 +1200,10 @@ void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uin
} }
} }
scanCG = g_auiSigLastScan[ SCAN_DIAG ][ uiLog2BlockSize > 3 ? uiLog2BlockSize-2-1 : 0 ]; scanCG = g_auiSigLastScan[ scanMode ][ uiLog2BlockSize > 3 ? uiLog2BlockSize-2-1 : 0 ];
if( uiLog2BlockSize == 3 ) if( uiLog2BlockSize == 3 )
{ {
scanCG = g_sigLastScan8x8[ SCAN_DIAG ]; scanCG = g_sigLastScan8x8[ scanMode ];
} }
else if( uiLog2BlockSize == 5 ) else if( uiLog2BlockSize == 5 )
{ {
@ -1222,7 +1266,7 @@ void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uin
else else
{ {
uint32_t uiSigCoeffGroup = (sig_coeffgroup_flag[ iCGBlkPos ] != 0); uint32_t uiSigCoeffGroup = (sig_coeffgroup_flag[ iCGBlkPos ] != 0);
uint32_t uiCtxSig = context_get_sigCoeffGroup(sig_coeffgroup_flag, iCGPosX, iCGPosY, SCAN_DIAG, width); uint32_t uiCtxSig = context_get_sigCoeffGroup(sig_coeffgroup_flag, iCGPosX, iCGPosY,width);
cabac.ctx = &baseCoeffGroupCtx[ uiCtxSig ]; cabac.ctx = &baseCoeffGroupCtx[ uiCtxSig ];
CABAC_BIN(&cabac,uiSigCoeffGroup,"significant_coeff_group"); CABAC_BIN(&cabac,uiSigCoeffGroup,"significant_coeff_group");
} }
@ -1238,7 +1282,7 @@ void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uin
uiSig = (coeff[ uiBlkPos ] != 0)?1:0; uiSig = (coeff[ uiBlkPos ] != 0)?1:0;
if( iScanPosSig > iSubPos || i == 0 || numNonZero ) if( iScanPosSig > iSubPos || i == 0 || numNonZero )
{ {
uiCtxSig = context_getSigCtxInc( patternSigCtx, SCAN_DIAG, uiPosX, uiPosY, uiLog2BlockSize, width, type ); uiCtxSig = context_getSigCtxInc( patternSigCtx, scanMode, uiPosX, uiPosY, uiLog2BlockSize, width, type );
cabac.ctx = &baseCtx[ uiCtxSig ]; cabac.ctx = &baseCtx[ uiCtxSig ];
CABAC_BIN(&cabac,uiSig,"significant_coeff_flag"); CABAC_BIN(&cabac,uiSig,"significant_coeff_flag");
} }
@ -1309,7 +1353,7 @@ void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uin
} }
//ToDo: enable sign hiding //ToDo: enable sign hiding
if( 0 && /*beValid */ signHidden ) if( beValid && /*beValid */ signHidden )
{ {
CABAC_BINS_EP(&cabac,(coeffSigns >> 1),(numNonZero-1),""); CABAC_BINS_EP(&cabac,(coeffSigns >> 1),(numNonZero-1),"");
} }
@ -1330,7 +1374,7 @@ void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uin
cabac_writeCoeffRemain(&cabac, abs_coeff[ idx ] - baseLevel, uiGoRiceParam ); cabac_writeCoeffRemain(&cabac, abs_coeff[ idx ] - baseLevel, uiGoRiceParam );
if(abs_coeff[idx] > 3*(1<<uiGoRiceParam)) if(abs_coeff[idx] > 3*(1<<uiGoRiceParam))
{ {
uiGoRiceParam = MIN(uiGoRiceParam+ 1, 4); uiGoRiceParam = MIN(uiGoRiceParam+1, 4);
} }
} }
if(abs_coeff[ idx ] >= 2) if(abs_coeff[ idx ] >= 2)
@ -1343,8 +1387,17 @@ void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uin
} }
} }
/*!
/* ToDo: fix for others than 32x32 */ \brief Encode (X,Y) position of the last significant coefficient
\param lastpos_x X component of last coefficient
\param lastpos_y Y component of last coefficient
\param width Block width
\param height Block height
\param type plane type / luminance or chrominance
\param scan scan type (diag, hor, ver)
This method encodes the X and Y component within a block of the last significant coefficient.
*/
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;
@ -1355,6 +1408,14 @@ void encode_lastSignificantXY(encoder_control* encoder,uint8_t lastpos_x, uint8_
cabac_ctx* basectxX = (type?g_CuCtxLastX_chroma:g_CuCtxLastX_luma); cabac_ctx* basectxX = (type?g_CuCtxLastX_chroma:g_CuCtxLastX_luma);
cabac_ctx* basectxY = (type?g_CuCtxLastY_chroma:g_CuCtxLastY_luma); cabac_ctx* basectxY = (type?g_CuCtxLastY_chroma:g_CuCtxLastY_luma);
/* ToDo: handle */
/*
if( scan == SCAN_VER )
{
SWAP( uiPosX, uiPosY,uint8_t );
}
*/
/* Last X binarization */ /* Last X binarization */
for(last_x = 0; last_x < uiGroupIdxX ; last_x++) for(last_x = 0; last_x < uiGroupIdxX ; last_x++)
{ {

View file

@ -67,11 +67,11 @@ void encode_slice_data(encoder_control* encoder);
void encode_slice_header(encoder_control* encoder); 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);
void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uint8_t type); void encode_CoeffNxN(encoder_control* encoder,int16_t* coeff, uint8_t width, uint8_t type, int8_t scanMode);
void init_tables(void); void init_tables(void);
static uint32_t* g_auiSigLastScan[4][7]; static uint32_t* g_auiSigLastScan[3][7];
int8_t g_aucConvertToBit[LCU_WIDTH+1]; int8_t g_aucConvertToBit[LCU_WIDTH+1];
static int8_t g_uiBitDepth = 8; static int8_t g_uiBitDepth = 8;
static int8_t g_uiBitIncrement = 0; static int8_t g_uiBitIncrement = 0;
@ -88,11 +88,11 @@ static uint32_t g_sigLastScanCG32x32[ 64 ] =
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 ] = static const uint32_t g_sigLastScan8x8[ 3 ][ 4 ] =
{ {0, 1, 2, 3}, { {0, 2, 1, 3},
{0, 1, 2, 3}, {0, 1, 2, 3},
{0, 2, 1, 3}, {0, 2, 1, 3}
{0, 2, 1, 3} }; };
// //
//4 8 16 32 64 128 //4 8 16 32 64 128
@ -115,10 +115,9 @@ static const uint8_t g_toBits[129] =
enum COEFF_SCAN_TYPE enum COEFF_SCAN_TYPE
{ {
SCAN_ZIGZAG = 0, SCAN_DIAG = 0, /*!< up-right diagonal scan */
SCAN_HOR, SCAN_HOR, /*!< horizontal first scan */
SCAN_VER, SCAN_VER /*!< vertical first scan */
SCAN_DIAG
}; };

View file

@ -18,7 +18,8 @@
#define MAX_DEPTH 3 /*!< smallest CU is LCU_WIDTH>>MAX_DEPTH */ #define MAX_DEPTH 3 /*!< smallest CU is LCU_WIDTH>>MAX_DEPTH */
#define MIN_SIZE 3 /*!< log2_min_coding_block_size */ #define MIN_SIZE 3 /*!< log2_min_coding_block_size */
#define ENABLE_PCM 1 #define ENABLE_PCM 0 /*!< Setting to 1 will enable using PCM blocks (current intra-search does not consider PCM) */
#define ENABLE_SIGN_HIDING 0 /*!< NEED QUANT CHANGES! */
/* END OF CONFIG VARIABLES */ /* END OF CONFIG VARIABLES */

View file

@ -236,6 +236,7 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
int16_t pred[LCU_WIDTH*LCU_WIDTH>>2]; int16_t pred[LCU_WIDTH*LCU_WIDTH>>2];
int16_t origBlock[LCU_WIDTH*LCU_WIDTH>>2]; int16_t origBlock[LCU_WIDTH*LCU_WIDTH>>2];
uint8_t *origShift = &orig[xpos+ypos*origstride]; uint8_t *origShift = &orig[xpos+ypos*origstride];
int8_t filter = (width<32);
SADfunction SADarray[4] = {&SAD4x4,&SAD8x8,&SAD16x16,&SAD32x32}; SADfunction SADarray[4] = {&SAD4x4,&SAD8x8,&SAD16x16,&SAD32x32};
uint8_t threshold = intraHorVerDistThres[g_toBits[width]]; /*!< Intra filtering threshold */ uint8_t threshold = intraHorVerDistThres[g_toBits[width]]; /*!< Intra filtering threshold */
#define COPY_PRED_TO_DST() for(y = 0; y < (int32_t)width; y++) { for(x = 0; x < (int32_t)width; x++) { dst[x+y*dststride] = pred[x+y*width]; } } #define COPY_PRED_TO_DST() for(y = 0; y < (int32_t)width; y++) { for(x = 0; x < (int32_t)width; x++) { dst[x+y*dststride] = pred[x+y*width]; } }
@ -262,19 +263,21 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
/* Test DC */ /* Test DC */
/*
x = intra_getDCPred(rec, recstride, xpos, ypos, width); x = intra_getDCPred(rec, recstride, xpos, ypos, width);
for(i = 0; i < (int32_t)(width*width); i++) for(i = 0; i < (int32_t)(width*width); i++)
{ {
pred[i] = x; pred[i] = x;
} }
CHECK_FOR_BEST(1); CHECK_FOR_BEST(1);
*/
/* Check angular that don't require filtering */ /* Check angular not requiring filtering */
for(i = 2; i < 35; i++) for(i = 2; i < 35; i++)
{ {
if(MIN(abs(i-26),abs(i-10)) <= threshold) if(MIN(abs(i-26),abs(i-10)) <= threshold)
{ {
intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, 0); intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, filter);
CHECK_FOR_BEST(i); CHECK_FOR_BEST(i);
} }
} }
@ -283,6 +286,7 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
intra_filter(rec,recstride,width,0); intra_filter(rec,recstride,width,0);
/* Test planar */ /* Test planar */
intra_getPlanarPred(rec, recstride, xpos, ypos, width, pred, width); intra_getPlanarPred(rec, recstride, xpos, ypos, width, pred, width);
CHECK_FOR_BEST(0); CHECK_FOR_BEST(0);
@ -292,15 +296,16 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
//chroma can use only 26 and 10 //chroma can use only 26 and 10
/* Test angular predictions which require filtered samples */ /* Test angular predictions which require filtered samples */
for(i = 2; i < 35; i++) for(i = 2; i < 35; i++)
{ {
if(MIN(abs(i-26),abs(i-10)) > threshold) if(MIN(abs(i-26),abs(i-10)) > threshold)
{ {
intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, 0); intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, filter);
CHECK_FOR_BEST(i); CHECK_FOR_BEST(i);
} }
} }
*sad = bestSAD; *sad = bestSAD;
#undef COPY_PRED_TO_DST #undef COPY_PRED_TO_DST
#undef CHECK_FOR_BEST #undef CHECK_FOR_BEST
@ -312,6 +317,7 @@ void intra_recon(int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,u
{ {
int32_t x,y,i; int32_t x,y,i;
int16_t pred[LCU_WIDTH*LCU_WIDTH>>2]; int16_t pred[LCU_WIDTH*LCU_WIDTH>>2];
int8_t filter = !chroma&&(width<32);
//int16_t* recShift = &rec[xpos+ypos*recstride]; //int16_t* recShift = &rec[xpos+ypos*recstride];
#define COPY_PRED_TO_DST() for(y = 0; y < (int32_t)width; y++) { for(x = 0; x < (int32_t)width; x++) { dst[x+y*dststride] = pred[x+y*width]; } } #define COPY_PRED_TO_DST() for(y = 0; y < (int32_t)width; y++) { for(x = 0; x < (int32_t)width; x++) { dst[x+y*dststride] = pred[x+y*width]; } }
@ -346,7 +352,7 @@ void intra_recon(int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,u
/* directional predictions */ /* directional predictions */
else else
{ {
intra_getAngularPred(rec, recstride,pred, width,width,width,mode, xpos?1:0, ypos?1:0, 0); intra_getAngularPred(rec, recstride,pred, width,width,width,mode, xpos?1:0, ypos?1:0, filter);
} }
COPY_PRED_TO_DST(); COPY_PRED_TO_DST();

View file

@ -20,6 +20,7 @@ int8_t intra_getDirLumaPredictor(picture* pic,uint32_t xCtb, uint32_t yCtb, uint
void intra_DCPredFiltering(uint8_t* pSrc, int32_t iSrcStride, uint8_t* rpDst, int32_t iDstStride, int32_t iWidth, int32_t iHeight ); void intra_DCPredFiltering(uint8_t* pSrc, int32_t iSrcStride, uint8_t* rpDst, int32_t iDstStride, int32_t iWidth, int32_t iHeight );
void intra_buildReferenceBorder(picture* pic, int32_t xCtb, int32_t yCtb,int8_t outwidth, int16_t* dst, int32_t dststride, int8_t chroma); void intra_buildReferenceBorder(picture* pic, int32_t xCtb, int32_t yCtb,int8_t outwidth, int16_t* dst, int32_t dststride, int8_t chroma);
void intra_filter(int16_t* ref, uint32_t stride,uint32_t width, int8_t mode);
/* Predictions */ /* Predictions */
int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride, uint32_t *sad); int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride, uint32_t *sad);

View file

@ -706,11 +706,6 @@ void quant(encoder_control* encoder, int16_t* pSrc, int16_t* pDes, /*int32_t** p
uint32_t scanIdx = SCAN_DIAG; uint32_t scanIdx = SCAN_DIAG;
if(scanIdx == SCAN_ZIGZAG)
{
scanIdx = SCAN_DIAG;
}
scan = g_auiSigLastScan[ scanIdx ][ log2BlockSize - 1 ]; scan = g_auiSigLastScan[ scanIdx ][ log2BlockSize - 1 ];
{ {
int32_t deltaU[32*32] ; int32_t deltaU[32*32] ;