buffer.c

来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 892 行 · 第 1/2 页

C
892
字号
/* Copyright 1996, ESS Technology, Inc.                                 *//* SCCSID @(#)buffer.c	4.15 12/09/04 *//* * $Log$ */#include "vcxi.h"#include "vp.h"#include "memmap.h"#include "debug.h"#include "util.h"#include "low.h"#include "buffer.h"#include "tdm.h"#include "xport.h"#include "mpeg1vid.h"#include "mpgaudio.h"#ifdef ECHO#include "echo.h"#endif#ifdef SPATIAL#include "kara.h"#endif#ifdef PRE_EMPHASIS#include "const.h"#endif#if (defined(CDG) || defined(CD_TEXT))#include "cd_text.h"#endif#ifdef TRACE_MP3_AUDIOBREAK#include "mp3.h"#endif/**************************************************************************** Local defines. ****************************************************************************/#ifdef JPEG_DEC#define	CONDITION_FOR_HUFDECA_XFER (!is_jpeg && !TDM_isCDDA && !ABV_draining)#define CONDITION_FOR_HUFDECA_EXIT (is_jpeg || TDM_isCDDA)#else#define	CONDITION_FOR_HUFDECA_XFER (!TDM_isCDDA && !ABV_draining)#define CONDITION_FOR_HUFDECA_EXIT (TDM_isCDDA)#endif /* JPEG_DEC */#define	done_but_needed(ch) \    ((!buscon_is_running(ch))&&(mask & buscon_##ch##_runbit))#undef	DUMP_VBV_WHEN_FULL/**************************************************************************** Debugging. ****************************************************************************/#ifndef ECHOKEYDEBUGVAR(PCM_starvings, 0);	/* Number of times PCM starved */#endifKEYDEBUGVAR(ABV_overflow, 0);	/* Number of times ABV overflowed */KEYDEBUGVAR(VBV_overflow, 0);	/* Number of times VBV overflowed */#define PRINTF(a)/**************************************************************************** Local function prototypes. ****************************************************************************//**************************************************************************** Local variables. ****************************************************************************/#define is_TDM	1/****************************************************************************** If there's enough room in DRAM initiate a xport buscon to sys buff.  rdptr == wrptr means buffer empty. In the case of TDM we do it anyway. ******************************************************************************/#ifdef XFER_USE_MACRO#define xportv_xfer_TDM()	do {					\    int space = VBV_rdptr - VBV_wrptr;					\    if (space <= 0) space += VBV_size;				  	\    if (space <= VBV_write) {						\	oh_my(0x16);							\	KEYDEBUGINC(1, VBV_overflow);					\	DBG_log_error(99, 1, space, VID_decoding_in_progress, 0, 0);	\	VBV_rdptr = VBV_wrptr;						\    }									\    buscon_xfer(xportv, BDMA_USEDX, VBV_wrptr, VBV_write, 1);		\} while (0)#define xporta_xfer_TDM()	do {					\    int i;								\    int space = ABV_rdptr - ABV_wrptr;					\    if (space <= 0) space += ABV_size;				  	\    if (space <= ABV_write) {						\	oh_my(0x17);							\	KEYDEBUGINC(1, ABV_overflow);					\	DBG_log_error(99, 2, space, VID_decoding_in_progress, 0, 0);	\	ABV_wrptr = ABV_rdptr;						\	for (i = 0; i < 2; i++) {					\	    ABV_wrptr += ABV_write;					\	    if (ABV_wrptr >= ABV_end) ABV_wrptr = ABV_start;		\	}								\	ABV_wrptr_save = ABV_wrptr;					\	BUF_ABV_overflow = 1;						\    }									\    buscon_xfer(xporta, BDMA_USEDX, ABV_wrptr, ABV_write, 1);		\    ABV_xfer_flag = 1;                                                  \} while (0)#elsevoid xportv_xfer_TDM(){    int space = VBV_rdptr - VBV_wrptr;    if (space <= 0) space += VBV_size;    if (space <= VBV_write) {	oh_my(0x16);	KEYDEBUGINC(1, VBV_overflow);	DBG_log_error(99, 1, space, VID_decoding_in_progress, 0, 0);	VBV_rdptr = VBV_wrptr;    }    buscon_xfer(xportv, BDMA_USEDX, VBV_wrptr, VBV_write, 1);}void xporta_xfer_TDM(){    int i;    int space = ABV_rdptr - ABV_wrptr;    if (space <= 0) space += ABV_size;    if (space <= ABV_write) {	oh_my(0x17);	KEYDEBUGINC(1, ABV_overflow);	DBG_log_error(99, 2, space, VID_decoding_in_progress, 0, 0);	/* 	 * Keep 2*ABV_write data in ABV so hufdeca can continue until	 * the next time we get into mpgaudio.	 */	ABV_wrptr = ABV_rdptr;	for (i = 0; i < 2; i++) {	    ABV_wrptr += ABV_write;	    if (ABV_wrptr >= ABV_end) ABV_wrptr = ABV_start;	}	ABV_wrptr_save = ABV_wrptr;	BUF_ABV_overflow = 1;    }    buscon_xfer(xporta, BDMA_USEDX, ABV_wrptr, ABV_write, 1);    ABV_xfer_flag = 1;}#endif#define xportv_xfer()	do {		\    if (is_TDM) xportv_xfer_TDM();	\    else xportv_xfer_non_TDM();		\} while (0);#define xporta_xfer()	do {		\    if (is_TDM) xporta_xfer_TDM();	\    else xporta_xfer_non_TDM();		\} while (0);#ifdef JPEG_DECvoid xportv_xfer_no_macro()    { xportv_xfer(); }#endif/****************************************************************************** Just finished a xport buscon to sys buff. Update sys buff write ptr. If xfer to huffdec is not running, start a new one. ******************************************************************************/#ifdef DUMP_VBV_WHEN_FULL#define VBV_wrap() do { 	\    static int fp = -1;		\    fp = DBG_dump_memory((char *)dram(VBV_start), 4*VBV_size, fp, "video.bit");\    VBV_wrptr = VBV_start;	\} while (0)#else#define VBV_wrap() VBV_wrptr = VBV_start#endif#ifdef DUMP_ABV_WHEN_FULL#define ABV_wrap() do { 	\    static int fp = -1;		\    fp = DBG_dump_memory((char *)dram(ABV_start), 4*ABV_size, fp, "audio.bit");\    ABV_wrptr = ABV_start;	\} while (0)#else#define ABV_wrap() ABV_wrptr = ABV_start#endif#ifdef WATCHDOG#define xportv_xfer_end()	do {				\    VBV_wrptr += VBV_write;					\    VBV_ABV_xport_xfer_count++;					\    if (VBV_wrptr == VBV_end) VBV_wrap();			\    DBG_log_buffer(20, VBV_write, VBV_wrptr, VBV_rdptr, 0, 0);	\    if (!VBV_draining) {					\	hufdecv_xfer();						\	if (VBV_draining) buscon_irq_enable(buscon_hufdecv_runbit);	\    }								\} while (0)#define xporta_xfer_end()	do {				\    ABV_wrptr += ABV_write;					\    VBV_ABV_xport_xfer_count++;					\    if (ABV_wrptr == ABV_end) ABV_wrap();			\    oh_my(0x10);						\    DBG_log_buffer(21, ABV_write, ABV_wrptr, ABV_rdptr, 0, 0);	\    if (CONDITION_FOR_HUFDECA_XFER) {				\	hufdeca_xfer();						\	if (ABV_draining) buscon_irq_enable(buscon_hufdeca_runbit);	\    }								\} while (0)#else#define xportv_xfer_end()	do {				\    VBV_wrptr += VBV_write;					\    if (VBV_wrptr == VBV_end) VBV_wrap();			\    DBG_log_buffer(20, VBV_write, VBV_wrptr, VBV_rdptr, 0, 0);	\    if (!VBV_draining) {					\	hufdecv_xfer();						\	if (VBV_draining) buscon_irq_enable(buscon_hufdecv_runbit);	\    }								\} while (0)#define xporta_xfer_end()	do {				\    ABV_wrptr += ABV_write;					\    if (ABV_wrptr == ABV_end) ABV_wrap();			\    oh_my(0x10);						\    DBG_log_buffer(21, ABV_write, ABV_wrptr, ABV_rdptr, 0, 0);	\    if (CONDITION_FOR_HUFDECA_XFER) {				\	hufdeca_xfer();						\	if (ABV_draining) buscon_irq_enable(buscon_hufdeca_runbit);	\    }								\} while (0)#endif/****************************************************************************** If there's enough data in sys buff and we're not CDDAing, initiate a xfer to huffdec,  ******************************************************************************/#ifdef XFER_USE_MACRO#define hufdecv_xfer()	do {						\    int data = VBV_wrptr - VBV_rdptr;					\    if (data < 0) data += VBV_size;					\    if (data >= VBV_read) {						\	buscon_xfer(hufdecv, BDMA_USEDX, VBV_rdptr, VBV_read, 1);	\    	VBV_draining = 1;						\    } else { 								\    	VBV_draining = 0;						\    }									\} while (0)#define hufdeca_xfer()	do {						\    int data;								\    if (CONDITION_FOR_HUFDECA_EXIT) break;				\    data = ABV_wrptr - ABV_rdptr;					\    if (data < 0) data += ABV_size;					\    if (data >= ABV_read) {						\	buscon_xfer(hufdeca, BDMA_USEDX, ABV_rdptr, ABV_read, 1);	\    	ABV_draining = 1;						\    } else {								\    	ABV_draining = 0;						\    }									\} while (0)#elsevoid hufdecv_xfer(){    int data = VBV_wrptr - VBV_rdptr;    if (data < 0) data += VBV_size;    if (data >= VBV_read) {	buscon_xfer(hufdecv, BDMA_USEDX, VBV_rdptr, VBV_read, 1);    	VBV_draining = 1;    } else {     	VBV_draining = 0;    }}void hufdeca_xfer(){    int data;    if (CONDITION_FOR_HUFDECA_EXIT) return;    data = ABV_wrptr - ABV_rdptr;    if (data < 0) data += ABV_size;    if (data >= ABV_read) {	buscon_xfer(hufdeca, BDMA_USEDX, ABV_rdptr, ABV_read, 1);    	ABV_draining = 1;    } else {    	ABV_draining = 0;    }}#endif/****************************************************************************** Just finished a xfer to huffdec. Update sys buff read ptr. If xport buscon is not running, start a new one. ******************************************************************************/#ifdef WATCHDOG #define hufdecv_xfer_end()	do {			\    VBV_rdptr += VBV_read;				\    VBV_ABV_huffman_xfer_count++;			\    if (VBV_rdptr == VBV_end) {				\	VBV_rdptr = VBV_start;				\	VBV_wrap_count++;				\    }							\    if (!VBV_filling) {					\	xportv_xfer();					\  	if (VBV_filling) buscon_irq_enable(buscon_xportv_runbit);	\    }							\} while (0)#define hufdeca_xfer_end()	do {			\    if (CONDITION_FOR_HUFDECA_EXIT) break;		\    ABV_rdptr += ABV_read;				\    VBV_ABV_huffman_xfer_count++;			\    if (ABV_rdptr == ABV_end) ABV_rdptr = ABV_start;	\    if (!ABV_filling) {					\	xporta_xfer();					\  	if (ABV_filling) buscon_irq_enable(buscon_xporta_runbit);	\    }							\} while (0)#else#define hufdecv_xfer_end()	do {			\    VBV_rdptr += VBV_read;				\    if (VBV_rdptr == VBV_end) {				\	VBV_rdptr = VBV_start;				\	VBV_wrap_count++;				\    }							\    if (!VBV_filling) {					\	xportv_xfer();					\  	if (VBV_filling) buscon_irq_enable(buscon_xportv_runbit);	\    }							\} while (0)#define hufdeca_xfer_end()	do {			\    if (CONDITION_FOR_HUFDECA_EXIT) break;		\    ABV_rdptr += ABV_read;				\    if (ABV_rdptr == ABV_end) ABV_rdptr = ABV_start;	\    if (!ABV_filling) {					\	xporta_xfer();					\  	if (ABV_filling) buscon_irq_enable(buscon_xporta_runbit);	\    }							\} while (0)#endif#ifdef JPEG_DECstatic int VBV_wrptr_save;/**************************************************************************** Kill the video xport buscon, then restart it again. If we don't have video huffdec buscon at this moment, kick it off. ****************************************************************************/void     VBV_flush_gateway(void){    if (dont_need_flush_video) return;    VBV_stop_filling();    VBV_wrptr_save = VBV_wrptr;    VBV_start_filling();    if (!VBV_draining) VBV_start_draining();}/**************************************************************************** Kill the video huffdec buscon, then restart it again. If we don't have video xport buscon at this moment, kick it off. ****************************************************************************/void    VBV_flush_cleanup(void){    if (dont_need_flush_video) return;    buscon_zap(hufdecv);    VBV_draining = 0;    VBV_rdptr = VBV_wrptr_save;    VBV_fullness = VBV_wrptr - VBV_rdptr;    if (VBV_fullness < 0) VBV_fullness += VBV_size;    VBV_start_draining();    if (!VBV_filling) VBV_start_filling();}#endif JPEG_DEC/**************************************************************************** Set various VBV/ABV operating parameters. In TDM mode a new xport buscon is started when the previous one finishes, no matter what. The system buffer will overflow if we're draining it too slow. Also when decoding from a file we disable the overflow-prevention mechanism. ****************************************************************************/void	VBV_ABV_set_parameters(int xfer_mode){    if (xfer_mode==0) {	VBV_alarm = 0;    }}/**************************************************************************** Start xportv buscon for the first time. For TDM once we start a xport buscon it self-sustains forever. ****************************************************************************/void	VBV_start_filling(void){    xportv_xfer();    buscon_irq_enable(buscon_xportv_runbit);    if (is_TDM) VBV_filling = 1;}/**************************************************************************** Start xporta buscon for the first time. For TDM once we start a xport buscon it self-sustains forever. ****************************************************************************/void	ABV_start_filling(void){    xporta_xfer();    buscon_irq_enable(buscon_xporta_runbit);    if (is_TDM) ABV_filling = 1;}#ifndef VCDLCvoid    ABV_start_draining(void){    hufdeca_xfer();    if (ABV_draining) {        buscon_irq_enable(buscon_hufdeca_runbit);    }}#endif/**************************************************************************** Start hufdecv_xfer for the first time. This is only used in the power-up logo whence we fill the VBV manually. ****************************************************************************/void	VBV_start_draining(void){    hufdecv_xfer();    if (VBV_draining) {    	buscon_irq_enable(buscon_hufdecv_runbit);    } else {    	assert(0);    }}/**************************************************************************** Kill the audio xport buscon. You should first stop the xport before doing this. We will flush the xport fifo and then the gateway fifo,

⌨️ 快捷键说明

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