?? huffman.c
字號:
/* Copyright 1996, ESS Technology, Inc. *//* SCCSID @(#)huffman.c 1.21 2/9/98 *//* * $Log$ */#include "mvd.h"#include "common.h"#include "debug.h"#include "huffman.h"#include "const.h"#include "vp.h"#ifdef SVCD#include "sysinfo.h"#endif#define PRINTF(a)/****************************************************************************** Huffman decoder initialisation.******************************************************************************/void HUFF_init(void){ int i, table_size; long *high_table;#ifdef SVCD high_table = (mpeg2)? T_huffman_high_table_MPEG2 : T_huffman_high_table_MPEG1;#else high_table = T_huffman_high_table;#endif mvd[huffdec_control] = 0x23; /* reset & load high-level tbl */ /* Load high-level table */#ifdef SVCD table_size = (mpeg2) ? T_huffman_high_table_MPEG2_SZ >> 2 : T_huffman_high_table_MPEG1_SZ >> 2 ;#else table_size = T_huffman_high_table_SZ >> 2;#endif assert(table_size <= 64); for (i = 0; i < table_size; i++) { mvd[huffdec_highsram+i] = high_table[i]; } /* Verify table */ for (i = 0; i < table_size; i++) { int val; val = mvd[huffdec_highsram+i] & 0xfffff; if (val != high_table[i]) { EPRINTF(("ERR: hd hsram_table fnd: %lx exp:%lx a:%x\n", val, high_table[i], i)); } } HUFF_reset_output_fifo_and_state(); PRINTF(("Done Huffman initialisation\n"));}/****************************************************************************** Reset huffman decoder. Used in emergency_save.******************************************************************************/void HUFF_reset_output_fifo_and_state(){ int i; mvd[huffdec_control] = 0x4ac0| HUFRESET;#ifdef SVCD mvd[huffdec_cmdblock] = (mpeg2) ?HUFFDEC_CMDBLOCK_JNU_MPEG2 : HUFFDEC_CMDBLOCK_JNU;/* set cmd block to idle*/#else mvd[huffdec_cmdblock] = HUFFDEC_CMDBLOCK_JNU; /* set cmd block to idle */#endif asm("nop"); mvd[huffdec_control] = 0x4ac0;#ifdef MPEG1#ifdef SVCD if (mpeg2) mvd[huffdec_ldinc_addr] = 0x5; /* for MPEG2 */ else mvd[huffdec_ldinc_addr] = 0x1dc; /* for MPEG1 */#else mvd[huffdec_ldinc_addr] = 0x1dc; /* for MPEG1 */#endif#else mvd[huffdec_ldinc_addr] = 0x5; /* for MPEG2 */#endif mvd[huffdec_packet_counter] = 0x100;#ifdef MPEG1 mvd[huffdec_cmdblock] = HUFFDEC_CMDBLOCK_MBA_ADDR;#endif}/****************************************************************************** Reset huffman decoder, DO not reset INPUT fifo. Used in emergency_save.******************************************************************************/#define VPSTAT_DH 0x2000void HUFF_reset_state_machine(){ int i; mvd[huffdec_control] = 0x4ac0| HUFDECRESET;#ifdef SVCD mvd[huffdec_cmdblock] = (mpeg2) ?HUFFDEC_CMDBLOCK_JNU_MPEG2 : HUFFDEC_CMDBLOCK_JNU;/* set cmd block to idle */ #else mvd[huffdec_cmdblock] = HUFFDEC_CMDBLOCK_JNU; /* set cmd block to idle */ #endif VP_cmdq_reset(0); /* clean up the NRLA fifo */ do { i = mvd[huffdec_nrlarisc]; } while (mvd[huffdec_stat1] & 0x3f); /* clean up the RLA fifo */ do { VP_block(0,VPSTAT_DH); risc_sleep_a_bit(100); } while (mvd[huffdec_stat1] & 0x3c0); VP_cmdq_reset(0); mvd[huffdec_control] = 0x4ac0;#ifdef MPEG1#ifdef SVCD if (mpeg2) mvd[huffdec_ldinc_addr] = 0x5; /* for MPEG2 */ else mvd[huffdec_ldinc_addr] = 0x1dc; /* for MPEG1 */ #else mvd[huffdec_ldinc_addr] = 0x1dc; /* for MPEG1 */ #endif #else mvd[huffdec_ldinc_addr] = 0x5; /* for MPEG2 */#endif mvd[huffdec_packet_counter] = 0x100;#ifdef MPEG1 mvd[huffdec_cmdblock] = HUFFDEC_CMDBLOCK_MBA_ADDR;#endif}/****************************************************************************** Hufdec gateway fifo wait subroutines.* Only works when the size of the two hufdec fifos are 16 dwords!* Also it seems that we can't wait for more than 12!******************************************************************************/#ifndef WAIT_HD_FIFO_USE_MACROvoid HUFF_wait_fifo_video(int number){ wait_huffdec_fifo(v, number);}void HUFF_wait_fifo_audio(int number){ wait_huffdec_fifo(a, number);}#endif/****************************************************************************** Various getbits subroutines.******************************************************************************/int HUFF_autoeat(void) /* 8 or fewer bits */{ do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); return (((unsigned char *)mvd)[((huffdec_stat0)<<2)+3]);}int HUFF_getbits(int n) /* 8 or fewer bits */{ assert(n <= 8); mvd[huffdec_eatamount] = n - 1; do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); return (((unsigned char *)mvd)[((huffdec_stat0)<<2)+3]);}int HUFF_getbits_med(int n) /* up to 16 bits */{ int answer; assert(n <= 16); mvd[huffdec_eatamount] = (n-1) & 7; do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); answer = ((unsigned char *)mvd)[((huffdec_stat0)<<2)+3]; if (n>8) { mvd[huffdec_eatamount] = 7; do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); answer <<= 8; answer |= ((unsigned char *)mvd)[((huffdec_stat0)<<2)+3]; } return(answer); }#ifdef AC3int HUFF_getbits_med_lj(int n) /* up to 16 bits, left justified */{ int answer; assert(n <= 16); if (n>8) { mvd[huffdec_eatamount] = 7; do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); answer = ((unsigned char *)mvd)[((huffdec_stat0)<<2)+3]; answer <<= 8; mvd[huffdec_eatamount] = 8 | ((n-1) & 7); do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); answer |= ((unsigned char *)mvd)[((huffdec_stat0)<<2)+3]; } else { mvd[huffdec_eatamount] = 8 | ((n-1) & 7); do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); answer = (((unsigned char *)mvd)[((huffdec_stat0)<<2)+3])<<8; } return(answer); }#endif#if defined(MPEG2) || defined(SVCD)int HUFF_getbits_big(int n) /* any number of bits */{ int answer; int n_bytes_left; mvd[huffdec_eatamount] = (n-1) & 7; do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); answer = ((unsigned char *)mvd)[((huffdec_stat0)<<2)+3]; n_bytes_left = (n - 1)>>3; while (n_bytes_left-- > 0) { mvd[huffdec_eatamount] = 7; do {} while ((mvd[huffdec_stat3] & 0xff) != 0xff); answer <<= 8; answer |= ((unsigned char *)mvd)[((huffdec_stat0)<<2)+3]; } return(answer); }#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -