vld.c

来自「著名的 helix realplayer 基于手机 symbian 系统的 播放」· C语言 代码 · 共 706 行 · 第 1/2 页

C
706
字号
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 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 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (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.  
 *  
 * 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 */
                        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
)
{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?