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) void bitstream_align(bitstream* stream)
{ {
if((stream->cur_bit&7) != 0) 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 * SAVE DATA TO OUTPUT
*/ */
int i,j; int i;
uint32_t correct_endian; uint32_t correct_endian;
if(stream->output) if(stream->output)
{ {
@ -214,14 +214,3 @@ void bitstream_flush(bitstream* stream)
bitstream_init(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(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_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_MPS(cabac_ctx* ctx) { ctx->ucState = g_aucNextStateMPS[ ctx->ucState ]; }
void cabac_init(cabac_data* data) void cabac_init(cabac_data* data)
{ {
data->fracBits = 0; data->fracBits = 0;
data->binCountIncrement = 0;
data->uiBinsCoded = 0;
cxt_buildNextStateTable(); cxt_buildNextStateTable();
} }
@ -123,23 +124,23 @@ void cabac_start(cabac_data* data)
data->bufferedByte = 0xff; data->bufferedByte = 0xff;
} }
void cabac_encodeBin(cabac_data* data, uint32_t binValue ) void cabac_encodeBin(cabac_data* data, uint32_t binValue )
{ {
uint32_t uiLPS; uint32_t uiLPS;
//printf("\tdecodeBin m_uiRange %d uivalue %d\n", data->uiRange, data->uiLow);
data->uiBinsCoded += data->binCountIncrement; data->uiBinsCoded += data->binCountIncrement;
data->ctx->binsCoded = 1; 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; 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) ) if( binValue != CTX_MPS(data->ctx) )
{ {
int numBits = g_aucRenormTable[ uiLPS >> 3 ]; int numBits = g_aucRenormTable[ uiLPS >> 3 ];
data->uiLow = ( data->uiLow + data->uiRange ) << numBits; data->uiLow = ( data->uiLow + data->uiRange ) << numBits;
data->uiRange = uiLPS << numBits; data->uiRange = uiLPS << numBits;
ctx_update_LPS(data->ctx); ctx_update_LPS(data->ctx);
@ -150,6 +151,7 @@ void cabac_encodeBin(cabac_data* data, uint32_t binValue )
ctx_update_MPS(data->ctx); ctx_update_MPS(data->ctx);
if ( data->uiRange >= 256 ) if ( data->uiRange >= 256 )
{ {
printf("enduiValue %d \n",data->uiLow);
return; return;
} }
@ -162,6 +164,7 @@ void cabac_encodeBin(cabac_data* data, uint32_t binValue )
{ {
cabac_write(data); cabac_write(data);
} }
printf("enduiValue %d \n",data->uiLow);
} }
void cabac_write(cabac_data* data) void cabac_write(cabac_data* data)
@ -250,9 +253,9 @@ void cabac_finish(cabac_data* data)
* *
* \param binValue bin value * \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->uiBinsCoded += data->binCountIncrement;
data->uiRange -= 2; data->uiRange -= 2;
if( binValue ) if( binValue )
@ -332,4 +335,32 @@ void cabac_encodeBinsEP(cabac_data* data, uint32_t binValues, int numBins )
{ {
cabac_write(data); 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_init(cabac_ctx* ctx,uint32_t qp, uint32_t initValue );
void cxt_buildNextStateTable(); void cxt_buildNextStateTable();
void ctx_update(cabac_ctx* ctx, int val ); void ctx_update(cabac_ctx* ctx, int val );
void ctx_update_LPS(cabac_ctx* ctx); //void ctx_update_LPS(cabac_ctx* ctx);
void ctx_update_MPS(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 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_write(cabac_data* data);
void cabac_finish(cabac_data* data); void cabac_finish(cabac_data* data);
void cabac_flush(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 #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\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 #else
#define CABAC_BIN(data, value, name) cabac_encodeBin(data, value); #define CABAC_BIN(data, value, name) cabac_encodeBin(data, value);
#endif #endif

View file

@ -73,6 +73,7 @@ void encode_one_frame(encoder_control* encoder)
cabac_start(&cabac); cabac_start(&cabac);
encode_slice_header(encoder); encode_slice_header(encoder);
bitstream_align(encoder->stream);
encode_slice_data(encoder); encode_slice_data(encoder);
cabac_flush(&cabac); cabac_flush(&cabac);
bitstream_align(encoder->stream); 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, "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, 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_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");
@ -227,12 +228,11 @@ void encode_slice_data(encoder_control* encoder)
{ {
uint16_t xCtb,yCtb; uint16_t xCtb,yCtb;
cxt_init(&SplitFlagSCModel, encoder->QP, 107); cxt_init(&SplitFlagSCModel, encoder->QP, 107);
cxt_init(&PCMFlagSCModel, encoder->QP, 0); //cxt_init(&PCMFlagSCModel, encoder->QP, 0);
cxt_init(&PartSizeSCModel, encoder->QP, 0); cxt_init(&PartSizeSCModel, encoder->QP, 154);
//SplitFlagSCModel.ucState = 15; //SplitFlagSCModel.ucState = 15;
PCMFlagSCModel.ucState = 0; //PCMFlagSCModel.ucState = 0;
PartSizeSCModel.ucState = 0; //PartSizeSCModel.ucState = 30;
//cxt_init(&cabac.ctx, 26, 87); //cxt_init(&cabac.ctx, 26, 87);
for(yCtb = 0; yCtb < encoder->in.height_in_LCU; yCtb++) 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; int i;
uint8_t split_flag = (depth!=1)?1:0; uint8_t split_flag = (depth!=1)?1:0;
cabac.ctx = &SplitFlagSCModel; cabac.ctx = &SplitFlagSCModel;
CABAC_BIN(&cabac, split_flag, "SplitFlag"); if(depth != 2)
if(split_flag)
{ {
encode_coding_tree(encoder,xCtb,yCtb,depth+1); CABAC_BIN(&cabac, split_flag, "SplitFlag");
encode_coding_tree(encoder,xCtb+1,yCtb,depth+1); if(split_flag)
encode_coding_tree(encoder,xCtb,yCtb+1,depth+1); {
encode_coding_tree(encoder,xCtb+1,yCtb+1,depth+1); encode_coding_tree(encoder,xCtb,yCtb,depth+1);
return; 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 ) */ /* coding_unit( x0, y0, log2CbSize ) */
/* prediction_unit 2Nx2N*/ /* prediction_unit 2Nx2N*/
//if !intra PREDMODE //if !intra PREDMODE
//PartSize /* if depth = MAX_DEPTH */
//cabac.ctx = &PartSizeSCModel; //PartSize
//CABAC_BIN(&cabac, 1, "PartSize"); if(depth == 2)
{
cabac.ctx = &PartSizeSCModel;
CABAC_BIN(&cabac, 1, "PartSize");
}
/*end partsize*/
//If MODE_INTRA //If MODE_INTRA
cabac.ctx = &PCMFlagSCModel; //cabac.ctx = &PCMFlagSCModel;
cabac_encodeBinTrm(&cabac, 1); cabac_encodeBinTrm(&cabac, 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");
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); bitstream_align(cabac.stream);
/* PCM sample */ /* PCM sample */
for(i = 0; i < 32*32; i++)
{
bitstream_put(cabac.stream, 100, 8);
}
//Cb
for(i = 0; i < 16*16; i++) 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 //endif
/* end prediction unit */ /* end prediction unit */