From 925f4020cd63f448ee8930964d7d0f392563972f Mon Sep 17 00:00:00 2001 From: Marko Viitanen Date: Thu, 7 Jun 2012 17:38:28 +0300 Subject: [PATCH] Fixed some CABAC bugs and more work on coding tree --- src/bitstream.h | 2 +- src/cabac.c | 12 +++++--- src/cabac.h | 16 ++++++++-- src/encmain.c | 1 + src/encoder.c | 81 +++++++++++++++++++++++++++++++++++++------------ src/encoder.h | 1 + src/global.h | 4 +-- 7 files changed, 86 insertions(+), 31 deletions(-) diff --git a/src/bitstream.h b/src/bitstream.h index 867b2a7c..9c4a2fe2 100644 --- a/src/bitstream.h +++ b/src/bitstream.h @@ -50,7 +50,7 @@ void init_exp_golomb(uint32_t len); static int WRITE_VALUE = 0; #define WRITE_U(stream, data, bits, name) { printf("%8d %-40s u(%d) : %d\n",WRITE_VALUE, name,bits,data); bitstream_put(stream,data,bits); WRITE_VALUE++;} #define WRITE_UE(stream, data, name) { printf("%8d %-40s ue(v): %d\n",WRITE_VALUE, name,data); bitstream_put_ue(stream,data); WRITE_VALUE++;} -#define WRITE_SE(stream, data, name) { printf("%8d %-40s se(v): %d\n",WRITE_VALUE, name,data); bitstream_put_se(stream,data); WRITE_VALUE++;} +#define WRITE_SE(stream, data, name) { printf("%8d %-40s se(v): %d\n",WRITE_VALUE, name,data); bitstream_put_se(stream,(data)); WRITE_VALUE++;} #else #define WRITE_U(stream, data, bits, name) { bitstream_put(stream,data,bits); } #define WRITE_UE(stream, data, name) { bitstream_put_ue(stream,data); } diff --git a/src/cabac.c b/src/cabac.c index bcf824bf..7953fd36 100644 --- a/src/cabac.c +++ b/src/cabac.c @@ -84,7 +84,7 @@ void cxt_init(cabac_ctx* ctx, uint32_t qp, uint32_t initValue ) { int slope = (initValue>>4)*5 - 45; int offset = ((initValue&15)<<3)-16; - int initState = MIN( MAX( 1, ( ( ( slope * qp ) >> 4 ) + offset ) ), 126 ); + int initState = MIN( MAX( 1, ( ( ( slope * (int)qp ) >> 4 ) + offset ) ), 126 ); uint8_t mpState = (initState >= 64 )?1:0; ctx->ucState = ( (mpState? (initState - 64):(63 - initState)) <<1) + mpState; ctx->binsCoded = 0; @@ -129,10 +129,11 @@ void cabac_encodeBin(cabac_data* data, uint32_t binValue ) { uint32_t uiLPS; data->uiBinsCoded += data->binCountIncrement; - data->ctx.binsCoded = 1; + data->ctx->binsCoded = 1; - uiLPS = g_aucLPSTable[ CTX_STATE(data->ctx) ][ ( data->uiRange >> 6 ) & 3 ]; + uiLPS = g_aucLPSTable[ CTX_STATE(data->ctx) ][ ( data->uiRange >> 6 ) -4 ]; data->uiRange -= uiLPS; + /*printf("\tdecodeBin m_uiRange %d uiLPS %d m_uiValue%d \n", data->uiRange,uiLPS,data->uiLow);*/ if( binValue != CTX_MPS(data->ctx) ) { @@ -140,13 +141,13 @@ void cabac_encodeBin(cabac_data* data, uint32_t binValue ) data->uiLow = ( data->uiLow + data->uiRange ) << numBits; data->uiRange = uiLPS << numBits; - ctx_update_LPS(&data->ctx); + ctx_update_LPS(data->ctx); data->bitsLeft -= numBits; } else { - ctx_update_MPS(&data->ctx); + ctx_update_MPS(data->ctx); if ( data->uiRange >= 256 ) { return; @@ -251,6 +252,7 @@ void cabac_finish(cabac_data* data) */ void cabac_encodeBinTrm(cabac_data* data, uint32_t binValue ) { + printf("\tdecodeBin m_uiRange %d uivalue %d\n", data->uiRange, data->uiLow); data->uiBinsCoded += data->binCountIncrement; data->uiRange -= 2; if( binValue ) diff --git a/src/cabac.h b/src/cabac.h index 253f3976..06e65782 100644 --- a/src/cabac.h +++ b/src/cabac.h @@ -27,8 +27,8 @@ typedef struct uint32_t binsCoded; } cabac_ctx; -#define CTX_STATE(ctx) (ctx.ucState>>1) -#define CTX_MPS(ctx) (ctx.ucState&1) +#define CTX_STATE(ctx) (ctx->ucState>>1) +#define CTX_MPS(ctx) (ctx->ucState&1) void cxt_init(cabac_ctx* ctx,uint32_t qp, uint32_t initValue ); void cxt_buildNextStateTable(); @@ -38,7 +38,7 @@ void ctx_update_MPS(cabac_ctx* ctx); typedef struct { - cabac_ctx ctx; + cabac_ctx *ctx; uint32_t uiLow; uint32_t uiRange; uint32_t bufferedByte; @@ -52,6 +52,7 @@ typedef struct extern cabac_data cabac; +void cabac_start(cabac_data* data); void cabac_init(cabac_data* data); void cabac_encodeBin(cabac_data* data, uint32_t binValue ); void cabac_encodeFlush(cabac_data* data, uint8_t end ); @@ -60,6 +61,15 @@ void cabac_encodeBinsEP(cabac_data* data, uint32_t binValues, int numBins ); void cabac_write(cabac_data* data); void cabac_finish(cabac_data* data); void cabac_flush(cabac_data* data); +void cabac_encodeBinTrm(cabac_data* data, uint32_t binValue ); +#ifdef _DEBUG +#define CABAC_BIN(data, value, name) { uint32_t prev_state = (data)->ctx->ucState;\ + cabac_encodeBin(data, value); \ + printf("\%s = %d\tprev_state=%d\tstate=%d\n",name,split_flag,prev_state, (data)->ctx->ucState);} +#else +#define CABAC_BIN(data, value, name) cabac_encodeBin(data, value); +#endif + #endif diff --git a/src/encmain.c b/src/encmain.c index d35fe396..fe312182 100644 --- a/src/encmain.c +++ b/src/encmain.c @@ -121,6 +121,7 @@ /* input init */ encoder->frame = 0; + encoder->QP = 1; init_encoder_input(&encoder->in, input, cfg->width, cfg->height); /* Start coding cycle */ diff --git a/src/encoder.c b/src/encoder.c index 0e311050..f04d39c9 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -25,7 +25,11 @@ #include "picture.h" #include "nal.h" -void init_encoder_control(encoder_control* control,bitstream* output) {control->stream = output;}; +void init_encoder_control(encoder_control* control,bitstream* output) +{ + control->stream = output; +} + void init_encoder_input(encoder_input* input,FILE* inputfile, uint32_t width, uint32_t height) { input->file = inputfile; @@ -46,7 +50,7 @@ void init_encoder_input(encoder_input* input,FILE* inputfile, uint32_t width, ui input->cur_pic.yData = (uint8_t *)malloc(width*height); input->cur_pic.uData = (uint8_t *)malloc((width*height)>>2); input->cur_pic.vData = (uint8_t *)malloc((width*height)>>2); -}; +} void encode_one_frame(encoder_control* encoder) @@ -67,6 +71,7 @@ void encode_one_frame(encoder_control* encoder) bitstream_clear_buffer(encoder->stream); + cabac_start(&cabac); encode_slice_header(encoder); encode_slice_data(encoder); cabac_flush(&cabac); @@ -77,6 +82,7 @@ void encode_one_frame(encoder_control* encoder) } else { + /* encode_slice_header(encoder); encode_slice_data(encoder); cabac_flush(&cabac); @@ -84,8 +90,8 @@ void encode_one_frame(encoder_control* encoder) bitstream_flush(encoder->stream); nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, NAL_IDR_SLICE, 0); bitstream_clear_buffer(encoder->stream); + */ } - } void encode_pic_parameter_set(encoder_control* encoder) @@ -104,7 +110,7 @@ void encode_pic_parameter_set(encoder_control* encoder) WRITE_UE(encoder->stream, 0, "num_ref_idx_l0_default_active_minus1"); WRITE_UE(encoder->stream, 0, "num_ref_idx_l1_default_active_minus1"); */ - WRITE_SE(encoder->stream, 0, "pic_init_qp_minus26"); + WRITE_SE(encoder->stream, encoder->QP-26, "pic_init_qp_minus26"); WRITE_U(encoder->stream, 0, 1, "constrained_intra_pred_flag"); WRITE_U(encoder->stream, 0, 1, "enable_temporal_mvp_flag"); WRITE_U(encoder->stream, 0, 2, "slice_granularity"); @@ -139,23 +145,23 @@ void encode_seq_parameter_set(encoder_control* encoder) WRITE_U(encoder->stream, 7, 4, "pcm_bit_depth_luma_minus1"); WRITE_U(encoder->stream, 7, 4, "pcm_bit_depth_chroma_minus1"); WRITE_U(encoder->stream, 0, 1, "qpprime_y_zero_transquant_bypass_flag"); - WRITE_UE(encoder->stream, 0, "log2_max_pic_order_cnt_lsb_minus4"); + WRITE_UE(encoder->stream, 4, "log2_max_pic_order_cnt_lsb_minus4"); WRITE_UE(encoder->stream, 0, "max_dec_pic_buffering"); WRITE_UE(encoder->stream, 0, "num_reorder_pics"); WRITE_UE(encoder->stream, 0, "max_latency_increase"); WRITE_U(encoder->stream, 0, 1, "restricted_ref_pic_lists_flag"); - WRITE_UE(encoder->stream, 0, "log2_min_coding_block_size_minus3"); - WRITE_UE(encoder->stream, 3, "log2_diff_max_min_coding_block_size"); + WRITE_UE(encoder->stream, 1, "log2_min_coding_block_size_minus3"); + WRITE_UE(encoder->stream, 2, "log2_diff_max_min_coding_block_size"); WRITE_UE(encoder->stream, 0, "log2_min_transform_block_size_minus2"); WRITE_UE(encoder->stream, 3, "log2_diff_max_min_transform_block_size"); //If log2MinCUSize == 3 - WRITE_U(encoder->stream, 0, 1, "DisInter4x4"); + //WRITE_U(encoder->stream, 0, 1, "DisInter4x4"); //IF PCM { WRITE_UE(encoder->stream, 0, "log2_min_pcm_coding_block_size_minus3"); - WRITE_UE(encoder->stream, 0, "log2_diff_max_min_pcm_coding_block_size"); + WRITE_UE(encoder->stream, 2, "log2_diff_max_min_pcm_coding_block_size"); } @@ -172,7 +178,7 @@ void encode_seq_parameter_set(encoder_control* encoder) WRITE_U(encoder->stream, 0, 1, "sample_adaptive_offset_enabled_flag"); WRITE_U(encoder->stream, 0, 1, "adaptive_loop_filter_enabled_flag"); //IF PCM - WRITE_U(encoder->stream, 0, 1, "pcm_loop_filter_disable_flag"); + WRITE_U(encoder->stream, 1, 1, "pcm_loop_filter_disable_flag"); //endif WRITE_U(encoder->stream, 0, 1, "temporal_id_nesting_flag"); WRITE_UE(encoder->stream, 0, "num_short_term_ref_pic_sets"); @@ -214,12 +220,21 @@ void encode_slice_header(encoder_control* encoder) } cabac_ctx SplitFlagSCModel; +cabac_ctx PCMFlagSCModel; +cabac_ctx PartSizeSCModel; void encode_slice_data(encoder_control* encoder) { uint16_t xCtb,yCtb; - cxt_init(&SplitFlagSCModel, 26, 0); - cxt_init(&cabac.ctx, 26, 0); + cxt_init(&SplitFlagSCModel, encoder->QP, 107); + cxt_init(&PCMFlagSCModel, encoder->QP, 0); + cxt_init(&PartSizeSCModel, encoder->QP, 0); + //SplitFlagSCModel.ucState = 15; + PCMFlagSCModel.ucState = 0; + PartSizeSCModel.ucState = 0; + + //cxt_init(&cabac.ctx, 26, 87); + for(yCtb = 0; yCtb < encoder->in.height_in_LCU; yCtb++) { for(xCtb = 0; xCtb < encoder->in.width_in_LCU; xCtb++) @@ -231,21 +246,47 @@ void encode_slice_data(encoder_control* encoder) } void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, uint8_t depth) -{ - - //Split flag - cabac_encodeBin(&cabac, 5); - +{ + int i; + uint8_t split_flag = (depth!=1)?1:0; + cabac.ctx = &SplitFlagSCModel; + CABAC_BIN(&cabac, split_flag, "SplitFlag"); + if(split_flag) + { + encode_coding_tree(encoder,xCtb,yCtb,depth+1); + encode_coding_tree(encoder,xCtb+1,yCtb,depth+1); + encode_coding_tree(encoder,xCtb,yCtb+1,depth+1); + encode_coding_tree(encoder,xCtb+1,yCtb+1,depth+1); + return; + } /* coding_unit( x0, y0, log2CbSize ) */ /* prediction_unit 2Nx2N*/ + //if !intra PREDMODE + //PartSize + //cabac.ctx = &PartSizeSCModel; + //CABAC_BIN(&cabac, 1, "PartSize"); //If MODE_INTRA - + cabac.ctx = &PCMFlagSCModel; + cabac_encodeBinTrm(&cabac, 1); + printf("\tIPCMFlag = 1\n"); + cabac_finish(&cabac); + WRITE_U(cabac.stream, 1, 1, "stop_bit"); + WRITE_U(cabac.stream, 0, 1, "stop_bit"); + //WRITE_U(cabac.stream, 0, 3, "num_subsequent_pcm"); + bitstream_align(cabac.stream); + /* PCM sample */ + for(i = 0; i < 16*16; i++) + { + bitstream_put(cabac.stream, 125, 8); + } + + /* end PCM sample //endif /* end prediction unit */ - cabac_encodeBin(&cabac, 0); //prev_intra_luma_pred_flag + //cabac_encodeBin(&cabac, 0); //prev_intra_luma_pred_flag - cabac_encodeBin(&cabac, 1); //rem_intra_luma_pred_mode + //cabac_encodeBin(&cabac, 1); //rem_intra_luma_pred_mode /* end coding_unit */ diff --git a/src/encoder.h b/src/encoder.h index 2a292bb3..de4105e5 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -47,6 +47,7 @@ typedef struct bitstream* stream; FILE *output; picture_list *ref; + uint8_t QP; } encoder_control; void init_encoder_control(encoder_control* control,bitstream* output); diff --git a/src/global.h b/src/global.h index df0bb88f..0b6a4ac5 100644 --- a/src/global.h +++ b/src/global.h @@ -20,8 +20,8 @@ #include #endif -#define MAX(a,b) (((a)<(b))?(b):(a)) -#define MIN(a,b) (((a)>(b))?(b):(a)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) #define LCU_WIDTH 64 /*!< Largest Coding Unit */