00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "global.h"
00021 #include "biariencode.h"
00022
00023
00024 static const byte rLPS_table_64x4[64][4]=
00025 {
00026 { 128, 176, 208, 240},
00027 { 128, 167, 197, 227},
00028 { 128, 158, 187, 216},
00029 { 123, 150, 178, 205},
00030 { 116, 142, 169, 195},
00031 { 111, 135, 160, 185},
00032 { 105, 128, 152, 175},
00033 { 100, 122, 144, 166},
00034 { 95, 116, 137, 158},
00035 { 90, 110, 130, 150},
00036 { 85, 104, 123, 142},
00037 { 81, 99, 117, 135},
00038 { 77, 94, 111, 128},
00039 { 73, 89, 105, 122},
00040 { 69, 85, 100, 116},
00041 { 66, 80, 95, 110},
00042 { 62, 76, 90, 104},
00043 { 59, 72, 86, 99},
00044 { 56, 69, 81, 94},
00045 { 53, 65, 77, 89},
00046 { 51, 62, 73, 85},
00047 { 48, 59, 69, 80},
00048 { 46, 56, 66, 76},
00049 { 43, 53, 63, 72},
00050 { 41, 50, 59, 69},
00051 { 39, 48, 56, 65},
00052 { 37, 45, 54, 62},
00053 { 35, 43, 51, 59},
00054 { 33, 41, 48, 56},
00055 { 32, 39, 46, 53},
00056 { 30, 37, 43, 50},
00057 { 29, 35, 41, 48},
00058 { 27, 33, 39, 45},
00059 { 26, 31, 37, 43},
00060 { 24, 30, 35, 41},
00061 { 23, 28, 33, 39},
00062 { 22, 27, 32, 37},
00063 { 21, 26, 30, 35},
00064 { 20, 24, 29, 33},
00065 { 19, 23, 27, 31},
00066 { 18, 22, 26, 30},
00067 { 17, 21, 25, 28},
00068 { 16, 20, 23, 27},
00069 { 15, 19, 22, 25},
00070 { 14, 18, 21, 24},
00071 { 14, 17, 20, 23},
00072 { 13, 16, 19, 22},
00073 { 12, 15, 18, 21},
00074 { 12, 14, 17, 20},
00075 { 11, 14, 16, 19},
00076 { 11, 13, 15, 18},
00077 { 10, 12, 15, 17},
00078 { 10, 12, 14, 16},
00079 { 9, 11, 13, 15},
00080 { 9, 11, 12, 14},
00081 { 8, 10, 12, 14},
00082 { 8, 9, 11, 13},
00083 { 7, 9, 11, 12},
00084 { 7, 9, 10, 12},
00085 { 7, 8, 10, 11},
00086 { 6, 8, 9, 11},
00087 { 6, 7, 9, 10},
00088 { 6, 7, 8, 9},
00089 { 2, 2, 2, 2}
00090 };
00091
00092 static const byte AC_next_state_MPS_64[64] =
00093 {
00094 1,2,3,4,5,6,7,8,9,10,
00095 11,12,13,14,15,16,17,18,19,20,
00096 21,22,23,24,25,26,27,28,29,30,
00097 31,32,33,34,35,36,37,38,39,40,
00098 41,42,43,44,45,46,47,48,49,50,
00099 51,52,53,54,55,56,57,58,59,60,
00100 61,62,62,63
00101 };
00102
00103 static const byte AC_next_state_LPS_64[64] =
00104 {
00105 0, 0, 1, 2, 2, 4, 4, 5, 6, 7,
00106 8, 9, 9,11,11,12,13,13,15,15,
00107 16,16,18,18,19,19,21,21,22,22,
00108 23,24,24,25,26,26,27,27,28,29,
00109 29,30,30,30,31,32,32,33,33,33,
00110 34,34,35,35,35,36,36,36,37,37,
00111 37,38,38,63
00112 };
00113
00114 static const byte renorm_table_32[32]={6,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
00115
00116
00117 void reset_pic_bin_count(ImageParameters *p_Img)
00118 {
00119 p_Img->pic_bin_count = 0;
00120 }
00121
00122 int get_pic_bin_count(ImageParameters *p_Img)
00123 {
00124 return p_Img->pic_bin_count;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 EncodingEnvironmentPtr arienco_create_encoding_environment(void)
00134 {
00135 EncodingEnvironmentPtr eep;
00136
00137 if ( (eep = (EncodingEnvironmentPtr) calloc(1,sizeof(EncodingEnvironment))) == NULL)
00138 no_mem_exit("arienco_create_encoding_environment: eep");
00139
00140 return eep;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 void arienco_delete_encoding_environment(EncodingEnvironmentPtr eep)
00150 {
00151 if (eep == NULL)
00152 {
00153 snprintf(errortext, ET_SIZE, "Error freeing eep (NULL pointer)");
00154 error (errortext, 200);
00155 }
00156 else
00157 free(eep);
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 static inline void put_one_byte_final(EncodingEnvironmentPtr eep, unsigned int b)
00167 {
00168 eep->Ecodestrm[(*eep->Ecodestrm_len)++] = (byte) b;
00169 }
00170
00171 static forceinline void put_buffer(EncodingEnvironmentPtr eep)
00172 {
00173 while(eep->Epbuf>=0)
00174 {
00175 eep->Ecodestrm[(*eep->Ecodestrm_len)++] = (byte) ((eep->Ebuffer>>((eep->Epbuf--)<<3))&0xFF);
00176 }
00177 while(eep->C > 7)
00178 {
00179 eep->C-=8;
00180 ++(eep->E);
00181 }
00182 eep->Ebuffer = 0;
00183 }
00184
00185 static inline void put_one_byte(EncodingEnvironmentPtr eep, int b)
00186 {
00187 if(eep->Epbuf == 3)
00188 {
00189 put_buffer(eep);
00190 }
00191 eep->Ebuffer <<= 8;
00192 eep->Ebuffer += (b);
00193
00194 ++(eep->Epbuf);
00195 }
00196
00197 static inline void put_one_word(EncodingEnvironmentPtr eep, int b)
00198 {
00199 if (eep->Epbuf >= 3)
00200 {
00201 put_buffer(eep);
00202 }
00203 eep->Ebuffer <<= 16;
00204 eep->Ebuffer += (b);
00205
00206 eep->Epbuf += 2;
00207 }
00208
00209 static forceinline void propagate_carry(EncodingEnvironmentPtr eep)
00210 {
00211 ++(eep->Ebuffer);
00212 while (eep->Echunks_outstanding > 0)
00213 {
00214 put_one_word(eep, 0);
00215 --(eep->Echunks_outstanding);
00216 }
00217 }
00218
00219 static inline void put_last_chunk_plus_outstanding(EncodingEnvironmentPtr eep, unsigned int l)
00220 {
00221 while (eep->Echunks_outstanding > 0)
00222 {
00223 put_one_word(eep, 0xFFFF);
00224 --(eep->Echunks_outstanding);
00225 }
00226 put_one_word(eep, l);
00227 }
00228
00229 static inline void put_last_chunk_plus_outstanding_final(EncodingEnvironmentPtr eep, unsigned int l)
00230 {
00231 while (eep->Echunks_outstanding > 0)
00232 {
00233 put_one_word(eep, 0xFFFF);
00234 --(eep->Echunks_outstanding);
00235 }
00236 put_one_byte(eep, l);
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 void arienco_reset_EC(EncodingEnvironmentPtr eep)
00246 {
00247 eep->E = 0;
00248 eep->C = 0;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 void arienco_start_encoding(EncodingEnvironmentPtr eep,
00258 unsigned char *code_buffer,
00259 int *code_len )
00260 {
00261 eep->Elow = 0;
00262 eep->Echunks_outstanding = 0;
00263 eep->Ebuffer = 0;
00264 eep->Epbuf = -1;
00265 eep->Ebits_to_go = BITS_TO_LOAD + 1;
00266
00267 eep->Ecodestrm = code_buffer;
00268 eep->Ecodestrm_len = code_len;
00269
00270 eep->Erange = HALF;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280 void set_pic_bin_count(ImageParameters *p_Img, EncodingEnvironmentPtr eep)
00281 {
00282 p_Img->pic_bin_count += (eep->E << 3) + eep->C;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 void arienco_done_encoding(Macroblock *currMB, EncodingEnvironmentPtr eep)
00292 {
00293 unsigned int low = eep->Elow;
00294 int remaining_bits = BITS_TO_LOAD - eep->Ebits_to_go;
00295 unsigned char mask;
00296 BitCounter *mbBits = &currMB->bits;
00297
00298
00299
00300 if (remaining_bits <= 5)
00301 {
00302 mbBits->mb_stuffing += (5 - remaining_bits);
00303 mask = (unsigned char) (255 - ((1 << (6 - remaining_bits)) - 1));
00304 low = (low >> (MASK_BITS)) & mask;
00305 low += (32 >> remaining_bits);
00306
00307 put_last_chunk_plus_outstanding_final(eep, low);
00308 put_buffer(eep);
00309 }
00310 else if(remaining_bits <= 13)
00311 {
00312 mbBits->mb_stuffing += (13 - remaining_bits);
00313 put_last_chunk_plus_outstanding_final(eep, ((low >> (MASK_BITS)) & 0xFF));
00314
00315 put_buffer(eep);
00316 if (remaining_bits > 6)
00317 {
00318 mask = (unsigned char) (255 - ((1 << (14 - remaining_bits)) - 1));
00319 low = (low >> (B_BITS)) & mask;
00320 low += (0x2000 >> remaining_bits);
00321 put_one_byte_final(eep, low);
00322 }
00323 else
00324 {
00325 put_one_byte_final(eep, 128);
00326 }
00327 }
00328 else
00329 {
00330 put_last_chunk_plus_outstanding(eep, ((low >> B_BITS) & B_LOAD_MASK));
00331 put_buffer(eep);
00332 mbBits->mb_stuffing += (21 - remaining_bits);
00333
00334 if (remaining_bits > 14)
00335 {
00336 mask = (unsigned char) (255 - ((1 << (22 - remaining_bits)) - 1));
00337 low = (low >> (MAX_BITS - 24)) & mask;
00338 low += (0x200000 >> remaining_bits);
00339 put_one_byte_final(eep, low);
00340 }
00341 else
00342 {
00343 put_one_byte_final(eep, 128);
00344 }
00345 }
00346 eep->Ebits_to_go = 8;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 void biari_encode_symbol(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct )
00358 {
00359 unsigned int low = eep->Elow;
00360 unsigned int range = eep->Erange;
00361 int bl = eep->Ebits_to_go;
00362 unsigned int rLPS = rLPS_table_64x4[bi_ct->state][(range>>6) & 3];
00363
00364 range -= rLPS;
00365
00366 ++(eep->C);
00367 bi_ct->count += eep->p_Img->cabac_encoding;
00368
00369
00370
00371
00372
00373
00374 if ((symbol != 0) == bi_ct->MPS)
00375 {
00376 bi_ct->state = AC_next_state_MPS_64[bi_ct->state];
00377
00378 if( range >= QUARTER )
00379 {
00380 eep->Erange = range;
00381 return;
00382 }
00383 else
00384 {
00385 range<<=1;
00386 if( --bl > MIN_BITS_TO_GO )
00387 {
00388 eep->Erange = range;
00389 eep->Ebits_to_go = bl;
00390 return;
00391 }
00392 }
00393 }
00394 else
00395 {
00396 unsigned int renorm = renorm_table_32[(rLPS>> 3) & 0x1F];
00397
00398 low += range<<bl;
00399 range = (rLPS <<renorm);
00400 bl-=renorm;
00401
00402 if (!bi_ct->state)
00403 bi_ct->MPS ^= 0x01;
00404
00405 bi_ct->state = AC_next_state_LPS_64[bi_ct->state];
00406
00407 if (low >= ONE)
00408 {
00409 low -= ONE;
00410 propagate_carry(eep);
00411 }
00412
00413 if( bl > MIN_BITS_TO_GO )
00414 {
00415 eep->Elow = low;
00416 eep->Erange = range;
00417 eep->Ebits_to_go = bl;
00418 return;
00419 }
00420 }
00421
00422
00423 eep->Elow = (low << BITS_TO_LOAD )& (ONE_M1);
00424 low = (low >> B_BITS) & B_LOAD_MASK;
00425
00426 if (low < B_LOAD_MASK)
00427 {
00428 put_last_chunk_plus_outstanding(eep, low);
00429 }
00430 else
00431 {
00432 ++(eep->Echunks_outstanding);
00433 }
00434 eep->Erange = range;
00435 eep->Ebits_to_go = bl + BITS_TO_LOAD;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445 void biari_encode_symbol_eq_prob(EncodingEnvironmentPtr eep, signed short symbol)
00446 {
00447 unsigned int low = eep->Elow;
00448 --(eep->Ebits_to_go);
00449 ++(eep->C);
00450
00451 if (symbol != 0)
00452 {
00453 low += eep->Erange << eep->Ebits_to_go;
00454 if (low >= ONE)
00455 {
00456 low -= ONE;
00457 propagate_carry(eep);
00458 }
00459 }
00460 if(eep->Ebits_to_go == MIN_BITS_TO_GO)
00461 {
00462 eep->Elow = (low << BITS_TO_LOAD )& (ONE_M1);
00463 low = (low >> B_BITS) & B_LOAD_MASK;
00464 if (low < B_LOAD_MASK)
00465 {
00466 put_last_chunk_plus_outstanding(eep, low);}
00467 else
00468 {
00469 ++(eep->Echunks_outstanding);
00470 }
00471
00472 eep->Ebits_to_go = BITS_TO_LOAD;
00473 return;
00474 }
00475 else
00476 {
00477 eep->Elow = low;
00478 return;
00479 }
00480 }
00481
00482
00483
00484
00485
00486
00487
00488 void biari_encode_symbol_final(EncodingEnvironmentPtr eep, signed short symbol)
00489 {
00490 unsigned int range = eep->Erange - 2;
00491 unsigned int low = eep->Elow;
00492 int bl = eep->Ebits_to_go;
00493
00494 ++(eep->C);
00495
00496 if (symbol == 0)
00497 {
00498 if( range >= QUARTER )
00499 {
00500 eep->Erange = range;
00501 return;
00502 }
00503 else
00504 {
00505 range<<=1;
00506 if( --bl > MIN_BITS_TO_GO )
00507 {
00508 eep->Erange = range;
00509 eep->Ebits_to_go = bl;
00510 return;
00511 }
00512 }
00513 }
00514 else
00515 {
00516 low += (range << bl);
00517 range = 2;
00518
00519 if (low >= ONE)
00520 {
00521 low -= ONE;
00522 propagate_carry(eep);
00523 }
00524 bl -= 7;
00525
00526 range <<= 7;
00527 if( bl > MIN_BITS_TO_GO )
00528 {
00529 eep->Erange = range;
00530 eep->Elow = low;
00531 eep->Ebits_to_go = bl;
00532 return;
00533 }
00534 }
00535
00536
00537
00538 eep->Elow = (low << BITS_TO_LOAD ) & (ONE_M1);
00539 low = (low >> B_BITS) & B_LOAD_MASK;
00540 if (low < B_LOAD_MASK)
00541 {
00542 put_last_chunk_plus_outstanding(eep, low);
00543 }
00544 else
00545 {
00546 ++(eep->Echunks_outstanding);
00547 }
00548
00549 eep->Erange = range;
00550 bl += BITS_TO_LOAD;
00551 eep->Ebits_to_go = bl;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560 void biari_init_context (int qp, BiContextTypePtr ctx, const char* ini)
00561 {
00562 int pstate = iClip3 ( 1, 126, ((ini[0]* qp) >> 4) + ini[1]);
00563
00564 if ( pstate >= 64 )
00565 {
00566 ctx->state = (uint16) (pstate - 64);
00567 ctx->MPS = 1;
00568 }
00569 else
00570 {
00571 ctx->state = (uint16) (63 - pstate);
00572 ctx->MPS = 0;
00573 }
00574
00575 ctx->count = 0;
00576 }
00577