BugFix: CABAC requires aligned byte, added align after slice_header.

This commit is contained in:
Marko Viitanen 2012-06-08 15:26:07 +03:00
parent 925f4020cd
commit 84af7eddac
4 changed files with 96 additions and 52 deletions

View file

@ -159,13 +159,13 @@ void bitstream_put(bitstream* stream, uint32_t data, uint8_t bits)
}
/*
* Align the bitstream
* \brief Align the bitstream
*/
void bitstream_align(bitstream* stream)
{
if((stream->cur_bit&7) != 0)
{
bitstream_put(stream,0, 8-stream->cur_bit&7);
bitstream_put(stream,0, 8-(stream->cur_bit&7));
}
}
@ -174,7 +174,7 @@ void bitstream_flush(bitstream* stream)
/*
* SAVE DATA TO OUTPUT
*/
int i,j;
int i;
uint32_t correct_endian;
if(stream->output)
{
@ -214,14 +214,3 @@ void bitstream_flush(bitstream* stream)
bitstream_init(stream);
}
/*
void bitstream_put_ue(bitstream* stream, uint32_t data)
{
bitstream_put(stream,exp_table[data].value,exp_table[data].len);
}
void bitstream_put_se(bitstream* stream, uint32_t data)
{
uint32_t index=(data<=0)?2*(uint32_t)(-data):2*(uint32_t)(data)-1;
bitstream_put(stream,exp_table[index].value,exp_table[index].len);
}
*/

View file

@ -104,13 +104,14 @@ void cxt_buildNextStateTable()
}
void ctx_update(cabac_ctx* ctx, int val ) { ctx->ucState = g_nextState[ctx->ucState][val]; }
void ctx_update_LPS(cabac_ctx* ctx) { ctx->ucState = g_aucNextStateLPS[ ctx->ucState ]; }
void ctx_update_MPS(cabac_ctx* ctx) { ctx->ucState = g_aucNextStateMPS[ ctx->ucState ]; }
//void ctx_update_LPS(cabac_ctx* ctx) { ctx->ucState = g_aucNextStateLPS[ ctx->ucState ]; }
//void ctx_update_MPS(cabac_ctx* ctx) { ctx->ucState = g_aucNextStateMPS[ ctx->ucState ]; }
void cabac_init(cabac_data* data)
{
data->fracBits = 0;
data->binCountIncrement = 0;
data->uiBinsCoded = 0;
cxt_buildNextStateTable();
}
@ -123,23 +124,23 @@ void cabac_start(cabac_data* data)
data->bufferedByte = 0xff;
}
void cabac_encodeBin(cabac_data* data, uint32_t binValue )
{
uint32_t uiLPS;
//printf("\tdecodeBin m_uiRange %d uivalue %d\n", data->uiRange, data->uiLow);
data->uiBinsCoded += data->binCountIncrement;
data->ctx->binsCoded = 1;
uiLPS = g_aucLPSTable[ CTX_STATE(data->ctx) ][ ( data->uiRange >> 6 ) -4 ];
uiLPS = g_aucLPSTable[ CTX_STATE(data->ctx) ][ ( data->uiRange >> 6 ) & 3 ];
data->uiRange -= uiLPS;
/*printf("\tdecodeBin m_uiRange %d uiLPS %d m_uiValue%d \n", data->uiRange,uiLPS,data->uiLow);*/
printf("\tencodeBin m_uiRange %d uiLPS %d m_uiValue %d ", data->uiRange,uiLPS,data->uiLow);
//Not the Most Propable Symbol?
if( binValue != CTX_MPS(data->ctx) )
{
int numBits = g_aucRenormTable[ uiLPS >> 3 ];
data->uiLow = ( data->uiLow + data->uiRange ) << numBits;
data->uiRange = uiLPS << numBits;
int numBits = g_aucRenormTable[ uiLPS >> 3 ];
data->uiLow = ( data->uiLow + data->uiRange ) << numBits;
data->uiRange = uiLPS << numBits;
ctx_update_LPS(data->ctx);
@ -150,6 +151,7 @@ void cabac_encodeBin(cabac_data* data, uint32_t binValue )
ctx_update_MPS(data->ctx);
if ( data->uiRange >= 256 )
{
printf("enduiValue %d \n",data->uiLow);
return;
}
@ -162,6 +164,7 @@ void cabac_encodeBin(cabac_data* data, uint32_t binValue )
{
cabac_write(data);
}
printf("enduiValue %d \n",data->uiLow);
}
void cabac_write(cabac_data* data)
@ -250,9 +253,9 @@ void cabac_finish(cabac_data* data)
*
* \param binValue bin value
*/
void cabac_encodeBinTrm(cabac_data* data, uint32_t binValue )
void cabac_encodeBinTrm(cabac_data* data, uint8_t binValue )
{
printf("\tdecodeBin m_uiRange %d uivalue %d\n", data->uiRange, data->uiLow);
printf("\tencodeBinTrm m_uiRange %d uivalue %d\n", data->uiRange, data->uiLow);
data->uiBinsCoded += data->binCountIncrement;
data->uiRange -= 2;
if( binValue )
@ -332,4 +335,32 @@ void cabac_encodeBinsEP(cabac_data* data, uint32_t binValues, int numBins )
{
cabac_write(data);
}
}
void cabac_encoderflush(cabac_data* data, uint8_t end)
{
cabac_encodeBinTrm(data,1);
cabac_finish(data);
bitstream_put(data->stream,1,1);
cabac_start(data);
data->uiRange = 2;
data->uiLow += 2;
data->uiLow <<= 7;
data->uiRange = 2 << 7;
data->bitsLeft -= 7;
if(data->bitsLeft < 12)
{
cabac_write(data);
}
cabac_finish(data);
if(!end)
{
bitstream_put(data->stream, 1, 1 ); // stop bit
}
}

View file

@ -33,8 +33,11 @@ typedef struct
void cxt_init(cabac_ctx* ctx,uint32_t qp, uint32_t initValue );
void cxt_buildNextStateTable();
void ctx_update(cabac_ctx* ctx, int val );
void ctx_update_LPS(cabac_ctx* ctx);
void ctx_update_MPS(cabac_ctx* ctx);
//void ctx_update_LPS(cabac_ctx* ctx);
//void ctx_update_MPS(cabac_ctx* ctx);
#define ctx_update_LPS(ctx) { (ctx)->ucState = g_aucNextStateLPS[ (ctx)->ucState ]; }
#define ctx_update_MPS(ctx) { (ctx)->ucState = g_aucNextStateMPS[ (ctx)->ucState ]; }
typedef struct
{
@ -61,13 +64,14 @@ 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 );
void cabac_encoderflush(cabac_data* data, uint8_t end);
void cabac_encodeBinTrm(cabac_data* data, uint8_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);}
printf("%s = %d prev_state=%d state=%d\n",name,split_flag,prev_state, (data)->ctx->ucState);}
#else
#define CABAC_BIN(data, value, name) cabac_encodeBin(data, value);
#endif

View file

@ -73,6 +73,7 @@ void encode_one_frame(encoder_control* encoder)
cabac_start(&cabac);
encode_slice_header(encoder);
bitstream_align(encoder->stream);
encode_slice_data(encoder);
cabac_flush(&cabac);
bitstream_align(encoder->stream);
@ -134,7 +135,7 @@ void encode_seq_parameter_set(encoder_control* encoder)
WRITE_U(encoder->stream, 0, 8, "reserved_zero_8bits");
WRITE_U(encoder->stream, 0, 8, "level_idc");
WRITE_UE(encoder->stream, 0, "seq_parameter_set_id");
WRITE_UE(encoder->stream, 0, "chroma_format_idc"); /* 0 = 4:0:0, 1 = 4:2:0, 2 = 4:2:2, 3 = 4:4:4 */
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_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.height, "pic_height_in_luma_samples");
@ -227,12 +228,11 @@ void encode_slice_data(encoder_control* encoder)
{
uint16_t xCtb,yCtb;
cxt_init(&SplitFlagSCModel, encoder->QP, 107);
cxt_init(&PCMFlagSCModel, encoder->QP, 0);
cxt_init(&PartSizeSCModel, encoder->QP, 0);
//cxt_init(&PCMFlagSCModel, encoder->QP, 0);
cxt_init(&PartSizeSCModel, encoder->QP, 154);
//SplitFlagSCModel.ucState = 15;
PCMFlagSCModel.ucState = 0;
PartSizeSCModel.ucState = 0;
//PCMFlagSCModel.ucState = 0;
//PartSizeSCModel.ucState = 30;
//cxt_init(&cabac.ctx, 26, 87);
for(yCtb = 0; yCtb < encoder->in.height_in_LCU; yCtb++)
@ -250,37 +250,57 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
int i;
uint8_t split_flag = (depth!=1)?1:0;
cabac.ctx = &SplitFlagSCModel;
CABAC_BIN(&cabac, split_flag, "SplitFlag");
if(split_flag)
if(depth != 2)
{
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;
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 depth = MAX_DEPTH */
//PartSize
if(depth == 2)
{
cabac.ctx = &PartSizeSCModel;
CABAC_BIN(&cabac, 1, "PartSize");
}
/*end partsize*/
//If MODE_INTRA
cabac.ctx = &PCMFlagSCModel;
//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");
WRITE_U(cabac.stream, 0, 1, "numSubseqIPCM_flag");
bitstream_align(cabac.stream);
/* PCM sample */
for(i = 0; i < 32*32; i++)
{
bitstream_put(cabac.stream, 100, 8);
}
//Cb
for(i = 0; i < 16*16; i++)
{
bitstream_put(cabac.stream, 125, 8);
bitstream_put(cabac.stream, 41, 8);
}
/* end PCM sample
//Cr
for(i = 0; i < 16*16; i++)
{
bitstream_put(cabac.stream, 78, 8);
}
/* end PCM sample */
cabac_start(&cabac);
//endif
/* end prediction unit */