125 lines
3.9 KiB
C
125 lines
3.9 KiB
C
/*
|
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
/*
|
|
* arith_routins.c
|
|
*
|
|
* This C file contains a function for finalizing the bitstream
|
|
* after arithmetic coding.
|
|
*
|
|
*/
|
|
|
|
#include "arith_routins.h"
|
|
|
|
|
|
/****************************************************************************
|
|
* WebRtcIsacfix_EncTerminate(...)
|
|
*
|
|
* Final call to the arithmetic coder for an encoder call. This function
|
|
* terminates and return byte stream.
|
|
*
|
|
* Input:
|
|
* - streamData : in-/output struct containing bitstream
|
|
*
|
|
* Return value : number of bytes in the stream
|
|
*/
|
|
WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
|
|
{
|
|
WebRtc_UWord16 *streamPtr;
|
|
WebRtc_UWord16 negCarry;
|
|
|
|
/* point to the right place in the stream buffer */
|
|
streamPtr = streamData->stream + streamData->stream_index;
|
|
|
|
/* find minimum length (determined by current interval width) */
|
|
if ( streamData->W_upper > 0x01FFFFFF )
|
|
{
|
|
streamData->streamval += 0x01000000;
|
|
|
|
/* if result is less than the added value we must take care of the carry */
|
|
if (streamData->streamval < 0x01000000)
|
|
{
|
|
/* propagate carry */
|
|
if (streamData->full == 0) {
|
|
/* Add value to current value */
|
|
negCarry = *streamPtr;
|
|
negCarry += 0x0100;
|
|
*streamPtr = negCarry;
|
|
|
|
/* if value is too big, propagate carry to next byte, and so on */
|
|
while (!(negCarry))
|
|
{
|
|
negCarry = *--streamPtr;
|
|
negCarry++;
|
|
*streamPtr = negCarry;
|
|
}
|
|
} else {
|
|
/* propagate carry by adding one to the previous byte in the
|
|
* stream if that byte is 0xFFFF we need to propagate the carry
|
|
* furhter back in the stream */
|
|
while ( !(++(*--streamPtr)) );
|
|
}
|
|
|
|
/* put pointer back to the old value */
|
|
streamPtr = streamData->stream + streamData->stream_index;
|
|
}
|
|
/* write remaining data to bitstream, if "full == 0" first byte has data */
|
|
if (streamData->full == 0) {
|
|
*streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
|
|
streamData->full = 1;
|
|
} else {
|
|
*streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32(
|
|
WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
|
|
streamData->full = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
streamData->streamval += 0x00010000;
|
|
|
|
/* if result is less than the added value we must take care of the carry */
|
|
if (streamData->streamval < 0x00010000)
|
|
{
|
|
/* propagate carry */
|
|
if (streamData->full == 0) {
|
|
/* Add value to current value */
|
|
negCarry = *streamPtr;
|
|
negCarry += 0x0100;
|
|
*streamPtr = negCarry;
|
|
|
|
/* if value to big, propagate carry to next byte, and so on */
|
|
while (!(negCarry))
|
|
{
|
|
negCarry = *--streamPtr;
|
|
negCarry++;
|
|
*streamPtr = negCarry;
|
|
}
|
|
} else {
|
|
/* Add carry to previous byte */
|
|
while ( !(++(*--streamPtr)) );
|
|
}
|
|
|
|
/* put pointer back to the old value */
|
|
streamPtr = streamData->stream + streamData->stream_index;
|
|
}
|
|
/* write remaining data (2 bytes) to bitstream */
|
|
if (streamData->full) {
|
|
*streamPtr++ = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16);
|
|
} else {
|
|
*streamPtr++ |= (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
|
|
*streamPtr = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 8)
|
|
& 0xFF00;
|
|
}
|
|
}
|
|
|
|
/* calculate stream length in bytes */
|
|
return (((streamPtr - streamData->stream)<<1) + !(streamData->full));
|
|
}
|