📄 buffer.c
字号:
/* SCCSID @(#)buffer.c 1.97 4/17/98 *//* * $Log$ */#include "common.h"#include "debug.h"#include "util.h"#include "low.h"#include "dsc.h"#include "buffer.h"#include "vp.h"#include "vcxi.h"#include "tdm.h"#include "sysinfo.h"#include "xport.h"#ifdef MPEG1#ifdef SVCD#include "mpegvid.h"#else#include "mpeg1vid.h"#endif#else#include "mpeg2vid.h"#endif#ifdef AC3#include "ac3.h"#else#include "mpgaudio.h"#endif#ifdef ECHO#include "echo.h"#endif#ifdef SPDIF#include "ioport.h"#endif#ifdef SPATIAL#include "kara.h"#endif/**************************************************************************** Local defines. ****************************************************************************/#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. ****************************************************************************/#ifdef MVD_BOARDstatic int is_TDM;#else#define is_TDM 1#endif#ifdef DVD_VCD#include "talk.h"static int a_xfer_cnt;static int ABV_is_full;#define check_abv_full() do { \ if (!ABV_is_full) { \ ABV_is_full = 1;; \ a_xfer_cnt = 1; \ } else a_xfer_cnt++; \} while (0)#define A_XFER_LIMIT 3500#define A_EMPTY_SLOT 1176 /* dword */#define check_abv_ok() do { \ if ((ABV_size - data) >= (A_EMPTY_SLOT + ABV_write)) { \ if (ABV_is_full && (a_xfer_cnt > A_XFER_LIMIT)) { \ ABV_is_full = 0; a_xfer_cnt = 0; \ tell_master_sbv_is_full(0); \ } \ } \} while (0)#endif/****************************************************************************** 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); \} while (0)#ifdef MVD_BOARD#define xportv_xfer_non_TDM() do { \ int space = VBV_rdptr - VBV_wrptr; \ if (space <= 0) space += VBV_size; \ if (space > VBV_write) { \ buscon_xfer(xportv, BDMA_USEDX, VBV_wrptr, VBV_write, 1); \ VBV_filling = 1; \ } else { \ VBV_filling = 0; \ } \ } while (0)#define xporta_xfer_non_TDM() do { \ int space = ABV_rdptr - ABV_wrptr; \ if (space <= 0) space += ABV_size; \ if (space > ABV_write) { \ buscon_xfer(xporta, BDMA_USEDX, ABV_wrptr, ABV_write, 1); \ ABV_filling = 1; \ } else { \ ABV_filling = 0; \ } \} while (0)#endif#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;#ifdef DVD_VCD if (TDM_isCDDA) /* since the data input rate is not same as the ouput data, we need to do checking and inform master to send more. */ check_abv_full();#endif 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);}#ifdef MVD_BOARDvoid xportv_xfer_non_TDM(){ int space = VBV_rdptr - VBV_wrptr; if (space <= 0) space += VBV_size; if (space > VBV_write) { buscon_xfer(xportv, BDMA_USEDX, VBV_wrptr, VBV_write, 1); VBV_filling = 1; } else { VBV_filling = 0; }}void xporta_xfer_non_TDM(){ int space = ABV_rdptr - ABV_wrptr; if (space <= 0) space += ABV_size; if (space > ABV_write) { buscon_xfer(xporta, BDMA_USEDX, ABV_wrptr, ABV_write, 1); ABV_filling = 1; } else { ABV_filling = 0; }}#endif#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);/****************************************************************************** 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 ((!TDM_isCDDA)&&(!ABV_draining)) { \ 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 ((!TDM_isCDDA)&&(!ABV_draining)) { \ 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 (TDM_isCDDA) 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 (TDM_isCDDA) 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; }}#ifdef DVD_VCDvoid ABV_check_underflow(){ int data; data = ABV_wrptr - ABV_rdptr; check_abv_ok();}#endif#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; \ if (!VBV_filling) { \ xportv_xfer(); \ if (VBV_filling) buscon_irq_enable(buscon_xportv_runbit); \ } \} while (0)#define hufdeca_xfer_end() do { \ if (TDM_isCDDA) 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -