Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /*
     12  * arith_routins.c
     13  *
     14  * This C file contains a function for finalizing the bitstream
     15  * after arithmetic coding.
     16  *
     17  */
     18 
     19 #include "arith_routins.h"
     20 
     21 
     22 /****************************************************************************
     23  * WebRtcIsacfix_EncTerminate(...)
     24  *
     25  * Final call to the arithmetic coder for an encoder call. This function
     26  * terminates and return byte stream.
     27  *
     28  * Input:
     29  *      - streamData        : in-/output struct containing bitstream
     30  *
     31  * Return value             : number of bytes in the stream
     32  */
     33 int16_t WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
     34 {
     35   uint16_t *streamPtr;
     36   uint16_t negCarry;
     37 
     38   /* point to the right place in the stream buffer */
     39   streamPtr = streamData->stream + streamData->stream_index;
     40 
     41   /* find minimum length (determined by current interval width) */
     42   if ( streamData->W_upper > 0x01FFFFFF )
     43   {
     44     streamData->streamval += 0x01000000;
     45 
     46     /* if result is less than the added value we must take care of the carry */
     47     if (streamData->streamval < 0x01000000)
     48     {
     49       /* propagate carry */
     50       if (streamData->full == 0) {
     51         /* Add value to current value */
     52         negCarry = *streamPtr;
     53         negCarry += 0x0100;
     54         *streamPtr = negCarry;
     55 
     56         /* if value is too big, propagate carry to next byte, and so on */
     57         while (!(negCarry))
     58         {
     59           negCarry = *--streamPtr;
     60           negCarry++;
     61           *streamPtr = negCarry;
     62         }
     63       } else {
     64         /* propagate carry by adding one to the previous byte in the
     65          * stream if that byte is 0xFFFF we need to propagate the carry
     66          * furhter back in the stream */
     67         while ( !(++(*--streamPtr)) );
     68       }
     69 
     70       /* put pointer back to the old value */
     71       streamPtr = streamData->stream + streamData->stream_index;
     72     }
     73     /* write remaining data to bitstream, if "full == 0" first byte has data */
     74     if (streamData->full == 0) {
     75       *streamPtr++ += (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
     76       streamData->full = 1;
     77     } else {
     78       *streamPtr = (uint16_t) WEBRTC_SPL_LSHIFT_W32(
     79           WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
     80       streamData->full = 0;
     81     }
     82   }
     83   else
     84   {
     85     streamData->streamval += 0x00010000;
     86 
     87     /* if result is less than the added value we must take care of the carry */
     88     if (streamData->streamval < 0x00010000)
     89     {
     90       /* propagate carry */
     91       if (streamData->full == 0) {
     92         /* Add value to current value */
     93         negCarry = *streamPtr;
     94         negCarry += 0x0100;
     95         *streamPtr = negCarry;
     96 
     97         /* if value to big, propagate carry to next byte, and so on */
     98         while (!(negCarry))
     99         {
    100           negCarry = *--streamPtr;
    101           negCarry++;
    102           *streamPtr = negCarry;
    103         }
    104       } else {
    105         /* Add carry to previous byte */
    106         while ( !(++(*--streamPtr)) );
    107       }
    108 
    109       /* put pointer back to the old value */
    110       streamPtr = streamData->stream + streamData->stream_index;
    111     }
    112     /* write remaining data (2 bytes) to bitstream */
    113     if (streamData->full) {
    114       *streamPtr++ = (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16);
    115     } else {
    116       *streamPtr++ |= (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
    117       *streamPtr = (uint16_t) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 8)
    118           & 0xFF00;
    119     }
    120   }
    121 
    122   /* calculate stream length in bytes */
    123   return (((streamPtr - streamData->stream)<<1) + !(streamData->full));
    124 }
    125