mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
BugFix: CABAC requires aligned byte, added align after slice_header.
This commit is contained in:
parent
925f4020cd
commit
84af7eddac
|
@ -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);
|
|
||||||
}
|
|
||||||
*/
|
|
55
src/cabac.c
55
src/cabac.c
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
12
src/cabac.h
12
src/cabac.h
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue