2025-04-27 07:49:33 -04:00

321 lines
12 KiB
C

//----------------------------------------------------------------------------
// STPIPE.C
//----------------------------------------------------------------------------
// Description : Pipeline Control routines
//----------------------------------------------------------------------------
// Copyright SGS Thomson Microelectronics ! Version alpha ! Jan 1st, 1995
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Include files
//----------------------------------------------------------------------------
#include "stdefs.h"
#include "common.h"
#include "STllapi.h"
#include "debug.h"
#ifdef STi3520A
#include "STi3520A.h"
#else
#include "STi3520.h"
#endif
//----------------------------------------------------------------------------
// GLOBAL Variables (avoid as possible)
//----------------------------------------------------------------------------
extern U8 Sequence;
//----------------------------------------------------------------------------
// Private Constants
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Private Types
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Private GLOBAL Variables (static)
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Functions (statics one are private)
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Set next reconstructed,forward and backward frame pointer
//----------------------------------------------------------------------------
VOID VideoSetRecons(PVIDEO pVideo)
{
/************************ I or P pictures ****************************/
if ( pVideo->pDecodedPict->pict_type != 0x3 )
{
if ( pVideo->frameStoreAttr == FORWARD_PRED ) /* pVideo->frameStoreAttr is the prediction
* attribute of BUFF_A */
{
if ( pVideo->fieldMode < 2 )
pVideo->frameStoreAttr = BACKWARD_PRED;
/* Change the prediction attribute */
if ( ( pVideo->fieldMode == 0 ) || ( pVideo->fieldMode == 2 ) )
// frame picture or first field of 2 field pictures
VideoStoreRFBBuf ( pVideo, pVideo->BufferA, pVideo->BufferB, pVideo->BufferB );
// rfp = A, ffp = bfp = B
else // second field of 2 field
// pictures
VideoStoreRFBBuf (pVideo, pVideo->BufferA, pVideo->BufferB, pVideo->BufferA );
// rfp = A, ffp = B, bfp = A
}
else
{
if ( pVideo->fieldMode < 2 ) // frame picture or 2 field
pVideo->frameStoreAttr = FORWARD_PRED;/* Change the prediction */
if ( ( pVideo->fieldMode == 0 ) || ( pVideo->fieldMode == 2 ) )
// frame picture or first field of 2 field pictures
VideoStoreRFBBuf (pVideo, pVideo->BufferB, pVideo->BufferA, pVideo->BufferA );
// rfp = B, ffp = bfp = A
else // seond field of 2 field
// pictures
VideoStoreRFBBuf (pVideo, pVideo->BufferB, pVideo->BufferA, pVideo->BufferB );
// rfp = B, ffp = A, bfp = B
}
}
/************************ B pictures ****************************/
else
{ /* B picture */
if ( pVideo->frameStoreAttr == FORWARD_PRED )
VideoStoreRFBBuf (pVideo, pVideo->BufferC, pVideo->BufferA, pVideo->BufferB );
else
VideoStoreRFBBuf ( pVideo, pVideo->BufferC, pVideo->BufferB, pVideo->BufferA );
}
/*********** common for all kind of pictures *********************/
/* test if displayed frame = reconstructed frame */
if ( ( pVideo->pCurrDisplay->buffer == pVideo->pDecodedPict->buffer ) && ( pVideo->currPictCount >= 4 ) && !pVideo->fieldMode )
pVideo->NextInstr.Ovw = 1;/* overwrite mode */
else
pVideo->NextInstr.Ovw = 0;/* not overwite mode */
}
//----------------------------------------------------------------------------
// Store reconstructed,forward and backward frame pointers */
//----------------------------------------------------------------------------
void VideoStoreRFBBuf ( PVIDEO pVideo, U16 rfp, U16 ffp, U16 bfp )
{
VideoWrite ( RFP, ( rfp >> 8 ) );
/* Address where to decode the next frame */
VideoWrite ( RFP + 1, ( rfp & 0xFF ) );
pVideo->pDecodedPict->buffer = rfp;
VideoWrite ( FFP, ( ffp >> 8 ) );
/* Used by P picture */
VideoWrite ( FFP + 1, ( ffp & 0xFF ) );
VideoWrite ( BFP, ( bfp >> 8 ) );
/* Used by P picture in case of dual prime */
VideoWrite ( BFP + 1, ( bfp & 0xFF ) );
}
//----------------------------------------------------------------------------
// Routine called on each VSYNC occurence
//----------------------------------------------------------------------------
VOID VideoVsyncRout(PVIDEO pVideo)
{
pVideo->VsyncInterrupt = TRUE;
if ( pVideo->VideoState == VIDEO_START_UP )
{
if ((VideoGetBBL()) > 2)
{
pVideo->NextInstr.Exe = 1;
pVideo->NextInstr.Seq = 1;
VideoStoreINS(pVideo); // Stores Instruction content
pVideo->VideoState = VIDEO_WAIT_FOR_DTS;
pVideo->ActiveState = VIDEO_WAIT_FOR_DTS;
}
return;
}
#if 0
if ( pVideo->VideoState == VIDEO_INIT )
{
pVideo->intMask = 0;
return;
}
#endif
if ( pVideo->VideoState == VIDEO_PAUSE )
return;
if ( ( !pVideo->needDataInBuff ) && ( pVideo->vbvReached == 1 ) )
{
pVideo->VsyncNumber++;
if ( pVideo->VsyncNumber > 4 * ( pVideo->decSlowDown + 1 ) )
{
VideoPipeReset (pVideo);
// reset_3500();
pVideo->VsyncNumber = 0;
}
VideoWrite ( DCF, 0 );
VideoWrite ( DCF + 1, pVideo->currDCF );
/***** bit buffer level is high enough to continue normal decoding and display ****/
/***** count of the number of time the current picture must be displayed ****/
if ( pVideo->pictDispIndex != pVideo->pCurrDisplay->nb_display_field )
pVideo->pictDispIndex++;
if ( pVideo->pictDispIndex >= pVideo->pCurrDisplay->nb_display_field - 1 )
{
// this is the time where the next INS should be stored
// into the chip
// We verify if the VSYNC phase (cur_field) is the same
// than the first field
// of the next picture to be displayed: if this is VSYNC #
// n, the next
// decoding will start on VSYNC # n+1 (opposite phase)
// while the next frame
// display will start on VSYNC # n+2 (same phase)
#ifdef STi3520A
/************* Youss R/2P buffer saving ***************************/
// If First Vsync after vbv is reached is of incorrect polarity,
// Program internal field inversion AND force first field to current
// field
// FistVsyncAfterVbv is a 3 state variable
// before vbv is reached FistVsyncAfterVbv = NOT_YET_VBV
// between vbv and following vsync FistVsyncAfterVbv = NOT_YET_VST
// after vsync following vbv FistVsyncAfterVbv = PAST_VBV_AND_VST
if (pVideo->FistVsyncAfterVbv == NOT_YET_VST)
{
if ( pVideo->pNextDisplay->first_field != pVideo->currField )
{
pVideo->currField = pVideo->pNextDisplay->first_field;
VideoWrite(VID_LSRh, 2);// field invertion mechanism.
pVideo->InvertedField = TRUE;
}
pVideo->FistVsyncAfterVbv = PAST_VBV_AND_VST;
}
#endif
if ( pVideo->pNextDisplay->first_field != pVideo->currField )
{ // this is the opposite phase
VideoWaitDec (pVideo); // put decoder in wait mode
pVideo->pictDispIndex--; // we must wait one field for
// the good phase
}
else
{ // this is the good phase for
// storage
// store the next instruction that will be taken into
// account on the next BOT VSYNC
VideoStoreINS ( pVideo );
if ( pVideo->VideoState == VIDEO_STEP ) /* store only one
* instrcution in step
* mode */
pVideo->VideoState = VIDEO_PAUSE;
}
}
// the current frame pointer has not been displayed enough
// times
// to start the decoding of the next frame
else // pVideo->pictDispIndex <
{ // pVideo->pCurrDisplay->nb_display_fi
// eld - 1
VideoWaitDec ( pVideo ); // put decoder in Wait mode
}
/* pan & scan vector has to be updated on each new VSYNC */
VideoSetPSV ( pVideo ); // store PSV for next field and
// LSO for current one
} // end of if(!empty)
else
/*** bit buffer level was not high enough to continue normal decoding *****/
/*** decoder has been stopped during PSD interrupt. It will be re-enabled */
/*** on the good VSYNC if the bit buffer level is high enough. ****/
/*** Polarity of the VSYNC on which the decoder was stopped is into empty */
if ( pVideo->needDataInBuff == pVideo->currField )
{
/* This is the good VSYNC phase to restart decoding */
/* verification of the bit buffer level before restarting */
/* the decoder has been stopped for at least two VSYNC */
S16 i;
i = VideoGetBBL();
if ( i >= (S16)pVideo->vbvDelay )
{ // BBL is high enough to restart
// "enable decoding" bit
DBG1('>');
VideoEnableDecoding(pVideo, ON);
pVideo->needDataInBuff = 0;
}
}
}
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
VOID VideoChooseField(PVIDEO pVideo)
{
// to avoid flicker with slow motion or step by step, the top field is displayed
// half of the time of the picture, and then the bottom field is displayed
if ( ( pVideo->decSlowDown ) || ( pVideo->VideoState == VIDEO_PAUSE )||(pVideo->perFrame == TRUE ))
{
S16 no_flicker[2];
U8 bfs = 0;
#ifdef STi3520A
bfs = VideoRead(CFG_BFS)&0x3F;// To check if B frame optimization is on
#endif
no_flicker[0] = VideoRead ( DCF );
no_flicker[1] = VideoRead ( DCF + 1 );
if ( pVideo->HalfRes == FALSE ) /* full resolution
* picture = 2 fields */
{
if ( ( ( ( ( pVideo->pictDispIndex + pVideo->decSlowDown ) > 0x7fff ) || ( pVideo->pictDispIndex == 1 ) ) && ( pVideo->VideoState != VIDEO_PAUSE ) )
|| ( ( pVideo->VideoState == VIDEO_PAUSE ) && ( !pVideo->displaySecondField ) ) )
{
/* display first field in two cases */
/* - first half of the pVideo->decSlowDownrisation time */
/* - first step() pVideo->currCommand */
if ( pVideo->pCurrDisplay->first_field == TOP )
{ /* first field = TOP field */
if(!bfs)
VideoWrite ( DCF, 0x4 );//FRZ set for STi3520A
else
VideoWrite ( DCF, 0x15 );//FRZ set for STi3520A
VideoWrite ( DCF + 1, no_flicker[1] | 0x80 );
}
else
{ /* first field = BOT field */
if(!bfs)
VideoWrite ( DCF, 0x5 );
else
VideoWrite ( DCF, 0x14 );//FRZ set for STi3520A
VideoWrite ( DCF + 1, no_flicker[1] | 0x80 );
}
}
else
{
/* display second field in two cases */
/* - second half of the pVideo->decSlowDownrisation time */
/* - second step() pVideo->currCommand */
if ( pVideo->pCurrDisplay->first_field == TOP )
{
if(!bfs)
VideoWrite ( DCF, 0x5);
else
VideoWrite ( DCF, 0x15 );//FRZ set for STi3520A
VideoWrite ( DCF + 1, no_flicker[1] | 0x80 );
}
else
{
if(!bfs)
VideoWrite ( DCF, 0x4);
else
VideoWrite ( DCF, 0x14 );//FRZ set for STi3520A
VideoWrite ( DCF + 1, no_flicker[1] | 0x80 );
}
}
}
}
}
//------------------------------- End of File --------------------------------