📄 text_bits.c
字号:
/**************************************************************************
* *
* This code is developed by Adam Li. This software is an *
* implementation of a part of one or more MPEG-4 Video tools as *
* specified in ISO/IEC 14496-2 standard. Those intending to use this *
* software module in hardware or software products are advised that its *
* use may infringe existing patents or copyrights, and any such use *
* would be at such party's own risk. The original developer of this *
* software module and his/her company, and subsequent editors and their *
* companies (including Project Mayo), will have no liability for use of *
* this software or modifications or derivatives thereof. *
* *
* Project Mayo gives users of the Codec a license to this software *
* module or modifications thereof for use in hardware or software *
* products claiming conformance to the MPEG-4 Video Standard as *
* described in the Open DivX license. *
* *
* The complete Open DivX license can be found at *
* http://www.projectmayo.com/opendivx/license.php . *
* *
**************************************************************************/
/**************************************************************************
*
* text_bits.c
*
* Copyright (C) 2001 Project Mayo
*
* Adam Li
*
* DivX Advance Research Center <darc@projectmayo.com>
*
**************************************************************************/
/* This file contains some utility functions to write to bitstreams for */
/* texture part of the coding. */
/* Some codes of this project come from MoMuSys MPEG-4 implementation. */
/* Please see seperate acknowledgement file for a list of contributors. */
#include "momusys.h"
#include "text_defs.h"
#include "bitstream.h"
#include "text_bits.h"
#include "putvlc.h"
#include "zigzag.h" /* added, 14-NOV-1996 MW */
#include "max_level.h" /* 3-mode esc */
Int IntraDC_dpcm (Int val, Int lum, Image *bitstream);
Int CodeCoeff (Int j_start, Int Mode, Int qcoeff[],
Int block, Int ncoeffs, Image *bitstream);
Int CodeCoeff_RVLC (Int j_start, Int Mode, Int qcoeff[],
Int block, Int ncoeffs, Image *bitstream);
/***********************************************************CommentBegin******
*
* -- MB_CodeCoeff -- Codes coefficients, does DC/AC prediction
*
* Purpose :
* Codes coefficients, does DC/AC prediction
*
* Arguments in :
* Int *qcoeff : quantized dct-coefficients
* Int Mode : encoding mode
* Int CBP : coded block pattern
* Int ncoeffs : number of coefficients per block
* Int x_pos : the horizontal position of the macroblock in the vop
* Int intra_dcpred_disable : disable the intradc prediction
* Int transp_pattern[]: Describes which blocks are transparent
*
* Arguments out :
* Bits *bits : struct to count the number of texture bits
* Image *bitstream : output bitstream
*
* Description :
* The intradc prediction can be switched off by setting the variable
* intradc_pred_disable to '1'.
*
***********************************************************CommentEnd********/
Void MB_CodeCoeff(Bits* bits, Int *qcoeff,
Int Mode, Int CBP, Int ncoeffs,
Int intra_dcpred_disable,
Image *DCbitstream,
Image *bitstream,
Int transp_pattern[], Int direction[],
Int error_res_disable,
Int reverse_vlc,
Int switched,
Int alternate_scan)
{
Int i, m, coeff[64];
Int *zz = alternate_scan ? zigzag_v : zigzag;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
if (intra_dcpred_disable == 0)
{
for (i = 0; i < 6; i++)
{
// if (i>3 || transp_pattern[i]!=1) /* Not transparent */
{
if (!alternate_scan)
{
switch (direction[i])
{
case 1: zz = zigzag_v; break;
case 2: zz = zigzag_h; break;
case 0: break;
default: fprintf(stderr, "MB_CodeCoeff(): Error in zigzag direction\n");
exit(-1);
}
}
/* Do the zigzag scanning of coefficients */
for (m = 0; m < 64; m++)
{
*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
}
if (switched==0)
{
if (error_res_disable)
{
if (i < 4)
bits->Y += IntraDC_dpcm(coeff[0],1,bitstream);
else
bits->C += IntraDC_dpcm(coeff[0],0,bitstream);
}
else
{
if (i < 4)
bits->Y += IntraDC_dpcm(coeff[0],1,DCbitstream);
else
bits->C += IntraDC_dpcm(coeff[0],0,DCbitstream);
}
}
/* Code AC coeffs. dep. on block pattern MW 15-NOV-1996 */
if ((i==0 && CBP&32) ||
(i==1 && CBP&16) ||
(i==2 && CBP&8) ||
(i==3 && CBP&4) ||
(i==4 && CBP&2) ||
(i==5 && CBP&1))
{
if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
{
if (i < 4)
bits->Y += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,bitstream);
else
bits->C += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
bitstream);
}
else
{
if (i < 4)
bits->Y += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
ncoeffs, bitstream);
else
bits->C += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
ncoeffs, bitstream);
}
}
}
}
}
else /* Without ACDC prediction */
{
for (i = 0; i < 6; i++)
{
// if (i>3 || transp_pattern[i]!=1) /* Not transparent */
{
/* Do the zigzag scanning of coefficients */
for (m = 0; m < 64; m++)
*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
if (switched==0)
{
if (error_res_disable)
{
if (coeff[0] != 128)
BitstreamPutBits(bitstream,(long)(coeff[0]),8L);
else
BitstreamPutBits(bitstream, 255L, 8L);
}
else
{
if (coeff[0] != 128)
BitstreamPutBits(DCbitstream,(long)(coeff[0]),8L);
else
BitstreamPutBits(DCbitstream,255L, 8L);
}
if (i < 4)
bits->Y += 8;
else
bits->C += 8;
}
if ((i==0 && CBP&32) || (i==1 && CBP&16) ||
(i==2 && CBP&8) || (i==3 && CBP&4) ||
(i==4 && CBP&2) || (i==5 && CBP&1))
{
/* send coeff, not qcoeff !!! MW 07-11-96 */
if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
{
if (i < 4)
bits->Y += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
bitstream);
else
bits->C += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
bitstream);
}
else
{
if (i < 4)
bits->Y += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
ncoeffs, bitstream);
else
bits->C += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
ncoeffs, bitstream);
}
}
}
}
}
}
else /* inter block encoding */
{
for (i = 0; i < 6; i++)
{
/* Do the zigzag scanning of coefficients */
for (m = 0; m < 64; m++)
*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
if ((i==0 && CBP&32) ||
(i==1 && CBP&16) ||
(i==2 && CBP&8) ||
(i==3 && CBP&4) ||
(i==4 && CBP&2) ||
(i==5 && CBP&1))
{
if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
{
if (i < 4)
bits->Y += CodeCoeff(0,Mode, coeff, i, ncoeffs, bitstream);
else
bits->C += CodeCoeff(0,Mode, coeff, i, ncoeffs, bitstream);
}
else
{
if (i < 4)
bits->Y += CodeCoeff_RVLC(0,Mode, coeff, i, ncoeffs,
bitstream);
else
bits->C += CodeCoeff_RVLC(0,Mode, coeff, i, ncoeffs,
bitstream);
}
}
}
}
}
/***********************************************************CommentBegin******
*
* -- IntraDC_dpcm -- DPCM Encoding of INTRADC in case of Intra macroblocks
*
* Purpose :
* DPCM Encoding of INTRADC in case of Intra macroblocks
*
* Arguments in :
* Int val : the difference value with respect to the previous
* INTRADC value
* Int lum : indicates whether the block is a luminance block (lum=1) or
* a chrominance block ( lum = 0)
*
* Arguments out :
* Image* bitstream : a pointer to the output bitstream
*
***********************************************************CommentEnd********/
Int
IntraDC_dpcm(Int val, Int lum, Image *bitstream)
{
Int n_bits;
Int absval, size = 0;
absval = ( val <0)?-val:val; /* abs(val) */
/* compute dct_dc_size */
size = 0;
while(absval)
{
absval>>=1;
size++;
}
if (lum)
{ /* luminance */
n_bits = PutDCsize_lum (size, bitstream);
}
else
{ /* chrominance */
n_bits = PutDCsize_chrom (size, bitstream);
}
if ( size != 0 )
{
if (val>=0)
{
;
}
else
{
absval = -val; /* set to "-val" MW 14-NOV-1996 */
val = (absval ^( (int)pow(2.0,(double)size)-1) );
}
BitstreamPutBits(bitstream, (long)(val), (long)(size));
n_bits += size;
if (size > 8)
BitstreamPutBits(bitstream, (long)1, (long)1);
}
return n_bits; /* # bits for intra_dc dpcm */
}
/***********************************************************CommentBegin******
*
* -- CodeCoeff -- VLC encoding of quantized DCT coefficients
*
* Purpose :
* VLC encoding of quantized DCT coefficients, except for
* INTRADC in case of Intra macroblocks
* Used by Bits_CountCoeff
*
* Arguments in :
* Int Mode : encoding mode
* Int *qcoeff: pointer to quantized dct coefficients
* Int block : number of the block in the macroblock (0-5)
* Int ncoeffs : the number of coefficients per block
*
* Arguments out :
* Image *bitstream : pointer to the output bitstream
*
* Return values :
* Int bits : number of bits added to the bitstream (?)
*
***********************************************************CommentEnd********/
Int CodeCoeff(Int j_start, Int Mode, Int qcoeff[], Int block, Int ncoeffs, Image *bitstream)
{
Int j, bits;
Int prev_run, run, prev_level, level, first;
Int prev_ind, ind, prev_s, s, length;
run = bits = 0;
first = 1;
prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
for (j = j_start; j< ncoeffs; j++)
{
/* The INTRADC encoding for INTRA Macroblocks is done in
Bits_CountCoeff */
{
/* do not enter this part for INTRADC coding for INTRA macro-
blocks */
/* encode AC coeff */
s = 0;
/* Increment run if coeff is zero */
if ((level = qcoeff[j]) == 0)
{
run++;
}
else
{
/* code run & level and count bits */
if (level < 0)
{
s = 1;
level = -level;
}
ind = level | run<<4;
ind = ind | 0<<12; /* Not last coeff */
if (!first)
{
/* Encode the previous ind */
if ((prev_run < 64) &&
(((prev_level < 13) && (Mode != MODE_INTRA &&
Mode != MODE_INTRA_Q))
|| ((prev_level < 28) && (Mode == MODE_INTRA ||
Mode == MODE_INTRA_Q))))
{
/* Separate tables for Intra luminance blocks */
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutCoeff_Intra(prev_run, prev_level,
0, bitstream);
}
else
{
length = PutCoeff_Inter(prev_run, prev_level,
0, bitstream);
}
}
else
length = 0;
/* First escape mode. Level offset */
if (length == 0)
{
if ( prev_run < 64 )
{
/* subtraction of Max level, last = 0 */
int level_minus_max;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
level_minus_max = prev_level -
intra_max_level[0][prev_run];
else
level_minus_max = prev_level -
inter_max_level[0][prev_run];
if ( ( (level_minus_max < 13) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q) ) ||
( (level_minus_max < 28) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) ) )
{
/* Separate tables for Intra luminance blocks */
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutLevelCoeff_Intra(prev_run, level_minus_max, 0, bitstream);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -