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 int pic_bin_count;
00118
00119 void reset_pic_bin_count(void)
00120 {
00121 pic_bin_count = 0;
00122 }
00123
00124 int get_pic_bin_count(void)
00125 {
00126 return pic_bin_count;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 EncodingEnvironmentPtr arienco_create_encoding_environment(void)
00136 {
00137 EncodingEnvironmentPtr eep;
00138
00139 if ( (eep = (EncodingEnvironmentPtr) calloc(1,sizeof(EncodingEnvironment))) == NULL)
00140 no_mem_exit("arienco_create_encoding_environment: eep");
00141
00142 return eep;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 void arienco_delete_encoding_environment(EncodingEnvironmentPtr eep)
00154 {
00155 if (eep == NULL)
00156 {
00157 snprintf(errortext, ET_SIZE, "Error freeing eep (NULL pointer)");
00158 error (errortext, 200);
00159 }
00160 else
00161 free(eep);
00162 }
00163
00164
00165
00166
00167
00168
00169
00170 static inline void put_one_byte_final(EncodingEnvironmentPtr eep, unsigned int b)
00171 {
00172 eep->Ecodestrm[(*eep->Ecodestrm_len)++] = b;
00173 }
00174
00175 static forceinline void put_buffer(EncodingEnvironmentPtr eep)
00176 {
00177 while(eep->Epbuf>=0)
00178 {
00179 eep->Ecodestrm[(*eep->Ecodestrm_len)++] = (eep->Ebuffer>>((eep->Epbuf--)<<3))&0xFF;
00180 }
00181 while(eep->C > 7)
00182 {
00183 eep->C-=8;
00184 eep->E++;
00185 }
00186 eep->Ebuffer = 0;
00187 }
00188
00189 static inline void put_one_byte(EncodingEnvironmentPtr eep, int b)
00190 {
00191 if(eep->Epbuf == 3)
00192 {
00193 put_buffer(eep);
00194 }
00195 eep->Ebuffer = (eep->Ebuffer<<8) + (b);
00196 eep->Epbuf++;
00197 }
00198
00199 static inline void put_one_word(EncodingEnvironmentPtr eep, int b)
00200 {
00201 if(eep->Epbuf>=3)
00202 {
00203 put_buffer(eep);
00204 }
00205 eep->Ebuffer = (eep->Ebuffer<<16) + (b);
00206 eep->Epbuf += 2;
00207 }
00208
00209 static forceinline void propagate_carry(EncodingEnvironmentPtr eep)
00210 {
00211 eep->Ebuffer +=1;
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-2;
00271
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281 void set_pic_bin_count(EncodingEnvironmentPtr eep)
00282 {
00283 pic_bin_count += eep->E*8 + eep->C;
00284 }
00285
00286
00287
00288
00289
00290
00291
00292 void arienco_done_encoding(EncodingEnvironmentPtr eep)
00293 {
00294 register unsigned int low = eep->Elow;
00295 int bl = eep->Ebits_to_go;
00296 int remaining_bits = BITS_TO_LOAD - bl;
00297 unsigned char mask;
00298 int* bitCount = img->mb_data[img->current_mb_nr].bitcounter;
00299
00300
00301
00302 if (remaining_bits <= 5)
00303 {
00304 bitCount[BITS_STUFFING]+=(5-remaining_bits);
00305 mask = 255 - ((1 << (6-remaining_bits)) - 1);
00306 low = (low >> (MAX_BITS - 8)) & mask;
00307 low += (1<<(5-remaining_bits));
00308
00309 put_last_chunk_plus_outstanding_final(eep, low);
00310 put_buffer(eep);
00311 }
00312 else if(remaining_bits <=13)
00313 {
00314 bitCount[BITS_STUFFING] += (13-remaining_bits);
00315 put_last_chunk_plus_outstanding_final(eep, ((low >> (MAX_BITS - 8)) & 0xFF));
00316
00317 put_buffer(eep);
00318 if (remaining_bits > 6)
00319 {
00320 mask = 255 - ((1 << (14 - remaining_bits)) - 1);
00321 low = (low >> (MAX_BITS - 16)) & mask;
00322 low += (1<<(13-remaining_bits));
00323 put_one_byte_final(eep, low);
00324 }
00325 else
00326 {
00327 put_one_byte_final(eep, 128);
00328 }
00329 }
00330 else
00331 {
00332 put_last_chunk_plus_outstanding(eep, ((low >> B_BITS) & B_LOAD_MASK));
00333 put_buffer(eep);
00334 bitCount[BITS_STUFFING]+=(21-remaining_bits);
00335
00336 if (remaining_bits > 14)
00337 {
00338 mask = 255 - ((1 << (22 - remaining_bits)) - 1);
00339 low = (low >> (MAX_BITS - 24)) & mask;
00340 low += (1<<(21-remaining_bits));
00341 put_one_byte_final(eep, low);
00342 }
00343 else
00344 {
00345 put_one_byte_final(eep, 128);
00346 }
00347 }
00348 eep->Ebits_to_go = 8;
00349 }
00350
00351 extern int cabac_encoding;
00352
00353
00354
00355
00356
00357
00358
00359
00360 void biari_encode_symbol(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct )
00361 {
00362 unsigned int low = eep->Elow;
00363 unsigned int range = eep->Erange;
00364 int bl = eep->Ebits_to_go;
00365 unsigned int rLPS = rLPS_table_64x4[bi_ct->state][(range>>6) & 3];
00366
00367 range -= rLPS;
00368
00369 eep->C++;
00370 bi_ct->count += cabac_encoding;
00371
00372
00373
00374
00375
00376
00377 if ((symbol != 0) == bi_ct->MPS)
00378 {
00379 bi_ct->state = AC_next_state_MPS_64[bi_ct->state];
00380
00381 if( range >= QUARTER )
00382 {
00383 eep->Erange = range;
00384 return;
00385 }
00386 else
00387 {
00388 range<<=1;
00389 if( --bl > MIN_BITS_TO_GO )
00390 {
00391 eep->Erange = range;
00392 eep->Ebits_to_go = bl;
00393 return;
00394 }
00395 }
00396 }
00397 else
00398 {
00399 unsigned int renorm = renorm_table_32[(rLPS>> 3) & 0x1F];
00400
00401 low += range<<bl;
00402 range = (rLPS <<renorm);
00403 bl-=renorm;
00404
00405 if (!bi_ct->state)
00406 bi_ct->MPS ^= 0x01;
00407
00408 bi_ct->state = AC_next_state_LPS_64[bi_ct->state];
00409
00410 if (low >= ONE)
00411 {
00412 low -= ONE;
00413 propagate_carry(eep);
00414 }
00415
00416 if( bl > MIN_BITS_TO_GO )
00417 {
00418 eep->Elow = low;
00419 eep->Erange = range;
00420 eep->Ebits_to_go = bl;
00421 return;
00422 }
00423 }
00424
00425
00426 eep->Elow = (low << BITS_TO_LOAD )& (ONE_M1);
00427 low = (low >> B_BITS) & B_LOAD_MASK;
00428
00429 if (low < B_LOAD_MASK)
00430 {
00431 put_last_chunk_plus_outstanding(eep, low);
00432 }
00433 else
00434 {
00435 eep->Echunks_outstanding++;
00436 }
00437 eep->Erange = range;
00438 eep->Ebits_to_go = bl + BITS_TO_LOAD;
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448 void biari_encode_symbol_eq_prob(EncodingEnvironmentPtr eep, signed short symbol)
00449 {
00450 register unsigned int low = eep->Elow;
00451 eep->Ebits_to_go--;
00452 eep->C++;
00453
00454 if (symbol != 0)
00455 {
00456 low += eep->Erange << eep->Ebits_to_go;
00457 if (low >= ONE)
00458 {
00459 low -= ONE;
00460 propagate_carry(eep);
00461 }
00462 }
00463 if(eep->Ebits_to_go == MIN_BITS_TO_GO)
00464 {
00465 eep->Elow = (low << BITS_TO_LOAD )& (ONE_M1);
00466 low = (low >> B_BITS) & B_LOAD_MASK;
00467 if (low < B_LOAD_MASK)
00468 {
00469 put_last_chunk_plus_outstanding(eep, low);}
00470 else
00471 {
00472 eep->Echunks_outstanding++;
00473 }
00474
00475 eep->Ebits_to_go = BITS_TO_LOAD;
00476 return;
00477 }
00478 else
00479 {
00480 eep->Elow = low;
00481 return;
00482 }
00483 }
00484
00485
00486
00487
00488
00489
00490
00491 void biari_encode_symbol_final(EncodingEnvironmentPtr eep, signed short symbol)
00492 {
00493 register unsigned int range = eep->Erange - 2;
00494 register unsigned int low = eep->Elow;
00495 int bl = eep->Ebits_to_go;
00496
00497 eep->C++;
00498
00499 if (symbol == 0)
00500 {
00501 if( range >= QUARTER )
00502 {
00503 eep->Erange = range;
00504 return;
00505 }
00506 else
00507 {
00508 range<<=1;
00509 if( --bl > MIN_BITS_TO_GO )
00510 {
00511 eep->Erange =range;
00512 eep->Ebits_to_go = bl;
00513 return;
00514 }
00515 }
00516 }
00517 else
00518 {
00519 low += range<<bl;
00520 range = 2;
00521
00522 if (low >= ONE)
00523 {
00524 low -= ONE;
00525 propagate_carry(eep);
00526 }
00527 bl -= 7;
00528
00529 range<<=7;
00530 if( bl > MIN_BITS_TO_GO )
00531 {
00532 eep->Erange = range;
00533 eep->Elow = low;
00534 eep->Ebits_to_go = bl;
00535 return;
00536 }
00537 }
00538
00539
00540
00541
00542 eep->Elow = (low << BITS_TO_LOAD ) & (ONE_M1);
00543 low = (low >> B_BITS) & B_LOAD_MASK;
00544 if (low < B_LOAD_MASK)
00545 {
00546 put_last_chunk_plus_outstanding(eep, low);
00547 }
00548 else
00549 {
00550 eep->Echunks_outstanding++;
00551 }
00552
00553 eep->Erange = range;
00554 bl += BITS_TO_LOAD;
00555 eep->Ebits_to_go = bl;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564 void biari_init_context (BiContextTypePtr ctx, const char* ini)
00565 {
00566 int pstate = iClip3 ( 1, 126, ((ini[0]* imax(0, img->currentSlice->qp)) >> 4) + ini[1]);
00567
00568 if ( pstate >= 64 )
00569 {
00570 ctx->state = (unsigned short) (pstate - 64);
00571 ctx->MPS = 1;
00572 }
00573 else
00574 {
00575 ctx->state = (unsigned short) (63 - pstate);
00576 ctx->MPS = 0;
00577 }
00578
00579 ctx->count = 0;
00580 }
00581