📄 ig_render.cpp
字号:
/*****************************************************************************
******************************************************************************
** **
** Copyright (c) 2005-2006 Videon Central, Inc. **
** All rights reserved. **
** **
** The computer program contained herein contains proprietary information **
** which is the property of Videon Central, Inc. The program may be used **
** and/or copied only with the written permission of Videon Central, Inc. **
** or in accordance with the terms and conditions stipulated in the **
** agreement/contract under which the programs have been supplied. **
** **
******************************************************************************
*****************************************************************************/
/**
* @file ig_render.cpp
*
* $Revision: 1.7 $
*
* render functions for the IG module
*
*/
#include "vcitypes.h"
#include "ig_defs.h"
#include "ig_parse.h"
#include "ig_util.h"
#include "ig_render.h"
#include "directfb.h"
#include "ig_graphics.h"
#include "utility.h"
#include "qa.h" /* for qa automation */
#define DEBUG_IG_RENDER DBG_ERROR
#define DBG_ON(x) (DEBUG_IG_RENDER >= x)
/* local prototypes */
static IG_STATUS IGWaitForPTS(ULONG PTS);
static IG_STATUS IGDoICSUpdate(INTERACTIVE_COMPOSITION_SEGMENT *ICSUpdate, int *UpdatedActivePage);
static IG_STATUS IGRenderEffectsSequence(EFFECT_SEQUENCE *Sequence);
static IG_STATUS IGUpdateOverOldPAGE(PAGE *NewPage, PAGE *OldPage);
static IG_STATUS IGICSDrawPage(PAGE *Page, int DoEffectsIn);
static IG_STATUS IGRenderEffect(EFFECT *Effect);
static IG_STATUS IGPSR10Procedure(PAGE *Page, ULONG PSR10);
static IG_STATUS IGFindButtonInBogsByID(PAGE* Page, USHORT ButtonID, BUTTON **Button, int *BogIndex);
static IG_STATUS IGFindButtonInBogsByNumber(PAGE* Page, USHORT ButtonNumber, BUTTON **Button, int *BogIndex);
static IG_STATUS IGDoButtonSelection(PAGE *Page, USHORT PSR10);
static IG_STATUS IGCopyBogs(PAGE *Dest, PAGE *Src);
static IG_STATUS IGEnableDefaultButtonsOnPage(PAGE *Page);
static IG_STATUS IGCompareButtonToDefaultValid(PAGE* Page, USHORT ButtonID, BUTTON **Button);
static IG_STATUS IGHasValidDefaultButtonID(PAGE* Page, BUTTON **Button);
static IG_STATUS IGDefaultSelectionIsButtonID(PAGE* Page, BUTTON **Button);
static IG_STATUS IGStartAnimation(PAGE *Page);
static USHORT IGGetBogIndex(PAGE *Page, USHORT ButtonID);
static void IGFreeBogs(PAGE *Page);
static void IGDisableBog(BUTTON_OVERLAP_GROUP *Bog, int NumButtons, USHORT ExceptionButtonID);
static void IGDisableAllButtonsOnPage(PAGE *Page);
/* print info */
#if DBG_ON(DBG_TRACE)
static void PrintICS(INTERACTIVE_COMPOSITION_SEGMENT *ICS);
static void PrintPages(PAGE *Pages, BYTE NumPages, int indent);
static void PrintBogs(BUTTON_OVERLAP_GROUP *Bogs, BYTE NumBogs, int indent);
static void PrintButton(BUTTON *Button, int indent);
#endif
/* calls that call the PE */
static IG_STATUS IGToPEICSValid(IG_ICSVALID_EVENT_INFO *Info);
static IG_STATUS IGToPEPageSelect(IG_PAGE_SELECT_EVENT_INFO *Info);
static IG_STATUS IGToPEButtonSelect(BUTTON *pButton);
static IG_STATUS IGToPEButtonActivate(BUTTON *pButton, PVOID pContext);
/* frame rates x 1000 for integer math */
ULONG VideoFrameRates[] = {0, 23976, 24000, 25000, 29970, 0, 50000, 59940, 0, 0, 0, 0, 0, 0, 0, 0};
/* extern'd */
extern PALETTE IGPalettes[IG_MAX_PALETTES];
extern IGINFO IGInfo;
extern int gWaitForFrame;
#define IsPopup() ((IGInfo.ICS->StreamAndUIModel & BIT6) ? 1 : 0)
#define IsOutMux() ((IGInfo.ICS->StreamAndUIModel & BIT7) ? 1 : 0)
/**
* IGRender - The render task for the IG module
*
* @param PVOID pvParam - NULL
*
* @return IG_STATUS
*/
ULONG IGRender(PVOID pvParam)
{
IG_RENDER_MSG *pMessage = NULL;
/* keep on requesint pts's till we are signal'd to stop */
while (IG_FLAGS_EXIT != IGInfo.QuitFlags)
{
/* Get a stream message */
pMessage = (IG_RENDER_MSG *)IGInfo.IGRenderQ->Read(OS_WAIT_FOREVER);
if (NULL == pMessage)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGRender(): Null RenderQ Message\n"));
OS_TaskYield();
continue;
}
/* pts check */
if (NULL == pMessage->ICS)
{
IGInfo.IGRenderQ->ReleaseMsg(pMessage);
pMessage = NULL;
OS_TaskYield();
continue;
}
IGWaitForPTS(pMessage->PTSRenderTime);
/* check quit flags */
if (IG_STATE_RUNNING != IGInfo.CurrentState)
{
/* free the memory */
IGFreeICS(pMessage->ICS);
IGInfo.IGRenderQ->ReleaseMsg(pMessage);
pMessage = NULL;
OS_TaskYield();
continue;
}
/* render the display update */
RenderICS(pMessage->ICS);
/* finished with it now */
IGInfo.IGRenderQ->ReleaseMsg(pMessage);
pMessage = NULL;
}
DBGPRINT(DBG_ON(DBG_ERROR), ("IGRender(): Leaving Task\n"));
OS_TaskExit();
return IG_STATUS_SUCCESS;
}
/**
* RenderICS - begin processing the Interactive Composition Segment
*
* @param ICS *ICS - The ICS object to render
*
* @return IG_STATUS
*/
IG_STATUS RenderICS(INTERACTIVE_COMPOSITION_SEGMENT *ICS)
{
IG_ICSVALID_EVENT_INFO PSRInfo;
IG_PAGE_SELECT_EVENT_INFO PageSelectInfo;
int fDidICSUpdate=0;
int UpdateActivePage=0;
int CurrentLevel = -1;
DBGPRINT(DBG_ON(DBG_TRACE), ("--RenderICS(): Num pages %d, state: %d\n", ICS->NumPages, ICS->CompDesc.CompositionState));
OS_SemTake(IGInfo.ICSLock, OS_WAIT_FOREVER);
/* check if this is an update */
if (IGInfo.ICS)
{
if (COMP_STATE_EPOCH_START == ICS->CompDesc.CompositionState)
{
/* reset IG state related to current ICS */
IGICSReset();
}
else
{
/* update the current ICS */
IGDoICSUpdate(ICS, &UpdateActivePage);
/* we updated the current ICS */
fDidICSUpdate = 1;
}
}
/* if we didn't do an update then this a new ICS */
if (0 == fDidICSUpdate)
{
/* do we already have an ICS? free it first if so */
if (IGInfo.ICS)
{
/* reset IG state related to current ICS */
IGICSReset();
}
/* attach new ICS */
IGInfo.ICS = ICS;
IGInfo.SelectionTimedout = 0;
}
/* fire PE Events to get the PSR info */
IGToPEICSValid(&PSRInfo);
/* set the size of the display layer */
IGInfo.IGDFBInfo.ScreenWidth = IGInfo.ICS->VideoDesc.Width;
IGInfo.IGDFBInfo.ScreenHeight = IGInfo.ICS->VideoDesc.Height;
/* get level, if it's not IG_DISPLAY_LEVEL, then set it */
IGInfo.IGDFBInfo.DispLayer->GetLevel(IGInfo.IGDFBInfo.DispLayer, &CurrentLevel);
/* if this is a popup and popups are enabled then setlevel up */
if ( (IsPopup() && IGInfo.fPopupEnabled) || (IsPopup() == 0))
{
if (CurrentLevel != IG_DISPLAY_LEVEL)
{
if (DFB_OK != IGInfo.IGDFBInfo.DispLayer->SetLevel(IGInfo.IGDFBInfo.DispLayer, IG_DISPLAY_LEVEL))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("RenderICS(): Failed to set the level to IG_DISPLAY_LEVEL\n"));
}
}
}
else
{
if (CurrentLevel != IG_DISPLAY_NO_SHOW)
{
if (DFB_OK != IGInfo.IGDFBInfo.DispLayer->SetLevel(IGInfo.IGDFBInfo.DispLayer, IG_DISPLAY_NO_SHOW))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("RenderICS(): Failed to set the level to IG_DISPLAY_NO_SHOW\n"));
}
}
}
/* if we did an update and the update changed the page currently displayed, then we need to redraw the page */
if ((fDidICSUpdate == 1) && (UpdateActivePage == 1))
{
/* updateing the current active page, must clear the screen first */
OS_SemTake(IGInfo.BlitLock, OS_WAIT_FOREVER);
IGGraphicsClearBuffer(NULL, 1);
/* tell the PE about this page and get PSR10 */
PageSelectInfo.pPage = IGInfo.ActivePage;
IGToPEPageSelect(&PageSelectInfo);
/* enable default buttons and tell PE about the page */
IGICSDrawPage(IGInfo.ActivePage, 1);
/* highlight the selected button on the page */
IGDoButtonSelection(IGInfo.ActivePage, (USHORT)(PageSelectInfo.PSR10));
/* set the palette */
IGGraphicsSetPalette(&IGPalettes[IGInfo.ActivePage->PaletteIDRef]);
OS_SemGive(IGInfo.BlitLock);
}
else if (0 == fDidICSUpdate)
{
/* spec 8.8.4.7.2.2, if stream model is set to 1 and we are in a popup, we don't display anything,
so just store the ICS, don't render it until we get a popup on */
if (IsPopup() && IsOutMux())
{
/* clear the selected page and button by setting to NULL,
we will enable these on a popup on command */
/* no selected page */
IGInfo.ActivePage = NULL;
PageSelectInfo.pPage = IGInfo.ActivePage;
IGToPEPageSelect(&PageSelectInfo);
/* no selected button */
IGInfo.SelectedButton = NULL;
IGToPEButtonSelect(IGInfo.SelectedButton);
OS_SemGive(IGInfo.ICSLock);
return IG_STATUS_SUCCESS;
}
if ((IGInfo.ICS->NumPages > 0) && (NULL != &IGInfo.ICS->Pages[0]))
{
IGInfo.ActivePage = &IGInfo.ICS->Pages[0];
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("RenderICS(): There are no pages in this ICS\n"));
/* no selected page */
IGInfo.ActivePage = NULL;
PageSelectInfo.pPage = IGInfo.ActivePage;
IGToPEPageSelect(&PageSelectInfo);
/* no selected button */
IGInfo.SelectedButton = NULL;
IGToPEButtonSelect(IGInfo.SelectedButton);
OS_SemGive(IGInfo.ICSLock);
return IG_STATUS_SUCCESS;
}
/* if we are supposed to be a startup menu condition then spin wait for pts's*/
if (IGInfo.SyncState == IG_DECODE_ASYNC)
{
/* give lock while we wait */
OS_SemGive(IGInfo.ICSLock);
/* otherwise wait for first PTS to be given after the IGRun call */
while ((gWaitForFrame > 0) && (IGInfo.CurrentState == IG_STATE_RUNNING))
{
OS_TaskYield();
}
/* take lock back */
OS_SemTake(IGInfo.ICSLock, OS_WAIT_FOREVER);
/* don't bother drawing the first frame */
if ( (IGInfo.ICS == NULL) || (IGInfo.CurrentState != IG_STATE_RUNNING) )
{
OS_SemGive(IGInfo.ICSLock);
return IG_STATUS_SUCCESS;
}
}
/* tell the PE about this page and get PSR10 */
PageSelectInfo.pPage = IGInfo.ActivePage;
IGToPEPageSelect(&PageSelectInfo);
/* draw page zero, this is the first draw of the new ICS */
OS_SemTake(IGInfo.BlitLock, OS_WAIT_FOREVER);
IGICSDrawPage(IGInfo.ActivePage, 1);
/* highlight the selected button on the page */
IGDoButtonSelection(IGInfo.ActivePage, (USHORT)(PageSelectInfo.PSR10));
/* set the palette */
IGGraphicsSetPalette(&IGPalettes[IGInfo.ActivePage->PaletteIDRef]);
OS_SemGive(IGInfo.BlitLock);
/* NOTE: the composition timeout and selection timeouts are only valid when
the stream model is '0' (multiplexed). If the stream is not multiplexed (preloaded)
then consider it a menu which is always valid for doing things like chapter searches
while watching the movie. */
if (0 == (IGInfo.ICS->StreamAndUIModel & BIT7))
{
/* composition timeout */
DBGPRINT(DBG_ON(DBG_TRACE), ("RenderICS(): Composition Timeout 0x%x\n", IGInfo.ICS->CompositionTimeoutPTS));
IGInfo.CompositionTimeoutPTS = IGInfo.ICS->CompositionTimeoutPTS;
/* selection timeout */
DBGPRINT(DBG_ON(DBG_TRACE), ("RenderICS(): Selection Timeout 0x%x\n", IGInfo.ICS->SelectionTimeoutPTS));
IGInfo.SelectionTimeoutPTS = IGInfo.ICS->SelectionTimeoutPTS;
}
else
{
IGInfo.CompositionTimeoutPTS = 0;
IGInfo.SelectionTimeoutPTS = 0;
}
}
/* show the page */
OS_TimerSet(IGInfo.TimerFlip, 1);
OS_TaskYield();
/* start any animations if any */
IGStartAnimation(IGInfo.ActivePage);
/* free the lock we are done */
OS_SemGive(IGInfo.ICSLock);
return IG_STATUS_SUCCESS;
}
/**
* IGICSReset - clear out state info about the current ICS, this is done in IGRenderICS when we get a new ICS
*
* @param none
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -