biariencode.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:13k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  * file biariencode.c
  4.  *
  5.  * brief
  6.  *   Routines for binary arithmetic encoding.
  7.  *
  8.  *   This modified implementation of the M Coder is based on JVT-U084 
  9.  *   with the choice of M_BITS = 16.
  10.  *
  11.  * author
  12.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  13.  *    - Detlev Marpe                    <marpe@hhi.de>
  14.  *    - Gabi Blaettermann
  15.  *    - Gunnar Marten
  16.  *************************************************************************************
  17.  */
  18. #include "global.h"
  19. #include "biariencode.h"
  20. int binCount = 0;
  21. int pic_bin_count;
  22. void reset_pic_bin_count(void)
  23. {
  24.   pic_bin_count = 0;
  25. }
  26. int get_pic_bin_count(void)
  27. {
  28.   return pic_bin_count;
  29. }
  30. /*!
  31.  ************************************************************************
  32.  * brief
  33.  *    Allocates memory for the EncodingEnvironment struct
  34.  ************************************************************************
  35.  */
  36. EncodingEnvironmentPtr arienco_create_encoding_environment(void)
  37. {
  38.   EncodingEnvironmentPtr eep;
  39.   if ( (eep = (EncodingEnvironmentPtr) calloc(1,sizeof(EncodingEnvironment))) == NULL)
  40.     no_mem_exit("arienco_create_encoding_environment: eep");
  41.   return eep;
  42. }
  43. /*!
  44.  ************************************************************************
  45.  * brief
  46.  *    Frees memory of the EncodingEnvironment struct
  47.  ************************************************************************
  48.  */
  49. void arienco_delete_encoding_environment(EncodingEnvironmentPtr eep)
  50. {
  51.   if (eep == NULL)
  52.   {
  53.     snprintf(errortext, ET_SIZE, "Error freeing eep (NULL pointer)");
  54.     error (errortext, 200);
  55.   }
  56.   else
  57.     free(eep);
  58. }
  59. /*!
  60.  ************************************************************************
  61.  * Macro for writing bytes of code
  62.  ***********************************************************************
  63.  */
  64. #define put_one_byte(b) { 
  65.   if(Epbuf==3){ 
  66.     put_buffer(eep);
  67.   } 
  68.   Ebuffer = (Ebuffer<<8) + (b); 
  69.   Epbuf++; 
  70. }
  71. #define put_one_word(b) { 
  72.   if(Epbuf>=3){ 
  73.     put_buffer(eep);
  74.   } 
  75.   Ebuffer = (Ebuffer<<16) + (b); 
  76.   Epbuf+=2; 
  77. }
  78. #define put_one_byte_final(b) { 
  79.   Ecodestrm[(*Ecodestrm_len)++] = b; 
  80. }
  81. #define _put_last_chunk_plus_outstanding(l) { 
  82.   while (Echunks_outstanding > 0) 
  83.   { 
  84.     put_one_word(0xFFFF); 
  85.     Echunks_outstanding--; 
  86.   } 
  87.   put_one_word(l); 
  88. }
  89. #define _put_last_chunk_plus_outstanding_final(l) { 
  90.   while (Echunks_outstanding > 0) 
  91.   { 
  92.     put_one_word(0xFFFF); 
  93.     Echunks_outstanding--; 
  94.   } 
  95.   put_one_byte(l); 
  96. }
  97. void put_buffer(EncodingEnvironmentPtr eep)
  98. {
  99.   while(Epbuf>=0)
  100.   {
  101.     Ecodestrm[(*Ecodestrm_len)++] =  (Ebuffer>>((Epbuf--)<<3))&0xFF; 
  102.   }
  103.   while(eep->C > 7)
  104.   {
  105.     eep->C-=8;
  106.     eep->E++;
  107.   }
  108.   Ebuffer=0; 
  109. }
  110. void propagate_carry(EncodingEnvironmentPtr eep)
  111. {
  112.   Ebuffer +=1; 
  113.   while (Echunks_outstanding > 0) 
  114.   { 
  115.     put_one_word(0); 
  116.     Echunks_outstanding--; 
  117.   }
  118. }
  119. /*!
  120. ************************************************************************
  121. * brief
  122. *    Initializes the EncodingEnvironment E and C values to zero
  123. ************************************************************************
  124. */
  125. void arienco_reset_EC(EncodingEnvironmentPtr eep)
  126. {
  127.   eep->E = 0;
  128.   eep->C = 0;
  129. }
  130. /*!
  131.  ************************************************************************
  132.  * brief
  133.  *    Initializes the EncodingEnvironment for the arithmetic coder
  134.  ************************************************************************
  135.  */
  136. void arienco_start_encoding(EncodingEnvironmentPtr eep,
  137.                             unsigned char *code_buffer,
  138.                             int *code_len )
  139. {
  140.   Elow = 0;
  141.   Echunks_outstanding = 0;
  142.   Ebuffer = 0;
  143.   Epbuf = -1;  // to remove redundant chunk ^^
  144.   Ebits_to_go = BITS_TO_LOAD + 1; // to swallow first redundant bit
  145.   Ecodestrm = code_buffer;
  146.   Ecodestrm_len = code_len;
  147.   Erange = HALF-2;
  148. }
  149. /*!
  150.  ************************************************************************
  151.  * brief
  152.  *    Returns the number of currently written bits
  153.  ************************************************************************
  154.  */
  155. int arienco_bits_written(EncodingEnvironmentPtr eep)
  156. {
  157.   return (((*Ecodestrm_len) + Epbuf + 1) << 3) + (Echunks_outstanding * BITS_TO_LOAD) + BITS_TO_LOAD - Ebits_to_go;
  158. }
  159. /*!
  160. ************************************************************************
  161. * brief
  162. *    add slice bin number to picture bin counter
  163. *    should be only used when slice is terminated
  164. ************************************************************************
  165. */
  166. void set_pic_bin_count(EncodingEnvironmentPtr eep)
  167. {
  168.   pic_bin_count += eep->E*8 + eep->C; // no of processed bins
  169. }
  170. /*!
  171.  ************************************************************************
  172.  * brief
  173.  *    Terminates the arithmetic codeword, writes stop bit and stuffing bytes (if any)
  174.  ************************************************************************
  175.  */
  176. void arienco_done_encoding(EncodingEnvironmentPtr eep)
  177. {
  178.   register unsigned int low = Elow;
  179.   int bl = Ebits_to_go;
  180.   int remaining_bits = BITS_TO_LOAD - bl; // output (2 + remaining) bits for terminating the codeword + one stop bit
  181.   unsigned char mask;
  182.   int* bitCount = img->mb_data[img->current_mb_nr].bitcounter;
  183.   //pic_bin_count += eep->E*8 + eep->C; // no of processed bins
  184.   if (remaining_bits <= 5) // one terminating byte 
  185.   {
  186.     bitCount[BITS_STUFFING]+=(5-remaining_bits);
  187.     mask = 255 - ((1 << (6-remaining_bits)) - 1); 
  188.     low = (low >> (MAX_BITS - 8)) & mask; // mask out the (2+remaining_bits) MSBs
  189.     low += (1<<(5-remaining_bits));       // put the terminating stop bit '1'
  190.     _put_last_chunk_plus_outstanding_final(low);
  191.     put_buffer(eep);
  192.   }
  193.   else if(remaining_bits <=13)            // two terminating bytes
  194.   {
  195.     bitCount[BITS_STUFFING]+=(13-remaining_bits);
  196.     _put_last_chunk_plus_outstanding_final(((low >> (MAX_BITS - 8)) & 0xFF)); // mask out the 8 MSBs for output
  197.     put_buffer(eep);
  198.     if (remaining_bits > 6)
  199.     {
  200.       mask = 255 - ((1 << (14 - remaining_bits)) - 1); 
  201.       low = (low >> (MAX_BITS - 16)) & mask; 
  202.       low += (1<<(13-remaining_bits));     // put the terminating stop bit '1'
  203.       put_one_byte_final(low);
  204.     }
  205.     else
  206.     {
  207.       put_one_byte_final(128); // second byte contains terminating stop bit '1' only
  208.     }
  209.   }
  210.   else             // three terminating bytes
  211.   { 
  212.     _put_last_chunk_plus_outstanding(((low >> (MAX_BITS - BITS_TO_LOAD)) & B_LOAD_MASK)); // mask out the 16 MSBs for output
  213.     put_buffer(eep);
  214.     bitCount[BITS_STUFFING]+=(21-remaining_bits);
  215.     if (remaining_bits > 14)
  216.     {
  217.       mask = 255 - ((1 << (22 - remaining_bits)) - 1); 
  218.       low = (low >> (MAX_BITS - 24)) & mask; 
  219.       low += (1<<(21-remaining_bits));       // put the terminating stop bit '1'
  220.       put_one_byte_final(low);
  221.     }
  222.     else
  223.     {
  224.       put_one_byte_final(128); // third byte contains terminating stop bit '1' only
  225.     }
  226.   }
  227.   Ebits_to_go=8;
  228. }
  229. extern int cabac_encoding;
  230. /*!
  231.  ************************************************************************
  232.  * brief
  233.  *    Actually arithmetic encoding of one binary symbol by using
  234.  *    the probability estimate of its associated context model
  235.  ************************************************************************
  236.  */
  237. void biari_encode_symbol(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct )
  238. {
  239.   register unsigned int range = Erange;
  240.   register unsigned int low = Elow;
  241.   unsigned int rLPS = rLPS_table_64x4[bi_ct->state][(range>>6) & 3]; 
  242.   register int bl = Ebits_to_go;
  243.   range -= rLPS;
  244.   eep->C++;
  245.   bi_ct->count += cabac_encoding;
  246.   /* covers all cases where code does not bother to shift down symbol to be 
  247.   * either 0 or 1, e.g. in some cases for cbp, mb_Type etc the code simply 
  248.   * masks off the bit position and passes in the resulting value */
  249.   symbol = (short) (symbol != 0);
  250.   if (symbol == bi_ct->MPS)  //MPS
  251.   {
  252.     bi_ct->state = AC_next_state_MPS_64[bi_ct->state]; // next state
  253.     if( range >= QUARTER ) // no renorm
  254.     {
  255.       Erange = range;
  256.       return;
  257.     }
  258.     else 
  259.     {   
  260.       range<<=1;
  261.       if( --bl > MIN_BITS_TO_GO )  // renorm once, no output
  262.       {
  263.         Erange = range;
  264.         Ebits_to_go = bl;
  265.         return;
  266.       }
  267.     }
  268.   } 
  269.   else         //LPS
  270.   {
  271.     unsigned int renorm;
  272.     low += range<<bl;
  273.     range = rLPS;
  274.     if (!bi_ct->state)
  275.       bi_ct->MPS ^= 0x01;               // switch MPS if necessary
  276.     bi_ct->state = AC_next_state_LPS_64[bi_ct->state]; // next state
  277.     renorm= renorm_table_32[(rLPS>> 3) & 0x1F];
  278.     bl-=renorm;
  279.     range<<=renorm;
  280.     if (low >= ONE) // output of carry needed
  281.     {
  282.       low -= ONE;
  283.       propagate_carry(eep);
  284.     }
  285.     if( bl > MIN_BITS_TO_GO )
  286.     {
  287.       Erange = range;
  288.       Elow = low;
  289.       Ebits_to_go = bl;
  290.       return;
  291.     }
  292.   }
  293.   //renorm needed
  294.   Elow = (low << BITS_TO_LOAD )& (ONE - 1);
  295.   low = (low >> (MAX_BITS - BITS_TO_LOAD)) & B_LOAD_MASK; // mask out the 8/16 MSBs for output
  296.   if (low < B_LOAD_MASK) // no carry possible, output now
  297.   {
  298.     _put_last_chunk_plus_outstanding(low);
  299.   }
  300.   else          // low == "FF.."; keep it, may affect future carry
  301.   {
  302.     Echunks_outstanding++;
  303.   }
  304.   Erange = range;
  305.   bl += BITS_TO_LOAD;
  306.   Ebits_to_go = bl;
  307. }
  308. /*!
  309.  ************************************************************************
  310.  * brief
  311.  *    Arithmetic encoding of one binary symbol assuming 
  312.  *    a fixed prob. distribution with p(symbol) = 0.5
  313.  ************************************************************************
  314.  */
  315. void biari_encode_symbol_eq_prob(EncodingEnvironmentPtr eep, signed short symbol)
  316. {
  317.   register unsigned int low = Elow;
  318.   Ebits_to_go--;  
  319.   eep->C++;
  320.   if (symbol != 0)
  321.   {
  322.     low += Erange<<Ebits_to_go;
  323.     if (low >= ONE) // output of carry needed
  324.     {
  325.       low -= ONE;
  326.       propagate_carry(eep);
  327.     }
  328.   }
  329.   if(Ebits_to_go == MIN_BITS_TO_GO)  // renorm needed
  330.   {
  331.     Elow = (low << BITS_TO_LOAD )& (ONE - 1);
  332.     low = (low >> (MAX_BITS - BITS_TO_LOAD)) & B_LOAD_MASK; // mask out the 8/16 MSBs for output
  333.     if (low < B_LOAD_MASK)      // no carry possible, output now
  334.     {
  335.       _put_last_chunk_plus_outstanding(low);}
  336.     else          // low == "FF"; keep it, may affect future carry
  337.     {
  338.       Echunks_outstanding++;
  339.     }
  340.     Ebits_to_go = BITS_TO_LOAD;
  341.     return;
  342.   }
  343.   else         // no renorm needed
  344.   {
  345.     Elow = low;
  346.     return;
  347.   }
  348. }
  349. /*!
  350.  ************************************************************************
  351.  * brief
  352.  *    Arithmetic encoding for last symbol before termination
  353.  ************************************************************************
  354.  */
  355. void biari_encode_symbol_final(EncodingEnvironmentPtr eep, signed short symbol)
  356. {
  357.   register unsigned int range = Erange-2;
  358.   register unsigned int low = Elow;
  359.   int bl = Ebits_to_go; 
  360.   eep->C++;
  361.   if (symbol == 0) // MPS
  362.   {
  363.     if( range >= QUARTER ) // no renorm
  364.     {
  365.       Erange = range;
  366.       return;
  367.     }
  368.     else 
  369.     {   
  370.       range<<=1;
  371.       if( --bl > MIN_BITS_TO_GO )  // renorm once, no output
  372.       {
  373.         Erange =range;
  374.         Ebits_to_go = bl;
  375.         return;
  376.       }
  377.     }
  378.   }
  379.   else     // LPS
  380.   {
  381.     low += range<<bl;
  382.     range = 2;
  383.     if (low >= ONE) // output of carry needed
  384.     {
  385.       low -= ONE; // remove MSB, i.e., carry bit
  386.       propagate_carry(eep);
  387.     }
  388.     bl -= 7; // 7 left shifts needed to renormalize
  389.     range<<=7;
  390.     if( bl > MIN_BITS_TO_GO )
  391.     {
  392.       Erange = range;
  393.       Elow = low;
  394.       Ebits_to_go = bl;
  395.       return;
  396.     }
  397.   }
  398.   //renorm needed
  399.   Elow = (low << BITS_TO_LOAD ) & (ONE - 1);
  400.   low = (low >> (MAX_BITS - BITS_TO_LOAD)) & B_LOAD_MASK; // mask out the 8/16 MSBs
  401.   if (low < B_LOAD_MASK)
  402.   {  // no carry possible, output now
  403.     _put_last_chunk_plus_outstanding(low);
  404.   }
  405.   else
  406.   {  // low == "FF"; keep it, may affect future carry
  407.     Echunks_outstanding++;
  408.   }
  409.   Erange = range;
  410.   bl += BITS_TO_LOAD;
  411.   Ebits_to_go = bl;
  412. }
  413. /*!
  414.  ************************************************************************
  415.  * brief
  416.  *    Initializes a given context with some pre-defined probability state
  417.  ************************************************************************
  418.  */
  419. void biari_init_context (BiContextTypePtr ctx, const int* ini)
  420. {
  421.   int pstate = iClip3 ( 1, 126, ((ini[0]* imax(0, img->currentSlice->qp)) >> 4) + ini[1]);
  422.   if ( pstate >= 64 )
  423.   {
  424.     ctx->state  = (unsigned short) (pstate - 64);
  425.     ctx->MPS    = 1;
  426.   }
  427.   else
  428.   {
  429.     ctx->state  = (unsigned short) (63 - pstate);
  430.     ctx->MPS    = 0;
  431.   }
  432.   ctx->count = 0;
  433. }