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 WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData) 34 { 35 WebRtc_UWord16 *streamPtr; 36 WebRtc_UWord16 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++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24); 76 streamData->full = 1; 77 } else { 78 *streamPtr = (WebRtc_UWord16) 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++ = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16); 115 } else { 116 *streamPtr++ |= (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24); 117 *streamPtr = (WebRtc_UWord16) 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