395 lines
8 KiB
C
395 lines
8 KiB
C
|
//
|
|||
|
// MODULE : DMPEG.C
|
|||
|
// PURPOSE : Entry point to lowlevel driver
|
|||
|
// AUTHOR : JBS Yadawa
|
|||
|
// CREATED : 7/20/96
|
|||
|
//
|
|||
|
//
|
|||
|
// Copyright (C) 1996 SGS-THOMSON Microelectronics
|
|||
|
//
|
|||
|
//
|
|||
|
// REVISION HISTORY :
|
|||
|
//
|
|||
|
// DATE :
|
|||
|
//
|
|||
|
// COMMENTS :
|
|||
|
//
|
|||
|
|
|||
|
#include "common.h"
|
|||
|
#include "dmpeg.h"
|
|||
|
#include "memio.h"
|
|||
|
#include "codedma.h"
|
|||
|
#include "sti3520A.h"
|
|||
|
#include "staudio.h"
|
|||
|
#include "board.h"
|
|||
|
#include "error.h"
|
|||
|
#include "debug.h"
|
|||
|
#include "i20reg.h"
|
|||
|
#include "zac3.h"
|
|||
|
#include "staudio.h"
|
|||
|
|
|||
|
#define CTRL_POWER_UP 0 // After reset
|
|||
|
#define CTRL_INIT 1 // Initialisation + test of the decoders
|
|||
|
#define CTRL_READY 2 // File openned
|
|||
|
#define CTRL_INIT_SYNC 3 // Initial sync.: defines start of audio and video
|
|||
|
#define CTRL_DECODE 4 // Normal decode
|
|||
|
#define CTRL_IDLE 5 // idle state
|
|||
|
|
|||
|
#define SLOW_MODE 0
|
|||
|
#define PLAY_MODE 1
|
|||
|
#define FAST_MODE 2
|
|||
|
|
|||
|
|
|||
|
CARD Card, *pCard = NULL;
|
|||
|
CTRL Ctrl, *pCtrl;
|
|||
|
DWORD OldlatchedSTC;
|
|||
|
DWORD OldvideoPTS;
|
|||
|
|
|||
|
static BOOL Avsync;
|
|||
|
static BOOL synchronizing;
|
|||
|
|
|||
|
static BYTE *tmpBuf;
|
|||
|
static ULONG tmpBase;
|
|||
|
static DWORD tmpAdr;
|
|||
|
|
|||
|
static BYTE I20Intr;
|
|||
|
static BOOL IntCtrl(void);
|
|||
|
static BYTE Irq;
|
|||
|
|
|||
|
BOOL dmpgOpen(ULONG Base, BYTE *DmaBuf, DWORD PhysicalAddress)
|
|||
|
{
|
|||
|
BOOL Found=FALSE;
|
|||
|
|
|||
|
|
|||
|
tmpBuf = DmaBuf;
|
|||
|
tmpBase = Base;
|
|||
|
tmpAdr = PhysicalAddress;
|
|||
|
|
|||
|
if(!BoardOpen(Base))
|
|||
|
{
|
|||
|
DPF((Trace,"Board initialization failed!!\n"));
|
|||
|
}
|
|||
|
// Open Audio and Video
|
|||
|
pCard = &Card;
|
|||
|
pCard->pVideo = &(pCard->Video);
|
|||
|
VideoOpen();
|
|||
|
pCard->pAudio = &(pCard->Audio);
|
|||
|
AudioOpen (pCard->pAudio);
|
|||
|
pCtrl = &Ctrl;
|
|||
|
pCtrl->ErrorMsg = NO_ERROR;
|
|||
|
pCtrl->CtrlState = CTRL_POWER_UP;
|
|||
|
pCtrl->AudioOn = FALSE;
|
|||
|
pCtrl->VideoOn = FALSE;
|
|||
|
Avsync = FALSE;
|
|||
|
|
|||
|
BoardDisableIRQ();
|
|||
|
VideoInitDecoder(DUAL_PES);// Initialise video in PES by default
|
|||
|
pCtrl->CtrlState = CTRL_INIT_SYNC;
|
|||
|
VideoInitPesParser(VIDEO_STREAM);
|
|||
|
InitAC3Decoder();
|
|||
|
AudioInitPesParser(AUDIO_STREAM);
|
|||
|
BoardEnableIRQ();
|
|||
|
VideoMaskInt (); // Restore Video interrupt mask
|
|||
|
DPF((Trace,"Calling Code DMA open!!\n"));
|
|||
|
return CodeDmaOpen(DmaBuf, PhysicalAddress);
|
|||
|
}
|
|||
|
|
|||
|
BOOL dmpgClose(void)
|
|||
|
{
|
|||
|
DPF((Trace,"dmpgClose!!\n"));
|
|||
|
if(pCard == NULL)
|
|||
|
return FALSE;
|
|||
|
VideoClose( );
|
|||
|
AudioClose( );
|
|||
|
BoardClose();
|
|||
|
CodeDmaClose();
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL dmpgPlay()
|
|||
|
{
|
|||
|
DPF((Trace,"dmpgPlay!!\n"));
|
|||
|
if(pCard == NULL)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
VideoRestoreInt (); // Restore Video interrupt mask
|
|||
|
pCtrl->DecodeMode = PLAY_MODE;
|
|||
|
AudioSetMode(pCtrl->DecodeMode, 0);
|
|||
|
VideoSetMode(pCtrl->DecodeMode, 0);
|
|||
|
if (pCtrl->CtrlState == CTRL_IDLE)
|
|||
|
pCtrl->CtrlState = CTRL_DECODE;
|
|||
|
VideoDecode();
|
|||
|
AudioDecode();
|
|||
|
AC3Command(AC3_UNMUTE); //ckw
|
|||
|
AC3Command(AC3_PLAY); //ckw
|
|||
|
AudioTransfer(TRUE); //ckw
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void dmpgReset(void)
|
|||
|
{
|
|||
|
dmpgPause();
|
|||
|
dmpgSeek();
|
|||
|
VideoMaskInt();
|
|||
|
}
|
|||
|
|
|||
|
BOOL dmpgPause(void)
|
|||
|
{
|
|||
|
DPF((Trace,"dmpgPause!!\n"));
|
|||
|
|
|||
|
if(pCard == NULL)
|
|||
|
return FALSE;
|
|||
|
switch(pCtrl->CtrlState)
|
|||
|
{
|
|||
|
case CTRL_POWER_UP:
|
|||
|
case CTRL_INIT:
|
|||
|
case CTRL_READY:
|
|||
|
break;
|
|||
|
case CTRL_INIT_SYNC:
|
|||
|
AudioPause();
|
|||
|
VideoPause();
|
|||
|
AudioTransfer(FALSE); //ckw
|
|||
|
AC3Command(AC3_MUTE); //ckw
|
|||
|
pCtrl->AudioOn = FALSE;
|
|||
|
pCtrl->VideoOn = FALSE;
|
|||
|
pCtrl->ActiveState = CTRL_INIT_SYNC;
|
|||
|
pCtrl->CtrlState = CTRL_IDLE;
|
|||
|
break;
|
|||
|
case CTRL_DECODE:
|
|||
|
AudioPause();
|
|||
|
VideoPause();
|
|||
|
AudioTransfer(FALSE); //ckw
|
|||
|
AC3Command(AC3_MUTE); //ckw
|
|||
|
|
|||
|
pCtrl->ActiveState = CTRL_DECODE;
|
|||
|
pCtrl->CtrlState = CTRL_IDLE;
|
|||
|
break;
|
|||
|
case CTRL_IDLE:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL dmpgSeek(void)
|
|||
|
{
|
|||
|
|
|||
|
DPF((Trace,"dmpgSeek!!\n"));
|
|||
|
if(pCard == NULL)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
CodeDmaFlush();
|
|||
|
pCtrl->CtrlState = CTRL_INIT_SYNC;
|
|||
|
VideoSeekDecoder(DUAL_PES);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL dmpgStop(void)
|
|||
|
{
|
|||
|
|
|||
|
DPF((Trace,"dmpgStop!!\n"));
|
|||
|
if(pCard == NULL)
|
|||
|
return FALSE;
|
|||
|
VideoMaskInt();
|
|||
|
dmpgPause();
|
|||
|
// dmpgClose();
|
|||
|
// dmpgOpen(tmpBase, tmpBuf, tmpAdr);
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
UINT dmpgSendVideo(BYTE *pPacket, DWORD uLen)
|
|||
|
{
|
|||
|
// DPF((Trace,"dmpgSendVideo!!\n"));
|
|||
|
UINT uRet;
|
|||
|
|
|||
|
if(pCard == NULL)
|
|||
|
return FALSE;
|
|||
|
|
|||
|
|
|||
|
uRet = (UINT)CodeDmaSendData(pPacket, uLen);
|
|||
|
|
|||
|
return uRet;
|
|||
|
}
|
|||
|
|
|||
|
UINT dmpgSendAudio(BYTE *pPacket, DWORD uLen)
|
|||
|
{
|
|||
|
|
|||
|
LONG abl, abf;
|
|||
|
|
|||
|
// DPF((Trace,"dmpgSendAudio!!\n"));
|
|||
|
if(pCard == NULL)
|
|||
|
return 0;
|
|||
|
abl = VideoGetABL();
|
|||
|
if((LONG)pCard->pVideo->AudioBufferSize - abl <= 2L)
|
|||
|
{
|
|||
|
// DebugPrint((DebugLevelTrace, "Audio Buffer FULL!!\n"));
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
abf = (pCard->pVideo->AudioBufferSize - abl -1) << 8;
|
|||
|
// DebugPrint((DebugLevelError,"SendAudio : %X %X %X %X %X %X, BBL = %x Size = %x\n",pPacket[0], pPacket[1], pPacket[2], pPacket[3], pPacket[4], pPacket[5], abl, pCard->pVideo->AudioBufferSize));
|
|||
|
if(abf < uLen)
|
|||
|
{
|
|||
|
SendAC3Data(pPacket, abf);
|
|||
|
return abf;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
SendAC3Data(pPacket, uLen);
|
|||
|
return uLen;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
BOOL dmpgInterrupt(void)
|
|||
|
{
|
|||
|
BOOL bRet = FALSE;
|
|||
|
|
|||
|
I20Intr = memInByte(I20_INTRSTATUS);
|
|||
|
memOutByte(I20_INTRSTATUS, I20Intr);
|
|||
|
|
|||
|
if(I20Intr & IFLAG_CODEDMA)
|
|||
|
{
|
|||
|
bRet = TRUE;
|
|||
|
CodeDmaInterrupt();
|
|||
|
}
|
|||
|
|
|||
|
if(I20Intr & IFLAG_GIRQ1)
|
|||
|
{
|
|||
|
bRet = TRUE;
|
|||
|
IntCtrl();
|
|||
|
}
|
|||
|
return bRet;
|
|||
|
}
|
|||
|
|
|||
|
void dmpgEnableIRQ()
|
|||
|
{
|
|||
|
DPF((Trace,"IrqEnabled!!\n"));
|
|||
|
VideoRestoreInt();
|
|||
|
BoardEnableIRQ();
|
|||
|
}
|
|||
|
|
|||
|
void dmpgDisableIRQ()
|
|||
|
{
|
|||
|
DPF((Trace,"IrqDisabled!!\n"));
|
|||
|
VideoMaskInt();
|
|||
|
BoardDisableIRQ();
|
|||
|
}
|
|||
|
|
|||
|
void CtrlInitSync(void)
|
|||
|
{
|
|||
|
switch (pCtrl->CtrlState) {
|
|||
|
case CTRL_INIT_SYNC:
|
|||
|
/*
|
|||
|
Initial synchronisation: the video decoder is always started.
|
|||
|
In case of system stream, the STC is initialised in interrupt with first
|
|||
|
video PTS available the video state becomes VIDEO_DECODE
|
|||
|
When the STC becomes equal (or higher) than the first Audio PTS the audio
|
|||
|
decoding can be enabled
|
|||
|
In case of Audio only bitstreams the video is stopped and audio enabled
|
|||
|
In case of Video only bitstreams, the video decoding continues while
|
|||
|
audio is disabled
|
|||
|
*/
|
|||
|
if (VideoGetState() == StateDecode) {
|
|||
|
// the STC is initialized in interrupt with (first video PTS - 3 fields)
|
|||
|
DWORD Stc;
|
|||
|
DWORD PtsAudio;
|
|||
|
Stc = AudioGetSTC();
|
|||
|
if (AudioIsFirstPTS()) {
|
|||
|
PtsAudio = AudioGetPTS();
|
|||
|
// if (Stc >= PtsAudio)
|
|||
|
{
|
|||
|
// AudioDecode();
|
|||
|
pCtrl->CtrlState = CTRL_DECODE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
pCtrl->ErrorMsg = VideoGetErrorMsg();
|
|||
|
break;
|
|||
|
|
|||
|
case CTRL_DECODE: // Audio and Video decoders are running
|
|||
|
if (pCtrl->ErrorMsg == NO_ERROR)
|
|||
|
pCtrl->ErrorMsg = VideoGetErrorMsg();
|
|||
|
if (pCtrl->ErrorMsg == NO_ERROR)
|
|||
|
pCtrl->ErrorMsg = AudioGetErrorMsg();
|
|||
|
break;
|
|||
|
|
|||
|
default :
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static BOOL IntCtrl(void)
|
|||
|
{
|
|||
|
long diff;
|
|||
|
WORD lattency;
|
|||
|
BOOL STIntr = FALSE;
|
|||
|
|
|||
|
BoardEnterInterrupt();
|
|||
|
VideoMaskInt();
|
|||
|
// AudioMaskInt();
|
|||
|
|
|||
|
// STIntr|=AudioAudioInt();
|
|||
|
STIntr = VideoVideoInt();
|
|||
|
|
|||
|
if (Avsync) {
|
|||
|
CtrlInitSync();
|
|||
|
if (VideoIsFirstDTS()) {
|
|||
|
// True only on the start of decode of the first picture with an assoicated valid PTS
|
|||
|
DWORD FirstStc;
|
|||
|
|
|||
|
FirstStc = VideoGetFirstDTS();
|
|||
|
AudioInitSTC(FirstStc);
|
|||
|
synchronizing = 0;
|
|||
|
}
|
|||
|
|
|||
|
if (AudioGetState() == AUDIO_DECODE) {
|
|||
|
if (VideoIsFirstField()) {
|
|||
|
synchronizing++;
|
|||
|
if (synchronizing >= 20)
|
|||
|
{
|
|||
|
// We must verify the synchronisation of the video on the audio STC
|
|||
|
DWORD latchedSTC, videoPTS;
|
|||
|
WORD mode;
|
|||
|
|
|||
|
latchedSTC = AudioGetVideoSTC();
|
|||
|
videoPTS = VideoGetPTS();
|
|||
|
mode =pCard->pVideo->StreamInfo.displayMode;
|
|||
|
lattency = 2200; /* 1.5 field duration for 60 Hz video */
|
|||
|
if (mode == 0) {
|
|||
|
lattency = 2700; /* 1.5 field duration for 50 Hz video */
|
|||
|
}
|
|||
|
diff = latchedSTC - videoPTS;
|
|||
|
OldlatchedSTC = latchedSTC;
|
|||
|
OldvideoPTS = videoPTS;
|
|||
|
|
|||
|
//---- If desynchronized
|
|||
|
if (labs(diff) > (long)lattency) {
|
|||
|
if (diff < 0)
|
|||
|
{
|
|||
|
VideoRepeat ();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
VideoSkip ();
|
|||
|
}
|
|||
|
}
|
|||
|
synchronizing = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
BoardLeaveInterrupt();
|
|||
|
VideoRestoreInt();
|
|||
|
// AudioRestoreInt();
|
|||
|
return STIntr;
|
|||
|
}
|
|||
|
|
|||
|
|