📄 vld.c
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: vld.c,v 1.3.34.1 2004/07/09 01:56:22 hubbe Exp $
*
* Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file,
* are subject to the current version of the RealNetworks Public
* Source License (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (the "RCSL") available at
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
* will apply. You may also obtain the license terms directly from
* RealNetworks. You may not use this file except in compliance with
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
* the rights, obligations and limitations governing use of the
* contents of the file.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxtypes.h"
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
//#include <ctype.h>
#include "dllindex.h"
#include "h261defs.h"
#include "h261func.h"
#include "vldstate.h"
#include "vldtabs.h"
#include "vld.h"
#include "machine.h"
#include "hvutils.h"
#include "h263plus.h"
#if defined(_WINDOWS)
#include "hxstrutl.h"
#endif /* _WINDOWS */
static int buildtable( int minBits, struct vlc_entry input[], DECTABENTRY output[DECTABSIZE]);
static int parse_bits( char vlc[], /* String with bit pattern */
int strmax, /* Max characters in "vlc" excluding terminating null */
int maxbits, /* Max # bits in codeword */
int * bits, /* Returns # bits; 0 < bits < maxbits+1 */
int * codeword, /* Returns codeword */
int minBits // Min # bits in codeword
);
// Get8Bits - return next 8 bits from bitstream
extern U8 Get8Bits( BS_PTR bs)
{
int k;
k = (*bs.byteptr << 8) | *(bs.byteptr + 1);
return (k >> (8 - bs.bitptr));
}
// IncBsPtr - Increment (or decrement) bitstream pointer
extern void IncBsPtr( BS_PTR * bs, int incr)
{
bs->bitptr += incr;
while (bs->bitptr > 7) {
++(bs->byteptr);
bs->bitptr -= 8;
}
while (bs->bitptr < 0) {
--(bs->byteptr);
bs->bitptr += 8;
}
return;
}
// FLDecSymbol - Decode fixed length symbol of length "bits"
// Return values: 1 OK: successful decoding; symbol returned in "value"
// 0 OUT_OF_BITS: consumed more than "numBits"; returning numBits < 0
extern int FLDecSymbol( BS_PTR * bs, // Bitstream pointer; incremented by this routine
int bits, // Symbol length
int * numBits, // Max # bits to decode; decremented by this routine
int * value // Returns decoded symbol
)
{
*value = 0;
while (bits > 8) {
*value |= Get8Bits( *bs ) << (bits - 8);
bits -= 8;
*numBits -= 8;
++bs->byteptr;
}
*value |= Get8Bits( *bs ) >> (8 - bits);
*numBits -= bits; // Subtract parsed bits
IncBsPtr( bs, bits); // Advance bitpointer
//printf("FLDecSymbol: value = %2x\n", *value );
if (*numBits < 0) {
return (OUT_OF_BITS);
}
return( OK );
}
// VLDecSymbol - Decode variable length symbol using dectable[tabNum]
// Return values: 1 OK: successful decoding; symbol returned in sym
// 0 OUT_OF_BITS: consumed more than "numBits"; returning numBits < 0
// -1 ILLEGAL_SYMBOL: bitstream error
// -2 ILLEGAL_STATE: internal program error
// -3 FINISHED_LAST_BLOCK: reached state ST263_FINISHED (program
// error for this routine)
extern int VLDecSymbol( BS_PTR * bs, // Bitstream pointer; incremented by this routine
int tabNum, // Use dectable[tabNum] for decoding
int * numBits, // Max # bits to decode; decremented by this routine
SYMBOL * sym // Returns decoded symbol
)
{
DECTABENTRY * entry;
/*printf( "Entered VLDecSymbol: bitstream = %2x %2x %2x %2x bitptr = %d\n",
*bs->byteptr, *(bs->byteptr + 1), *(bs->byteptr + 2),
*(bs->byteptr + 3), bs->bitptr);*/
entry = &dectable [tabNum] [Get8Bits( *bs )];
while (entry->bits < 0) { // Long codeword; sym.value indicates table */
*numBits += entry->bits; // Subtract parsed bits
IncBsPtr( bs, -entry->bits); // Advance bitpointer
//printf("VLDecSymbol - long symbol: "); printsym( entry->sym ); printf("\n");
entry = &dectable [ entry->sym.value ] [Get8Bits( *bs )];
}
*numBits -= entry->bits; // Subtract parsed bits
IncBsPtr( bs, entry->bits); // Advance bitpointer
/*{
//int input;
printf("VLDecSymbol: "); printsym( entry->sym ); printf("\n");
printf(" Cont? (<0 to exit): ");
scanf("%d", &input);
if (input < 0) exit(0);
}*/
if (entry->sym.type == SYM_EXIT) { // Premature exit
if (*numBits < 0) {
return (OUT_OF_BITS);
} else {
return (entry->sym.value);
}
}
*sym = entry->sym;
if (*numBits < 0) {
return (OUT_OF_BITS);
}
return( OK );
}
// InitDecodeTable - Generate decoding tables
extern void InitDecodeTable( void )
{
int minBits;
minBits = 1; // Codeword strings need to be non-empty
buildtable( minBits, dct_next, dectable[TAB_DCT_NEXT]);
buildtable( minBits, dct_first, dectable[TAB_DCT_FIRST]);
buildtable( minBits, dct_00100, dectable[TAB_DCT_00100]);
buildtable( minBits, dct_000000, dectable[TAB_DCT_000000]);
buildtable( minBits, escape_run, dectable[TAB_ESCAPE_RUN]);
buildtable( minBits, escape_level, dectable[TAB_ESCAPE_LEVEL]);
buildtable( minBits, intra_dc, dectable[TAB_INTRA_DC]);
buildtable( minBits, last_intra_dc, dectable[TAB_LAST_INTRA_DC]);
buildtable( minBits, mba_startcode, dectable[TAB_MBA_STARTCODE]);
buildtable( minBits, long_mba, dectable[TAB_LONG_MBA]);
buildtable( minBits, long_startcode, dectable[TAB_LONG_STARTCODE]);
buildtable( minBits, mtype, dectable[TAB_MTYPE]);
buildtable( minBits, long_mtype, dectable[TAB_LONG_MTYPE]);
buildtable( minBits, mvd, dectable[TAB_MVD]);
buildtable( minBits, long_mvd, dectable[TAB_LONG_MVD]);
buildtable( minBits, cbp, dectable[TAB_CBP]);
buildtable( minBits, long_cbp, dectable[TAB_LONG_CBP]);
buildtable( minBits, quant_tr, dectable[TAB_QUANT_TR]); //Don't parse strings
buildtable( minBits, gei_pei, dectable[TAB_GEI_PEI]);
buildtable( minBits, long_spare, dectable[TAB_LONG_SPARE]); //Don't parse strings
buildtable( minBits, gn, dectable[TAB_GN]);
buildtable( minBits, ptype, dectable[TAB_PTYPE]); //Don't parse strings
buildtable( minBits, illegal_state, dectable[TAB_ILLEGAL_STATE]);
// Generate H.263 decoding tables
buildtable( minBits, mcbpc263, dectable[TAB263_MCBPC_INTER] );
buildtable( minBits, long_mcbpc263, dectable[TAB263_LONG_MCBPC_INTER] );
buildtable( minBits, long_startcode263, dectable[TAB263_LONG_STARTCODE] );
buildtable( minBits, zeros_and_start263, dectable[TAB263_ZEROS_AND_START] );
buildtable( minBits, intra_mcbpc263, dectable[TAB263_MCBPC_INTRA] );
buildtable( minBits, long_intra_mcbpc263, dectable[TAB263_LONG_MCBPC_INTRA] );
buildtable( minBits, modb263, dectable[TAB263_MODB] );
buildtable( minBits, cbpy263, dectable[TAB263_CBPY] );
buildtable( minBits, intra_cbpy263, dectable[TAB263_CBPY_INTRA] );
buildtable( minBits, dquant263, dectable[TAB263_DQUANT] );
buildtable( minBits, mvd263, dectable[TAB263_MVD] );
buildtable( minBits, long_mvd263, dectable[TAB263_LONG_MVD] );
buildtable( minBits, tcoef, dectable[TAB263_TCOEF] );
buildtable( minBits, tcoef_0001, dectable[TAB263_TCOEF_0001] );
buildtable( minBits, tcoef_0000_1, dectable[TAB263_TCOEF_0000_1] );
buildtable( minBits, tcoef_0000_0, dectable[TAB263_TCOEF_0000_0] );
buildtable( minBits, esc263_run, dectable[TAB263_ESC_RUN] );
buildtable( minBits, esc263_level, dectable[TAB263_ESCAPE_LEVEL] );
buildtable( minBits, intra263_dc, dectable[TAB263_INTRA_DC] );
#ifdef DO_H263_PLUS
buildtable( minBits, modb263plus, dectable[TAB263PLUS_MODB] );
buildtable( minBits, intra_mode263plus, dectable[TAB263PLUS_INTRA_MODE] );
buildtable( minBits, tcoef_plus, dectable[TAB263PLUS_TCOEF] );
buildtable( minBits, tcoef_0001_plus, dectable[TAB263PLUS_TCOEF_0001] );
buildtable( minBits, tcoef_0000_1_plus, dectable[TAB263PLUS_TCOEF_0000_1] );
buildtable( minBits, tcoef_0000_0_plus, dectable[TAB263PLUS_TCOEF_0000_0] );
#endif
minBits = 0; // Accept empty codeword string (length 0) to produce SYM_EXIT
buildtable( minBits, finished_263blk, dectable[TAB263_FINISHED] );
/*{
int i, ntab;
printf("\nDiagnostic print of table #: ");
scanf("%d", &ntab);
while (ntab >= 0) {
printf( "Entry Type Value Length Statechange\n");
for (i = 0; i < 256; i++) {
printf( " %3d %3d %3d %3d %3d\n", i,
dectable[ntab][i].sym.type, dectable[ntab][i].sym.value,
dectable[ntab][i].bits, dectable[ntab][i].statechange);
}
printf("\nDiagnostic print of table #: ");
scanf("%d", &ntab);
}
printf("\nselectdectab:\n");
for (i = 0; i < NUMSTATES; ++i)
{
if (i % 10 == 0) printf("\n%3d ", i);
if (i % 10 == 5) printf(" ");
printf("%3d", selectdectab[i] );
}
printf("\n");
}*/
return;
}
// buildtable - Generate 8-bit (DECTABBITS) decode table;
// Contains 256 (DECTABSIZE) entries
static int buildtable( int minBits, struct vlc_entry input[], DECTABENTRY output[DECTABSIZE])
{
int i, j, bits, codeword, flc, value, status;
char msg[120]; /* Flawfinder: ignore */
for (i = 0; i < DECTABSIZE; i++) {
output[i].sym.type = SYM_EXIT;
output[i].sym.value = ILLEGAL_SYMBOL;
}
if (strcmpi( input[0].vlc, "FLC")) { /* VLC is default */
flc = 0;
//printf("Variable length\n");
i = 0;
} else {
flc = 1;
//printf("Fixed length\n");
i = 1;
}
//printf( " Hex Type Value Statechange\n");
while (strcmpi( input[i].vlc, "End")) { /* Process until "End" */
status = parse_bits( input[i].vlc, MAX_STRING_VLD-1, DECTABBITS,
&bits, &codeword, minBits);
if (status != OK) {
sprintf( msg, "Error in parse_bits from buildtable"); /* Flawfinder: ignore */
H261ErrMsg( msg );
return( H261_ERROR );
}
codeword <<= DECTABBITS - bits;
value = input[i].value;
if (flc == 0) { /* Do one codeword if VLC code */
input[i].last_value = value;
}
while (value <= input[i].last_value) {
//strpad( input[i].vlc, ' ', MAX_STRING_VLD-1);
//printf( "%3d: %s %2x %4d %4d %4d Bits = %d\n",
// i, input[i].vlc, codeword, input[i].type, value,
// input[i].statechange, bits);
/* Build decode table */
for (j = codeword; j < codeword + (1 << (DECTABBITS - bits)); j++) {
if (output[j].sym.type != SYM_EXIT ||
output[j].sym.value != ILLEGAL_SYMBOL) {
sprintf( msg, "String %d: Entry %d done previously", i, j); /* Flawfinder: ignore */
H261ErrMsg( msg );
return( H261_ERROR );
}
output[j].sym.type = input[i].type;
output[j].sym.value = value;
output[j].statechange = input[i].statechange;
/* Signal long codeword by inverting "bits" */
if (input[i].type == SYM_ESCAPE) {
output[j].bits = -bits;
} else {
output[j].bits = bits;
}
}
++value;
codeword += (1 << (DECTABBITS - bits));
}
if (++i > DECTABSIZE) {
goto no_end;
}
}
/* if (flc == 0) {
printf("Reached End after finding %d variable length codes\n", i);
} else {
printf("Reached End after finding %d fixed length entries\n", i-1);
}
*/
return (OK);
no_end:
sprintf( msg, "No End mark"); /* Flawfinder: ignore */
H261ErrMsg( msg );
return( H261_ERROR );
}
// Parse bitstring "vlc", return length in "bits" and value in "codeword"
static int parse_bits( char vlc[], /* String with bit pattern */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -