Windows2003-3790/enduser/netmeeting/av/codecs/dec/dech263/sac.c
2020-09-30 16:53:55 +02:00

380 lines
11 KiB
C

/* File: sv_h263_sac.c */
/*****************************************************************************
** Copyright (c) Digital Equipment Corporation, 1995, 1997 **
** **
** All Rights Reserved. Unpublished rights reserved under the copyright **
** laws of the United States. **
** **
** The software contained on this media is proprietary to and embodies **
** the confidential technology of Digital Equipment Corporation. **
** Possession, use, duplication or dissemination of the software and **
** media is authorized only pursuant to a valid written license from **
** Digital Equipment Corporation. **
** **
** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
** Government is subject to restrictions as set forth in Subparagraph **
** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
******************************************************************************/
/*
#define _SLIBDEBUG_
*/
#include "sv_h263.h"
#include "sv_intrn.h"
#include "SC_err.h"
#include "proto.h"
#ifdef _SLIBDEBUG_
#include "sc_debug.h"
#define _DEBUG_ 0 /* detailed debuging statements */
#define _VERBOSE_ 1 /* show progress */
#define _VERIFY_ 0 /* verify correct operation */
#define _WARN_ 1 /* warnings about strange behavior */
extern void *dbg;
#endif
#define q1 16384
#define q2 32768
#define q3 49152
#define top 65535
/* local prototypes */
static void bit_out_psc_layer(ScBitstream_t *BSIn);
static int sv_H263bit_opp_bits(ScBitstream_t *BSOut, int bit);
static int sv_H263bit_in_psc_layer(ScBitstream_t *BSOut, int bit);
/*********************************************************************
* SAC Decoder Algorithm as Specified in H26P Annex -E
*
* Name: decode_a_symbol
*
* Description: Decodes an Aritmetically Encoded Symbol
*
* Input: array holding cumulative freq. data
* also uses static data for decoding endpoints
* and code_value variable
*
* Returns: Index to relevant symbol model
*
* Side Effects: Modifies low, high, length, cum and code_value
*
* Author: Wayne Ellis <ellis_w_wayne@bt-web.bt.co.uk>
*
*********************************************************************/
static qword low=0, high=top, zerorun=0; /* decoder and encoder */
static qword code_value, bit; /* decoder */
static qword opposite_bits=0; /* encoder */
int sv_H263SACDecode_a_symbol(ScBitstream_t *BSIn, int cumul_freq[ ])
{
qword length, cum, sacindex;
length = high - low + 1;
cum = (-1 + (code_value - low + 1) * cumul_freq[0]) / length;
for (sacindex = 1; cumul_freq[sacindex] > cum; sacindex++);
high = low - 1 + (length * cumul_freq[sacindex-1]) / cumul_freq[0];
low += (length * cumul_freq[sacindex]) / cumul_freq[0];
for ( ; ; ) {
if (high < q2) ;
else if (low >= q2) {
code_value -= q2;
low -= q2;
high -= q2;
}
else if (low >= q1 && high < q3) {
code_value -= q1;
low -= q1;
high -= q1;
}
else
{
_SlibDebug(_VERBOSE_,
ScDebugPrintf(dbg, "sv_H263SACDecode_a_symbol() code_value=%ld sacindex=%ld\n",
code_value, sacindex) );
break;
}
low = low << 1;
high = (high << 1) + 1;
bit_out_psc_layer(BSIn);
code_value = (code_value << 1) + bit;
}
return ((int)sacindex-1);
}
/*********************************************************************
*
* Name: decoder_reset
*
* Description: Fills Decoder FIFO after a fixed word length
* string has been detected.
*
* Input: None
*
* Returns: Nothing
*
* Side Effects: Fills Arithmetic Decoder FIFO
*
* Author: Wayne Ellis <ellis_w_wayne@bt-web.bt.co.uk>
*
*********************************************************************/
void sv_H263SACDecoderReset(ScBitstream_t *BSIn)
{
int i;
_SlibDebug(_VERBOSE_, ScDebugPrintf(dbg, "sv_H263SACDecoderReset() bytepos=%d\n",
(int)ScBSBytePosition(BSIn)) );
zerorun = 0; /* clear consecutive zero's counter */
code_value = 0;
low = 0;
high = top;
for (i = 1; i <= 16; i++) {
bit_out_psc_layer(BSIn);
code_value = (code_value << 1) + bit;
}
}
/*********************************************************************
*
* Name: bit_out_psc_layer
*
* Description: Gets a bit from the Encoded Stream, Checks for
* and removes any PSC emulation prevention bits
* inserted at the decoder, provides 'zeros' to the
* Arithmetic Decoder FIFO to allow it to finish
* data prior to the next PSC. (Garbage bits)
*
* Input: None
*
* Returns: Nothing
*
* Side Effects: Gets a bit from the Input Data Stream
*
* Author: Wayne Ellis <ellis_w_wayne@bt-web.bt.co.uk>
*
*********************************************************************/
static void bit_out_psc_layer(ScBitstream_t *BSIn)
{
if (ScBSPeekBits(BSIn, 17)!=1) /* check for startcode in Arithmetic Decoder FIFO */
{
_SlibDebug(_DEBUG_, ScDebugPrintf(dbg, "bit_out_psc_layer()\n") );
bit = ScBSGetBit(BSIn);
if (zerorun > 13) { /* if number of consecutive zeros = 14 */
if (!bit) {
_SlibDebug(_WARN_,
ScDebugPrintf(dbg, "bit_out_psc_layer() PSC/GBSC, Header Data, or Encoded Stream Error\n") );
zerorun = 1;
}
else { /* if there is a 'stuffing bit present */
/*
if (H263_DEC_trace)
printf("Removing Startcode Emulation Prevention bit \n");
*/
bit = ScBSGetBit(BSIn); /* overwrite the last bit */
zerorun = !bit; /* zerorun=1 if bit is a '0' */
}
}
else { /* if consecutive zero's not exceeded 14 */
if (!bit) zerorun++;
else zerorun = 0;
}
} /* end of if !(showbits(17)) */
else {
_SlibDebug(_WARN_, ScDebugPrintf(dbg, "bit_out_psc_layer() startcode found, using 'Garbage bits'\n") );
bit = 0;
}
/*
printf("lastbit = %ld bit = %ld zerorun = %ld \n", lastbit, bit, zerorun);
lastbit = bit;
*/
/* latent diagnostics */
}
/*********************************************************************
*
* SAC Encoder Module
* Algorithm as specified in H263 (Annex E)
*
*********************************************************************/
/*********************************************************************
*
* Name: AR_Encode
*
* Description: Encodes a symbol using syntax based arithmetic
* coding. Algorithm specified in H.263 (Annex E).
*
* Input: Array holding cumulative frequency data.
* Index into specific cumulative frequency array.
* Static data for encoding endpoints.
*
* Returns: Number of bits used while encoding symbol.
*
* Side Effects: Modifies low, high, length and opposite_bits
* variables.
*
*********************************************************************/
int sv_H263AREncode(SvH263CompressInfo_t *H263Info, ScBitstream_t *BSOut,
int index, int cumul_freq[ ])
{
qword length;
int bitcount=0;
if (index<0)
return -1; /* Escape Code */
length = high - low + 1;
high = low - 1 + (length * cumul_freq[index]) / cumul_freq[0];
low += (length * cumul_freq[index+1]) / cumul_freq[0];
for ( ; ; ) {
if (high < q2) {
bitcount+=sv_H263bit_opp_bits(BSOut, 0);
}
else if (low >= q2) {
bitcount+=sv_H263bit_opp_bits(BSOut, 1);
low -= q2;
high -= q2;
}
else if (low >= q1 && high < q3) {
opposite_bits += 1;
low -= q1;
high -= q1;
}
else break;
low *= 2;
high = 2*high+1;
}
return bitcount;
}
static int sv_H263bit_opp_bits(ScBitstream_t *BSOut, int bit) /* Output a bit and the following opposite bits */
{
int bitcount=0;
bitcount = sv_H263bit_in_psc_layer(BSOut, bit);
while(opposite_bits > 0){
bitcount += sv_H263bit_in_psc_layer(BSOut, !bit);
opposite_bits--;
}
return bitcount;
}
/*********************************************************************
*
* Name: encoder_flush
*
* Description: Completes arithmetic coding stream before any
* fixed length codes are transmitted.
*
* Input: None
*
* Returns: Number of bits used.
*
* Side Effects: Resets low, high, zerorun and opposite_bits
* variables.
*
*********************************************************************/
int sv_H263AREncoderFlush(SvH263CompressInfo_t *H263Info, ScBitstream_t *BSOut)
{
int bitcount = 0;
_SlibDebug(_VERBOSE_, ScDebugPrintf(dbg, "sv_H263AREncoderFlush() bytepos=%d\n",
(int)ScBSBytePosition(BSOut)) );
opposite_bits++;
if (low < q1) {
bitcount+=sv_H263bit_opp_bits(BSOut, 0);
}
else {
bitcount+=sv_H263bit_opp_bits(BSOut, 1);
}
low = 0;
high = top;
zerorun=0;
return bitcount;
}
/*********************************************************************
*
* Name: bit_in_psc_layer
*
* Description: Inserts a bit into output bitstream and avoids
* picture start code emulation by stuffing a one
* bit.
*
* Input: Bit to be output.
*
* Returns: Nothing
*
* Side Effects: Updates zerorun variable.
*
*********************************************************************/
static int sv_H263bit_in_psc_layer(ScBitstream_t *BSOut, int bit)
{
int bitcount = 0;
if (zerorun > 13) {
_SlibDebug(_DEBUG_, ScDebugPrintf(dbg,
"sv_H263bit_in_psc_layer() bytepos=%d, PSC emulation...Bit stuffed\n",
(int)ScBSBytePosition(BSOut)) );
svH263mputb(1);
bitcount++;
zerorun = 0;
}
svH263mputb(bit);
bitcount++;
if (bit)
zerorun = 0;
else
zerorun++;
return bitcount;
}
/*********************************************************************
*
* Name: indexfn
*
* Description: Translates between symbol value and symbol
* index.
*
* Input: Symbol value, index table, max number of
* values.
*
* Returns: Index into cumulative frequency tables or
* escape code.
*
* Side Effects: none
*
*********************************************************************/
int sv_H263IndexFN(int value, int table[], int max)
{
int n=0;
while(1) {
if (table[n++]==value) return n-1;
if (n>max) return -1;
}
}