📄 huffman.c
字号:
/* Copyright 1996, ESS Technology, Inc. *//* SCCSID @(#)huffman.c 4.2 11/12/03 *//* * $Log$ */#include "mvd.h"#include "common.h"#include "debug.h"#include "huffman.h"#include "const.h"#include "vp.h"#define PRINTF(a)/****************************************************************************** Huffman decoder initialisation.******************************************************************************/void HUFF_init(void){ int i, table_size; long *high_table; high_table = T_huffman_high_table; mvd[huffdec_control] = 0x23; /* reset & load high-level tbl */ /* Load high-level table */ table_size = T_huffman_high_table_SZ >> 2; 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; volatile int stat; mvd[huffdec_control] = 0x4ac0| HUFRESET; mvd[huffdec_cmdblock] = HUFFDEC_CMDBLOCK_JNU; /* set cmd block to idle */ asm("nop"); mvd[huffdec_control] = 0x4ac0; stat = mvd[huffdec_stat2] & 0xff; stat = stat || stat<<8; mvd[0xb01c/4] = stat; /*To init r1,r2, work with both old and new compiler*/ mvd[huffdec_ldinc_addr] = 0x1dc; /* for MPEG1 */ mvd[huffdec_packet_counter] = 0x100; mvd[huffdec_cmdblock] = HUFFDEC_CMDBLOCK_MBA_ADDR;}/****************************************************************************** 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; mvd[huffdec_cmdblock] = HUFFDEC_CMDBLOCK_JNU; /* set cmd block to idle */ 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; mvd[huffdec_ldinc_addr] = 0x1dc; /* for MPEG1 */ mvd[huffdec_packet_counter] = 0x100; mvd[huffdec_cmdblock] = HUFFDEC_CMDBLOCK_MBA_ADDR;}/****************************************************************************** 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); }int HUFF_getbits_big(int n) /* any number of bits */{ int answer, status; 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);}void HUFF_wait_idle(void){ volatile int stat2, last_stat2; int n = 0; VP_cmdq_wait_empty; while (1) { stat2 = mvd[huffdec_stat2] & 0x1ffff; if (stat2 != last_stat2) n=0; else n++; if (n>10) break; last_stat2 = stat2; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -