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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
*/
|
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_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
|
||||
}
|
||||
}
|
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_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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue