More context models and work on the intra coding

This commit is contained in:
Marko Viitanen 2012-06-12 17:35:45 +03:00
parent 9bfd542b73
commit 620541a7fc
5 changed files with 110 additions and 39 deletions

View file

@ -76,6 +76,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View file

@ -71,9 +71,13 @@ void cabac_encodeBinTrm(cabac_data* data, uint8_t binValue );
#ifdef _DEBUG #ifdef _DEBUG
#define CABAC_BIN(data, value, name) { uint32_t prev_state = (data)->ctx->ucState;\ #define CABAC_BIN(data, value, name) { uint32_t prev_state = (data)->ctx->ucState;\
cabac_encodeBin(data, value); \ cabac_encodeBin(data, value); \
printf("%s = %d prev_state=%d state=%d\n",name,split_flag,prev_state, (data)->ctx->ucState);} printf("%s = %d prev_state=%d state=%d\n",name,value,prev_state, (data)->ctx->ucState);}
#define CABAC_BINS_EP(data, value,bins, name) { uint32_t prev_state = (data)->ctx->ucState;\
cabac_encodeBinsEP(data, value,bins); \
printf("%s = %d prev_state=%d state=%d\n",name,value,prev_state, (data)->ctx->ucState);}
#else #else
#define CABAC_BIN(data, value, name) cabac_encodeBin(data, value); #define CABAC_BIN(data, value, name) cabac_encodeBin(data, value);
#define CABAC_BINS_EP(data, value,bins, name) cabac_encodeBinsEP(data, value,bins);
#endif #endif
#endif #endif

View file

@ -122,6 +122,7 @@
/* input init */ /* input init */
encoder->frame = 0; encoder->frame = 0;
encoder->QP = 10; encoder->QP = 10;
encoder->in.video_format = FORMAT_420;
init_encoder_input(&encoder->in, input, cfg->width, cfg->height); init_encoder_input(&encoder->in, input, cfg->width, cfg->height);
/* Start coding cycle */ /* Start coding cycle */

View file

@ -156,7 +156,7 @@ void encode_seq_parameter_set(encoder_control* encoder)
WRITE_U(encoder->stream, 0, 8, "reserved_zero_8bits"); WRITE_U(encoder->stream, 0, 8, "reserved_zero_8bits");
WRITE_U(encoder->stream, 0, 8, "level_idc"); WRITE_U(encoder->stream, 0, 8, "level_idc");
WRITE_UE(encoder->stream, 0, "seq_parameter_set_id"); WRITE_UE(encoder->stream, 0, "seq_parameter_set_id");
WRITE_UE(encoder->stream, 1, "chroma_format_idc"); /* 0 = 4:0:0, 1 = 4:2:0, 2 = 4:2:2, 3 = 4:4:4 */ WRITE_UE(encoder->stream, encoder->in.video_format, "chroma_format_idc"); /* 0 = 4:0:0, 1 = 4:2:0, 2 = 4:2:2, 3 = 4:4:4 */
WRITE_U(encoder->stream, 0, 3, "max_temporal_layers_minus1"); WRITE_U(encoder->stream, 0, 3, "max_temporal_layers_minus1");
WRITE_UE(encoder->stream, encoder->in.width, "pic_width_in_luma_samples"); WRITE_UE(encoder->stream, encoder->in.width, "pic_width_in_luma_samples");
WRITE_UE(encoder->stream, encoder->in.height, "pic_height_in_luma_samples"); WRITE_UE(encoder->stream, encoder->in.height, "pic_height_in_luma_samples");
@ -208,7 +208,9 @@ void encode_seq_parameter_set(encoder_control* encoder)
WRITE_UE(encoder->stream, 0, "num_short_term_ref_pic_sets"); WRITE_UE(encoder->stream, 0, "num_short_term_ref_pic_sets");
WRITE_U(encoder->stream, 0, 1, "long_term_ref_pics_present_flag"); WRITE_U(encoder->stream, 0, 1, "long_term_ref_pics_present_flag");
WRITE_U(encoder->stream, 0, 2, "tiles_or_entropy_coding_sync_idc"); WRITE_U(encoder->stream, 0, 2, "tiles_or_entropy_coding_sync_idc");
WRITE_U(encoder->stream, 0, 1, "sps_extension_flag"); WRITE_U(encoder->stream, 0, 1, "sps_extension_flag");
WRITE_U(encoder->stream, 1, 8, "stuffing");
} }
void encode_slice_header(encoder_control* encoder) void encode_slice_header(encoder_control* encoder)
@ -253,8 +255,12 @@ cabac_ctx g_SplitFlagSCModel[3]; /*<! \brief split flag context models */
cabac_ctx g_IntraModeSCModel; /*<! \brief intra mode context models */ cabac_ctx g_IntraModeSCModel; /*<! \brief intra mode context models */
cabac_ctx g_ChromaPredSCModel[2]; cabac_ctx g_ChromaPredSCModel[2];
cabac_ctx g_TransSubdivSCModel[4]; /*<! \brief intra mode context models */ cabac_ctx g_TransSubdivSCModel[4]; /*<! \brief intra mode context models */
cabac_ctx g_QtCbfSCModel[8]; cabac_ctx g_QtCbfSCModelY[5];
cabac_ctx PartSizeSCModel; cabac_ctx g_QtCbfSCModelU[5];
cabac_ctx g_QtCbfSCModelV[5];
cabac_ctx g_PartSizeSCModel;
cabac_ctx g_CUSigCoeffGroupSCModel[4];
cabac_ctx g_CUSigSCModel[45];
void encode_slice_data(encoder_control* encoder) void encode_slice_data(encoder_control* encoder)
{ {
@ -274,10 +280,18 @@ void encode_slice_data(encoder_control* encoder)
for(i = 0; i < 4; i++) for(i = 0; i < 4; i++)
{ {
cxt_init(&g_TransSubdivSCModel[i], encoder->QP, INIT_TRANS_SUBDIV_FLAG[SLICE_I][i]); cxt_init(&g_TransSubdivSCModel[i], encoder->QP, INIT_TRANS_SUBDIV_FLAG[SLICE_I][i]);
cxt_init(&g_CUSigCoeffGroupSCModel[i], encoder->QP, INIT_SIG_CG_FLAG[SLICE_I][i]);
} }
for(i = 0; i < 8; i++) for(i = 0; i < 5; i++)
{ {
cxt_init(&g_QtCbfSCModel[i], encoder->QP, INIT_QT_CBF[SLICE_I][i]); cxt_init(&g_QtCbfSCModelY[i], encoder->QP, INIT_QT_CBF[SLICE_I][i+5]);
cxt_init(&g_QtCbfSCModelU[i], encoder->QP, INIT_QT_CBF[SLICE_I][i+5]);
cxt_init(&g_QtCbfSCModelV[i], encoder->QP, INIT_QT_CBF[SLICE_I][i]);
}
for(i = 0; i < 45; i++)
{
cxt_init(&g_CUSigSCModel[i], encoder->QP, INIT_SIG_FLAG[SLICE_I][i]);
} }
encoder->in.cur_pic.CU[1][0].type = CU_INTRA; encoder->in.cur_pic.CU[1][0].type = CU_INTRA;
@ -345,16 +359,16 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
//PartSize //PartSize
if(depth == MAX_DEPTH) if(depth == MAX_DEPTH)
{ {
cabac.ctx = &PartSizeSCModel; cabac.ctx = &g_PartSizeSCModel;
CABAC_BIN(&cabac, 1, "PartSize"); CABAC_BIN(&cabac, 1, "PartSize");
} }
/*end partsize*/ /*end partsize*/
//If MODE_INTRA //If MODE_INTRA
//cabac.ctx = &PCMFlagSCModel; //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(encoder->in.cur_pic.CU[depth][(xCtb>>(MAX_DEPTH-depth))+(yCtb>>(MAX_DEPTH-depth))*(encoder->in.width_in_LCU<<MAX_DEPTH)].type <= CU_PCM)
{ {
cabac_encodeBinTrm(&cabac, 1); cabac_encodeBinTrm(&cabac, 1); /* IPCMFlag == 1 */
//printf("\tIPCMFlag = 1\n"); //printf("\tIPCMFlag = 1\n");
cabac_finish(&cabac); cabac_finish(&cabac);
WRITE_U(cabac.stream, 1, 1, "stop_bit"); WRITE_U(cabac.stream, 1, 1, "stop_bit");
@ -371,47 +385,87 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
{ {
bitstream_put(cabac.stream, base[x+y*encoder->in.width], 8); bitstream_put(cabac.stream, base[x+y*encoder->in.width], 8);
} }
} }
//Cb if(encoder->in.video_format != FORMAT_400)
for(y = 0; y < LCU_WIDTH>>(depth+1); y++)
{ {
for(x = 0; x < LCU_WIDTH>>(depth+1); x++) //Cb
for(y = 0; y < LCU_WIDTH>>(depth+1); y++)
{ {
bitstream_put(cabac.stream, baseCb[x+y*(encoder->in.width>>1)], 8); for(x = 0; x < LCU_WIDTH>>(depth+1); x++)
{
bitstream_put(cabac.stream, baseCb[x+y*(encoder->in.width>>1)], 8);
}
} }
}
//Cr //Cr
for(y = 0; y < LCU_WIDTH>>(depth+1); y++) for(y = 0; y < LCU_WIDTH>>(depth+1); y++)
{
for(x = 0; x < LCU_WIDTH>>(depth+1); x++)
{ {
bitstream_put(cabac.stream, baseCr[x+y*(encoder->in.width>>1)], 8); for(x = 0; x < LCU_WIDTH>>(depth+1); x++)
{
bitstream_put(cabac.stream, baseCr[x+y*(encoder->in.width>>1)], 8);
}
} }
} }
} }
/* end PCM sample */ /* end PCM sample */
cabac_start(&cabac); cabac_start(&cabac);
} /* end Code IPCM block */ } /* end Code IPCM block */
else else
{ {
cabac_encodeBinTrm(&cabac, 0); /* IPCMFlag == 0 */ cabac_encodeBinTrm(&cabac, 0); /* IPCMFlag == 0 */
cabac.ctx = &g_IntraModeSCModel; cabac.ctx = &g_IntraModeSCModel;
CABAC_BIN(&cabac,0,"IntraPred"); CABAC_BIN(&cabac,0,"IntraPred");
cabac.ctx = &g_ChromaPredSCModel[0]; /*
CABAC_BIN(&cabac,0,"IntraPredChroma"); Int preds[3] = {-1, -1, -1};
Int predNum = pcCU->getIntraDirLumaPredictor(absPartIdx+partOffset*j, preds);
*/
CABAC_BINS_EP(&cabac, 0, 5, "intraPredMode");
cabac.ctx = &g_ChromaPredSCModel[0];
CABAC_BIN(&cabac,0,"IntraPredChroma");
cabac.ctx = &g_TransSubdivSCModel[1]; /* //uiLog2TransformBlockSize */ /* Coeff */
CABAC_BIN(&cabac,0,"TransformSubdivFlag"); /* Transform tree */
cabac.ctx = &g_TransSubdivSCModel[1]; /* //uiLog2TransformBlockSize */
CABAC_BIN(&cabac,0,"TransformSubdivFlag");
/* Transform tree */ {
uint8_t CbY = 0,CbU = 0,CbV = 0;
/*
Quant and transform ...
*/
CbY = 1;
/* end Transform tree */ /* Non-zero chroma U Tcoeffs */
cabac.ctx = &g_QtCbfSCModelU[0];
CABAC_BIN(&cabac,CbU,"cbf_chroma_u");
} /* Non-zero chroma V Tcoeffs */
cabac.ctx = &g_QtCbfSCModelU[0];
CABAC_BIN(&cabac,CbV,"cbf_chroma_v");
/* Non-zero luma Tcoeffs */
cabac.ctx = &g_QtCbfSCModelY[1];
CABAC_BIN(&cabac,CbY,"cbf_luma");
/* CoeffNxN */
if(CbY)
{
}
}
/* end Transform tree */
/* end Coeff */
}
//endif //endif
/* end prediction unit */ /* end prediction unit */

View file

@ -27,6 +27,8 @@ typedef struct
} encoder_me; } encoder_me;
enum { FORMAT_400 = 0, FORMAT_420, FORMAT_422, FORMAT_444 };
/* Input info struct */ /* Input info struct */
typedef struct typedef struct
{ {
@ -36,6 +38,7 @@ typedef struct
uint32_t height_in_LCU; uint32_t height_in_LCU;
uint32_t width_in_LCU; uint32_t width_in_LCU;
picture cur_pic; picture cur_pic;
uint8_t video_format;
} encoder_input; } encoder_input;
typedef struct typedef struct
@ -77,13 +80,21 @@ static const uint8_t INIT_TRANS_SUBDIV_FLAG[3][4] =
{ CNU, 224, 167, 122 } { CNU, 224, 167, 122 }
}; };
static const uint8_t INIT_QT_CBF[3][8] = static const uint8_t INIT_QT_CBF[3][10] =
{ {
{ 153, 111, CNU, CNU, CNU, 149, 92, 167 }, { 153, 111, CNU, CNU, CNU, 149, 92, 167, CNU, CNU },
{ 153, 111, CNU, CNU, CNU, 149, 107, 167 }, { 153, 111, CNU, CNU, CNU, 149, 107, 167, CNU, CNU },
{ 111, 141, CNU, CNU, CNU, 94, 138, 182 } { 111, 141, CNU, CNU, CNU, 94, 138, 182, CNU, CNU }
}; };
static const uint8_t INIT_SIG_CG_FLAG[3][4] =
{ { 121, 140, 61, 154 }, { 121, 140, 61, 154 }, { 91, 171, 134, 141 } };
static const uint8_t INIT_SIG_FLAG[3][45] =
{{170,154,139,153,139,123,123, 63,124,153,153,152,152,152,137,152,137,137,166,183,140,136,153,154,170,153,138,138,122,121,122,121,167,153,167,136,121,122,136,121,122,91,151,183,140,},
{155,154,139,153,139,123,123, 63,153,153,153,152,152,152,137,152,137,122,166,183,140,136,153,154,170,153,123,123,107,121,107,121,167,153,167,136,149,107,136,121,122,91,151,183,140,},
{111,111,125,110,110, 94,124,108,124,139,139,139,168,124,138,124,138,107,107,125,141,179,153,125,140,139,182,182,152,136,152,136,153,182,137,149,192,152,224,136,31,136,136,139,111,} };
#endif #endif