biariencode.c
来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 582 行 · 第 1/2 页
C
582 行
void arienco_done_encoding(EncodingEnvironmentPtr eep)
{
register unsigned int low = eep->Elow;
int bl = eep->Ebits_to_go;
int remaining_bits = BITS_TO_LOAD - bl; // output (2 + remaining) bits for terminating the codeword + one stop bit
unsigned char mask;
int* bitCount = img->mb_data[img->current_mb_nr].bitcounter;
//pic_bin_count += eep->E*8 + eep->C; // no of processed bins
if (remaining_bits <= 5) // one terminating byte
{
bitCount[BITS_STUFFING]+=(5-remaining_bits);
mask = 255 - ((1 << (6-remaining_bits)) - 1);
low = (low >> (MAX_BITS - 8)) & mask; // mask out the (2+remaining_bits) MSBs
low += (1<<(5-remaining_bits)); // put the terminating stop bit '1'
put_last_chunk_plus_outstanding_final(eep, low);
put_buffer(eep);
}
else if(remaining_bits <=13) // two terminating bytes
{
bitCount[BITS_STUFFING] += (13-remaining_bits);
put_last_chunk_plus_outstanding_final(eep, ((low >> (MAX_BITS - 8)) & 0xFF)); // mask out the 8 MSBs for output
put_buffer(eep);
if (remaining_bits > 6)
{
mask = 255 - ((1 << (14 - remaining_bits)) - 1);
low = (low >> (MAX_BITS - 16)) & mask;
low += (1<<(13-remaining_bits)); // put the terminating stop bit '1'
put_one_byte_final(eep, low);
}
else
{
put_one_byte_final(eep, 128); // second byte contains terminating stop bit '1' only
}
}
else // three terminating bytes
{
put_last_chunk_plus_outstanding(eep, ((low >> B_BITS) & B_LOAD_MASK)); // mask out the 16 MSBs for output
put_buffer(eep);
bitCount[BITS_STUFFING]+=(21-remaining_bits);
if (remaining_bits > 14)
{
mask = 255 - ((1 << (22 - remaining_bits)) - 1);
low = (low >> (MAX_BITS - 24)) & mask;
low += (1<<(21-remaining_bits)); // put the terminating stop bit '1'
put_one_byte_final(eep, low);
}
else
{
put_one_byte_final(eep, 128); // third byte contains terminating stop bit '1' only
}
}
eep->Ebits_to_go = 8;
}
extern int cabac_encoding;
/*!
************************************************************************
* \brief
* Actually arithmetic encoding of one binary symbol by using
* the probability estimate of its associated context model
************************************************************************
*/
void biari_encode_symbol(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct )
{
unsigned int low = eep->Elow;
unsigned int range = eep->Erange;
int bl = eep->Ebits_to_go;
unsigned int rLPS = rLPS_table_64x4[bi_ct->state][(range>>6) & 3];
range -= rLPS;
eep->C++;
bi_ct->count += cabac_encoding;
/* covers all cases where code does not bother to shift down symbol to be
* either 0 or 1, e.g. in some cases for cbp, mb_Type etc the code simply
* masks off the bit position and passes in the resulting value */
//symbol = (short) (symbol != 0);
if ((symbol != 0) == bi_ct->MPS) //MPS
{
bi_ct->state = AC_next_state_MPS_64[bi_ct->state]; // next state
if( range >= QUARTER ) // no renorm
{
eep->Erange = range;
return;
}
else
{
range<<=1;
if( --bl > MIN_BITS_TO_GO ) // renorm once, no output
{
eep->Erange = range;
eep->Ebits_to_go = bl;
return;
}
}
}
else //LPS
{
unsigned int renorm = renorm_table_32[(rLPS>> 3) & 0x1F];
low += range<<bl;
range = (rLPS <<renorm);
bl-=renorm;
if (!bi_ct->state)
bi_ct->MPS ^= 0x01; // switch MPS if necessary
bi_ct->state = AC_next_state_LPS_64[bi_ct->state]; // next state
if (low >= ONE) // output of carry needed
{
low -= ONE;
propagate_carry(eep);
}
if( bl > MIN_BITS_TO_GO )
{
eep->Elow = low;
eep->Erange = range;
eep->Ebits_to_go = bl;
return;
}
}
//renorm needed
eep->Elow = (low << BITS_TO_LOAD )& (ONE_M1);
low = (low >> B_BITS) & B_LOAD_MASK; // mask out the 8/16 MSBs for output
if (low < B_LOAD_MASK) // no carry possible, output now
{
put_last_chunk_plus_outstanding(eep, low);
}
else // low == "FF.."; keep it, may affect future carry
{
eep->Echunks_outstanding++;
}
eep->Erange = range;
eep->Ebits_to_go = bl + BITS_TO_LOAD;
}
/*!
************************************************************************
* \brief
* Arithmetic encoding of one binary symbol assuming
* a fixed prob. distribution with p(symbol) = 0.5
************************************************************************
*/
void biari_encode_symbol_eq_prob(EncodingEnvironmentPtr eep, signed short symbol)
{
register unsigned int low = eep->Elow;
eep->Ebits_to_go--;
eep->C++;
if (symbol != 0)
{
low += eep->Erange << eep->Ebits_to_go;
if (low >= ONE) // output of carry needed
{
low -= ONE;
propagate_carry(eep);
}
}
if(eep->Ebits_to_go == MIN_BITS_TO_GO) // renorm needed
{
eep->Elow = (low << BITS_TO_LOAD )& (ONE_M1);
low = (low >> B_BITS) & B_LOAD_MASK; // mask out the 8/16 MSBs for output
if (low < B_LOAD_MASK) // no carry possible, output now
{
put_last_chunk_plus_outstanding(eep, low);}
else // low == "FF"; keep it, may affect future carry
{
eep->Echunks_outstanding++;
}
eep->Ebits_to_go = BITS_TO_LOAD;
return;
}
else // no renorm needed
{
eep->Elow = low;
return;
}
}
/*!
************************************************************************
* \brief
* Arithmetic encoding for last symbol before termination
************************************************************************
*/
void biari_encode_symbol_final(EncodingEnvironmentPtr eep, signed short symbol)
{
register unsigned int range = eep->Erange - 2;
register unsigned int low = eep->Elow;
int bl = eep->Ebits_to_go;
eep->C++;
if (symbol == 0) // MPS
{
if( range >= QUARTER ) // no renorm
{
eep->Erange = range;
return;
}
else
{
range<<=1;
if( --bl > MIN_BITS_TO_GO ) // renorm once, no output
{
eep->Erange =range;
eep->Ebits_to_go = bl;
return;
}
}
}
else // LPS
{
low += range<<bl;
range = 2;
if (low >= ONE) // output of carry needed
{
low -= ONE; // remove MSB, i.e., carry bit
propagate_carry(eep);
}
bl -= 7; // 7 left shifts needed to renormalize
range<<=7;
if( bl > MIN_BITS_TO_GO )
{
eep->Erange = range;
eep->Elow = low;
eep->Ebits_to_go = bl;
return;
}
}
//renorm needed
eep->Elow = (low << BITS_TO_LOAD ) & (ONE_M1);
low = (low >> B_BITS) & B_LOAD_MASK; // mask out the 8/16 MSBs
if (low < B_LOAD_MASK)
{ // no carry possible, output now
put_last_chunk_plus_outstanding(eep, low);
}
else
{ // low == "FF"; keep it, may affect future carry
eep->Echunks_outstanding++;
}
eep->Erange = range;
bl += BITS_TO_LOAD;
eep->Ebits_to_go = bl;
}
/*!
************************************************************************
* \brief
* Initializes a given context with some pre-defined probability state
************************************************************************
*/
void biari_init_context (BiContextTypePtr ctx, const char* ini)
{
int pstate = iClip3 ( 1, 126, ((ini[0]* imax(0, img->currentSlice->qp)) >> 4) + ini[1]);
if ( pstate >= 64 )
{
ctx->state = (unsigned short) (pstate - 64);
ctx->MPS = 1;
}
else
{
ctx->state = (unsigned short) (63 - pstate);
ctx->MPS = 0;
}
ctx->count = 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?